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>()); }
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); }
/// <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); }
/// <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(); } } }