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