mirror of
https://github.com/TalAloni/SMBLibrary.git
synced 2025-04-30 02:37:49 +02:00
NTFileSystemHelper: Added OpenFile helper method
This commit is contained in:
parent
2460401955
commit
b24345b5ca
3 changed files with 55 additions and 60 deletions
|
@ -256,6 +256,53 @@ namespace SMBLibrary.Server
|
|||
}
|
||||
}
|
||||
|
||||
public static NTStatus OpenFile(out Stream stream, IFileSystem fileSystem, string path, FileAccess fileAccess, ShareAccess shareAccess, bool buffered, ConnectionState state)
|
||||
{
|
||||
stream = null;
|
||||
FileShare fileShare = NTFileSystemHelper.ToFileShare(shareAccess);
|
||||
state.LogToServer(Severity.Verbose, "OpenFile: Opening '{0}', Access={1}, Share={2}, Buffered={3}", path, fileAccess, fileShare, buffered);
|
||||
try
|
||||
{
|
||||
stream = fileSystem.OpenFile(path, FileMode.Open, fileAccess, fileShare);
|
||||
}
|
||||
catch (DirectoryNotFoundException)
|
||||
{
|
||||
state.LogToServer(Severity.Debug, "OpenFile: Cannot open '{0}'. Directory not found.", path);
|
||||
return NTStatus.STATUS_NO_SUCH_FILE;
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
state.LogToServer(Severity.Debug, "OpenFile: Cannot open '{0}'. File not found.", path);
|
||||
return NTStatus.STATUS_NO_SUCH_FILE;
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
ushort errorCode = IOExceptionHelper.GetWin32ErrorCode(ex);
|
||||
if (errorCode == (ushort)Win32Error.ERROR_SHARING_VIOLATION)
|
||||
{
|
||||
state.LogToServer(Severity.Debug, "OpenFile: Cannot open '{0}'. Sharing violation.", path);
|
||||
return NTStatus.STATUS_SHARING_VIOLATION;
|
||||
}
|
||||
else
|
||||
{
|
||||
state.LogToServer(Severity.Debug, "OpenFile: Cannot open '{0}'. Data Error.", path);
|
||||
return NTStatus.STATUS_DATA_ERROR;
|
||||
}
|
||||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
state.LogToServer(Severity.Debug, "OpenFile: Cannot open '{0}'. Access Denied.", path);
|
||||
return NTStatus.STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
if (buffered)
|
||||
{
|
||||
stream = new PrefetchedStream(stream);
|
||||
}
|
||||
|
||||
return NTStatus.STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
public static NTStatus ReadFile(out byte[] data, OpenFileObject openFile, long offset, int maxCount, ConnectionState state)
|
||||
{
|
||||
data = null;
|
||||
|
|
|
@ -57,9 +57,7 @@ namespace SMBLibrary.Server.SMB1
|
|||
return new ErrorResponse(CommandName.SMB_COM_NT_CREATE_ANDX);
|
||||
}
|
||||
|
||||
IFileSystem fileSystem = fileSystemShare.FileSystem;
|
||||
FileAccess fileAccess = NTFileSystemHelper.ToFileAccess(request.DesiredAccess);
|
||||
FileShare fileShare = NTFileSystemHelper.ToFileShare(request.ShareAccess);
|
||||
|
||||
Stream stream;
|
||||
bool deleteOnClose = false;
|
||||
|
@ -69,6 +67,7 @@ namespace SMBLibrary.Server.SMB1
|
|||
}
|
||||
else
|
||||
{
|
||||
IFileSystem fileSystem = fileSystemShare.FileSystem;
|
||||
// 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).
|
||||
|
@ -76,38 +75,12 @@ namespace SMBLibrary.Server.SMB1
|
|||
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;
|
||||
state.LogToServer(Severity.Verbose, "NTCreate: Opening '{0}', Access={1}, Share={2}, Buffered={3}", path, fileAccess, fileShare, buffered);
|
||||
try
|
||||
NTStatus openStatus = NTFileSystemHelper.OpenFile(out stream, fileSystem, path, fileAccess, request.ShareAccess, buffered, state);
|
||||
if (openStatus != NTStatus.STATUS_SUCCESS)
|
||||
{
|
||||
stream = fileSystem.OpenFile(path, FileMode.Open, fileAccess, fileShare);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
ushort errorCode = IOExceptionHelper.GetWin32ErrorCode(ex);
|
||||
if (errorCode == (ushort)Win32Error.ERROR_SHARING_VIOLATION)
|
||||
{
|
||||
state.LogToServer(Severity.Debug, "NTCreate: Sharing violation opening '{0}'", path);
|
||||
header.Status = NTStatus.STATUS_SHARING_VIOLATION;
|
||||
return new ErrorResponse(CommandName.SMB_COM_NT_CREATE_ANDX);
|
||||
}
|
||||
else
|
||||
{
|
||||
state.LogToServer(Severity.Debug, "NTCreate: Sharing violation opening '{0}', Data Error", path);
|
||||
header.Status = NTStatus.STATUS_DATA_ERROR;
|
||||
return new ErrorResponse(CommandName.SMB_COM_NT_CREATE_ANDX);
|
||||
}
|
||||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
state.LogToServer(Severity.Debug, "NTCreate: Sharing violation opening '{0}', Access Denied", path);
|
||||
header.Status = NTStatus.STATUS_ACCESS_DENIED;
|
||||
header.Status = openStatus;
|
||||
return new ErrorResponse(CommandName.SMB_COM_NT_CREATE_ANDX);
|
||||
}
|
||||
|
||||
if (buffered)
|
||||
{
|
||||
stream = new PrefetchedStream(stream);
|
||||
}
|
||||
}
|
||||
|
||||
ushort? fileID = session.AddOpenFile(path, stream, deleteOnClose);
|
||||
|
|
|
@ -50,9 +50,7 @@ namespace SMBLibrary.Server.SMB2
|
|||
return new ErrorResponse(request.CommandName, createStatus);
|
||||
}
|
||||
|
||||
IFileSystem fileSystem = fileSystemShare.FileSystem;
|
||||
FileAccess fileAccess = NTFileSystemHelper.ToFileAccess(request.DesiredAccess.File);
|
||||
FileShare fileShare = NTFileSystemHelper.ToFileShare(request.ShareAccess);
|
||||
|
||||
Stream stream;
|
||||
bool deleteOnClose = false;
|
||||
|
@ -62,6 +60,7 @@ namespace SMBLibrary.Server.SMB2
|
|||
}
|
||||
else
|
||||
{
|
||||
IFileSystem fileSystem = fileSystemShare.FileSystem;
|
||||
// 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).
|
||||
|
@ -69,34 +68,10 @@ namespace SMBLibrary.Server.SMB2
|
|||
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;
|
||||
state.LogToServer(Severity.Verbose, "Create: Opening '{0}', Access={1}, Share={2}, Buffered={3}", path, fileAccess, fileShare, buffered);
|
||||
try
|
||||
NTStatus openStatus = NTFileSystemHelper.OpenFile(out stream, fileSystem, path, fileAccess, request.ShareAccess, buffered, state);
|
||||
if (openStatus != NTStatus.STATUS_SUCCESS)
|
||||
{
|
||||
stream = fileSystem.OpenFile(path, FileMode.Open, fileAccess, fileShare);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
ushort errorCode = IOExceptionHelper.GetWin32ErrorCode(ex);
|
||||
if (errorCode == (ushort)Win32Error.ERROR_SHARING_VIOLATION)
|
||||
{
|
||||
state.LogToServer(Severity.Debug, "NTCreate: Sharing violation opening '{0}'", path);
|
||||
return new ErrorResponse(request.CommandName, NTStatus.STATUS_SHARING_VIOLATION);
|
||||
}
|
||||
else
|
||||
{
|
||||
state.LogToServer(Severity.Debug, "NTCreate: Sharing violation opening '{0}', Data Error", path);
|
||||
return new ErrorResponse(request.CommandName, NTStatus.STATUS_DATA_ERROR);
|
||||
}
|
||||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
state.LogToServer(Severity.Debug, "NTCreate: Sharing violation opening '{0}', Access Denied", path);
|
||||
return new ErrorResponse(request.CommandName, NTStatus.STATUS_ACCESS_DENIED);
|
||||
}
|
||||
|
||||
if (buffered)
|
||||
{
|
||||
stream = new PrefetchedStream(stream);
|
||||
return new ErrorResponse(request.CommandName, openStatus);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue