public override void WriteBytes(byte[] buffer, int offset)
 {
     for (int index = 0; index < m_entries.Count; index++)
     {
         FileStreamEntry entry       = m_entries[index];
         int             entryLength = entry.PaddedLength;
         entry.NextEntryOffset = (index < m_entries.Count - 1) ? (uint)entryLength : 0;
         entry.WriteBytes(buffer, offset);
         offset += entryLength;
     }
 }
 public FileStreamInformation(byte[] buffer, int offset)
 {
     if (offset < buffer.Length)
     {
         FileStreamEntry entry;
         do
         {
             entry = new FileStreamEntry(buffer, offset);
             m_entries.Add(entry);
             offset += (int)entry.NextEntryOffset;
         }while (entry.NextEntryOffset != 0);
     }
 }
 public override void WriteBytes(byte[] buffer, int offset)
 {
     for (int index = 0; index < m_entries.Count; index++)
     {
         FileStreamEntry entry = m_entries[index];
         entry.WriteBytes(buffer, offset);
         int entryLength = entry.Length;
         offset += entryLength;
         if (index < m_entries.Count - 1)
         {
             // [MS-FSCC] When multiple FILE_STREAM_INFORMATION data elements are present in the buffer, each MUST be aligned on an 8-byte boundary
             int padding = (8 - (entryLength % 8)) % 8;
             offset += padding;
         }
     }
 }
        public NTStatus GetFileInformation(out FileInformation result, object handle, FileInformationClass informationClass)
        {
            FileHandle      fileHandle = (FileHandle)handle;
            string          path       = fileHandle.Path;
            FileSystemEntry entry;

            try
            {
                entry = m_fileSystem.GetEntry(path);
            }
            catch (Exception ex)
            {
                NTStatus status = ToNTStatus(ex);
                Log(Severity.Verbose, "GetFileInformation on '{0}' failed. {1}", path, status);
                result = null;
                return(status);
            }

            if (entry == null)
            {
                result = null;
                return(NTStatus.STATUS_NO_SUCH_FILE);
            }

            switch (informationClass)
            {
            case FileInformationClass.FileBasicInformation:
            {
                FileBasicInformation information = new FileBasicInformation();
                information.CreationTime   = entry.CreationTime;
                information.LastAccessTime = entry.LastAccessTime;
                information.LastWriteTime  = entry.LastWriteTime;
                information.ChangeTime     = entry.LastWriteTime;
                information.FileAttributes = GetFileAttributes(entry);
                result = information;
                return(NTStatus.STATUS_SUCCESS);
            }

            case FileInformationClass.FileStandardInformation:
            {
                FileStandardInformation information = new FileStandardInformation();
                information.AllocationSize = (long)GetAllocationSize(entry.Size);
                information.EndOfFile      = (long)entry.Size;
                information.Directory      = entry.IsDirectory;
                information.DeletePending  = fileHandle.DeleteOnClose;
                result = information;
                return(NTStatus.STATUS_SUCCESS);
            }

            case FileInformationClass.FileInternalInformation:
            {
                FileInternalInformation information = new FileInternalInformation();
                result = information;
                return(NTStatus.STATUS_SUCCESS);
            }

            case FileInformationClass.FileEaInformation:
            {
                FileEaInformation information = new FileEaInformation();
                information.EaSize = 0;
                result             = information;
                return(NTStatus.STATUS_SUCCESS);
            }

            case FileInformationClass.FileAccessInformation:
            {
                result = null;
                return(NTStatus.STATUS_NOT_IMPLEMENTED);
            }

            case FileInformationClass.FileNameInformation:
            {
                FileNameInformation information = new FileNameInformation();
                information.FileName = entry.Name;
                result = information;
                return(NTStatus.STATUS_SUCCESS);
            }

            case FileInformationClass.FilePositionInformation:
            {
                result = null;
                return(NTStatus.STATUS_NOT_IMPLEMENTED);
            }

            case FileInformationClass.FileFullEaInformation:
            {
                result = null;
                return(NTStatus.STATUS_NOT_IMPLEMENTED);
            }

            case FileInformationClass.FileModeInformation:
            {
                result = null;
                return(NTStatus.STATUS_NOT_IMPLEMENTED);
            }

            case FileInformationClass.FileAlignmentInformation:
            {
                result = null;
                return(NTStatus.STATUS_NOT_IMPLEMENTED);
            }

            case FileInformationClass.FileAllInformation:
            {
                FileAllInformation information = new FileAllInformation();
                information.BasicInformation.CreationTime      = entry.CreationTime;
                information.BasicInformation.LastAccessTime    = entry.LastAccessTime;
                information.BasicInformation.LastWriteTime     = entry.LastWriteTime;
                information.BasicInformation.ChangeTime        = entry.LastWriteTime;
                information.BasicInformation.FileAttributes    = GetFileAttributes(entry);
                information.StandardInformation.AllocationSize = (long)GetAllocationSize(entry.Size);
                information.StandardInformation.EndOfFile      = (long)entry.Size;
                information.StandardInformation.Directory      = entry.IsDirectory;
                information.StandardInformation.DeletePending  = fileHandle.DeleteOnClose;
                information.NameInformation.FileName           = entry.Name;
                result = information;
                return(NTStatus.STATUS_SUCCESS);
            }

            case FileInformationClass.FileAlternateNameInformation:
            {
                result = null;
                return(NTStatus.STATUS_NOT_IMPLEMENTED);
            }

            case FileInformationClass.FileStreamInformation:
            {
                // This information class is used to enumerate the data streams of a file or a directory.
                // A buffer of FileStreamInformation data elements is returned by the server.
                FileStreamInformation information = new FileStreamInformation();
                FileStreamEntry       streamEntry = new FileStreamEntry();
                streamEntry.StreamSize           = (long)entry.Size;
                streamEntry.StreamAllocationSize = (long)GetAllocationSize(entry.Size);
                streamEntry.StreamName           = "::$DATA";
                information.Entries.Add(streamEntry);
                result = information;
                return(NTStatus.STATUS_SUCCESS);
            }

            case FileInformationClass.FilePipeInformation:
            {
                result = null;
                return(NTStatus.STATUS_NOT_IMPLEMENTED);
            }

            case FileInformationClass.FilePipeLocalInformation:
            {
                result = null;
                return(NTStatus.STATUS_NOT_IMPLEMENTED);
            }

            case FileInformationClass.FilePipeRemoteInformation:
            {
                result = null;
                return(NTStatus.STATUS_NOT_IMPLEMENTED);
            }

            case FileInformationClass.FileCompressionInformation:
            {
                result = null;
                return(NTStatus.STATUS_NOT_IMPLEMENTED);
            }

            case FileInformationClass.FileNetworkOpenInformation:
            {
                FileNetworkOpenInformation information = new FileNetworkOpenInformation();
                information.CreationTime   = entry.CreationTime;
                information.LastAccessTime = entry.LastAccessTime;
                information.LastWriteTime  = entry.LastWriteTime;
                information.ChangeTime     = entry.LastWriteTime;
                information.AllocationSize = (long)GetAllocationSize(entry.Size);
                information.EndOfFile      = (long)entry.Size;
                information.FileAttributes = GetFileAttributes(entry);
                result = information;
                return(NTStatus.STATUS_SUCCESS);
            }

            case FileInformationClass.FileAttributeTagInformation:
            {
                result = null;
                return(NTStatus.STATUS_NOT_IMPLEMENTED);
            }

            default:
                result = null;
                return(NTStatus.STATUS_INVALID_INFO_CLASS);
            }
        }
        public NTStatus GetFileInformation(out FileInformation result, object handle, FileInformationClass informationClass)
        {
            FileHandle      fileHandle = (FileHandle)handle;
            string          path       = fileHandle.Path;
            FileSystemEntry entry;

            try
            {
                entry = m_fileSystem.GetEntry(path);
            }
            catch (Exception ex)
            {
                if (ex is IOException || ex is UnauthorizedAccessException)
                {
                    NTStatus status = ToNTStatus(ex);
                    Log(Severity.Verbose, "GetFileInformation on '{0}' failed. {1}", path, status);
                    result = null;
                    return(status);
                }
                else
                {
                    throw;
                }
            }

            switch (informationClass)
            {
            case FileInformationClass.FileBasicInformation:
            {
                FileBasicInformation information = new FileBasicInformation();
                information.CreationTime   = entry.CreationTime;
                information.LastAccessTime = entry.LastAccessTime;
                information.LastWriteTime  = entry.LastWriteTime;
                information.ChangeTime     = entry.LastWriteTime;
                information.FileAttributes = GetFileAttributes(entry);
                result = information;
                return(NTStatus.STATUS_SUCCESS);
            }

            case FileInformationClass.FileStandardInformation:
            {
                FileStandardInformation information = new FileStandardInformation();
                information.AllocationSize = (long)GetAllocationSize(entry.Size);
                information.EndOfFile      = (long)entry.Size;
                information.Directory      = entry.IsDirectory;
                information.DeletePending  = fileHandle.DeleteOnClose;
                result = information;
                return(NTStatus.STATUS_SUCCESS);
            }

            case FileInformationClass.FileInternalInformation:
            {
                FileInternalInformation information = new FileInternalInformation();
                result = information;
                return(NTStatus.STATUS_SUCCESS);
            }

            case FileInformationClass.FileEaInformation:
            {
                FileEaInformation information = new FileEaInformation();
                information.EaSize = 0;
                result             = information;
                return(NTStatus.STATUS_SUCCESS);
            }

            case FileInformationClass.FileAccessInformation:
            {
                result = null;
                return(NTStatus.STATUS_NOT_IMPLEMENTED);
            }

            case FileInformationClass.FileNameInformation:
            {
                FileNameInformation information = new FileNameInformation();
                information.FileName = entry.Name;
                result = information;
                return(NTStatus.STATUS_SUCCESS);
            }

            case FileInformationClass.FilePositionInformation:
            {
                result = null;
                return(NTStatus.STATUS_NOT_IMPLEMENTED);
            }

            case FileInformationClass.FileFullEaInformation:
            {
                result = null;
                return(NTStatus.STATUS_NOT_IMPLEMENTED);
            }

            case FileInformationClass.FileModeInformation:
            {
                result = null;
                return(NTStatus.STATUS_NOT_IMPLEMENTED);
            }

            case FileInformationClass.FileAlignmentInformation:
            {
                result = null;
                return(NTStatus.STATUS_NOT_IMPLEMENTED);
            }

            case FileInformationClass.FileAllInformation:
            {
                FileAllInformation information = new FileAllInformation();
                information.BasicInformation.CreationTime      = entry.CreationTime;
                information.BasicInformation.LastAccessTime    = entry.LastAccessTime;
                information.BasicInformation.LastWriteTime     = entry.LastWriteTime;
                information.BasicInformation.ChangeTime        = entry.LastWriteTime;
                information.BasicInformation.FileAttributes    = GetFileAttributes(entry);
                information.StandardInformation.AllocationSize = (long)GetAllocationSize(entry.Size);
                information.StandardInformation.EndOfFile      = (long)entry.Size;
                information.StandardInformation.Directory      = entry.IsDirectory;
                information.StandardInformation.DeletePending  = fileHandle.DeleteOnClose;
                information.NameInformation.FileName           = entry.Name;
                result = information;
                return(NTStatus.STATUS_SUCCESS);
            }

            case FileInformationClass.FileAlternateNameInformation:
            {
                // If there is no alternate name Windows will return STATUS_OBJECT_NAME_NOT_FOUND
                result = null;
                return(NTStatus.STATUS_OBJECT_NAME_NOT_FOUND);
            }

            case FileInformationClass.FileStreamInformation:
            {
                // This information class is used to enumerate the data streams of a file or a directory.
                // A buffer of FileStreamInformation data elements is returned by the server.
                FileStreamInformation information = new FileStreamInformation();
                List <KeyValuePair <string, ulong> > dataStreams = m_fileSystem.ListDataStreams(fileHandle.Path);
                foreach (KeyValuePair <string, ulong> dataStream in dataStreams)
                {
                    FileStreamEntry streamEntry = new FileStreamEntry();
                    ulong           streamSize  = dataStream.Value;
                    streamEntry.StreamSize           = (long)streamSize;
                    streamEntry.StreamAllocationSize = (long)GetAllocationSize(streamSize);
                    streamEntry.StreamName           = dataStream.Key;
                    information.Entries.Add(streamEntry);
                }
                result = information;
                return(NTStatus.STATUS_SUCCESS);
            }

            case FileInformationClass.FilePipeInformation:
            {
                result = null;
                return(NTStatus.STATUS_NOT_IMPLEMENTED);
            }

            case FileInformationClass.FilePipeLocalInformation:
            {
                result = null;
                return(NTStatus.STATUS_NOT_IMPLEMENTED);
            }

            case FileInformationClass.FilePipeRemoteInformation:
            {
                result = null;
                return(NTStatus.STATUS_NOT_IMPLEMENTED);
            }

            case FileInformationClass.FileCompressionInformation:
            {
                result = null;
                return(NTStatus.STATUS_NOT_IMPLEMENTED);
            }

            case FileInformationClass.FileNetworkOpenInformation:
            {
                FileNetworkOpenInformation information = new FileNetworkOpenInformation();
                information.CreationTime   = entry.CreationTime;
                information.LastAccessTime = entry.LastAccessTime;
                information.LastWriteTime  = entry.LastWriteTime;
                information.ChangeTime     = entry.LastWriteTime;
                information.AllocationSize = (long)GetAllocationSize(entry.Size);
                information.EndOfFile      = (long)entry.Size;
                information.FileAttributes = GetFileAttributes(entry);
                result = information;
                return(NTStatus.STATUS_SUCCESS);
            }

            case FileInformationClass.FileAttributeTagInformation:
            {
                result = null;
                return(NTStatus.STATUS_NOT_IMPLEMENTED);
            }

            default:
                result = null;
                return(NTStatus.STATUS_INVALID_INFO_CLASS);
            }
        }