dll: FspFileSystemLoop

This commit is contained in:
Bill Zissimopoulos 2015-12-15 13:15:44 -08:00
parent 0f2139f32a
commit 44a17d0b4d
7 changed files with 186 additions and 5 deletions

View File

@ -173,6 +173,7 @@
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\src\dll\debug.c" /> <ClCompile Include="..\..\src\dll\debug.c" />
<ClCompile Include="..\..\src\dll\fsctl.c" /> <ClCompile Include="..\..\src\dll\fsctl.c" />
<ClCompile Include="..\..\src\dll\loop.c" />
<ClCompile Include="..\..\src\dll\ntstatus.c" /> <ClCompile Include="..\..\src\dll\ntstatus.c" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -23,6 +23,9 @@
<ClCompile Include="..\..\src\dll\debug.c"> <ClCompile Include="..\..\src\dll\debug.c">
<Filter>Source</Filter> <Filter>Source</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\dll\loop.c">
<Filter>Source</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\inc\winfsp\fsctl.h"> <ClInclude Include="..\..\inc\winfsp\fsctl.h">

View File

@ -19,6 +19,34 @@
#define FSP_API __declspec(dllimport) #define FSP_API __declspec(dllimport)
#endif #endif
#include <winfsp/fsctl.h>
typedef struct _FSP_FILE_SYSTEM FSP_FILE_SYSTEM;
typedef NTSTATUS FSP_FILE_SYSTEM_PR(FSP_FILE_SYSTEM *, FSP_FSCTL_TRANSACT_REQ *);
typedef VOID FSP_FILE_SYSTEM_OP(FSP_FILE_SYSTEM *, FSP_FSCTL_TRANSACT_REQ *);
typedef struct _FSP_FILE_SYSTEM
{
UINT16 Version;
PVOID UserContext;
HANDLE VolumeHandle;
FSP_FILE_SYSTEM_PR *ProcessRequest;
FSP_FILE_SYSTEM_OP *Operations[FspFsctlTransactKindCount];
} FSP_FILE_SYSTEM;
FSP_API NTSTATUS FspFileSystemCreate(FSP_FILE_SYSTEM_PR *ProcessRequest,
FSP_FILE_SYSTEM **PFileSystem);
FSP_API VOID FspFileSystemDelete(FSP_FILE_SYSTEM *FileSystem);
FSP_API NTSTATUS FspFileSystemLoop(FSP_FILE_SYSTEM *FileSystem);
FSP_API NTSTATUS FspProcessRequestDirect(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request);
FSP_API NTSTATUS FspProcessRequestInPool(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request);
FSP_API NTSTATUS FspProduceResponse(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_RSP *Response);
FSP_API NTSTATUS FspProduceResponseWithStatus(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, NTSTATUS Result);
FSP_API NTSTATUS FspNtStatusFromWin32(DWORD Error); FSP_API NTSTATUS FspNtStatusFromWin32(DWORD Error);
FSP_API VOID FspDebugLog(const char *format, ...); FSP_API VOID FspDebugLog(const char *format, ...);

View File

@ -241,16 +241,23 @@ FSP_API NTSTATUS FspFsctlTransact(HANDLE VolumeHandle,
PVOID RequestBuf, SIZE_T *PRequestBufSize) PVOID RequestBuf, SIZE_T *PRequestBufSize)
{ {
NTSTATUS Result = STATUS_SUCCESS; NTSTATUS Result = STATUS_SUCCESS;
DWORD Bytes; DWORD Bytes = 0;
if (0 != *PRequestBufSize)
{
Bytes = (DWORD)*PRequestBufSize;
*PRequestBufSize = 0;
}
if (!DeviceIoControl(VolumeHandle, FSP_FSCTL_TRANSACT, if (!DeviceIoControl(VolumeHandle, FSP_FSCTL_TRANSACT,
ResponseBuf, (DWORD)ResponseBufSize, RequestBuf, (DWORD)*PRequestBufSize, ResponseBuf, (DWORD)ResponseBufSize, RequestBuf, Bytes,
&Bytes, 0)) &Bytes, 0))
{ {
Result = FspNtStatusFromWin32(GetLastError()); Result = FspNtStatusFromWin32(GetLastError());
goto exit; goto exit;
} }
if (0 != *PRequestBufSize)
*PRequestBufSize = Bytes; *PRequestBufSize = Bytes;
exit: exit:

View File

@ -9,7 +9,6 @@
#define WINFSP_DLL_INTERNAL #define WINFSP_DLL_INTERNAL
#include <winfsp/winfsp.h> #include <winfsp/winfsp.h>
#include <winfsp/fsctl.h>
#include <strsafe.h> #include <strsafe.h>
#define LIBRARY_NAME "WinFsp" #define LIBRARY_NAME "WinFsp"

144
src/dll/loop.c Normal file
View File

@ -0,0 +1,144 @@
/**
* @file dll/loop.c
*
* @copyright 2015 Bill Zissimopoulos
*/
#include <dll/library.h>
typedef struct _FSP_WORK_ITEM
{
FSP_FILE_SYSTEM *FileSystem;
__declspec(align(MEMORY_ALLOCATION_ALIGNMENT)) UINT8 RequestBuf[];
} FSP_WORK_ITEM;
FSP_API NTSTATUS FspFileSystemCreate(FSP_FILE_SYSTEM_PR *ProcessRequest,
FSP_FILE_SYSTEM **PFileSystem)
{
FSP_FILE_SYSTEM *FileSystem;
*PFileSystem = 0;
if (0 == ProcessRequest)
return STATUS_INVALID_PARAMETER;
FileSystem = malloc(sizeof *FileSystem);
if (0 == FileSystem)
return STATUS_INSUFFICIENT_RESOURCES;
memset(FileSystem, 0, sizeof *FileSystem);
FileSystem->ProcessRequest = ProcessRequest;
*PFileSystem = FileSystem;
return STATUS_SUCCESS;
}
FSP_API VOID FspFileSystemDelete(FSP_FILE_SYSTEM *FileSystem)
{
free(FileSystem);
}
FSP_API NTSTATUS FspFileSystemLoop(FSP_FILE_SYSTEM *FileSystem)
{
NTSTATUS Result;
PUINT8 RequestBuf, RequestBufEnd;
SIZE_T RequestBufSize;
FSP_FSCTL_TRANSACT_REQ *Request, *NextRequest;
RequestBuf = malloc(FSP_FSCTL_TRANSACT_REQ_BUFFER_SIZEMIN);
if (0 == RequestBuf)
return STATUS_INSUFFICIENT_RESOURCES;
for (;;)
{
RequestBufSize = FSP_FSCTL_TRANSACT_REQ_BUFFER_SIZEMIN;
Result = FspFsctlTransact(FileSystem->VolumeHandle, 0, 0, RequestBuf, &RequestBufSize);
if (!NT_SUCCESS(Result))
goto exit;
RequestBufEnd = RequestBuf + RequestBufSize;
Request = (PVOID)RequestBuf;
for (;;)
{
NextRequest = FspFsctlTransactConsumeRequest(Request, RequestBufEnd);
if (0 == NextRequest)
break;
Result = FileSystem->ProcessRequest(FileSystem, Request);
if (!NT_SUCCESS(Result))
goto exit;
Request = NextRequest;
}
}
exit:
free(RequestBuf);
return Result;
}
FSP_API NTSTATUS FspProcessRequestDirect(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request)
{
if (FspFsctlTransactKindCount <= Request->Kind || 0 == FileSystem->Operations[Request->Kind])
return FspProduceResponseWithStatus(FileSystem, Request, STATUS_INVALID_DEVICE_REQUEST);
FileSystem->Operations[Request->Kind](FileSystem, Request);
return STATUS_SUCCESS;
}
static DWORD WINAPI FspProcessRequestInPoolWorker(PVOID Param)
{
FSP_WORK_ITEM *WorkItem = Param;
FSP_FSCTL_TRANSACT_REQ *Request = (PVOID)WorkItem->RequestBuf;
WorkItem->FileSystem->Operations[Request->Kind](WorkItem->FileSystem, Request);
free(WorkItem);
return 0;
}
FSP_API NTSTATUS FspProcessRequestInPool(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request)
{
if (FspFsctlTransactKindCount <= Request->Kind || 0 == FileSystem->Operations[Request->Kind])
return FspProduceResponseWithStatus(FileSystem, Request, STATUS_INVALID_DEVICE_REQUEST);
FSP_WORK_ITEM *WorkItem;
BOOLEAN Success;
WorkItem = malloc(sizeof *WorkItem + Request->Size);
if (0 == WorkItem)
return STATUS_INSUFFICIENT_RESOURCES;
WorkItem->FileSystem = FileSystem;
memcpy(WorkItem->RequestBuf, Request, Request->Size);
Success = QueueUserWorkItem(FspProcessRequestInPoolWorker, WorkItem, WT_EXECUTEDEFAULT);
if (!Success)
{
free(WorkItem);
return FspNtStatusFromWin32(GetLastError());
}
return STATUS_SUCCESS;
}
FSP_API NTSTATUS FspProduceResponse(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_RSP *Response)
{
return FspFsctlTransact(FileSystem->VolumeHandle, Response, Response->Size, 0, 0);
}
FSP_API NTSTATUS FspProduceResponseWithStatus(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, NTSTATUS Result)
{
FSP_FSCTL_TRANSACT_RSP Response = { 0 };
Response.Size = sizeof Response;
Response.Kind = Request->Kind;
Response.Hint = Request->Hint;
Response.IoStatus.Status = Result;
return FspProduceResponse(FileSystem, &Response);
}

View File

@ -1,5 +1,4 @@
#include <winfsp/winfsp.h> #include <winfsp/winfsp.h>
#include <winfsp/fsctl.h>
#include <tlib/testsuite.h> #include <tlib/testsuite.h>
#include <process.h> #include <process.h>
#include <strsafe.h> #include <strsafe.h>