NTFileSystemAdapter.Query.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /* Copyright (C) 2014-2018 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.IO;
  10. using Utilities;
  11. namespace SMBLibrary
  12. {
  13. public partial class NTFileSystemAdapter
  14. {
  15. public NTStatus GetFileInformation(out FileInformation result, object handle, FileInformationClass informationClass)
  16. {
  17. FileHandle fileHandle = (FileHandle)handle;
  18. string path = fileHandle.Path;
  19. FileSystemEntry entry;
  20. try
  21. {
  22. entry = m_fileSystem.GetEntry(path);
  23. }
  24. catch (Exception ex)
  25. {
  26. if (ex is IOException || ex is UnauthorizedAccessException)
  27. {
  28. NTStatus status = ToNTStatus(ex);
  29. Log(Severity.Verbose, "GetFileInformation on '{0}' failed. {1}", path, status);
  30. result = null;
  31. return status;
  32. }
  33. else
  34. {
  35. throw;
  36. }
  37. }
  38. switch (informationClass)
  39. {
  40. case FileInformationClass.FileBasicInformation:
  41. {
  42. FileBasicInformation information = new FileBasicInformation();
  43. information.CreationTime = entry.CreationTime;
  44. information.LastAccessTime = entry.LastAccessTime;
  45. information.LastWriteTime = entry.LastWriteTime;
  46. information.ChangeTime = entry.LastWriteTime;
  47. information.FileAttributes = GetFileAttributes(entry);
  48. result = information;
  49. return NTStatus.STATUS_SUCCESS;
  50. }
  51. case FileInformationClass.FileStandardInformation:
  52. {
  53. FileStandardInformation information = new FileStandardInformation();
  54. information.AllocationSize = (long)GetAllocationSize(entry.Size);
  55. information.EndOfFile = (long)entry.Size;
  56. information.Directory = entry.IsDirectory;
  57. information.DeletePending = fileHandle.DeleteOnClose;
  58. result = information;
  59. return NTStatus.STATUS_SUCCESS;
  60. }
  61. case FileInformationClass.FileInternalInformation:
  62. {
  63. FileInternalInformation information = new FileInternalInformation();
  64. result = information;
  65. return NTStatus.STATUS_SUCCESS;
  66. }
  67. case FileInformationClass.FileEaInformation:
  68. {
  69. FileEaInformation information = new FileEaInformation();
  70. information.EaSize = 0;
  71. result = information;
  72. return NTStatus.STATUS_SUCCESS;
  73. }
  74. case FileInformationClass.FileAccessInformation:
  75. {
  76. result = null;
  77. return NTStatus.STATUS_NOT_IMPLEMENTED;
  78. }
  79. case FileInformationClass.FileNameInformation:
  80. {
  81. FileNameInformation information = new FileNameInformation();
  82. information.FileName = entry.Name;
  83. result = information;
  84. return NTStatus.STATUS_SUCCESS;
  85. }
  86. case FileInformationClass.FilePositionInformation:
  87. {
  88. result = null;
  89. return NTStatus.STATUS_NOT_IMPLEMENTED;
  90. }
  91. case FileInformationClass.FileFullEaInformation:
  92. {
  93. result = null;
  94. return NTStatus.STATUS_NOT_IMPLEMENTED;
  95. }
  96. case FileInformationClass.FileModeInformation:
  97. {
  98. result = null;
  99. return NTStatus.STATUS_NOT_IMPLEMENTED;
  100. }
  101. case FileInformationClass.FileAlignmentInformation:
  102. {
  103. result = null;
  104. return NTStatus.STATUS_NOT_IMPLEMENTED;
  105. }
  106. case FileInformationClass.FileAllInformation:
  107. {
  108. FileAllInformation information = new FileAllInformation();
  109. information.BasicInformation.CreationTime = entry.CreationTime;
  110. information.BasicInformation.LastAccessTime = entry.LastAccessTime;
  111. information.BasicInformation.LastWriteTime = entry.LastWriteTime;
  112. information.BasicInformation.ChangeTime = entry.LastWriteTime;
  113. information.BasicInformation.FileAttributes = GetFileAttributes(entry);
  114. information.StandardInformation.AllocationSize = (long)GetAllocationSize(entry.Size);
  115. information.StandardInformation.EndOfFile = (long)entry.Size;
  116. information.StandardInformation.Directory = entry.IsDirectory;
  117. information.StandardInformation.DeletePending = fileHandle.DeleteOnClose;
  118. information.NameInformation.FileName = entry.Name;
  119. result = information;
  120. return NTStatus.STATUS_SUCCESS;
  121. }
  122. case FileInformationClass.FileAlternateNameInformation:
  123. {
  124. // If there is no alternate name Windows will return STATUS_OBJECT_NAME_NOT_FOUND
  125. result = null;
  126. return NTStatus.STATUS_OBJECT_NAME_NOT_FOUND;
  127. }
  128. case FileInformationClass.FileStreamInformation:
  129. {
  130. // This information class is used to enumerate the data streams of a file or a directory.
  131. // A buffer of FileStreamInformation data elements is returned by the server.
  132. FileStreamInformation information = new FileStreamInformation();
  133. List<KeyValuePair<string, ulong>> dataStreams = m_fileSystem.ListDataStreams(fileHandle.Path);
  134. foreach (KeyValuePair<string, ulong> dataStream in dataStreams)
  135. {
  136. FileStreamEntry streamEntry = new FileStreamEntry();
  137. ulong streamSize = dataStream.Value;
  138. streamEntry.StreamSize = (long)streamSize;
  139. streamEntry.StreamAllocationSize = (long)GetAllocationSize(streamSize);
  140. streamEntry.StreamName = dataStream.Key;
  141. information.Entries.Add(streamEntry);
  142. }
  143. result = information;
  144. return NTStatus.STATUS_SUCCESS;
  145. }
  146. case FileInformationClass.FilePipeInformation:
  147. {
  148. result = null;
  149. return NTStatus.STATUS_NOT_IMPLEMENTED;
  150. }
  151. case FileInformationClass.FilePipeLocalInformation:
  152. {
  153. result = null;
  154. return NTStatus.STATUS_NOT_IMPLEMENTED;
  155. }
  156. case FileInformationClass.FilePipeRemoteInformation:
  157. {
  158. result = null;
  159. return NTStatus.STATUS_NOT_IMPLEMENTED;
  160. }
  161. case FileInformationClass.FileCompressionInformation:
  162. {
  163. result = null;
  164. return NTStatus.STATUS_NOT_IMPLEMENTED;
  165. }
  166. case FileInformationClass.FileNetworkOpenInformation:
  167. {
  168. FileNetworkOpenInformation information = new FileNetworkOpenInformation();
  169. information.CreationTime = entry.CreationTime;
  170. information.LastAccessTime = entry.LastAccessTime;
  171. information.LastWriteTime = entry.LastWriteTime;
  172. information.ChangeTime = entry.LastWriteTime;
  173. information.AllocationSize = (long)GetAllocationSize(entry.Size);
  174. information.EndOfFile = (long)entry.Size;
  175. information.FileAttributes = GetFileAttributes(entry);
  176. result = information;
  177. return NTStatus.STATUS_SUCCESS;
  178. }
  179. case FileInformationClass.FileAttributeTagInformation:
  180. {
  181. result = null;
  182. return NTStatus.STATUS_NOT_IMPLEMENTED;
  183. }
  184. default:
  185. result = null;
  186. return NTStatus.STATUS_INVALID_INFO_CLASS;
  187. }
  188. }
  189. public static FileAttributes GetFileAttributes(FileSystemEntry entry)
  190. {
  191. FileAttributes attributes = 0;
  192. if (entry.IsHidden)
  193. {
  194. attributes |= FileAttributes.Hidden;
  195. }
  196. if (entry.IsReadonly)
  197. {
  198. attributes |= FileAttributes.ReadOnly;
  199. }
  200. if (entry.IsArchived)
  201. {
  202. attributes |= FileAttributes.Archive;
  203. }
  204. if (entry.IsDirectory)
  205. {
  206. attributes |= FileAttributes.Directory;
  207. }
  208. if (attributes == 0)
  209. {
  210. attributes = FileAttributes.Normal;
  211. }
  212. return attributes;
  213. }
  214. }
  215. }