diff --git a/SMBLibrary/Server/OpenedFileObject.cs b/SMBLibrary/Server/OpenedFileObject.cs index b16758f..2634a2d 100644 --- a/SMBLibrary/Server/OpenedFileObject.cs +++ b/SMBLibrary/Server/OpenedFileObject.cs @@ -1,4 +1,4 @@ -/* Copyright (C) 2014-2016 Tal Aloni . All rights reserved. +/* Copyright (C) 2014-2017 Tal Aloni . 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; } } } diff --git a/SMBLibrary/Server/ResponseHelpers/NTCreateHelper.cs b/SMBLibrary/Server/ResponseHelpers/NTCreateHelper.cs index f342f87..a1d0348 100644 --- a/SMBLibrary/Server/ResponseHelpers/NTCreateHelper.cs +++ b/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); diff --git a/SMBLibrary/Server/ResponseHelpers/ServerResponseHelper.cs b/SMBLibrary/Server/ResponseHelpers/ServerResponseHelper.cs index 5a57bde..db27d89 100644 --- a/SMBLibrary/Server/ResponseHelpers/ServerResponseHelper.cs +++ b/SMBLibrary/Server/ResponseHelpers/ServerResponseHelper.cs @@ -1,4 +1,4 @@ -/* Copyright (C) 2014 Tal Aloni . All rights reserved. +/* Copyright (C) 2014-2017 Tal Aloni . 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; } diff --git a/SMBLibrary/Server/SMBServer.cs b/SMBLibrary/Server/SMBServer.cs index e3fd875..081c426 100644 --- a/SMBLibrary/Server/SMBServer.cs +++ b/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) { diff --git a/SMBLibrary/Server/StateObject.cs b/SMBLibrary/Server/StateObject.cs index 0e0c3e6..d0ebe74 100644 --- a/SMBLibrary/Server/StateObject.cs +++ b/SMBLibrary/Server/StateObject.cs @@ -189,9 +189,14 @@ 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; }