SMB1FileSystemHelper.Set.cs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  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.IO;
  10. using System.Text;
  11. using SMBLibrary.SMB1;
  12. using Utilities;
  13. namespace SMBLibrary.Server.SMB1
  14. {
  15. public partial class SMB1FileSystemHelper
  16. {
  17. public static NTStatus SetFileInformation(IFileSystem fileSystem, OpenFileObject openFile, SetInformation information, ConnectionState state)
  18. {
  19. if (information is SetFileBasicInfo)
  20. {
  21. SetFileBasicInfo basicInfo = (SetFileBasicInfo)information;
  22. bool isHidden = (basicInfo.ExtFileAttributes & ExtendedFileAttributes.Hidden) > 0;
  23. bool isReadonly = (basicInfo.ExtFileAttributes & ExtendedFileAttributes.Readonly) > 0;
  24. bool isArchived = (basicInfo.ExtFileAttributes & ExtendedFileAttributes.Archive) > 0;
  25. try
  26. {
  27. fileSystem.SetAttributes(openFile.Path, isHidden, isReadonly, isArchived);
  28. }
  29. catch (UnauthorizedAccessException)
  30. {
  31. state.LogToServer(Severity.Debug, "SetFileInformation: Failed to set file attributes on '{0}'. Access Denied.", openFile.Path);
  32. return NTStatus.STATUS_ACCESS_DENIED;
  33. }
  34. try
  35. {
  36. fileSystem.SetDates(openFile.Path, basicInfo.CreationTime, basicInfo.LastWriteTime, basicInfo.LastAccessTime);
  37. }
  38. catch (IOException ex)
  39. {
  40. ushort errorCode = IOExceptionHelper.GetWin32ErrorCode(ex);
  41. if (errorCode == (ushort)Win32Error.ERROR_SHARING_VIOLATION)
  42. {
  43. // Returning STATUS_SHARING_VIOLATION is undocumented but apparently valid
  44. state.LogToServer(Severity.Debug, "SetFileInformation: Failed to set file dates on '{0}'. Sharing Violation.", openFile.Path);
  45. return NTStatus.STATUS_SHARING_VIOLATION;
  46. }
  47. else
  48. {
  49. state.LogToServer(Severity.Debug, "SetFileInformation: Failed to set file dates on '{0}'. Data Error.", openFile.Path);
  50. return NTStatus.STATUS_DATA_ERROR;
  51. }
  52. }
  53. catch (UnauthorizedAccessException)
  54. {
  55. state.LogToServer(Severity.Debug, "SetFileInformation: Failed to set file dates on '{0}'. Access Denied.", openFile.Path);
  56. return NTStatus.STATUS_ACCESS_DENIED;
  57. }
  58. return NTStatus.STATUS_SUCCESS;
  59. }
  60. else if (information is SetFileDispositionInfo)
  61. {
  62. if (((SetFileDispositionInfo)information).DeletePending)
  63. {
  64. // We're supposed to delete the file on close, but it's too late to report errors at this late stage
  65. if (openFile.Stream != null)
  66. {
  67. openFile.Stream.Close();
  68. }
  69. try
  70. {
  71. state.LogToServer(Severity.Information, "SetFileInformation: Deleting file '{0}'", openFile.Path);
  72. fileSystem.Delete(openFile.Path);
  73. }
  74. catch (IOException ex)
  75. {
  76. ushort errorCode = IOExceptionHelper.GetWin32ErrorCode(ex);
  77. if (errorCode == (ushort)Win32Error.ERROR_SHARING_VIOLATION)
  78. {
  79. state.LogToServer(Severity.Information, "SetFileInformation: Error deleting '{0}'. Sharing Violation.", openFile.Path);
  80. return NTStatus.STATUS_SHARING_VIOLATION;
  81. }
  82. else
  83. {
  84. state.LogToServer(Severity.Information, "SetFileInformation: Error deleting '{0}'. Data Error.", openFile.Path);
  85. return NTStatus.STATUS_DATA_ERROR;
  86. }
  87. }
  88. catch (UnauthorizedAccessException)
  89. {
  90. state.LogToServer(Severity.Information, "SetFileInformation: Error deleting '{0}', Access Denied.", openFile.Path);
  91. return NTStatus.STATUS_ACCESS_DENIED;
  92. }
  93. }
  94. return NTStatus.STATUS_SUCCESS;
  95. }
  96. else if (information is SetFileAllocationInfo)
  97. {
  98. // This information level is used to set the file length in bytes.
  99. // Note: the input will NOT be a multiple of the cluster size / bytes per sector.
  100. ulong allocationSize = ((SetFileAllocationInfo)information).AllocationSize;
  101. try
  102. {
  103. openFile.Stream.SetLength((long)allocationSize);
  104. }
  105. catch (IOException ex)
  106. {
  107. ushort errorCode = IOExceptionHelper.GetWin32ErrorCode(ex);
  108. if (errorCode == (ushort)Win32Error.ERROR_SHARING_VIOLATION)
  109. {
  110. state.LogToServer(Severity.Debug, "SetFileInformation: Cannot set allocation for '{0}'. Sharing Violation.", openFile.Path);
  111. return NTStatus.STATUS_SHARING_VIOLATION;
  112. }
  113. else
  114. {
  115. state.LogToServer(Severity.Debug, "SetFileInformation: Cannot set allocation for '{0}'. Data Error.", openFile.Path);
  116. return NTStatus.STATUS_DATA_ERROR;
  117. }
  118. }
  119. catch (UnauthorizedAccessException)
  120. {
  121. state.LogToServer(Severity.Debug, "SetFileInformation: Cannot set allocation for '{0}'. Access Denied.", openFile.Path);
  122. return NTStatus.STATUS_ACCESS_DENIED;
  123. }
  124. return NTStatus.STATUS_SUCCESS;
  125. }
  126. else if (information is SetFileEndOfFileInfo)
  127. {
  128. ulong endOfFile = ((SetFileEndOfFileInfo)information).EndOfFile;
  129. try
  130. {
  131. openFile.Stream.SetLength((long)endOfFile);
  132. }
  133. catch (IOException ex)
  134. {
  135. ushort errorCode = IOExceptionHelper.GetWin32ErrorCode(ex);
  136. if (errorCode == (ushort)Win32Error.ERROR_SHARING_VIOLATION)
  137. {
  138. state.LogToServer(Severity.Debug, "SetFileInformation: Cannot set end of file for '{0}'. Sharing Violation.", openFile.Path);
  139. return NTStatus.STATUS_SHARING_VIOLATION;
  140. }
  141. else
  142. {
  143. state.LogToServer(Severity.Debug, "SetFileInformation: Cannot set end of file for '{0}'. Data Error.", openFile.Path);
  144. return NTStatus.STATUS_DATA_ERROR;
  145. }
  146. }
  147. catch (UnauthorizedAccessException)
  148. {
  149. state.LogToServer(Severity.Debug, "SetFileInformation: Cannot set end of file for '{0}'. Access Denied.", openFile.Path);
  150. return NTStatus.STATUS_ACCESS_DENIED;
  151. }
  152. return NTStatus.STATUS_SUCCESS;
  153. }
  154. else
  155. {
  156. return NTStatus.STATUS_NOT_IMPLEMENTED;
  157. }
  158. }
  159. }
  160. }