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\fsctl.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\path.c" />
<ClCompile Include="..\..\src\dll\volinfo.c" />

View File

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

View File

@ -29,8 +29,10 @@ extern "C" {
* File System
*/
typedef struct _FSP_FILE_SYSTEM FSP_FILE_SYSTEM;
typedef VOID FSP_FILE_SYSTEM_DISPATCHER(FSP_FILE_SYSTEM *, FSP_FSCTL_TRANSACT_REQ *);
typedef NTSTATUS FSP_FILE_SYSTEM_OPERATION(FSP_FILE_SYSTEM *, FSP_FSCTL_TRANSACT_REQ *);
typedef VOID FSP_FILE_SYSTEM_OPERATION_GUARD(FSP_FILE_SYSTEM *,
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
{
NTSTATUS (*GetVolumeInfo)(FSP_FILE_SYSTEM *FileSystem,
@ -89,31 +91,39 @@ typedef struct _FSP_FILE_SYSTEM
WCHAR VolumeName[FSP_FSCTL_VOLUME_NAME_SIZEMAX / sizeof(WCHAR)];
HANDLE VolumeHandle;
PVOID UserContext;
NTSTATUS DispatcherResult;
FSP_FILE_SYSTEM_DISPATCHER *Dispatcher;
FSP_FILE_SYSTEM_DISPATCHER *EnterOperation, *LeaveOperation;
FSP_FILE_SYSTEM_OPERATION_GUARD *EnterOperation, *LeaveOperation;
FSP_FILE_SYSTEM_OPERATION *Operations[FspFsctlTransactKindCount];
const FSP_FILE_SYSTEM_INTERFACE *Interface;
HANDLE DispatcherThread;
ULONG DispatcherThreadCount;
NTSTATUS DispatcherResult;
} FSP_FILE_SYSTEM;
FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath,
const FSP_FSCTL_VOLUME_PARAMS *VolumeParams,
const FSP_FILE_SYSTEM_INTERFACE *Interface,
FSP_FILE_SYSTEM **PFileSystem);
FSP_API VOID FspFileSystemDelete(FSP_FILE_SYSTEM *FileSystem);
FSP_API NTSTATUS FspFileSystemLoop(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);
FSP_API NTSTATUS FspFileSystemStartDispatcher(FSP_FILE_SYSTEM *FileSystem, ULONG ThreadCount);
FSP_API VOID FspFileSystemStopDispatcher(FSP_FILE_SYSTEM *FileSystem);
static inline
VOID FspFileSystemSetDispatcher(FSP_FILE_SYSTEM *FileSystem,
FSP_FILE_SYSTEM_DISPATCHER *Dispatcher,
FSP_FILE_SYSTEM_DISPATCHER *EnterOperation,
FSP_FILE_SYSTEM_DISPATCHER *LeaveOperation)
VOID FspFileSystemEnterOperation(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
{
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->LeaveOperation = LeaveOperation;
}
@ -124,7 +134,6 @@ VOID FspFileSystemSetOperation(FSP_FILE_SYSTEM *FileSystem,
{
FileSystem->Operations[Index] = Operation;
}
static inline
VOID FspFileSystemGetDispatcherResult(FSP_FILE_SYSTEM *FileSystem,
NTSTATUS *PDispatcherResult)
@ -142,26 +151,6 @@ VOID FspFileSystemSetDispatcherResult(FSP_FILE_SYSTEM *FileSystem,
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
*/
@ -178,36 +167,19 @@ FSP_API NTSTATUS FspAssignSecurity(FSP_FILE_SYSTEM *FileSystem,
FSP_API VOID FspDeleteSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
NTSTATUS (*CreateFunc)());
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_FSCTL_TRANSACT_REQ *Request);
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
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_FSCTL_TRANSACT_REQ *Request);
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
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_FSCTL_TRANSACT_REQ *Request);
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
FSP_API NTSTATUS FspFileSystemOpQueryVolumeInformation(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request);
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);
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
static inline
NTSTATUS FspAccessCheck(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request,

View File

@ -7,7 +7,7 @@
#include <dll/library.h>
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)
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->Req.Cleanup.Delete);
return FspFileSystemSendCleanupResponse(FileSystem, Request);
}
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);
return STATUS_SUCCESS;
}

View File

@ -7,25 +7,11 @@
#include <dll/library.h>
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)
FileSystem->Interface->Close(FileSystem, Request,
(PVOID)Request->Req.Close.UserContext);
return FspFileSystemSendCloseResponse(FileSystem, Request);
}
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);
return STATUS_SUCCESS;
}

View File

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

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>
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;
FSP_FSCTL_FILE_INFO FileInfo;
if (0 == FileSystem->Interface->GetFileInfo)
return FspFileSystemSendResponseWithStatus(FileSystem, Request, STATUS_INVALID_DEVICE_REQUEST);
return STATUS_INVALID_DEVICE_REQUEST;
memset(&FileInfo, 0, sizeof FileInfo);
Result = FileSystem->Interface->GetFileInfo(FileSystem, Request,
(PVOID)Request->Req.QueryInformation.UserContext, &FileInfo);
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_FSCTL_TRANSACT_REQ *Request)
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
{
NTSTATUS Result;
FSP_FSCTL_FILE_INFO FileInfo;
@ -95,37 +96,8 @@ FSP_API NTSTATUS FspFileSystemOpSetInformation(FSP_FILE_SYSTEM *FileSystem,
}
if (!NT_SUCCESS(Result))
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
return Result;
return FspFileSystemSendSetInformationResponse(FileSystem, Request, &FileInfo);
}
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);
memcpy(&Response->Rsp.SetInformation.FileInfo, &FileInfo, sizeof FileInfo);
return STATUS_SUCCESS;
}

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>
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;
FSP_FSCTL_VOLUME_INFO VolumeInfo;
if (0 == FileSystem->Interface->GetVolumeInfo)
return FspFileSystemSendResponseWithStatus(FileSystem, Request, STATUS_INVALID_DEVICE_REQUEST);
return STATUS_INVALID_DEVICE_REQUEST;
memset(&VolumeInfo, 0, sizeof VolumeInfo);
Result = FileSystem->Interface->GetVolumeInfo(FileSystem, Request, &VolumeInfo);
if (!NT_SUCCESS(Result))
return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result);
return Result;
return FspFileSystemSendQueryVolumeInformationResponse(FileSystem, Request, &VolumeInfo);
}
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);
memcpy(&Response->Rsp.QueryVolumeInformation.VolumeInfo, &VolumeInfo, sizeof VolumeInfo);
return STATUS_SUCCESS;
}

View File

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

View File

@ -553,13 +553,15 @@ static FSP_FILE_SYSTEM_INTERFACE MemfsInterface =
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;
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;
LeaveCriticalSection(&Memfs->Lock);
@ -618,11 +620,9 @@ NTSTATUS MemfsCreate(ULONG Flags, ULONG FileInfoTimeout,
InitializeCriticalSection(&Memfs->Lock);
if (Flags & MemfsThreadPool)
FspFileSystemSetDispatcher(Memfs->FileSystem,
FspFileSystemPoolDispatcher,
MemfsEnterOperation,
MemfsLeaveOperation);
FspFileSystemSetOperationGuard(Memfs->FileSystem,
MemfsEnterOperation,
MemfsLeaveOperation);
/*
* Create root directory.
@ -661,6 +661,16 @@ VOID MemfsDelete(MEMFS *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)
{
return Memfs->FileSystem;

View File

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