Преглед на файлове

honor FILE_DELETE_ON_CLOSE flag

Tal Aloni преди 8 години
родител
ревизия
ab858afee9

+ 4 - 2
SMBLibrary/Server/OpenedFileObject.cs

@@ -1,4 +1,4 @@
-/* Copyright (C) 2014-2016 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
+/* Copyright (C) 2014-2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
  * 
  * You can redistribute this program and/or modify it under the terms of
  * the GNU Lesser Public License as published by the Free Software Foundation,
@@ -15,11 +15,13 @@ namespace SMBLibrary.Server
     {
         public string Path;
         public Stream Stream;
+        public bool DeleteOnClose;
 
-        public OpenedFileObject(string path, Stream stream)
+        public OpenedFileObject(string path, Stream stream, bool deleteOnClose)
         {
             Path = path;
             Stream = stream;
+            DeleteOnClose = deleteOnClose;
         }
     }
 }

+ 3 - 1
SMBLibrary/Server/ResponseHelpers/NTCreateHelper.cs

@@ -246,6 +246,7 @@ namespace SMBLibrary.Server
                 }
 
                 Stream stream;
+                bool deleteOnClose = false;
                 if (fileAccess == (FileAccess)0 || entry.IsDirectory)
                 {
                     stream = null;
@@ -255,6 +256,7 @@ namespace SMBLibrary.Server
                     // When FILE_OPEN_REPARSE_POINT is specified, the operation should continue normally if the file is not a reparse point.
                     // FILE_OPEN_REPARSE_POINT is a hint that the caller does not intend to actually read the file, with the exception
                     // of a file copy operation (where the caller will attempt to simply copy the reparse point).
+                    deleteOnClose = (request.CreateOptions & CreateOptions.FILE_DELETE_ON_CLOSE) > 0;
                     bool openReparsePoint = (request.CreateOptions & CreateOptions.FILE_OPEN_REPARSE_POINT) > 0;
                     bool disableBuffering = (request.CreateOptions & CreateOptions.FILE_NO_INTERMEDIATE_BUFFERING) > 0;
                     bool buffered = (request.CreateOptions & CreateOptions.FILE_SEQUENTIAL_ONLY) > 0 && !disableBuffering && !openReparsePoint;
@@ -290,7 +292,7 @@ namespace SMBLibrary.Server
                     }
                 }
 
-                ushort fileID = state.AddOpenedFile(path, stream);
+                ushort fileID = state.AddOpenedFile(path, stream, deleteOnClose);
                 if (isExtended)
                 {
                     NTCreateAndXResponseExtended response = CreateResponseExtendedFromFileSystemEntry(entry, fileID);

+ 15 - 4
SMBLibrary/Server/ResponseHelpers/ServerResponseHelper.cs

@@ -1,4 +1,4 @@
-/* Copyright (C) 2014 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
+/* Copyright (C) 2014-2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
  * 
  * You can redistribute this program and/or modify it under the terms of
  * the GNU Lesser Public License as published by the Free Software Foundation,
@@ -15,16 +15,27 @@ namespace SMBLibrary.Server
 {
     public partial class ServerResponseHelper
     {
-        internal static SMBCommand GetCloseResponse(SMBHeader header, CloseRequest request, StateObject state)
+        internal static SMBCommand GetCloseResponse(SMBHeader header, CloseRequest request, object share, StateObject state)
         {
-            string openedFilePath = state.GetOpenedFilePath(request.FID);
-            if (openedFilePath == null)
+            OpenedFileObject openedFile = state.GetOpenedFileObject(request.FID);
+            if (openedFile == null)
             {
                 header.Status = NTStatus.STATUS_SMB_BAD_FID;
                 return new ErrorResponse(CommandName.SMB_COM_CLOSE);
             }
 
             state.RemoveOpenedFile(request.FID);
+            if (openedFile.DeleteOnClose && share is FileSystemShare)
+            {
+                try
+                {
+                    ((FileSystemShare)share).FileSystem.Delete(openedFile.Path);
+                }
+                catch
+                {
+                    System.Diagnostics.Debug.Print("[{0}] Close: Cannot delete '{1}'", DateTime.Now.ToString("HH:mm:ss:ffff"), openedFile.Path);
+                }
+            }
             CloseResponse response = new CloseResponse();
             return response;
         }

+ 1 - 1
SMBLibrary/Server/SMBServer.cs

@@ -346,7 +346,7 @@ namespace SMBLibrary.Server
                     else if (command is CloseRequest)
                     {
                         CloseRequest request = (CloseRequest)command;
-                        return ServerResponseHelper.GetCloseResponse(header, request, state);
+                        return ServerResponseHelper.GetCloseResponse(header, request, share, state);
                     }
                     else if (command is FlushRequest)
                     {

+ 6 - 1
SMBLibrary/Server/StateObject.cs

@@ -190,8 +190,13 @@ namespace SMBLibrary.Server
 
         public ushort AddOpenedFile(string relativePath, Stream stream)
         {
+            return AddOpenedFile(relativePath, stream, false);
+        }
+
+        public ushort AddOpenedFile(string relativePath, Stream stream, bool deleteOnClose)
+        {
             ushort fileID = AllocateFileID();
-            m_openedFiles.Add(fileID, new OpenedFileObject(relativePath, stream));
+            m_openedFiles.Add(fileID, new OpenedFileObject(relativePath, stream, deleteOnClose));
             return fileID;
         }