dll: major overhaul of FSP_FILE_SYSTEM dispatching

This commit is contained in:
Bill Zissimopoulos 2016-02-16 17:03:00 -08:00
parent f8d5273e04
commit d8c35f26b0
13 changed files with 337 additions and 476 deletions

View File

@ -31,7 +31,7 @@
<ClCompile Include="..\..\src\dll\fileinfo.c" /> <ClCompile Include="..\..\src\dll\fileinfo.c" />
<ClCompile Include="..\..\src\dll\fsctl.c" /> <ClCompile Include="..\..\src\dll\fsctl.c" />
<ClCompile Include="..\..\src\dll\library.c" /> <ClCompile Include="..\..\src\dll\library.c" />
<ClCompile Include="..\..\src\dll\loop.c" /> <ClCompile Include="..\..\src\dll\dispatch.c" />
<ClCompile Include="..\..\src\dll\ntstatus.c" /> <ClCompile Include="..\..\src\dll\ntstatus.c" />
<ClCompile Include="..\..\src\dll\path.c" /> <ClCompile Include="..\..\src\dll\path.c" />
<ClCompile Include="..\..\src\dll\volinfo.c" /> <ClCompile Include="..\..\src\dll\volinfo.c" />

View File

@ -37,9 +37,6 @@
<ClCompile Include="..\..\src\dll\fsctl.c"> <ClCompile Include="..\..\src\dll\fsctl.c">
<Filter>Source</Filter> <Filter>Source</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\dll\loop.c">
<Filter>Source</Filter>
</ClCompile>
<ClCompile Include="..\..\src\dll\create.c"> <ClCompile Include="..\..\src\dll\create.c">
<Filter>Source</Filter> <Filter>Source</Filter>
</ClCompile> </ClCompile>
@ -58,6 +55,9 @@
<ClCompile Include="..\..\src\dll\volinfo.c"> <ClCompile Include="..\..\src\dll\volinfo.c">
<Filter>Source</Filter> <Filter>Source</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\dll\dispatch.c">
<Filter>Source</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\..\src\dll\ntstatus.i"> <None Include="..\..\src\dll\ntstatus.i">

View File

@ -29,8 +29,10 @@ extern "C" {
* File System * File System
*/ */
typedef struct _FSP_FILE_SYSTEM FSP_FILE_SYSTEM; typedef struct _FSP_FILE_SYSTEM FSP_FILE_SYSTEM;
typedef VOID FSP_FILE_SYSTEM_DISPATCHER(FSP_FILE_SYSTEM *, FSP_FSCTL_TRANSACT_REQ *); typedef VOID FSP_FILE_SYSTEM_OPERATION_GUARD(FSP_FILE_SYSTEM *,
typedef NTSTATUS FSP_FILE_SYSTEM_OPERATION(FSP_FILE_SYSTEM *, FSP_FSCTL_TRANSACT_REQ *); FSP_FSCTL_TRANSACT_REQ *, FSP_FSCTL_TRANSACT_RSP *);
typedef NTSTATUS FSP_FILE_SYSTEM_OPERATION(FSP_FILE_SYSTEM *,
FSP_FSCTL_TRANSACT_REQ *, FSP_FSCTL_TRANSACT_RSP *);
typedef struct _FSP_FILE_SYSTEM_INTERFACE typedef struct _FSP_FILE_SYSTEM_INTERFACE
{ {
NTSTATUS (*GetVolumeInfo)(FSP_FILE_SYSTEM *FileSystem, NTSTATUS (*GetVolumeInfo)(FSP_FILE_SYSTEM *FileSystem,
@ -89,31 +91,39 @@ typedef struct _FSP_FILE_SYSTEM
WCHAR VolumeName[FSP_FSCTL_VOLUME_NAME_SIZEMAX / sizeof(WCHAR)]; WCHAR VolumeName[FSP_FSCTL_VOLUME_NAME_SIZEMAX / sizeof(WCHAR)];
HANDLE VolumeHandle; HANDLE VolumeHandle;
PVOID UserContext; PVOID UserContext;
NTSTATUS DispatcherResult; FSP_FILE_SYSTEM_OPERATION_GUARD *EnterOperation, *LeaveOperation;
FSP_FILE_SYSTEM_DISPATCHER *Dispatcher;
FSP_FILE_SYSTEM_DISPATCHER *EnterOperation, *LeaveOperation;
FSP_FILE_SYSTEM_OPERATION *Operations[FspFsctlTransactKindCount]; FSP_FILE_SYSTEM_OPERATION *Operations[FspFsctlTransactKindCount];
const FSP_FILE_SYSTEM_INTERFACE *Interface; const FSP_FILE_SYSTEM_INTERFACE *Interface;
HANDLE DispatcherThread;
ULONG DispatcherThreadCount;
NTSTATUS DispatcherResult;
} FSP_FILE_SYSTEM; } FSP_FILE_SYSTEM;
FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath, FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath,
const FSP_FSCTL_VOLUME_PARAMS *VolumeParams, const FSP_FSCTL_VOLUME_PARAMS *VolumeParams,
const FSP_FILE_SYSTEM_INTERFACE *Interface, const FSP_FILE_SYSTEM_INTERFACE *Interface,
FSP_FILE_SYSTEM **PFileSystem); FSP_FILE_SYSTEM **PFileSystem);
FSP_API VOID FspFileSystemDelete(FSP_FILE_SYSTEM *FileSystem); FSP_API VOID FspFileSystemDelete(FSP_FILE_SYSTEM *FileSystem);
FSP_API NTSTATUS FspFileSystemLoop(FSP_FILE_SYSTEM *FileSystem); FSP_API NTSTATUS FspFileSystemStartDispatcher(FSP_FILE_SYSTEM *FileSystem, ULONG ThreadCount);
FSP_API VOID FspFileSystemStopDispatcher(FSP_FILE_SYSTEM *FileSystem);
FSP_API VOID FspFileSystemDirectDispatcher(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request);
FSP_API VOID FspFileSystemPoolDispatcher(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request);
static inline static inline
VOID FspFileSystemSetDispatcher(FSP_FILE_SYSTEM *FileSystem, VOID FspFileSystemEnterOperation(FSP_FILE_SYSTEM *FileSystem,
FSP_FILE_SYSTEM_DISPATCHER *Dispatcher, FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
FSP_FILE_SYSTEM_DISPATCHER *EnterOperation, {
FSP_FILE_SYSTEM_DISPATCHER *LeaveOperation) if (0 != FileSystem->EnterOperation)
FileSystem->EnterOperation(FileSystem, Request, Response);
}
static inline
VOID FspFileSystemLeaveOperation(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
{
if (0 != FileSystem->LeaveOperation)
FileSystem->LeaveOperation(FileSystem, Request, Response);
}
static inline
VOID FspFileSystemSetOperationGuard(FSP_FILE_SYSTEM *FileSystem,
FSP_FILE_SYSTEM_OPERATION_GUARD *EnterOperation,
FSP_FILE_SYSTEM_OPERATION_GUARD *LeaveOperation)
{ {
FileSystem->Dispatcher = Dispatcher;
FileSystem->EnterOperation = EnterOperation; FileSystem->EnterOperation = EnterOperation;
FileSystem->LeaveOperation = LeaveOperation; FileSystem->LeaveOperation = LeaveOperation;
} }
@ -124,7 +134,6 @@ VOID FspFileSystemSetOperation(FSP_FILE_SYSTEM *FileSystem,
{ {
FileSystem->Operations[Index] = Operation; FileSystem->Operations[Index] = Operation;
} }
static inline static inline
VOID FspFileSystemGetDispatcherResult(FSP_FILE_SYSTEM *FileSystem, VOID FspFileSystemGetDispatcherResult(FSP_FILE_SYSTEM *FileSystem,
NTSTATUS *PDispatcherResult) NTSTATUS *PDispatcherResult)
@ -142,26 +151,6 @@ VOID FspFileSystemSetDispatcherResult(FSP_FILE_SYSTEM *FileSystem,
InterlockedCompareExchange(&FileSystem->DispatcherResult, DispatcherResult, 0); InterlockedCompareExchange(&FileSystem->DispatcherResult, DispatcherResult, 0);
} }
static inline
VOID FspFileSystemEnterOperation(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request)
{
if (0 != FileSystem->EnterOperation)
FileSystem->EnterOperation(FileSystem, Request);
}
static inline
VOID FspFileSystemLeaveOperation(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request)
{
if (0 != FileSystem->LeaveOperation)
FileSystem->LeaveOperation(FileSystem, Request);
}
FSP_API NTSTATUS FspFileSystemSendResponse(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_RSP *Response);
FSP_API NTSTATUS FspFileSystemSendResponseWithStatus(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, NTSTATUS Result);
/* /*
* File System Operations * File System Operations
*/ */
@ -178,36 +167,19 @@ FSP_API NTSTATUS FspAssignSecurity(FSP_FILE_SYSTEM *FileSystem,
FSP_API VOID FspDeleteSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, FSP_API VOID FspDeleteSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
NTSTATUS (*CreateFunc)()); NTSTATUS (*CreateFunc)());
FSP_API NTSTATUS FspFileSystemOpCreate(FSP_FILE_SYSTEM *FileSystem, FSP_API NTSTATUS FspFileSystemOpCreate(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request); FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
FSP_API NTSTATUS FspFileSystemOpOverwrite(FSP_FILE_SYSTEM *FileSystem, FSP_API NTSTATUS FspFileSystemOpOverwrite(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request); FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
FSP_API NTSTATUS FspFileSystemOpCleanup(FSP_FILE_SYSTEM *FileSystem, FSP_API NTSTATUS FspFileSystemOpCleanup(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request); FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
FSP_API NTSTATUS FspFileSystemOpClose(FSP_FILE_SYSTEM *FileSystem, FSP_API NTSTATUS FspFileSystemOpClose(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request); FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
FSP_API NTSTATUS FspFileSystemOpQueryInformation(FSP_FILE_SYSTEM *FileSystem, FSP_API NTSTATUS FspFileSystemOpQueryInformation(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request); FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
FSP_API NTSTATUS FspFileSystemOpSetInformation(FSP_FILE_SYSTEM *FileSystem, FSP_API NTSTATUS FspFileSystemOpSetInformation(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request); FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
FSP_API NTSTATUS FspFileSystemOpQueryVolumeInformation(FSP_FILE_SYSTEM *FileSystem, FSP_API NTSTATUS FspFileSystemOpQueryVolumeInformation(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request); FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
FSP_API NTSTATUS FspFileSystemSendCreateResponse(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, UINT_PTR Information,
PVOID FileNode, UINT32 GrantedAccess, const FSP_FSCTL_FILE_INFO *FileInfo);
FSP_API NTSTATUS FspFileSystemSendOverwriteResponse(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request,
const FSP_FSCTL_FILE_INFO *FileInfo);
FSP_API NTSTATUS FspFileSystemSendCleanupResponse(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request);
FSP_API NTSTATUS FspFileSystemSendCloseResponse(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request);
FSP_API NTSTATUS FspFileSystemSendQueryInformationResponse(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_FILE_INFO *FileInfo);
FSP_API NTSTATUS FspFileSystemSendSetInformationResponse(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_FILE_INFO *FileInfo);
FSP_API NTSTATUS FspFileSystemSendQueryVolumeInformationResponse(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_VOLUME_INFO *VolumeInfo);
static inline static inline
NTSTATUS FspAccessCheck(FSP_FILE_SYSTEM *FileSystem, NTSTATUS FspAccessCheck(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_REQ *Request,

View File

@ -7,7 +7,7 @@
#include <dll/library.h> #include <dll/library.h>
FSP_API NTSTATUS FspFileSystemOpCleanup(FSP_FILE_SYSTEM *FileSystem, FSP_API NTSTATUS FspFileSystemOpCleanup(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request) FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
{ {
if (0 != FileSystem->Interface->Cleanup) if (0 != FileSystem->Interface->Cleanup)
FileSystem->Interface->Cleanup(FileSystem, Request, FileSystem->Interface->Cleanup(FileSystem, Request,
@ -15,19 +15,5 @@ FSP_API NTSTATUS FspFileSystemOpCleanup(FSP_FILE_SYSTEM *FileSystem,
0 != Request->FileName.Size ? (PWSTR)Request->Buffer : 0, 0 != Request->FileName.Size ? (PWSTR)Request->Buffer : 0,
0 != Request->Req.Cleanup.Delete); 0 != Request->Req.Cleanup.Delete);
return FspFileSystemSendCleanupResponse(FileSystem, Request); return STATUS_SUCCESS;
}
FSP_API NTSTATUS FspFileSystemSendCleanupResponse(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request)
{
FSP_FSCTL_TRANSACT_RSP Response;
memset(&Response, 0, sizeof Response);
Response.Size = sizeof Response;
Response.Kind = FspFsctlTransactCleanupKind;
Response.Hint = Request->Hint;
Response.IoStatus.Status = STATUS_SUCCESS;
Response.IoStatus.Information = 0;
return FspFileSystemSendResponse(FileSystem, &Response);
} }

View File

@ -7,25 +7,11 @@
#include <dll/library.h> #include <dll/library.h>
FSP_API NTSTATUS FspFileSystemOpClose(FSP_FILE_SYSTEM *FileSystem, FSP_API NTSTATUS FspFileSystemOpClose(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request) FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
{ {
if (0 != FileSystem->Interface->Close) if (0 != FileSystem->Interface->Close)
FileSystem->Interface->Close(FileSystem, Request, FileSystem->Interface->Close(FileSystem, Request,
(PVOID)Request->Req.Close.UserContext); (PVOID)Request->Req.Close.UserContext);
return FspFileSystemSendCloseResponse(FileSystem, Request); return STATUS_SUCCESS;
}
FSP_API NTSTATUS FspFileSystemSendCloseResponse(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request)
{
FSP_FSCTL_TRANSACT_RSP Response;
memset(&Response, 0, sizeof Response);
Response.Size = sizeof Response;
Response.Kind = FspFsctlTransactCloseKind;
Response.Hint = Request->Hint;
Response.IoStatus.Status = STATUS_SUCCESS;
Response.IoStatus.Information = 0;
return FspFileSystemSendResponse(FileSystem, &Response);
} }

View File

@ -219,7 +219,7 @@ FSP_API NTSTATUS FspAssignSecurity(FSP_FILE_SYSTEM *FileSystem,
&FspFileGenericMapping)) &FspFileGenericMapping))
return FspNtStatusFromWin32(GetLastError()); return FspNtStatusFromWin32(GetLastError());
DEBUGLOGSD("SDDL=%s", *PSecurityDescriptor); //DEBUGLOGSD("SDDL=%s", *PSecurityDescriptor);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -298,7 +298,7 @@ NTSTATUS FspFileSystemOverwriteCheck(FSP_FILE_SYSTEM *FileSystem,
} }
static NTSTATUS FspFileSystemOpCreate_FileCreate(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS FspFileSystemOpCreate_FileCreate(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request) FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
{ {
NTSTATUS Result; NTSTATUS Result;
UINT32 GrantedAccess; UINT32 GrantedAccess;
@ -308,12 +308,12 @@ static NTSTATUS FspFileSystemOpCreate_FileCreate(FSP_FILE_SYSTEM *FileSystem,
Result = FspFileSystemCreateCheck(FileSystem, Request, TRUE, &GrantedAccess, &ParentDescriptor); Result = FspFileSystemCreateCheck(FileSystem, Request, TRUE, &GrantedAccess, &ParentDescriptor);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); return Result;
Result = FspAssignSecurity(FileSystem, Request, ParentDescriptor, &ObjectDescriptor); Result = FspAssignSecurity(FileSystem, Request, ParentDescriptor, &ObjectDescriptor);
FspDeleteSecurityDescriptor(ParentDescriptor, FspAccessCheckEx); FspDeleteSecurityDescriptor(ParentDescriptor, FspAccessCheckEx);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); return Result;
FileNode = 0; FileNode = 0;
memset(&FileInfo, 0, sizeof FileInfo); memset(&FileInfo, 0, sizeof FileInfo);
@ -323,14 +323,17 @@ static NTSTATUS FspFileSystemOpCreate_FileCreate(FSP_FILE_SYSTEM *FileSystem,
&FileNode, &FileInfo); &FileNode, &FileInfo);
FspDeleteSecurityDescriptor(ObjectDescriptor, FspAssignSecurity); FspDeleteSecurityDescriptor(ObjectDescriptor, FspAssignSecurity);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); return Result;
return FspFileSystemSendCreateResponse(FileSystem, Request, Response->IoStatus.Information = FILE_CREATED;
FILE_CREATED, FileNode, GrantedAccess, &FileInfo); Response->Rsp.Create.Opened.UserContext = (UINT_PTR)FileNode;
Response->Rsp.Create.Opened.GrantedAccess = GrantedAccess;
memcpy(&Response->Rsp.Create.Opened.FileInfo, &FileInfo, sizeof FileInfo);
return STATUS_SUCCESS;
} }
static NTSTATUS FspFileSystemOpCreate_FileOpen(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS FspFileSystemOpCreate_FileOpen(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request) FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
{ {
NTSTATUS Result; NTSTATUS Result;
UINT32 GrantedAccess; UINT32 GrantedAccess;
@ -339,7 +342,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOpen(FSP_FILE_SYSTEM *FileSystem,
Result = FspFileSystemOpenCheck(FileSystem, Request, TRUE, &GrantedAccess); Result = FspFileSystemOpenCheck(FileSystem, Request, TRUE, &GrantedAccess);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); return Result;
FileNode = 0; FileNode = 0;
memset(&FileInfo, 0, sizeof FileInfo); memset(&FileInfo, 0, sizeof FileInfo);
@ -347,14 +350,17 @@ static NTSTATUS FspFileSystemOpCreate_FileOpen(FSP_FILE_SYSTEM *FileSystem,
(PWSTR)Request->Buffer, Request->Req.Create.CaseSensitive, Request->Req.Create.CreateOptions, (PWSTR)Request->Buffer, Request->Req.Create.CaseSensitive, Request->Req.Create.CreateOptions,
&FileNode, &FileInfo); &FileNode, &FileInfo);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); return Result;
return FspFileSystemSendCreateResponse(FileSystem, Request, Response->IoStatus.Information = FILE_OPENED;
FILE_OPENED, FileNode, GrantedAccess, &FileInfo); Response->Rsp.Create.Opened.UserContext = (UINT_PTR)FileNode;
Response->Rsp.Create.Opened.GrantedAccess = GrantedAccess;
memcpy(&Response->Rsp.Create.Opened.FileInfo, &FileInfo, sizeof FileInfo);
return STATUS_SUCCESS;
} }
static NTSTATUS FspFileSystemOpCreate_FileOpenIf(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS FspFileSystemOpCreate_FileOpenIf(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request) FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
{ {
NTSTATUS Result; NTSTATUS Result;
UINT32 GrantedAccess; UINT32 GrantedAccess;
@ -367,7 +373,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenIf(FSP_FILE_SYSTEM *FileSystem,
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
{ {
if (STATUS_OBJECT_NAME_NOT_FOUND != Result) if (STATUS_OBJECT_NAME_NOT_FOUND != Result)
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); return Result;
Create = TRUE; Create = TRUE;
} }
@ -381,7 +387,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenIf(FSP_FILE_SYSTEM *FileSystem,
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
{ {
if (STATUS_OBJECT_NAME_NOT_FOUND != Result) if (STATUS_OBJECT_NAME_NOT_FOUND != Result)
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); return Result;
Create = TRUE; Create = TRUE;
} }
} }
@ -390,12 +396,12 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenIf(FSP_FILE_SYSTEM *FileSystem,
{ {
Result = FspFileSystemCreateCheck(FileSystem, Request, FALSE, &GrantedAccess, &ParentDescriptor); Result = FspFileSystemCreateCheck(FileSystem, Request, FALSE, &GrantedAccess, &ParentDescriptor);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); return Result;
Result = FspAssignSecurity(FileSystem, Request, ParentDescriptor, &ObjectDescriptor); Result = FspAssignSecurity(FileSystem, Request, ParentDescriptor, &ObjectDescriptor);
FspDeleteSecurityDescriptor(ParentDescriptor, FspAccessCheckEx); FspDeleteSecurityDescriptor(ParentDescriptor, FspAccessCheckEx);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); return Result;
FileNode = 0; FileNode = 0;
memset(&FileInfo, 0, sizeof FileInfo); memset(&FileInfo, 0, sizeof FileInfo);
@ -405,15 +411,18 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenIf(FSP_FILE_SYSTEM *FileSystem,
&FileNode, &FileInfo); &FileNode, &FileInfo);
FspDeleteSecurityDescriptor(ObjectDescriptor, FspAssignSecurity); FspDeleteSecurityDescriptor(ObjectDescriptor, FspAssignSecurity);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); return Result;
} }
return FspFileSystemSendCreateResponse(FileSystem, Request, Response->IoStatus.Information = Create ? FILE_CREATED : FILE_OPENED;
Create ? FILE_CREATED : FILE_OPENED, FileNode, GrantedAccess, &FileInfo); Response->Rsp.Create.Opened.UserContext = (UINT_PTR)FileNode;
Response->Rsp.Create.Opened.GrantedAccess = GrantedAccess;
memcpy(&Response->Rsp.Create.Opened.FileInfo, &FileInfo, sizeof FileInfo);
return STATUS_SUCCESS;
} }
static NTSTATUS FspFileSystemOpCreate_FileOverwrite(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS FspFileSystemOpCreate_FileOverwrite(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request) FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
{ {
NTSTATUS Result; NTSTATUS Result;
UINT32 GrantedAccess; UINT32 GrantedAccess;
@ -423,7 +432,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOverwrite(FSP_FILE_SYSTEM *FileSystem,
Result = FspFileSystemOverwriteCheck(FileSystem, Request, TRUE, &GrantedAccess); Result = FspFileSystemOverwriteCheck(FileSystem, Request, TRUE, &GrantedAccess);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); return Result;
FileNode = 0; FileNode = 0;
memset(&FileInfo, 0, sizeof FileInfo); memset(&FileInfo, 0, sizeof FileInfo);
@ -431,14 +440,17 @@ static NTSTATUS FspFileSystemOpCreate_FileOverwrite(FSP_FILE_SYSTEM *FileSystem,
(PWSTR)Request->Buffer, Request->Req.Create.CaseSensitive, Request->Req.Create.CreateOptions, (PWSTR)Request->Buffer, Request->Req.Create.CaseSensitive, Request->Req.Create.CreateOptions,
&FileNode, &FileInfo); &FileNode, &FileInfo);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); return Result;
return FspFileSystemSendCreateResponse(FileSystem, Request, Response->IoStatus.Information = Supersede ? FILE_SUPERSEDED : FILE_OVERWRITTEN;
Supersede ? FILE_SUPERSEDED : FILE_OVERWRITTEN, FileNode, GrantedAccess, &FileInfo); Response->Rsp.Create.Opened.UserContext = (UINT_PTR)FileNode;
Response->Rsp.Create.Opened.GrantedAccess = GrantedAccess;
memcpy(&Response->Rsp.Create.Opened.FileInfo, &FileInfo, sizeof FileInfo);
return STATUS_SUCCESS;
} }
static NTSTATUS FspFileSystemOpCreate_FileOverwriteIf(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS FspFileSystemOpCreate_FileOverwriteIf(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request) FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
{ {
NTSTATUS Result; NTSTATUS Result;
UINT32 GrantedAccess; UINT32 GrantedAccess;
@ -451,7 +463,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOverwriteIf(FSP_FILE_SYSTEM *FileSyste
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
{ {
if (STATUS_OBJECT_NAME_NOT_FOUND != Result) if (STATUS_OBJECT_NAME_NOT_FOUND != Result)
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); return Result;
Create = TRUE; Create = TRUE;
} }
@ -465,7 +477,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOverwriteIf(FSP_FILE_SYSTEM *FileSyste
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
{ {
if (STATUS_OBJECT_NAME_NOT_FOUND != Result) if (STATUS_OBJECT_NAME_NOT_FOUND != Result)
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); return Result;
Create = TRUE; Create = TRUE;
} }
} }
@ -474,12 +486,12 @@ static NTSTATUS FspFileSystemOpCreate_FileOverwriteIf(FSP_FILE_SYSTEM *FileSyste
{ {
Result = FspFileSystemCreateCheck(FileSystem, Request, FALSE, &GrantedAccess, &ParentDescriptor); Result = FspFileSystemCreateCheck(FileSystem, Request, FALSE, &GrantedAccess, &ParentDescriptor);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); return Result;
Result = FspAssignSecurity(FileSystem, Request, ParentDescriptor, &ObjectDescriptor); Result = FspAssignSecurity(FileSystem, Request, ParentDescriptor, &ObjectDescriptor);
FspDeleteSecurityDescriptor(ParentDescriptor, FspAccessCheckEx); FspDeleteSecurityDescriptor(ParentDescriptor, FspAccessCheckEx);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); return Result;
FileNode = 0; FileNode = 0;
memset(&FileInfo, 0, sizeof FileInfo); memset(&FileInfo, 0, sizeof FileInfo);
@ -489,15 +501,18 @@ static NTSTATUS FspFileSystemOpCreate_FileOverwriteIf(FSP_FILE_SYSTEM *FileSyste
&FileNode, &FileInfo); &FileNode, &FileInfo);
FspDeleteSecurityDescriptor(ObjectDescriptor, FspAssignSecurity); FspDeleteSecurityDescriptor(ObjectDescriptor, FspAssignSecurity);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); return Result;
} }
return FspFileSystemSendCreateResponse(FileSystem, Request, Response->IoStatus.Information = Create ? FILE_CREATED : FILE_OVERWRITTEN;
Create ? FILE_CREATED : FILE_OVERWRITTEN, FileNode, GrantedAccess, &FileInfo); Response->Rsp.Create.Opened.UserContext = (UINT_PTR)FileNode;
Response->Rsp.Create.Opened.GrantedAccess = GrantedAccess;
memcpy(&Response->Rsp.Create.Opened.FileInfo, &FileInfo, sizeof FileInfo);
return STATUS_SUCCESS;
} }
static NTSTATUS FspFileSystemOpCreate_FileOpenTargetDirectory(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS FspFileSystemOpCreate_FileOpenTargetDirectory(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request) FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
{ {
NTSTATUS Result; NTSTATUS Result;
WCHAR Root[2] = L"\\"; WCHAR Root[2] = L"\\";
@ -510,7 +525,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenTargetDirectory(FSP_FILE_SYSTEM *F
Result = FspAccessCheck(FileSystem, Request, TRUE, TRUE, Result = FspAccessCheck(FileSystem, Request, TRUE, TRUE,
Request->Req.Create.DesiredAccess, &GrantedAccess); Request->Req.Create.DesiredAccess, &GrantedAccess);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); return Result;
FileNode = 0; FileNode = 0;
memset(&FileInfo, 0, sizeof FileInfo); memset(&FileInfo, 0, sizeof FileInfo);
@ -520,7 +535,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenTargetDirectory(FSP_FILE_SYSTEM *F
&FileNode, &FileInfo); &FileNode, &FileInfo);
FspPathCombine((PWSTR)Request->Buffer, Suffix); FspPathCombine((PWSTR)Request->Buffer, Suffix);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); return Result;
Information = FILE_OPENED; Information = FILE_OPENED;
if (0 != FileSystem->Interface->GetSecurity) if (0 != FileSystem->Interface->GetSecurity)
@ -529,46 +544,51 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenTargetDirectory(FSP_FILE_SYSTEM *F
Information = NT_SUCCESS(Result) ? FILE_EXISTS : FILE_DOES_NOT_EXIST; Information = NT_SUCCESS(Result) ? FILE_EXISTS : FILE_DOES_NOT_EXIST;
} }
return FspFileSystemSendCreateResponse(FileSystem, Request, Response->IoStatus.Information = Information;
Information, FileNode, GrantedAccess, &FileInfo); Response->Rsp.Create.Opened.UserContext = (UINT_PTR)FileNode;
Response->Rsp.Create.Opened.GrantedAccess = GrantedAccess;
memcpy(&Response->Rsp.Create.Opened.FileInfo, &FileInfo, sizeof FileInfo);
return STATUS_SUCCESS;
} }
FSP_API NTSTATUS FspFileSystemOpCreate(FSP_FILE_SYSTEM *FileSystem, FSP_API NTSTATUS FspFileSystemOpCreate(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request) FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
{ {
if (0 == FileSystem->Interface->Create || if (0 == FileSystem->Interface->Create ||
0 == FileSystem->Interface->Open || 0 == FileSystem->Interface->Open ||
0 == FileSystem->Interface->Overwrite) 0 == FileSystem->Interface->Overwrite)
return FspFileSystemSendResponseWithStatus(FileSystem, Request, STATUS_INVALID_DEVICE_REQUEST); return STATUS_INVALID_DEVICE_REQUEST;
if (Request->Req.Create.OpenTargetDirectory) if (Request->Req.Create.OpenTargetDirectory)
return FspFileSystemOpCreate_FileOpenTargetDirectory(FileSystem, Request); return FspFileSystemOpCreate_FileOpenTargetDirectory(FileSystem, Request, Response);
switch ((Request->Req.Create.CreateOptions >> 24) & 0xff) switch ((Request->Req.Create.CreateOptions >> 24) & 0xff)
{ {
case FILE_CREATE: case FILE_CREATE:
return FspFileSystemOpCreate_FileCreate(FileSystem, Request); return FspFileSystemOpCreate_FileCreate(FileSystem, Request, Response);
case FILE_OPEN: case FILE_OPEN:
return FspFileSystemOpCreate_FileOpen(FileSystem, Request); return FspFileSystemOpCreate_FileOpen(FileSystem, Request, Response);
case FILE_OPEN_IF: case FILE_OPEN_IF:
return FspFileSystemOpCreate_FileOpenIf(FileSystem, Request); return FspFileSystemOpCreate_FileOpenIf(FileSystem, Request, Response);
case FILE_OVERWRITE: case FILE_OVERWRITE:
return FspFileSystemOpCreate_FileOverwrite(FileSystem, Request);
case FILE_SUPERSEDE: case FILE_SUPERSEDE:
return FspFileSystemOpCreate_FileOverwrite(FileSystem, Request); return FspFileSystemOpCreate_FileOverwrite(FileSystem, Request, Response);
case FILE_OVERWRITE_IF: case FILE_OVERWRITE_IF:
return FspFileSystemOpCreate_FileOverwriteIf(FileSystem, Request); return FspFileSystemOpCreate_FileOverwriteIf(FileSystem, Request, Response);
default: default:
return FspFileSystemSendResponseWithStatus(FileSystem, Request, STATUS_INVALID_PARAMETER); return STATUS_INVALID_PARAMETER;
} }
} }
FSP_API NTSTATUS FspFileSystemOpOverwrite(FSP_FILE_SYSTEM *FileSystem, FSP_API NTSTATUS FspFileSystemOpOverwrite(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request) FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
{ {
NTSTATUS Result; NTSTATUS Result;
FSP_FSCTL_FILE_INFO FileInfo; FSP_FSCTL_FILE_INFO FileInfo;
if (0 == FileSystem->Interface->Overwrite)
return STATUS_INVALID_DEVICE_REQUEST;
memset(&FileInfo, 0, sizeof FileInfo); memset(&FileInfo, 0, sizeof FileInfo);
Result = FileSystem->Interface->Overwrite(FileSystem, Request, Result = FileSystem->Interface->Overwrite(FileSystem, Request,
(PVOID)Request->Req.Overwrite.UserContext, (PVOID)Request->Req.Overwrite.UserContext,
@ -580,42 +600,9 @@ FSP_API NTSTATUS FspFileSystemOpOverwrite(FSP_FILE_SYSTEM *FileSystem,
if (0 != FileSystem->Interface->Close) if (0 != FileSystem->Interface->Close)
FileSystem->Interface->Close(FileSystem, Request, FileSystem->Interface->Close(FileSystem, Request,
(PVOID)Request->Req.Overwrite.UserContext); (PVOID)Request->Req.Overwrite.UserContext);
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); return Result;
} }
return FspFileSystemSendOverwriteResponse(FileSystem, Request, &FileInfo); memcpy(&Response->Rsp.Overwrite.FileInfo, &FileInfo, sizeof FileInfo);
} return STATUS_SUCCESS;
FSP_API NTSTATUS FspFileSystemSendCreateResponse(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, UINT_PTR Information,
PVOID FileNode, UINT32 GrantedAccess, const FSP_FSCTL_FILE_INFO *FileInfo)
{
FSP_FSCTL_TRANSACT_RSP Response;
memset(&Response, 0, sizeof Response);
Response.Size = sizeof Response;
Response.Kind = FspFsctlTransactCreateKind;
Response.Hint = Request->Hint;
Response.IoStatus.Status = STATUS_SUCCESS;
Response.IoStatus.Information = Information;
Response.Rsp.Create.Opened.UserContext = (UINT_PTR)FileNode;
Response.Rsp.Create.Opened.GrantedAccess = GrantedAccess;
memcpy(&Response.Rsp.Create.Opened.FileInfo, FileInfo, sizeof *FileInfo);
return FspFileSystemSendResponse(FileSystem, &Response);
}
FSP_API NTSTATUS FspFileSystemSendOverwriteResponse(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request,
const FSP_FSCTL_FILE_INFO *FileInfo)
{
FSP_FSCTL_TRANSACT_RSP Response;
memset(&Response, 0, sizeof Response);
Response.Size = sizeof Response;
Response.Kind = FspFsctlTransactOverwriteKind;
Response.Hint = Request->Hint;
Response.IoStatus.Status = STATUS_SUCCESS;
Response.IoStatus.Information = 0;
memcpy(&Response.Rsp.Overwrite.FileInfo, FileInfo, sizeof *FileInfo);
return FspFileSystemSendResponse(FileSystem, &Response);
} }

184
src/dll/dispatch.c Normal file
View File

@ -0,0 +1,184 @@
/**
* @file dll/dispatch.c
*
* @copyright 2015 Bill Zissimopoulos
*/
#include <dll/library.h>
enum
{
FspFileSystemDispatcherThreadCountMin = 2,
};
static FSP_FILE_SYSTEM_INTERFACE FspFileSystemNullInterface;
FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath,
const FSP_FSCTL_VOLUME_PARAMS *VolumeParams,
const FSP_FILE_SYSTEM_INTERFACE *Interface,
FSP_FILE_SYSTEM **PFileSystem)
{
NTSTATUS Result;
FSP_FILE_SYSTEM *FileSystem;
*PFileSystem = 0;
if (0 == Interface)
Interface = &FspFileSystemNullInterface;
FileSystem = MemAlloc(sizeof *FileSystem);
if (0 == FileSystem)
return STATUS_INSUFFICIENT_RESOURCES;
memset(FileSystem, 0, sizeof *FileSystem);
Result = FspFsctlCreateVolume(DevicePath, VolumeParams,
FileSystem->VolumeName, sizeof FileSystem->VolumeName,
&FileSystem->VolumeHandle);
if (!NT_SUCCESS(Result))
{
MemFree(FileSystem);
return Result;
}
FileSystem->Operations[FspFsctlTransactCreateKind] = FspFileSystemOpCreate;
FileSystem->Operations[FspFsctlTransactOverwriteKind] = FspFileSystemOpOverwrite;
FileSystem->Operations[FspFsctlTransactCleanupKind] = FspFileSystemOpCleanup;
FileSystem->Operations[FspFsctlTransactCloseKind] = FspFileSystemOpClose;
FileSystem->Operations[FspFsctlTransactQueryInformationKind] = FspFileSystemOpQueryInformation;
FileSystem->Operations[FspFsctlTransactSetInformationKind] = FspFileSystemOpSetInformation;
FileSystem->Operations[FspFsctlTransactQueryVolumeInformationKind] = FspFileSystemOpQueryVolumeInformation;
// !!!: ...
FileSystem->Interface = Interface;
*PFileSystem = FileSystem;
return STATUS_SUCCESS;
}
FSP_API VOID FspFileSystemDelete(FSP_FILE_SYSTEM *FileSystem)
{
CloseHandle(FileSystem->VolumeHandle);
MemFree(FileSystem);
}
static DWORD WINAPI FspFileSystemDispatcherThread(PVOID FileSystem0)
{
FSP_FILE_SYSTEM *FileSystem = FileSystem0;
NTSTATUS Result;
SIZE_T RequestSize;
FSP_FSCTL_TRANSACT_REQ *Request = 0;
FSP_FSCTL_TRANSACT_RSP *Response = 0;
HANDLE DispatcherThread = 0;
Request = MemAlloc(FSP_FSCTL_TRANSACT_BUFFER_SIZEMIN);
Response = MemAlloc(FSP_FSCTL_TRANSACT_RSP_SIZEMAX);
if (0 == Request || 0 == Response)
{
Result = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
}
if (1 < FileSystem->DispatcherThreadCount)
{
FileSystem->DispatcherThreadCount--;
DispatcherThread = CreateThread(0, 0, FspFileSystemDispatcherThread, FileSystem, 0, 0);
if (0 == DispatcherThread)
{
Result = FspNtStatusFromWin32(GetLastError());
goto exit;
}
}
memset(Response, 0, sizeof *Response);
for (;;)
{
RequestSize = FSP_FSCTL_TRANSACT_BUFFER_SIZEMIN;
Result = FspFsctlTransact(FileSystem->VolumeHandle,
Response, Response->Size, Request, &RequestSize, FALSE);
if (!NT_SUCCESS(Result))
goto exit;
FspFileSystemGetDispatcherResult(FileSystem, &Result);
if (!NT_SUCCESS(Result))
goto exit;
memset(Response, 0, sizeof *Response);
if (0 == RequestSize)
continue;
#if 0
FspDebugLog("FspFileSystemDispatcherThread: TID=%ld, Request={Kind=%d, Hint=%p}\n",
GetCurrentThreadId(), Request->Kind, (PVOID)Request->Hint);
#endif
Response->Size = sizeof *Response;
Response->Kind = Request->Kind;
Response->Hint = Request->Hint;
if (FspFsctlTransactKindCount > Request->Kind && 0 != FileSystem->Operations[Request->Kind])
{
FspFileSystemEnterOperation(FileSystem, Request, Response);
Response->IoStatus.Status =
FileSystem->Operations[Request->Kind](FileSystem, Request, Response);
FspFileSystemLeaveOperation(FileSystem, Request, Response);
}
else
Response->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
FspFileSystemGetDispatcherResult(FileSystem, &Result);
if (!NT_SUCCESS(Result))
goto exit;
}
exit:
MemFree(Response);
MemFree(Request);
FspFileSystemSetDispatcherResult(FileSystem, Result);
if (0 != DispatcherThread)
{
WaitForSingleObject(DispatcherThread, INFINITE);
CloseHandle(DispatcherThread);
}
return Result;
}
FSP_API NTSTATUS FspFileSystemStartDispatcher(FSP_FILE_SYSTEM *FileSystem, ULONG ThreadCount)
{
if (0 != FileSystem->DispatcherThread)
return STATUS_INVALID_PARAMETER;
if (0 == ThreadCount)
{
DWORD_PTR ProcessMask, SystemMask;
if (!GetProcessAffinityMask(GetCurrentProcess(), &ProcessMask, &SystemMask))
return FspNtStatusFromWin32(GetLastError());
for (ThreadCount = 0; 0 != ProcessMask; ProcessMask >>= 1)
ThreadCount += ProcessMask & 1;
}
if (ThreadCount < FspFileSystemDispatcherThreadCountMin)
ThreadCount = FspFileSystemDispatcherThreadCountMin;
FileSystem->DispatcherThreadCount = ThreadCount;
FileSystem->DispatcherThread = CreateThread(0, 0,
FspFileSystemDispatcherThread, FileSystem, 0, 0);
if (0 == FileSystem->DispatcherThread)
return FspNtStatusFromWin32(GetLastError());
return STATUS_SUCCESS;
}
FSP_API VOID FspFileSystemStopDispatcher(FSP_FILE_SYSTEM *FileSystem)
{
if (0 == FileSystem->DispatcherThread)
return;
FspFileSystemSetDispatcherResult(FileSystem, STATUS_CANCELLED);
WaitForSingleObject(FileSystem->DispatcherThread, INFINITE);
CloseHandle(FileSystem->DispatcherThread);
}

View File

@ -7,25 +7,26 @@
#include <dll/library.h> #include <dll/library.h>
FSP_API NTSTATUS FspFileSystemOpQueryInformation(FSP_FILE_SYSTEM *FileSystem, FSP_API NTSTATUS FspFileSystemOpQueryInformation(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request) FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
{ {
NTSTATUS Result; NTSTATUS Result;
FSP_FSCTL_FILE_INFO FileInfo; FSP_FSCTL_FILE_INFO FileInfo;
if (0 == FileSystem->Interface->GetFileInfo) if (0 == FileSystem->Interface->GetFileInfo)
return FspFileSystemSendResponseWithStatus(FileSystem, Request, STATUS_INVALID_DEVICE_REQUEST); return STATUS_INVALID_DEVICE_REQUEST;
memset(&FileInfo, 0, sizeof FileInfo); memset(&FileInfo, 0, sizeof FileInfo);
Result = FileSystem->Interface->GetFileInfo(FileSystem, Request, Result = FileSystem->Interface->GetFileInfo(FileSystem, Request,
(PVOID)Request->Req.QueryInformation.UserContext, &FileInfo); (PVOID)Request->Req.QueryInformation.UserContext, &FileInfo);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); return Result;
return FspFileSystemSendQueryInformationResponse(FileSystem, Request, &FileInfo); memcpy(&Response->Rsp.QueryInformation.FileInfo, &FileInfo, sizeof FileInfo);
return STATUS_SUCCESS;
} }
FSP_API NTSTATUS FspFileSystemOpSetInformation(FSP_FILE_SYSTEM *FileSystem, FSP_API NTSTATUS FspFileSystemOpSetInformation(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request) FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
{ {
NTSTATUS Result; NTSTATUS Result;
FSP_FSCTL_FILE_INFO FileInfo; FSP_FSCTL_FILE_INFO FileInfo;
@ -95,37 +96,8 @@ FSP_API NTSTATUS FspFileSystemOpSetInformation(FSP_FILE_SYSTEM *FileSystem,
} }
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); return Result;
return FspFileSystemSendSetInformationResponse(FileSystem, Request, &FileInfo); memcpy(&Response->Rsp.SetInformation.FileInfo, &FileInfo, sizeof FileInfo);
} return STATUS_SUCCESS;
FSP_API NTSTATUS FspFileSystemSendQueryInformationResponse(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_FILE_INFO *FileInfo)
{
FSP_FSCTL_TRANSACT_RSP Response;
memset(&Response, 0, sizeof Response);
Response.Size = sizeof Response;
Response.Kind = FspFsctlTransactQueryInformationKind;
Response.Hint = Request->Hint;
Response.IoStatus.Status = STATUS_SUCCESS;
Response.IoStatus.Information = 0;
Response.Rsp.QueryInformation.FileInfo = *FileInfo;
return FspFileSystemSendResponse(FileSystem, &Response);
}
FSP_API NTSTATUS FspFileSystemSendSetInformationResponse(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_FILE_INFO *FileInfo)
{
FSP_FSCTL_TRANSACT_RSP Response;
memset(&Response, 0, sizeof Response);
Response.Size = sizeof Response;
Response.Kind = FspFsctlTransactSetInformationKind;
Response.Hint = Request->Hint;
Response.IoStatus.Status = STATUS_SUCCESS;
Response.IoStatus.Information = 0;
Response.Rsp.SetInformation.FileInfo = *FileInfo;
return FspFileSystemSendResponse(FileSystem, &Response);
} }

View File

@ -1,194 +0,0 @@
/**
* @file dll/loop.c
*
* @copyright 2015 Bill Zissimopoulos
*/
#include <dll/library.h>
typedef struct _FSP_DISPATCHER_WORK_ITEM
{
FSP_FILE_SYSTEM *FileSystem;
__declspec(align(MEMORY_ALLOCATION_ALIGNMENT)) UINT8 RequestBuf[];
} FSP_DISPATCHER_WORK_ITEM;
static FSP_FILE_SYSTEM_INTERFACE FspFileSystemNullInterface;
FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath,
const FSP_FSCTL_VOLUME_PARAMS *VolumeParams,
const FSP_FILE_SYSTEM_INTERFACE *Interface,
FSP_FILE_SYSTEM **PFileSystem)
{
NTSTATUS Result;
FSP_FILE_SYSTEM *FileSystem;
*PFileSystem = 0;
if (0 == Interface)
Interface = &FspFileSystemNullInterface;
FileSystem = MemAlloc(sizeof *FileSystem);
if (0 == FileSystem)
return STATUS_INSUFFICIENT_RESOURCES;
memset(FileSystem, 0, sizeof *FileSystem);
Result = FspFsctlCreateVolume(DevicePath, VolumeParams,
FileSystem->VolumeName, sizeof FileSystem->VolumeName,
&FileSystem->VolumeHandle);
if (!NT_SUCCESS(Result))
{
MemFree(FileSystem);
return Result;
}
FileSystem->Dispatcher = FspFileSystemDirectDispatcher;
FileSystem->Operations[FspFsctlTransactCreateKind] = FspFileSystemOpCreate;
FileSystem->Operations[FspFsctlTransactOverwriteKind] = FspFileSystemOpOverwrite;
FileSystem->Operations[FspFsctlTransactCleanupKind] = FspFileSystemOpCleanup;
FileSystem->Operations[FspFsctlTransactCloseKind] = FspFileSystemOpClose;
FileSystem->Operations[FspFsctlTransactQueryInformationKind] = FspFileSystemOpQueryInformation;
FileSystem->Operations[FspFsctlTransactSetInformationKind] = FspFileSystemOpSetInformation;
FileSystem->Operations[FspFsctlTransactQueryVolumeInformationKind] = FspFileSystemOpQueryVolumeInformation;
// !!!: ...
FileSystem->Interface = Interface;
*PFileSystem = FileSystem;
return STATUS_SUCCESS;
}
FSP_API VOID FspFileSystemDelete(FSP_FILE_SYSTEM *FileSystem)
{
CloseHandle(FileSystem->VolumeHandle);
MemFree(FileSystem);
}
FSP_API NTSTATUS FspFileSystemLoop(FSP_FILE_SYSTEM *FileSystem)
{
NTSTATUS Result;
PUINT8 RequestBuf, RequestBufEnd;
SIZE_T RequestBufSize;
FSP_FSCTL_TRANSACT_REQ *Request, *NextRequest;
RequestBuf = MemAlloc(FSP_FSCTL_TRANSACT_BUFFER_SIZEMIN);
if (0 == RequestBuf)
return STATUS_INSUFFICIENT_RESOURCES;
for (;;)
{
RequestBufSize = FSP_FSCTL_TRANSACT_BUFFER_SIZEMIN;
Result = FspFsctlTransact(FileSystem->VolumeHandle, 0, 0, RequestBuf, &RequestBufSize, FALSE);
if (!NT_SUCCESS(Result))
goto exit;
FspFileSystemGetDispatcherResult(FileSystem, &Result);
if (!NT_SUCCESS(Result))
goto exit;
Request = (PVOID)RequestBuf;
RequestBufEnd = RequestBuf + RequestBufSize;
for (;;)
{
NextRequest = FspFsctlTransactConsumeRequest(Request, RequestBufEnd);
if (0 == NextRequest)
break;
FileSystem->Dispatcher(FileSystem, Request);
FspFileSystemGetDispatcherResult(FileSystem, &Result);
if (!NT_SUCCESS(Result))
goto exit;
Request = NextRequest;
}
}
exit:
MemFree(RequestBuf);
return Result;
}
FSP_API VOID FspFileSystemDirectDispatcher(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request)
{
NTSTATUS DispatcherResult;
if (FspFsctlTransactKindCount <= Request->Kind || 0 == FileSystem->Operations[Request->Kind])
DispatcherResult = FspFileSystemSendResponseWithStatus(FileSystem,
Request, STATUS_INVALID_DEVICE_REQUEST);
else
{
FspFileSystemEnterOperation(FileSystem, Request);
DispatcherResult = FileSystem->Operations[Request->Kind](FileSystem, Request);
FspFileSystemLeaveOperation(FileSystem, Request);
}
FspFileSystemSetDispatcherResult(FileSystem, DispatcherResult);
}
static DWORD WINAPI FspFileSystemPoolDispatcherWorker(PVOID Param)
{
NTSTATUS DispatcherResult;
FSP_DISPATCHER_WORK_ITEM *WorkItem = Param;
FSP_FILE_SYSTEM *FileSystem = WorkItem->FileSystem;
FSP_FSCTL_TRANSACT_REQ *Request = (PVOID)WorkItem->RequestBuf;
FspFileSystemEnterOperation(FileSystem, Request);
DispatcherResult = FileSystem->Operations[Request->Kind](FileSystem, Request);
FspFileSystemLeaveOperation(FileSystem, Request);
FspFileSystemSetDispatcherResult(FileSystem, DispatcherResult);
MemFree(WorkItem);
return 0;
}
FSP_API VOID FspFileSystemPoolDispatcher(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request)
{
NTSTATUS DispatcherResult;
if (FspFsctlTransactKindCount <= Request->Kind || 0 == FileSystem->Operations[Request->Kind])
DispatcherResult = FspFileSystemSendResponseWithStatus(FileSystem,
Request, STATUS_INVALID_DEVICE_REQUEST);
else
{
FSP_DISPATCHER_WORK_ITEM *WorkItem = MemAlloc(sizeof *WorkItem + Request->Size);
if (0 == WorkItem)
DispatcherResult = STATUS_INSUFFICIENT_RESOURCES;
else
{
WorkItem->FileSystem = FileSystem;
memcpy(WorkItem->RequestBuf, Request, Request->Size);
if (QueueUserWorkItem(FspFileSystemPoolDispatcherWorker, WorkItem, WT_EXECUTEDEFAULT))
DispatcherResult = STATUS_SUCCESS;
else
{
DispatcherResult = FspNtStatusFromWin32(GetLastError());
MemFree(WorkItem);
}
}
}
FspFileSystemSetDispatcherResult(FileSystem, DispatcherResult);
}
FSP_API NTSTATUS FspFileSystemSendResponse(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_RSP *Response)
{
return FspFsctlTransact(FileSystem->VolumeHandle, Response, Response->Size, 0, 0, FALSE);
}
FSP_API NTSTATUS FspFileSystemSendResponseWithStatus(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, NTSTATUS Result)
{
FSP_FSCTL_TRANSACT_RSP Response;
memset(&Response, 0, sizeof Response);
Response.Size = sizeof Response;
Response.Kind = Request->Kind;
Response.Hint = Request->Hint;
Response.IoStatus.Status = Result;
return FspFileSystemSendResponse(FileSystem, &Response);
}

View File

@ -7,33 +7,19 @@
#include <dll/library.h> #include <dll/library.h>
FSP_API NTSTATUS FspFileSystemOpQueryVolumeInformation(FSP_FILE_SYSTEM *FileSystem, FSP_API NTSTATUS FspFileSystemOpQueryVolumeInformation(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request) FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
{ {
NTSTATUS Result; NTSTATUS Result;
FSP_FSCTL_VOLUME_INFO VolumeInfo; FSP_FSCTL_VOLUME_INFO VolumeInfo;
if (0 == FileSystem->Interface->GetVolumeInfo) if (0 == FileSystem->Interface->GetVolumeInfo)
return FspFileSystemSendResponseWithStatus(FileSystem, Request, STATUS_INVALID_DEVICE_REQUEST); return STATUS_INVALID_DEVICE_REQUEST;
memset(&VolumeInfo, 0, sizeof VolumeInfo); memset(&VolumeInfo, 0, sizeof VolumeInfo);
Result = FileSystem->Interface->GetVolumeInfo(FileSystem, Request, &VolumeInfo); Result = FileSystem->Interface->GetVolumeInfo(FileSystem, Request, &VolumeInfo);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); return Result;
return FspFileSystemSendQueryVolumeInformationResponse(FileSystem, Request, &VolumeInfo); memcpy(&Response->Rsp.QueryVolumeInformation.VolumeInfo, &VolumeInfo, sizeof VolumeInfo);
} return STATUS_SUCCESS;
FSP_API NTSTATUS FspFileSystemSendQueryVolumeInformationResponse(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_VOLUME_INFO *VolumeInfo)
{
FSP_FSCTL_TRANSACT_RSP Response;
memset(&Response, 0, sizeof Response);
Response.Size = sizeof Response;
Response.Kind = FspFsctlTransactQueryVolumeInformationKind;
Response.Hint = Request->Hint;
Response.IoStatus.Status = STATUS_SUCCESS;
Response.IoStatus.Information = 0;
Response.Rsp.QueryVolumeInformation.VolumeInfo = *VolumeInfo;
return FspFileSystemSendResponse(FileSystem, &Response);
} }

View File

@ -6,42 +6,22 @@
extern int WinFspDiskTests; extern int WinFspDiskTests;
extern int WinFspNetTests; extern int WinFspNetTests;
struct memfs_data
{
MEMFS *Memfs;
HANDLE Thread;
};
static unsigned __stdcall memfs_thread(void *Memfs0)
{
MEMFS *Memfs = Memfs0;
return FspFileSystemLoop(MemfsFileSystem(Memfs));
}
void *memfs_start_ex(ULONG Flags, ULONG FileInfoTimeout) void *memfs_start_ex(ULONG Flags, ULONG FileInfoTimeout)
{ {
if (-1 == Flags) if (-1 == Flags)
return 0; return 0;
struct memfs_data *data;
MEMFS *Memfs; MEMFS *Memfs;
HANDLE Thread;
NTSTATUS Result; NTSTATUS Result;
data = malloc(sizeof *data);
ASSERT(0 != data);
Result = MemfsCreate(Flags, FileInfoTimeout, 1000, 65500, &Memfs); Result = MemfsCreate(Flags, FileInfoTimeout, 1000, 65500, &Memfs);
ASSERT(NT_SUCCESS(Result)); ASSERT(NT_SUCCESS(Result));
ASSERT(0 != Memfs); ASSERT(0 != Memfs);
Thread = (HANDLE)_beginthreadex(0, 0, memfs_thread, Memfs, 0, 0); Result = MemfsStart(Memfs);
ASSERT(0 != Thread); ASSERT(NT_SUCCESS(Result));
data->Memfs = Memfs; return Memfs;
data->Thread = Thread;
return data;
} }
void *memfs_start(ULONG Flags) void *memfs_start(ULONG Flags)
@ -54,24 +34,16 @@ void memfs_stop(void *data)
if (0 == data) if (0 == data)
return; return;
MEMFS *Memfs = ((struct memfs_data *)data)->Memfs; MEMFS *Memfs = data;
HANDLE Thread = ((struct memfs_data *)data)->Thread;
DWORD ExitCode;
FspFileSystemSetDispatcherResult(MemfsFileSystem(Memfs), STATUS_CANCELLED); MemfsStop(Memfs);
WaitForSingleObject(Thread, INFINITE);
GetExitCodeThread(Thread, &ExitCode);
CloseHandle(Thread);
ASSERT(STATUS_CANCELLED == ExitCode);
MemfsDelete(Memfs); MemfsDelete(Memfs);
} }
PWSTR memfs_volumename(void *data) PWSTR memfs_volumename(void *data)
{ {
MEMFS *Memfs = ((struct memfs_data *)data)->Memfs; MEMFS *Memfs = data;
return MemfsFileSystem(Memfs)->VolumeName; return MemfsFileSystem(Memfs)->VolumeName;
} }

View File

@ -553,13 +553,15 @@ static FSP_FILE_SYSTEM_INTERFACE MemfsInterface =
Rename, Rename,
}; };
static VOID MemfsEnterOperation(FSP_FILE_SYSTEM *FileSystem, FSP_FSCTL_TRANSACT_REQ *Request) static VOID MemfsEnterOperation(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
{ {
MEMFS *Memfs = (MEMFS *)FileSystem->UserContext; MEMFS *Memfs = (MEMFS *)FileSystem->UserContext;
EnterCriticalSection(&Memfs->Lock); EnterCriticalSection(&Memfs->Lock);
} }
static VOID MemfsLeaveOperation(FSP_FILE_SYSTEM *FileSystem, FSP_FSCTL_TRANSACT_REQ *Request) static VOID MemfsLeaveOperation(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
{ {
MEMFS *Memfs = (MEMFS *)FileSystem->UserContext; MEMFS *Memfs = (MEMFS *)FileSystem->UserContext;
LeaveCriticalSection(&Memfs->Lock); LeaveCriticalSection(&Memfs->Lock);
@ -618,11 +620,9 @@ NTSTATUS MemfsCreate(ULONG Flags, ULONG FileInfoTimeout,
InitializeCriticalSection(&Memfs->Lock); InitializeCriticalSection(&Memfs->Lock);
if (Flags & MemfsThreadPool) FspFileSystemSetOperationGuard(Memfs->FileSystem,
FspFileSystemSetDispatcher(Memfs->FileSystem, MemfsEnterOperation,
FspFileSystemPoolDispatcher, MemfsLeaveOperation);
MemfsEnterOperation,
MemfsLeaveOperation);
/* /*
* Create root directory. * Create root directory.
@ -661,6 +661,16 @@ VOID MemfsDelete(MEMFS *Memfs)
free(Memfs); free(Memfs);
} }
NTSTATUS MemfsStart(MEMFS *Memfs)
{
return FspFileSystemStartDispatcher(Memfs->FileSystem, 0);
}
VOID MemfsStop(MEMFS *Memfs)
{
FspFileSystemStopDispatcher(Memfs->FileSystem);
}
FSP_FILE_SYSTEM *MemfsFileSystem(MEMFS *Memfs) FSP_FILE_SYSTEM *MemfsFileSystem(MEMFS *Memfs)
{ {
return Memfs->FileSystem; return Memfs->FileSystem;

View File

@ -19,14 +19,14 @@ enum
{ {
MemfsDisk = 0x00, MemfsDisk = 0x00,
MemfsNet = 0x01, MemfsNet = 0x01,
MemfsSingleThread = 0x00,
MemfsThreadPool = 0x02,
}; };
NTSTATUS MemfsCreate(ULONG Flags, ULONG FileInfoTimeout, NTSTATUS MemfsCreate(ULONG Flags, ULONG FileInfoTimeout,
ULONG MaxFileNodes, ULONG MaxFileSize, ULONG MaxFileNodes, ULONG MaxFileSize,
MEMFS **PMemfs); MEMFS **PMemfs);
VOID MemfsDelete(MEMFS *Memfs); VOID MemfsDelete(MEMFS *Memfs);
NTSTATUS MemfsStart(MEMFS *Memfs);
VOID MemfsStop(MEMFS *Memfs);
FSP_FILE_SYSTEM *MemfsFileSystem(MEMFS *Memfs); FSP_FILE_SYSTEM *MemfsFileSystem(MEMFS *Memfs);
#ifdef __cplusplus #ifdef __cplusplus