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
* 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;
}
}
}

View file

@ -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);

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
* 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;
}

View file

@ -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)
{

View file

@ -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;
}