SMB1FileStoreHelper.QueryDirectory.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /* Copyright (C) 2014-2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
  2. *
  3. * You can redistribute this program and/or modify it under the terms of
  4. * the GNU Lesser Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. */
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Text;
  10. using SMBLibrary.SMB1;
  11. using Utilities;
  12. namespace SMBLibrary.Server.SMB1
  13. {
  14. internal partial class SMB1FileStoreHelper
  15. {
  16. // Filename pattern examples:
  17. // '\Directory' - Get the directory entry
  18. // '\Directory\*' - List the directory files
  19. // '\Directory\s*' - List the directory files starting with s (cmd.exe will use this syntax when entering 's' and hitting tab for autocomplete)
  20. // '\Directory\<.inf' (Update driver will use this syntax)
  21. // '\Directory\exefile"*' (cmd.exe will use this syntax when entering an exe without its extension, explorer will use this opening a directory from the run menu)
  22. /// <param name="fileNamePattern">The filename pattern to search for. This field MAY contain wildcard characters</param>
  23. /// <exception cref="System.UnauthorizedAccessException"></exception>
  24. public static NTStatus QueryDirectory(out List<QueryDirectoryFileInformation> result, INTFileStore fileStore, string fileNamePattern, FileInformationClass fileInformation, SecurityContext securityContext)
  25. {
  26. int separatorIndex = fileNamePattern.LastIndexOf('\\');
  27. if (separatorIndex >= 0)
  28. {
  29. string path = fileNamePattern.Substring(0, separatorIndex + 1);
  30. string fileName = fileNamePattern.Substring(separatorIndex + 1);
  31. object handle;
  32. FileStatus fileStatus;
  33. DirectoryAccessMask accessMask = DirectoryAccessMask.FILE_LIST_DIRECTORY | DirectoryAccessMask.FILE_TRAVERSE | DirectoryAccessMask.SYNCHRONIZE;
  34. CreateOptions createOptions = CreateOptions.FILE_DIRECTORY_FILE | CreateOptions.FILE_SYNCHRONOUS_IO_NONALERT;
  35. NTStatus status = fileStore.CreateFile(out handle, out fileStatus, path, accessMask, 0, ShareAccess.FILE_SHARE_READ | ShareAccess.FILE_SHARE_WRITE, CreateDisposition.FILE_OPEN, createOptions, securityContext);
  36. if (status != NTStatus.STATUS_SUCCESS)
  37. {
  38. result = null;
  39. return status;
  40. }
  41. status = fileStore.QueryDirectory(out result, handle, fileName, fileInformation);
  42. fileStore.CloseFile(handle);
  43. return status;
  44. }
  45. else
  46. {
  47. result = null;
  48. return NTStatus.STATUS_INVALID_PARAMETER;
  49. }
  50. }
  51. /// <exception cref="SMBLibrary.UnsupportedInformationLevelException"></exception>
  52. public static FindInformationList GetFindInformationList(List<QueryDirectoryFileInformation> entries, FindInformationLevel informationLevel, bool isUnicode, bool returnResumeKeys, int maxLength)
  53. {
  54. FindInformationList result = new FindInformationList();
  55. int pageLength = 0;
  56. for (int index = 0; index < entries.Count; index++)
  57. {
  58. FindInformation infoEntry = GetFindInformation(entries[index], informationLevel, isUnicode, returnResumeKeys);
  59. int entryLength = infoEntry.GetLength(isUnicode);
  60. if (pageLength + entryLength <= maxLength)
  61. {
  62. result.Add(infoEntry);
  63. pageLength += entryLength;
  64. }
  65. else
  66. {
  67. break;
  68. }
  69. }
  70. return result;
  71. }
  72. /// <exception cref="SMBLibrary.UnsupportedInformationLevelException"></exception>
  73. public static FindInformation GetFindInformation(QueryDirectoryFileInformation entry, FindInformationLevel informationLevel, bool isUnicode, bool returnResumeKeys)
  74. {
  75. switch (informationLevel)
  76. {
  77. case FindInformationLevel.SMB_FIND_FILE_DIRECTORY_INFO:
  78. {
  79. FileDirectoryInformation fileDirectoryInfo = (FileDirectoryInformation)entry;
  80. FindFileDirectoryInfo result = new FindFileDirectoryInfo();
  81. result.FileIndex = fileDirectoryInfo.FileIndex;
  82. result.CreationTime = fileDirectoryInfo.CreationTime;
  83. result.LastAccessTime = fileDirectoryInfo.LastAccessTime;
  84. result.LastWriteTime = fileDirectoryInfo.LastWriteTime;
  85. result.LastAttrChangeTime = fileDirectoryInfo.LastWriteTime;
  86. result.EndOfFile = fileDirectoryInfo.EndOfFile;
  87. result.AllocationSize = fileDirectoryInfo.AllocationSize;
  88. result.ExtFileAttributes = (ExtendedFileAttributes)fileDirectoryInfo.FileAttributes;
  89. result.FileName = fileDirectoryInfo.FileName;
  90. return result;
  91. }
  92. case FindInformationLevel.SMB_FIND_FILE_FULL_DIRECTORY_INFO:
  93. {
  94. FileFullDirectoryInformation fileFullDirectoryInfo = (FileFullDirectoryInformation)entry;
  95. FindFileFullDirectoryInfo result = new FindFileFullDirectoryInfo();
  96. result.FileIndex = fileFullDirectoryInfo.FileIndex;
  97. result.CreationTime = fileFullDirectoryInfo.CreationTime;
  98. result.LastAccessTime = fileFullDirectoryInfo.LastAccessTime;
  99. result.LastWriteTime = fileFullDirectoryInfo.LastWriteTime;
  100. result.LastAttrChangeTime = fileFullDirectoryInfo.LastWriteTime;
  101. result.EndOfFile = fileFullDirectoryInfo.EndOfFile;
  102. result.AllocationSize = fileFullDirectoryInfo.AllocationSize;
  103. result.ExtFileAttributes = (ExtendedFileAttributes)fileFullDirectoryInfo.FileAttributes;
  104. result.EASize = fileFullDirectoryInfo.EaSize;
  105. result.FileName = fileFullDirectoryInfo.FileName;
  106. return result;
  107. }
  108. case FindInformationLevel.SMB_FIND_FILE_NAMES_INFO:
  109. {
  110. FileNamesInformation fileNamesInfo = (FileNamesInformation)entry;
  111. FindFileNamesInfo result = new FindFileNamesInfo();
  112. result.FileIndex = fileNamesInfo.FileIndex;
  113. result.FileName = fileNamesInfo.FileName;
  114. return result;
  115. }
  116. case FindInformationLevel.SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
  117. {
  118. FileBothDirectoryInformation fileBothDirectoryInfo = (FileBothDirectoryInformation)entry;
  119. FindFileBothDirectoryInfo result = new FindFileBothDirectoryInfo();
  120. result.FileIndex = fileBothDirectoryInfo.FileIndex;
  121. result.CreationTime = fileBothDirectoryInfo.CreationTime;
  122. result.LastAccessTime = fileBothDirectoryInfo.LastAccessTime;
  123. result.LastWriteTime = fileBothDirectoryInfo.LastWriteTime;
  124. result.LastChangeTime = fileBothDirectoryInfo.LastWriteTime;
  125. result.EndOfFile = fileBothDirectoryInfo.EndOfFile;
  126. result.AllocationSize = fileBothDirectoryInfo.AllocationSize;
  127. result.ExtFileAttributes = (ExtendedFileAttributes)fileBothDirectoryInfo.FileAttributes;
  128. result.EASize = fileBothDirectoryInfo.EaSize;
  129. result.Reserved = fileBothDirectoryInfo.Reserved;
  130. result.ShortName = fileBothDirectoryInfo.ShortName;
  131. result.FileName = fileBothDirectoryInfo.FileName;
  132. return result;
  133. }
  134. case FindInformationLevel.SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO:
  135. {
  136. FileIdFullDirectoryInformation fileIDFullDirectoryInfo = (FileIdFullDirectoryInformation)entry;
  137. FindFileIDFullDirectoryInfo result = new FindFileIDFullDirectoryInfo();
  138. result.FileIndex = fileIDFullDirectoryInfo.FileIndex;
  139. result.CreationTime = fileIDFullDirectoryInfo.CreationTime;
  140. result.LastAccessTime = fileIDFullDirectoryInfo.LastAccessTime;
  141. result.LastWriteTime = fileIDFullDirectoryInfo.LastWriteTime;
  142. result.LastAttrChangeTime = fileIDFullDirectoryInfo.LastWriteTime;
  143. result.EndOfFile = fileIDFullDirectoryInfo.EndOfFile;
  144. result.AllocationSize = fileIDFullDirectoryInfo.AllocationSize;
  145. result.ExtFileAttributes = (ExtendedFileAttributes)fileIDFullDirectoryInfo.FileAttributes;
  146. result.EASize = fileIDFullDirectoryInfo.EaSize;
  147. result.Reserved = fileIDFullDirectoryInfo.Reserved;
  148. result.FileID = fileIDFullDirectoryInfo.FileId;
  149. result.FileName = fileIDFullDirectoryInfo.FileName;
  150. return result;
  151. }
  152. case FindInformationLevel.SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO:
  153. {
  154. FileIdBothDirectoryInformation fileIDBothDirectoryInfo = (FileIdBothDirectoryInformation)entry;
  155. FindFileIDBothDirectoryInfo result = new FindFileIDBothDirectoryInfo();
  156. result.FileIndex = fileIDBothDirectoryInfo.FileIndex;
  157. result.CreationTime = fileIDBothDirectoryInfo.CreationTime;
  158. result.LastAccessTime = fileIDBothDirectoryInfo.LastAccessTime;
  159. result.LastWriteTime = fileIDBothDirectoryInfo.LastWriteTime;
  160. result.LastChangeTime = fileIDBothDirectoryInfo.LastWriteTime;
  161. result.EndOfFile = fileIDBothDirectoryInfo.EndOfFile;
  162. result.AllocationSize = fileIDBothDirectoryInfo.AllocationSize;
  163. result.ExtFileAttributes = (ExtendedFileAttributes)fileIDBothDirectoryInfo.FileAttributes;
  164. result.EASize = fileIDBothDirectoryInfo.EaSize;
  165. result.Reserved = fileIDBothDirectoryInfo.Reserved1;
  166. result.ShortName = fileIDBothDirectoryInfo.ShortName;
  167. result.Reserved2 = fileIDBothDirectoryInfo.Reserved2;
  168. result.FileID = fileIDBothDirectoryInfo.FileId;
  169. result.FileName = fileIDBothDirectoryInfo.FileName;
  170. return result;
  171. }
  172. default:
  173. {
  174. throw new UnsupportedInformationLevelException();
  175. }
  176. }
  177. }
  178. }
  179. }