mirror of
https://github.com/TalAloni/SMBLibrary.git
synced 2025-07-03 00:03:19 +02:00
Added DeviceIOControl to the INTFileStore interface, relevant functionality moved to the object store layer
This commit is contained in:
parent
0d5898bb60
commit
3e158fb855
9 changed files with 90 additions and 59 deletions
|
@ -370,6 +370,12 @@ namespace SMBLibrary
|
|||
return NTStatus.STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
public NTStatus DeviceIOControl(object handle, uint ctlCode, byte[] input, out byte[] output, int maxOutputLength)
|
||||
{
|
||||
output = null;
|
||||
return NTStatus.STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
public void Log(Severity severity, string message)
|
||||
{
|
||||
// To be thread-safe we must capture the delegate reference first
|
||||
|
|
22
SMBLibrary/NTFileStore/Enums/IoControlCode.cs
Normal file
22
SMBLibrary/NTFileStore/Enums/IoControlCode.cs
Normal file
|
@ -0,0 +1,22 @@
|
|||
|
||||
namespace SMBLibrary
|
||||
{
|
||||
public enum IoControlCode : uint
|
||||
{
|
||||
FSCTL_DFS_GET_REFERRALS = 0x00060194, // SMB2-specific processing
|
||||
FSCTL_DFS_GET_REFERRALS_EX = 0x000601B0, // SMB2-specific processing
|
||||
FSCTL_SET_REPARSE_POINT = 0x000900A4, // SMB2-specific processing
|
||||
FSCTL_FILE_LEVEL_TRIM = 0x00098208, // SMB2-specific processing
|
||||
FSCTL_PIPE_WAIT = 0x00110018, // SMB2-specific processing
|
||||
FSCTL_PIPE_PEEK = 0x0011400C, // SMB2-specific processing
|
||||
FSCTL_PIPE_TRANSCEIVE = 0x0011C017, // SMB2-specific processing
|
||||
FSCTL_SRV_REQUEST_RESUME_KEY = 0x00140078, // SMB2-specific processing
|
||||
FSCTL_VALIDATE_NEGOTIATE_INFO = 0x00140204, // SMB2-specific processing
|
||||
FSCTL_LMR_REQUEST_RESILIENCY = 0x001401D4, // SMB2-specific processing
|
||||
FSCTL_QUERY_NETWORK_INTERFACE_INFO = 0x001401FC, // SMB2-specific processing
|
||||
FSCTL_SRV_ENUMERATE_SNAPSHOTS = 0x00144064, // SMB2-specific processing
|
||||
FSCTL_SRV_COPYCHUNK = 0x001440F2, // SMB2-specific processing
|
||||
FSCTL_SRV_READ_HASH = 0x001441BB, // SMB2-specific processing
|
||||
FSCTL_SRV_COPYCHUNK_WRITE = 0x001480F2, // SMB2-specific processing
|
||||
}
|
||||
}
|
|
@ -33,5 +33,7 @@ namespace SMBLibrary
|
|||
NTStatus SetFileInformation(object handle, FileInformation information);
|
||||
|
||||
NTStatus GetFileSystemInformation(out FileSystemInformation result, FileSystemInformationClass informationClass);
|
||||
|
||||
NTStatus DeviceIOControl(object handle, uint ctlCode, byte[] input, out byte[] output, int maxOutputLength);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -99,6 +99,28 @@ namespace SMBLibrary
|
|||
return NTStatus.STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
public NTStatus DeviceIOControl(object handle, uint ctlCode, byte[] input, out byte[] output, int maxOutputLength)
|
||||
{
|
||||
output = null;
|
||||
if (ctlCode == (uint)IoControlCode.FSCTL_PIPE_TRANSCEIVE)
|
||||
{
|
||||
int numberOfBytesWritten;
|
||||
NTStatus writeStatus = WriteFile(out numberOfBytesWritten, handle, 0, input);
|
||||
if (writeStatus != NTStatus.STATUS_SUCCESS)
|
||||
{
|
||||
return writeStatus;
|
||||
}
|
||||
NTStatus readStatus = ReadFile(out output, handle, 0, maxOutputLength);
|
||||
if (readStatus != NTStatus.STATUS_SUCCESS)
|
||||
{
|
||||
return readStatus;
|
||||
}
|
||||
return NTStatus.STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
return NTStatus.STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
public NTStatus QueryDirectory(out List<QueryDirectoryFileInformation> result, object directoryHandle, string fileName, FileInformationClass informationClass)
|
||||
{
|
||||
result = null;
|
||||
|
|
|
@ -93,6 +93,7 @@
|
|||
<Compile Include="NTFileStore\Enums\FileSystemInformation\FileSystemControlFlags.cs" />
|
||||
<Compile Include="NTFileStore\Enums\FileSystemInformation\FileSystemInformationClass.cs" />
|
||||
<Compile Include="NTFileStore\Enums\FileSystemInformation\SectorSizeInformationFlags.cs" />
|
||||
<Compile Include="NTFileStore\Enums\IoControlCode.cs" />
|
||||
<Compile Include="NTFileStore\Enums\NtCreateFile\CreateDisposition.cs" />
|
||||
<Compile Include="NTFileStore\Enums\NtCreateFile\CreateOptions.cs" />
|
||||
<Compile Include="NTFileStore\Enums\NtCreateFile\FileStatus.cs" />
|
||||
|
|
|
@ -80,7 +80,7 @@ namespace SMBLibrary.Server.SMB1
|
|||
}
|
||||
else if (subcommand is NTTransactIOCTLRequest)
|
||||
{
|
||||
subcommandResponse = GetSubcommandResponse(header, (NTTransactIOCTLRequest)subcommand);
|
||||
subcommandResponse = GetSubcommandResponse(header, (NTTransactIOCTLRequest)subcommand, share, state);
|
||||
}
|
||||
else if (subcommand is NTTransactSetSecurityDescriptor)
|
||||
{
|
||||
|
@ -112,25 +112,28 @@ namespace SMBLibrary.Server.SMB1
|
|||
return response;
|
||||
}
|
||||
|
||||
private static NTTransactIOCTLResponse GetSubcommandResponse(SMB1Header header, NTTransactIOCTLRequest subcommand)
|
||||
private static NTTransactIOCTLResponse GetSubcommandResponse(SMB1Header header, NTTransactIOCTLRequest subcommand, ISMBShare share, SMB1ConnectionState state)
|
||||
{
|
||||
const uint FSCTL_CREATE_OR_GET_OBJECT_ID = 0x900C0;
|
||||
|
||||
SMB1Session session = state.GetSession(header.UID);
|
||||
NTTransactIOCTLResponse response = new NTTransactIOCTLResponse();
|
||||
if (subcommand.IsFsctl)
|
||||
{
|
||||
if (subcommand.FunctionCode == FSCTL_CREATE_OR_GET_OBJECT_ID)
|
||||
OpenFileObject openFile = session.GetOpenFileObject(subcommand.FID);
|
||||
if (openFile == null)
|
||||
{
|
||||
ObjectIDBufferType1 objectID = new ObjectIDBufferType1();
|
||||
objectID.ObjectId = Guid.NewGuid();
|
||||
response.Data = objectID.GetBytes();
|
||||
return response;
|
||||
}
|
||||
else
|
||||
{
|
||||
header.Status = NTStatus.STATUS_NOT_IMPLEMENTED;
|
||||
header.Status = NTStatus.STATUS_INVALID_HANDLE;
|
||||
return null;
|
||||
}
|
||||
int maxOutputLength = UInt16.MaxValue;
|
||||
byte[] output;
|
||||
header.Status = share.FileStore.DeviceIOControl(openFile.Handle, subcommand.FunctionCode, subcommand.Data, out output, maxOutputLength);
|
||||
if (header.Status != NTStatus.STATUS_SUCCESS)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
response.Data = output;
|
||||
return response;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -134,14 +134,7 @@ namespace SMBLibrary.Server.SMB1
|
|||
}
|
||||
else if (subcommand is TransactionTransactNamedPipeRequest)
|
||||
{
|
||||
if (!(share is NamedPipeShare))
|
||||
{
|
||||
// [MS-CIFS] If the pipe is not a message mode pipe, the Trans subsystem MUST fail the request with STATUS_INVALID_PARAMETER
|
||||
header.Status = NTStatus.STATUS_INVALID_PARAMETER;
|
||||
return new ErrorResponse(CommandName.SMB_COM_TRANSACTION);
|
||||
}
|
||||
|
||||
subcommandResponse = TransactionSubcommandHelper.GetSubcommandResponse(header, (TransactionTransactNamedPipeRequest)subcommand, (NamedPipeShare)share, state);
|
||||
subcommandResponse = TransactionSubcommandHelper.GetSubcommandResponse(header, (TransactionTransactNamedPipeRequest)subcommand, share, state);
|
||||
}
|
||||
else if (subcommand is TransactionRawWriteNamedPipeRequest)
|
||||
{
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace SMBLibrary.Server.SMB1
|
|||
{
|
||||
public class TransactionSubcommandHelper
|
||||
{
|
||||
internal static TransactionTransactNamedPipeResponse GetSubcommandResponse(SMB1Header header, TransactionTransactNamedPipeRequest subcommand, NamedPipeShare share, SMB1ConnectionState state)
|
||||
internal static TransactionTransactNamedPipeResponse GetSubcommandResponse(SMB1Header header, TransactionTransactNamedPipeRequest subcommand, ISMBShare share, SMB1ConnectionState state)
|
||||
{
|
||||
SMB1Session session = state.GetSession(header.UID);
|
||||
OpenFileObject openFile = session.GetOpenFileObject(subcommand.FID);
|
||||
|
@ -26,19 +26,15 @@ namespace SMBLibrary.Server.SMB1
|
|||
return null;
|
||||
}
|
||||
|
||||
int maxOutputLength = UInt16.MaxValue;
|
||||
byte[] output;
|
||||
header.Status = share.FileStore.DeviceIOControl(openFile.Handle, (uint)IoControlCode.FSCTL_PIPE_TRANSCEIVE, subcommand.WriteData, out output, maxOutputLength);
|
||||
if (header.Status != NTStatus.STATUS_SUCCESS)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
TransactionTransactNamedPipeResponse response = new TransactionTransactNamedPipeResponse();
|
||||
int numberOfBytesWritten;
|
||||
header.Status = share.FileStore.WriteFile(out numberOfBytesWritten, openFile.Handle, 0, subcommand.WriteData);
|
||||
if (header.Status != NTStatus.STATUS_SUCCESS)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
int maxCount = UInt16.MaxValue;
|
||||
header.Status = share.FileStore.ReadFile(out response.ReadData, openFile.Handle, 0, maxCount);
|
||||
if (header.Status != NTStatus.STATUS_SUCCESS)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
response.ReadData = output;
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,14 +14,11 @@ namespace SMBLibrary.Server.SMB2
|
|||
{
|
||||
public class IOCtlHelper
|
||||
{
|
||||
private const uint FSCTL_DFS_GET_REFERRALS = 0x00060194;
|
||||
private const uint FSCTL_DFS_GET_REFERRALS_EX = 0x000601B0;
|
||||
private const uint FSCTL_PIPE_TRANSCEIVE = 0x0011C017;
|
||||
|
||||
internal static SMB2Command GetIOCtlResponse(IOCtlRequest request, ISMBShare share, SMB2ConnectionState state)
|
||||
{
|
||||
SMB2Session session = state.GetSession(request.Header.SessionID);
|
||||
if (request.CtlCode == FSCTL_DFS_GET_REFERRALS || request.CtlCode == FSCTL_DFS_GET_REFERRALS_EX)
|
||||
if (request.CtlCode == (uint)IoControlCode.FSCTL_DFS_GET_REFERRALS ||
|
||||
request.CtlCode == (uint)IoControlCode.FSCTL_DFS_GET_REFERRALS_EX)
|
||||
{
|
||||
// [MS-SMB2] 3.3.5.15.2 Handling a DFS Referral Information Request
|
||||
return new ErrorResponse(request.CommandName, NTStatus.STATUS_FS_DRIVER_REQUIRED);
|
||||
|
@ -33,29 +30,18 @@ namespace SMBLibrary.Server.SMB2
|
|||
return new ErrorResponse(request.CommandName, NTStatus.STATUS_FILE_CLOSED);
|
||||
}
|
||||
|
||||
if (share is NamedPipeShare)
|
||||
int maxOutputLength = (int)request.MaxOutputResponse;
|
||||
byte[] output;
|
||||
NTStatus status = share.FileStore.DeviceIOControl(openFile.Handle, request.CtlCode, request.Input, out output, maxOutputLength);
|
||||
if (status != NTStatus.STATUS_SUCCESS)
|
||||
{
|
||||
if (request.CtlCode == FSCTL_PIPE_TRANSCEIVE)
|
||||
{
|
||||
IOCtlResponse response = new IOCtlResponse();
|
||||
response.CtlCode = request.CtlCode;
|
||||
int numberOfBytesWritten;
|
||||
NTStatus writeStatus = share.FileStore.WriteFile(out numberOfBytesWritten, openFile.Handle, 0, request.Input);
|
||||
if (writeStatus != NTStatus.STATUS_SUCCESS)
|
||||
{
|
||||
return new ErrorResponse(request.CommandName, writeStatus);
|
||||
}
|
||||
int maxCount = (int)request.MaxOutputResponse;
|
||||
NTStatus readStatus = share.FileStore.ReadFile(out response.Output, openFile.Handle, 0, maxCount);
|
||||
if (readStatus != NTStatus.STATUS_SUCCESS)
|
||||
{
|
||||
return new ErrorResponse(request.CommandName, readStatus);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
return new ErrorResponse(request.CommandName, status);
|
||||
}
|
||||
|
||||
return new ErrorResponse(request.CommandName, NTStatus.STATUS_NOT_SUPPORTED);
|
||||
IOCtlResponse response = new IOCtlResponse();
|
||||
response.CtlCode = request.CtlCode;
|
||||
response.Output = output;
|
||||
return response;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue