From dd259ad45cfe9590cd41219f0caa85c78322c1fb Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Thu, 31 Dec 2015 16:00:31 -0800 Subject: [PATCH] dll: FSP_FILE_SYSTEM::DispatcherResult --- inc/winfsp/winfsp.h | 24 +++++++++++++++--- src/dll/loop.c | 61 +++++++++++++++++++++++++++------------------ 2 files changed, 57 insertions(+), 28 deletions(-) diff --git a/inc/winfsp/winfsp.h b/inc/winfsp/winfsp.h index e31e90fb..6d65f5f8 100644 --- a/inc/winfsp/winfsp.h +++ b/inc/winfsp/winfsp.h @@ -22,8 +22,8 @@ #include typedef struct _FSP_FILE_SYSTEM FSP_FILE_SYSTEM; -typedef NTSTATUS FSP_FILE_SYSTEM_DISPATCHER(FSP_FILE_SYSTEM *, FSP_FSCTL_TRANSACT_REQ *); -typedef VOID FSP_FILE_SYSTEM_OPERATION(FSP_FILE_SYSTEM *, FSP_FSCTL_TRANSACT_REQ *); +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 struct _FSP_FILE_SYSTEM { UINT16 Version; @@ -31,6 +31,7 @@ typedef struct _FSP_FILE_SYSTEM HANDLE VolumeHandle; PVOID UserContext; FSP_FILE_SYSTEM_DISPATCHER *Dispatcher; + NTSTATUS DispatcherResult; FSP_FILE_SYSTEM_OPERATION *Operations[FspFsctlTransactKindCount]; } FSP_FILE_SYSTEM; @@ -40,11 +41,26 @@ FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath, FSP_FILE_SYSTEM **PFileSystem); FSP_API VOID FspFileSystemDelete(FSP_FILE_SYSTEM *FileSystem); FSP_API NTSTATUS FspFileSystemLoop(FSP_FILE_SYSTEM *FileSystem); -FSP_API NTSTATUS FspFileSystemDirectDispatcher(FSP_FILE_SYSTEM *FileSystem, +FSP_API VOID FspFileSystemDirectDispatcher(FSP_FILE_SYSTEM *FileSystem, FSP_FSCTL_TRANSACT_REQ *Request); -FSP_API NTSTATUS FspFileSystemPoolDispatcher(FSP_FILE_SYSTEM *FileSystem, +FSP_API VOID FspFileSystemPoolDispatcher(FSP_FILE_SYSTEM *FileSystem, FSP_FSCTL_TRANSACT_REQ *Request); +static VOID FspFileSystemGetDispatcherResult(FSP_FILE_SYSTEM *FileSystem, + NTSTATUS *PDispatcherResult) +{ + /* 32-bit reads are atomic */ + *PDispatcherResult = FileSystem->DispatcherResult; + MemoryBarrier(); +} +static VOID FspFileSystemSetDispatcherResult(FSP_FILE_SYSTEM *FileSystem, + NTSTATUS DispatcherResult) +{ + if (NT_SUCCESS(DispatcherResult)) + return; + InterlockedCompareExchange(&FileSystem->DispatcherResult, DispatcherResult, 0); +} + FSP_API NTSTATUS FspSendResponse(FSP_FILE_SYSTEM *FileSystem, FSP_FSCTL_TRANSACT_RSP *Response); FSP_API NTSTATUS FspSendResponseWithStatus(FSP_FILE_SYSTEM *FileSystem, diff --git a/src/dll/loop.c b/src/dll/loop.c index 50a690e4..b5f81b44 100644 --- a/src/dll/loop.c +++ b/src/dll/loop.c @@ -75,7 +75,9 @@ FSP_API NTSTATUS FspFileSystemLoop(FSP_FILE_SYSTEM *FileSystem) if (0 == NextRequest) break; - Result = FileSystem->Dispatcher(FileSystem, Request); + FileSystem->Dispatcher(FileSystem, Request); + + FspFileSystemGetDispatcherResult(FileSystem, &Result); if (!NT_SUCCESS(Result)) goto exit; @@ -89,50 +91,61 @@ exit: return Result; } -FSP_API NTSTATUS FspFileSystemDirectDispatcher(FSP_FILE_SYSTEM *FileSystem, +FSP_API VOID FspFileSystemDirectDispatcher(FSP_FILE_SYSTEM *FileSystem, FSP_FSCTL_TRANSACT_REQ *Request) { - if (FspFsctlTransactKindCount <= Request->Kind || 0 == FileSystem->Operations[Request->Kind]) - return FspSendResponseWithStatus(FileSystem, Request, STATUS_INVALID_DEVICE_REQUEST); + NTSTATUS DispatcherResult; - FileSystem->Operations[Request->Kind](FileSystem, Request); - return STATUS_SUCCESS; + if (FspFsctlTransactKindCount <= Request->Kind || 0 == FileSystem->Operations[Request->Kind]) + DispatcherResult = FspSendResponseWithStatus(FileSystem, Request, STATUS_INVALID_DEVICE_REQUEST); + else + DispatcherResult = FileSystem->Operations[Request->Kind](FileSystem, Request); + + FspFileSystemSetDispatcherResult(FileSystem, DispatcherResult); } static DWORD WINAPI FspFileSystemPoolDispatcherWorker(PVOID Param) { + NTSTATUS DispatcherResult; FSP_DISPATCHER_WORK_ITEM *WorkItem = Param; FSP_FSCTL_TRANSACT_REQ *Request = (PVOID)WorkItem->RequestBuf; - WorkItem->FileSystem->Operations[Request->Kind](WorkItem->FileSystem, Request); + DispatcherResult = WorkItem->FileSystem->Operations[Request->Kind](WorkItem->FileSystem, Request); MemFree(WorkItem); + FspFileSystemSetDispatcherResult(WorkItem->FileSystem, DispatcherResult); + return 0; } -FSP_API NTSTATUS FspFileSystemPoolDispatcher(FSP_FILE_SYSTEM *FileSystem, +FSP_API VOID FspFileSystemPoolDispatcher(FSP_FILE_SYSTEM *FileSystem, FSP_FSCTL_TRANSACT_REQ *Request) { + NTSTATUS DispatcherResult; + if (FspFsctlTransactKindCount <= Request->Kind || 0 == FileSystem->Operations[Request->Kind]) - return FspSendResponseWithStatus(FileSystem, Request, STATUS_INVALID_DEVICE_REQUEST); - - FSP_DISPATCHER_WORK_ITEM *WorkItem = MemAlloc(sizeof *WorkItem + Request->Size); - if (0 == WorkItem) - return STATUS_INSUFFICIENT_RESOURCES; - - WorkItem->FileSystem = FileSystem; - memcpy(WorkItem->RequestBuf, Request, Request->Size); - - BOOLEAN Success = QueueUserWorkItem( - FspFileSystemPoolDispatcherWorker, WorkItem, WT_EXECUTEDEFAULT); - if (!Success) + DispatcherResult = FspSendResponseWithStatus(FileSystem, Request, STATUS_INVALID_DEVICE_REQUEST); + else { - NTSTATUS Result0 = FspNtStatusFromWin32(GetLastError()); - MemFree(WorkItem); - return Result0; + 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); + } + } } - return STATUS_SUCCESS; + FspFileSystemSetDispatcherResult(FileSystem, DispatcherResult); } FSP_API NTSTATUS FspSendResponse(FSP_FILE_SYSTEM *FileSystem,