NTFileSystemAdapter.Set.cs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  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 SetFileInformation(object handle, FileInformation information)
  16. {
  17. FileHandle fileHandle = (FileHandle)handle;
  18. if (information is FileBasicInformation)
  19. {
  20. FileBasicInformation basicInformation = (FileBasicInformation)information;
  21. bool isHidden = ((basicInformation.FileAttributes & FileAttributes.Hidden) > 0);
  22. bool isReadonly = (basicInformation.FileAttributes & FileAttributes.ReadOnly) > 0;
  23. bool isArchived = (basicInformation.FileAttributes & FileAttributes.Archive) > 0;
  24. try
  25. {
  26. m_fileSystem.SetAttributes(fileHandle.Path, isHidden, isReadonly, isArchived);
  27. }
  28. catch (Exception ex)
  29. {
  30. if (ex is IOException || ex is UnauthorizedAccessException)
  31. {
  32. NTStatus status = ToNTStatus(ex);
  33. Log(Severity.Verbose, "SetFileInformation: Failed to set file attributes on '{0}'. {1}.", fileHandle.Path, status);
  34. return status;
  35. }
  36. else
  37. {
  38. throw;
  39. }
  40. }
  41. try
  42. {
  43. m_fileSystem.SetDates(fileHandle.Path, basicInformation.CreationTime, basicInformation.LastWriteTime, basicInformation.LastAccessTime);
  44. }
  45. catch (Exception ex)
  46. {
  47. if (ex is IOException || ex is UnauthorizedAccessException)
  48. {
  49. NTStatus status = ToNTStatus(ex);
  50. Log(Severity.Verbose, "SetFileInformation: Failed to set file dates on '{0}'. {1}.", fileHandle.Path, status);
  51. return status;
  52. }
  53. else
  54. {
  55. throw;
  56. }
  57. }
  58. return NTStatus.STATUS_SUCCESS;
  59. }
  60. else if (information is FileRenameInformationType2)
  61. {
  62. FileRenameInformationType2 renameInformation = (FileRenameInformationType2)information;
  63. string newFileName = renameInformation.FileName;
  64. if (!newFileName.StartsWith(@"\"))
  65. {
  66. newFileName = @"\" + newFileName;
  67. }
  68. if (fileHandle.Stream != null)
  69. {
  70. fileHandle.Stream.Close();
  71. }
  72. // Note: it's possible that we just want to upcase / downcase a filename letter.
  73. try
  74. {
  75. if (renameInformation.ReplaceIfExists && (IsFileExists(newFileName)))
  76. {
  77. m_fileSystem.Delete(newFileName);
  78. }
  79. m_fileSystem.Move(fileHandle.Path, newFileName);
  80. Log(Severity.Information, "SetFileInformation: Renamed '{0}' to '{1}'", fileHandle.Path, newFileName);
  81. }
  82. catch (Exception ex)
  83. {
  84. if (ex is IOException || ex is UnauthorizedAccessException)
  85. {
  86. NTStatus status = ToNTStatus(ex);
  87. Log(Severity.Verbose, "SetFileInformation: Cannot rename '{0}' to '{1}'. {2}.", fileHandle.Path, newFileName, status);
  88. return status;
  89. }
  90. else
  91. {
  92. throw;
  93. }
  94. }
  95. fileHandle.Path = newFileName;
  96. return NTStatus.STATUS_SUCCESS;
  97. }
  98. else if (information is FileDispositionInformation)
  99. {
  100. if (((FileDispositionInformation)information).DeletePending)
  101. {
  102. // We're supposed to delete the file on close, but it's too late to report errors at this late stage
  103. if (fileHandle.Stream != null)
  104. {
  105. fileHandle.Stream.Close();
  106. }
  107. try
  108. {
  109. m_fileSystem.Delete(fileHandle.Path);
  110. Log(Severity.Information, "SetFileInformation: Deleted '{0}'", fileHandle.Path);
  111. }
  112. catch (Exception ex)
  113. {
  114. if (ex is IOException || ex is UnauthorizedAccessException)
  115. {
  116. NTStatus status = ToNTStatus(ex);
  117. Log(Severity.Information, "SetFileInformation: Error deleting '{0}'. {1}.", fileHandle.Path, status);
  118. return status;
  119. }
  120. else
  121. {
  122. throw;
  123. }
  124. }
  125. }
  126. return NTStatus.STATUS_SUCCESS;
  127. }
  128. else if (information is FileAllocationInformation)
  129. {
  130. long allocationSize = ((FileAllocationInformation)information).AllocationSize;
  131. try
  132. {
  133. fileHandle.Stream.SetLength(allocationSize);
  134. }
  135. catch (Exception ex)
  136. {
  137. if (ex is IOException || ex is UnauthorizedAccessException)
  138. {
  139. NTStatus status = ToNTStatus(ex);
  140. Log(Severity.Verbose, "SetFileInformation: Cannot set allocation for '{0}'. {1}.", fileHandle.Path, status);
  141. return status;
  142. }
  143. else
  144. {
  145. throw;
  146. }
  147. }
  148. return NTStatus.STATUS_SUCCESS;
  149. }
  150. else if (information is FileEndOfFileInformation)
  151. {
  152. long endOfFile = ((FileEndOfFileInformation)information).EndOfFile;
  153. try
  154. {
  155. fileHandle.Stream.SetLength(endOfFile);
  156. }
  157. catch (Exception ex)
  158. {
  159. if (ex is IOException || ex is UnauthorizedAccessException)
  160. {
  161. NTStatus status = ToNTStatus(ex);
  162. Log(Severity.Verbose, "SetFileInformation: Cannot set end of file for '{0}'. {1}.", fileHandle.Path, status);
  163. return status;
  164. }
  165. else
  166. {
  167. throw;
  168. }
  169. }
  170. return NTStatus.STATUS_SUCCESS;
  171. }
  172. else
  173. {
  174. return NTStatus.STATUS_NOT_IMPLEMENTED;
  175. }
  176. }
  177. private bool IsFileExists(string path)
  178. {
  179. try
  180. {
  181. m_fileSystem.GetEntry(path);
  182. }
  183. catch (FileNotFoundException)
  184. {
  185. return false;
  186. }
  187. catch (DirectoryNotFoundException)
  188. {
  189. return false;
  190. }
  191. return true;
  192. }
  193. }
  194. }