honor FILE_DELETE_ON_CLOSE flag

This commit is contained in:
Tal Aloni 2017-01-06 10:42:15 +02:00
parent 0f1a691747
commit ab858afee9
5 changed files with 29 additions and 9 deletions

View file

@ -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 * 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, * the GNU Lesser Public License as published by the Free Software Foundation,
@ -15,11 +15,13 @@ namespace SMBLibrary.Server
{ {
public string Path; public string Path;
public Stream Stream; public Stream Stream;
public bool DeleteOnClose;
public OpenedFileObject(string path, Stream stream) public OpenedFileObject(string path, Stream stream, bool deleteOnClose)
{ {
Path = path; Path = path;
Stream = stream; Stream = stream;
DeleteOnClose = deleteOnClose;
} }
} }
} }

View file

@ -246,6 +246,7 @@ namespace SMBLibrary.Server
} }
Stream stream; Stream stream;
bool deleteOnClose = false;
if (fileAccess == (FileAccess)0 || entry.IsDirectory) if (fileAccess == (FileAccess)0 || entry.IsDirectory)
{ {
stream = null; 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. // 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 // 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). // 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 openReparsePoint = (request.CreateOptions & CreateOptions.FILE_OPEN_REPARSE_POINT) > 0;
bool disableBuffering = (request.CreateOptions & CreateOptions.FILE_NO_INTERMEDIATE_BUFFERING) > 0; bool disableBuffering = (request.CreateOptions & CreateOptions.FILE_NO_INTERMEDIATE_BUFFERING) > 0;
bool buffered = (request.CreateOptions & CreateOptions.FILE_SEQUENTIAL_ONLY) > 0 && !disableBuffering && !openReparsePoint; 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) if (isExtended)
{ {
NTCreateAndXResponseExtended response = CreateResponseExtendedFromFileSystemEntry(entry, fileID); NTCreateAndXResponseExtended response = CreateResponseExtendedFromFileSystemEntry(entry, fileID);

View file

@ -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 * 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, * the GNU Lesser Public License as published by the Free Software Foundation,
@ -15,16 +15,27 @@ namespace SMBLibrary.Server
{ {
public partial class ServerResponseHelper 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); OpenedFileObject openedFile = state.GetOpenedFileObject(request.FID);
if (openedFilePath == null) if (openedFile == null)
{ {
header.Status = NTStatus.STATUS_SMB_BAD_FID; header.Status = NTStatus.STATUS_SMB_BAD_FID;
return new ErrorResponse(CommandName.SMB_COM_CLOSE); return new ErrorResponse(CommandName.SMB_COM_CLOSE);
} }
state.RemoveOpenedFile(request.FID); 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(); CloseResponse response = new CloseResponse();
return response; return response;
} }

View file

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

View file

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