Esempio n. 1
0
        public NTStatus QueryDirectory(out List <QueryDirectoryFileInformation> result, object handle, string fileName, FileInformationClass informationClass)
        {
            IO_STATUS_BLOCK ioStatusBlock;

            byte[]         buffer            = new byte[4096];
            UNICODE_STRING fileNameStructure = new UNICODE_STRING(fileName);

            result = new List <QueryDirectoryFileInformation>();
            bool restartScan = true;

            while (true)
            {
                NTStatus status = NtQueryDirectoryFile((IntPtr)handle, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, out ioStatusBlock, buffer, (uint)buffer.Length, (byte)informationClass, false, ref fileNameStructure, restartScan);
                if (status == NTStatus.STATUS_NO_MORE_FILES)
                {
                    break;
                }
                else if (status != NTStatus.STATUS_SUCCESS)
                {
                    return(status);
                }
                int numberOfBytesWritten = (int)ioStatusBlock.Information;
                buffer = ByteReader.ReadBytes(buffer, 0, numberOfBytesWritten);
                List <QueryDirectoryFileInformation> page = QueryDirectoryFileInformation.ReadFileInformationList(buffer, 0, informationClass);
                result.AddRange(page);
                restartScan = false;
            }
            fileNameStructure.Dispose();
            return(NTStatus.STATUS_SUCCESS);
        }
        public List <QueryDirectoryFileInformation> GetFileInformationList(FileInformationClass fileInformationClass)
        {
            if (OutputBuffer.Length > 0)
            {
                return(QueryDirectoryFileInformation.ReadFileInformationList(OutputBuffer, 0, fileInformationClass));
            }

            return(new List <QueryDirectoryFileInformation>());
        }
Esempio n. 3
0
        private static List <QueryDirectoryFileInformation> FromFileSystemEntries(List <FileSystemEntry> entries, FileInformationClass informationClass)
        {
            List <QueryDirectoryFileInformation> result = new List <QueryDirectoryFileInformation>();

            foreach (FileSystemEntry entry in entries)
            {
                QueryDirectoryFileInformation information = FromFileSystemEntry(entry, informationClass);
                result.Add(information);
            }
            return(result);
        }
 public void SetFileInformationList(List <QueryDirectoryFileInformation> fileInformationList)
 {
     OutputBuffer = QueryDirectoryFileInformation.GetBytes(fileInformationList);
 }
Esempio n. 5
0
 /// <exception cref="SmbLibraryStd.UnsupportedInformationLevelException"></exception>
 public static FindInformation ToFindInformation(QueryDirectoryFileInformation fileInformation)
 {
     if (fileInformation is FileDirectoryInformation)
     {
         FileDirectoryInformation fileDirectoryInfo = (FileDirectoryInformation)fileInformation;
         FindFileDirectoryInfo    result            = new FindFileDirectoryInfo();
         result.FileIndex          = fileDirectoryInfo.FileIndex;
         result.CreationTime       = fileDirectoryInfo.CreationTime;
         result.LastAccessTime     = fileDirectoryInfo.LastAccessTime;
         result.LastWriteTime      = fileDirectoryInfo.LastWriteTime;
         result.LastAttrChangeTime = fileDirectoryInfo.LastWriteTime;
         result.EndOfFile          = fileDirectoryInfo.EndOfFile;
         result.AllocationSize     = fileDirectoryInfo.AllocationSize;
         result.ExtFileAttributes  = (ExtendedFileAttributes)fileDirectoryInfo.FileAttributes;
         result.FileName           = fileDirectoryInfo.FileName;
         return(result);
     }
     else if (fileInformation is FileFullDirectoryInformation)
     {
         FileFullDirectoryInformation fileFullDirectoryInfo = (FileFullDirectoryInformation)fileInformation;
         FindFileFullDirectoryInfo    result = new FindFileFullDirectoryInfo();
         result.FileIndex          = fileFullDirectoryInfo.FileIndex;
         result.CreationTime       = fileFullDirectoryInfo.CreationTime;
         result.LastAccessTime     = fileFullDirectoryInfo.LastAccessTime;
         result.LastWriteTime      = fileFullDirectoryInfo.LastWriteTime;
         result.LastAttrChangeTime = fileFullDirectoryInfo.LastWriteTime;
         result.EndOfFile          = fileFullDirectoryInfo.EndOfFile;
         result.AllocationSize     = fileFullDirectoryInfo.AllocationSize;
         result.ExtFileAttributes  = (ExtendedFileAttributes)fileFullDirectoryInfo.FileAttributes;
         result.EASize             = fileFullDirectoryInfo.EaSize;
         result.FileName           = fileFullDirectoryInfo.FileName;
         return(result);
     }
     else if (fileInformation is FileNamesInformation)
     {
         FileNamesInformation fileNamesInfo = (FileNamesInformation)fileInformation;
         FindFileNamesInfo    result        = new FindFileNamesInfo();
         result.FileIndex = fileNamesInfo.FileIndex;
         result.FileName  = fileNamesInfo.FileName;
         return(result);
     }
     else if (fileInformation is FileBothDirectoryInformation)
     {
         FileBothDirectoryInformation fileBothDirectoryInfo = (FileBothDirectoryInformation)fileInformation;
         FindFileBothDirectoryInfo    result = new FindFileBothDirectoryInfo();
         result.FileIndex         = fileBothDirectoryInfo.FileIndex;
         result.CreationTime      = fileBothDirectoryInfo.CreationTime;
         result.LastAccessTime    = fileBothDirectoryInfo.LastAccessTime;
         result.LastWriteTime     = fileBothDirectoryInfo.LastWriteTime;
         result.LastChangeTime    = fileBothDirectoryInfo.LastWriteTime;
         result.EndOfFile         = fileBothDirectoryInfo.EndOfFile;
         result.AllocationSize    = fileBothDirectoryInfo.AllocationSize;
         result.ExtFileAttributes = (ExtendedFileAttributes)fileBothDirectoryInfo.FileAttributes;
         result.EASize            = fileBothDirectoryInfo.EaSize;
         result.Reserved          = fileBothDirectoryInfo.Reserved;
         result.ShortName         = fileBothDirectoryInfo.ShortName;
         result.FileName          = fileBothDirectoryInfo.FileName;
         return(result);
     }
     else if (fileInformation is FileIdFullDirectoryInformation)
     {
         FileIdFullDirectoryInformation fileIDFullDirectoryInfo = (FileIdFullDirectoryInformation)fileInformation;
         FindFileIDFullDirectoryInfo    result = new FindFileIDFullDirectoryInfo();
         result.FileIndex          = fileIDFullDirectoryInfo.FileIndex;
         result.CreationTime       = fileIDFullDirectoryInfo.CreationTime;
         result.LastAccessTime     = fileIDFullDirectoryInfo.LastAccessTime;
         result.LastWriteTime      = fileIDFullDirectoryInfo.LastWriteTime;
         result.LastAttrChangeTime = fileIDFullDirectoryInfo.LastWriteTime;
         result.EndOfFile          = fileIDFullDirectoryInfo.EndOfFile;
         result.AllocationSize     = fileIDFullDirectoryInfo.AllocationSize;
         result.ExtFileAttributes  = (ExtendedFileAttributes)fileIDFullDirectoryInfo.FileAttributes;
         result.EASize             = fileIDFullDirectoryInfo.EaSize;
         result.Reserved           = fileIDFullDirectoryInfo.Reserved;
         result.FileID             = fileIDFullDirectoryInfo.FileId;
         result.FileName           = fileIDFullDirectoryInfo.FileName;
         return(result);
     }
     else if (fileInformation is FileIdBothDirectoryInformation)
     {
         FileIdBothDirectoryInformation fileIDBothDirectoryInfo = (FileIdBothDirectoryInformation)fileInformation;
         FindFileIDBothDirectoryInfo    result = new FindFileIDBothDirectoryInfo();
         result.FileIndex         = fileIDBothDirectoryInfo.FileIndex;
         result.CreationTime      = fileIDBothDirectoryInfo.CreationTime;
         result.LastAccessTime    = fileIDBothDirectoryInfo.LastAccessTime;
         result.LastWriteTime     = fileIDBothDirectoryInfo.LastWriteTime;
         result.LastChangeTime    = fileIDBothDirectoryInfo.LastWriteTime;
         result.EndOfFile         = fileIDBothDirectoryInfo.EndOfFile;
         result.AllocationSize    = fileIDBothDirectoryInfo.AllocationSize;
         result.ExtFileAttributes = (ExtendedFileAttributes)fileIDBothDirectoryInfo.FileAttributes;
         result.EASize            = fileIDBothDirectoryInfo.EaSize;
         result.Reserved          = fileIDBothDirectoryInfo.Reserved1;
         result.ShortName         = fileIDBothDirectoryInfo.ShortName;
         result.Reserved2         = fileIDBothDirectoryInfo.Reserved2;
         result.FileID            = fileIDBothDirectoryInfo.FileId;
         result.FileName          = fileIDBothDirectoryInfo.FileName;
         return(result);
     }
     else
     {
         throw new NotImplementedException();
     }
 }
        internal static SMB2Command GetQueryDirectoryResponse(QueryDirectoryRequest request, ISMBShare share, SMB2ConnectionState state)
        {
            SMB2Session    session  = state.GetSession(request.Header.SessionID);
            OpenFileObject openFile = session.GetOpenFileObject(request.FileId);

            if (openFile == null)
            {
                state.LogToServer(Severity.Verbose, "Query Directory failed. Invalid FileId. (SessionID: {0}, TreeID: {1}, FileId: {2})", request.Header.SessionID, request.Header.TreeID, request.FileId.Volatile);
                return(new ErrorResponse(request.CommandName, NTStatus.STATUS_FILE_CLOSED));
            }

            if (!((FileSystemShare)share).HasReadAccess(session.SecurityContext, openFile.Path))
            {
                state.LogToServer(Severity.Verbose, "Query Directory on '{0}{1}' failed. User '{2}' was denied access.", share.Name, openFile.Path, session.UserName);
                return(new ErrorResponse(request.CommandName, NTStatus.STATUS_ACCESS_DENIED));
            }

            FileSystemShare fileSystemShare = (FileSystemShare)share;

            FileID     fileID     = request.FileId;
            OpenSearch openSearch = session.GetOpenSearch(fileID);

            if (openSearch == null || request.Reopen)
            {
                if (request.Reopen)
                {
                    session.RemoveOpenSearch(fileID);
                }
                List <QueryDirectoryFileInformation> entries;
                NTStatus searchStatus = share.FileStore.QueryDirectory(out entries, openFile.Handle, request.FileName, request.FileInformationClass);
                if (searchStatus != NTStatus.STATUS_SUCCESS)
                {
                    state.LogToServer(Severity.Verbose, "Query Directory on '{0}{1}', Searched for '{2}', NTStatus: {3}", share.Name, openFile.Path, request.FileName, searchStatus.ToString());
                    return(new ErrorResponse(request.CommandName, searchStatus));
                }
                state.LogToServer(Severity.Information, "Query Directory on '{0}{1}', Searched for '{2}', found {3} matching entries", share.Name, openFile.Path, request.FileName, entries.Count);
                openSearch = session.AddOpenSearch(fileID, entries, 0);
            }

            if (request.Restart || request.Reopen)
            {
                openSearch.EnumerationLocation = 0;
            }

            if (openSearch.Entries.Count == 0)
            {
                // [MS-SMB2] If there are no entries to return [..] the server MUST fail the request with STATUS_NO_SUCH_FILE.
                session.RemoveOpenSearch(fileID);
                return(new ErrorResponse(request.CommandName, NTStatus.STATUS_NO_SUCH_FILE));
            }

            if (openSearch.EnumerationLocation == openSearch.Entries.Count)
            {
                return(new ErrorResponse(request.CommandName, NTStatus.STATUS_NO_MORE_FILES));
            }

            List <QueryDirectoryFileInformation> page = new List <QueryDirectoryFileInformation>();
            int pageLength = 0;

            for (int index = openSearch.EnumerationLocation; index < openSearch.Entries.Count; index++)
            {
                QueryDirectoryFileInformation fileInformation = openSearch.Entries[index];
                if (fileInformation.FileInformationClass != request.FileInformationClass)
                {
                    // We do not support changing FileInformationClass during a search (unless SMB2_REOPEN is set).
                    return(new ErrorResponse(request.CommandName, NTStatus.STATUS_INVALID_PARAMETER));
                }

                int entryLength = fileInformation.Length;
                if (pageLength + entryLength <= request.OutputBufferLength)
                {
                    page.Add(fileInformation);
                    int paddedLength = (int)Math.Ceiling((double)entryLength / 8) * 8;
                    pageLength += paddedLength;
                    openSearch.EnumerationLocation = index + 1;
                }
                else
                {
                    break;
                }

                if (request.ReturnSingleEntry)
                {
                    break;
                }
            }

            QueryDirectoryResponse response = new QueryDirectoryResponse();

            response.SetFileInformationList(page);
            return(response);
        }
Esempio n. 7
0
        /// <exception cref="SMBLibrary.UnsupportedInformationLevelException"></exception>
        public static FindInformation GetFindInformation(QueryDirectoryFileInformation entry, FindInformationLevel informationLevel, bool isUnicode, bool returnResumeKeys)
        {
            switch (informationLevel)
            {
            case FindInformationLevel.SMB_FIND_FILE_DIRECTORY_INFO:
            {
                FileDirectoryInformation fileDirectoryInfo = (FileDirectoryInformation)entry;

                FindFileDirectoryInfo result = new FindFileDirectoryInfo();
                result.FileIndex          = fileDirectoryInfo.FileIndex;
                result.CreationTime       = fileDirectoryInfo.CreationTime;
                result.LastAccessTime     = fileDirectoryInfo.LastAccessTime;
                result.LastWriteTime      = fileDirectoryInfo.LastWriteTime;
                result.LastAttrChangeTime = fileDirectoryInfo.LastWriteTime;
                result.EndOfFile          = fileDirectoryInfo.EndOfFile;
                result.AllocationSize     = fileDirectoryInfo.AllocationSize;
                result.ExtFileAttributes  = (ExtendedFileAttributes)fileDirectoryInfo.FileAttributes;
                result.FileName           = fileDirectoryInfo.FileName;
                return(result);
            }

            case FindInformationLevel.SMB_FIND_FILE_FULL_DIRECTORY_INFO:
            {
                FileFullDirectoryInformation fileFullDirectoryInfo = (FileFullDirectoryInformation)entry;

                FindFileFullDirectoryInfo result = new FindFileFullDirectoryInfo();
                result.FileIndex          = fileFullDirectoryInfo.FileIndex;
                result.CreationTime       = fileFullDirectoryInfo.CreationTime;
                result.LastAccessTime     = fileFullDirectoryInfo.LastAccessTime;
                result.LastWriteTime      = fileFullDirectoryInfo.LastWriteTime;
                result.LastAttrChangeTime = fileFullDirectoryInfo.LastWriteTime;
                result.EndOfFile          = fileFullDirectoryInfo.EndOfFile;
                result.AllocationSize     = fileFullDirectoryInfo.AllocationSize;
                result.ExtFileAttributes  = (ExtendedFileAttributes)fileFullDirectoryInfo.FileAttributes;
                result.EASize             = fileFullDirectoryInfo.EaSize;
                result.FileName           = fileFullDirectoryInfo.FileName;
                return(result);
            }

            case FindInformationLevel.SMB_FIND_FILE_NAMES_INFO:
            {
                FileNamesInformation fileNamesInfo = (FileNamesInformation)entry;

                FindFileNamesInfo result = new FindFileNamesInfo();
                result.FileIndex = fileNamesInfo.FileIndex;
                result.FileName  = fileNamesInfo.FileName;
                return(result);
            }

            case FindInformationLevel.SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
            {
                FileBothDirectoryInformation fileBothDirectoryInfo = (FileBothDirectoryInformation)entry;

                FindFileBothDirectoryInfo result = new FindFileBothDirectoryInfo();
                result.FileIndex         = fileBothDirectoryInfo.FileIndex;
                result.CreationTime      = fileBothDirectoryInfo.CreationTime;
                result.LastAccessTime    = fileBothDirectoryInfo.LastAccessTime;
                result.LastWriteTime     = fileBothDirectoryInfo.LastWriteTime;
                result.LastChangeTime    = fileBothDirectoryInfo.LastWriteTime;
                result.EndOfFile         = fileBothDirectoryInfo.EndOfFile;
                result.AllocationSize    = fileBothDirectoryInfo.AllocationSize;
                result.ExtFileAttributes = (ExtendedFileAttributes)fileBothDirectoryInfo.FileAttributes;
                result.EASize            = fileBothDirectoryInfo.EaSize;
                result.Reserved          = fileBothDirectoryInfo.Reserved;
                result.ShortName         = fileBothDirectoryInfo.ShortName;
                result.FileName          = fileBothDirectoryInfo.FileName;
                return(result);
            }

            default:
            {
                throw new UnsupportedInformationLevelException();
            }
            }
        }