From d8c35f26b0c8066e3d62f54a9b41439caaca2bd9 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Tue, 16 Feb 2016 17:03:00 -0800 Subject: [PATCH] dll: major overhaul of FSP_FILE_SYSTEM dispatching --- build/VStudio/winfsp_dll.vcxproj | 2 +- build/VStudio/winfsp_dll.vcxproj.filters | 6 +- inc/winfsp/winfsp.h | 96 ++++------- src/dll/cleanup.c | 18 +-- src/dll/close.c | 18 +-- src/dll/create.c | 157 +++++++++--------- src/dll/dispatch.c | 184 +++++++++++++++++++++ src/dll/fileinfo.c | 46 ++---- src/dll/loop.c | 194 ----------------------- src/dll/volinfo.c | 24 +-- tst/winfsp-tests/memfs-test.c | 40 +---- tst/winfsp-tests/memfs.cpp | 24 ++- tst/winfsp-tests/memfs.h | 4 +- 13 files changed, 337 insertions(+), 476 deletions(-) create mode 100644 src/dll/dispatch.c delete mode 100644 src/dll/loop.c diff --git a/build/VStudio/winfsp_dll.vcxproj b/build/VStudio/winfsp_dll.vcxproj index bd90458e..1eee73b0 100644 --- a/build/VStudio/winfsp_dll.vcxproj +++ b/build/VStudio/winfsp_dll.vcxproj @@ -31,7 +31,7 @@ - + diff --git a/build/VStudio/winfsp_dll.vcxproj.filters b/build/VStudio/winfsp_dll.vcxproj.filters index 9fc6a263..cc90aed0 100644 --- a/build/VStudio/winfsp_dll.vcxproj.filters +++ b/build/VStudio/winfsp_dll.vcxproj.filters @@ -37,9 +37,6 @@ Source - - Source - Source @@ -58,6 +55,9 @@ Source + + Source + diff --git a/inc/winfsp/winfsp.h b/inc/winfsp/winfsp.h index 0304bcf8..0b01c395 100644 --- a/inc/winfsp/winfsp.h +++ b/inc/winfsp/winfsp.h @@ -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, diff --git a/src/dll/cleanup.c b/src/dll/cleanup.c index 65e83e53..c6d1a942 100644 --- a/src/dll/cleanup.c +++ b/src/dll/cleanup.c @@ -7,7 +7,7 @@ #include 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; } diff --git a/src/dll/close.c b/src/dll/close.c index c8330abd..6a4cb243 100644 --- a/src/dll/close.c +++ b/src/dll/close.c @@ -7,25 +7,11 @@ #include 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; } diff --git a/src/dll/create.c b/src/dll/create.c index b368d3b4..d849e441 100644 --- a/src/dll/create.c +++ b/src/dll/create.c @@ -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; } diff --git a/src/dll/dispatch.c b/src/dll/dispatch.c new file mode 100644 index 00000000..79b02b9b --- /dev/null +++ b/src/dll/dispatch.c @@ -0,0 +1,184 @@ +/** + * @file dll/dispatch.c + * + * @copyright 2015 Bill Zissimopoulos + */ + +#include + +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); +} diff --git a/src/dll/fileinfo.c b/src/dll/fileinfo.c index ef53bc4b..16c7c298 100644 --- a/src/dll/fileinfo.c +++ b/src/dll/fileinfo.c @@ -7,25 +7,26 @@ #include 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; } diff --git a/src/dll/loop.c b/src/dll/loop.c deleted file mode 100644 index e7b21923..00000000 --- a/src/dll/loop.c +++ /dev/null @@ -1,194 +0,0 @@ -/** - * @file dll/loop.c - * - * @copyright 2015 Bill Zissimopoulos - */ - -#include - -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); -} diff --git a/src/dll/volinfo.c b/src/dll/volinfo.c index 171dcc6a..3693bd68 100644 --- a/src/dll/volinfo.c +++ b/src/dll/volinfo.c @@ -7,33 +7,19 @@ #include 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; } diff --git a/tst/winfsp-tests/memfs-test.c b/tst/winfsp-tests/memfs-test.c index 71273f03..44bfa034 100644 --- a/tst/winfsp-tests/memfs-test.c +++ b/tst/winfsp-tests/memfs-test.c @@ -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; } diff --git a/tst/winfsp-tests/memfs.cpp b/tst/winfsp-tests/memfs.cpp index c481dee2..8569de80 100644 --- a/tst/winfsp-tests/memfs.cpp +++ b/tst/winfsp-tests/memfs.cpp @@ -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; diff --git a/tst/winfsp-tests/memfs.h b/tst/winfsp-tests/memfs.h index b1cbf1c9..e64be365 100644 --- a/tst/winfsp-tests/memfs.h +++ b/tst/winfsp-tests/memfs.h @@ -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