mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-29 19:18:39 -05:00 
			
		
		
		
	dll: FspFileSystemLoop
This commit is contained in:
		| @@ -173,6 +173,7 @@ | ||||
|   <ItemGroup> | ||||
|     <ClCompile Include="..\..\src\dll\debug.c" /> | ||||
|     <ClCompile Include="..\..\src\dll\fsctl.c" /> | ||||
|     <ClCompile Include="..\..\src\dll\loop.c" /> | ||||
|     <ClCompile Include="..\..\src\dll\ntstatus.c" /> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|   | ||||
| @@ -23,6 +23,9 @@ | ||||
|     <ClCompile Include="..\..\src\dll\debug.c"> | ||||
|       <Filter>Source</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\src\dll\loop.c"> | ||||
|       <Filter>Source</Filter> | ||||
|     </ClCompile> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <ClInclude Include="..\..\inc\winfsp\fsctl.h"> | ||||
|   | ||||
| @@ -19,6 +19,34 @@ | ||||
| #define FSP_API                         __declspec(dllimport) | ||||
| #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 VOID FspDebugLog(const char *format, ...); | ||||
|  | ||||
|   | ||||
| @@ -241,17 +241,24 @@ FSP_API NTSTATUS FspFsctlTransact(HANDLE VolumeHandle, | ||||
|     PVOID RequestBuf, SIZE_T *PRequestBufSize) | ||||
| { | ||||
|     NTSTATUS Result = STATUS_SUCCESS; | ||||
|     DWORD Bytes; | ||||
|     DWORD Bytes = 0; | ||||
|  | ||||
|     if (0 != *PRequestBufSize) | ||||
|     { | ||||
|         Bytes = (DWORD)*PRequestBufSize; | ||||
|         *PRequestBufSize = 0; | ||||
|     } | ||||
|  | ||||
|     if (!DeviceIoControl(VolumeHandle, FSP_FSCTL_TRANSACT, | ||||
|         ResponseBuf, (DWORD)ResponseBufSize, RequestBuf, (DWORD)*PRequestBufSize, | ||||
|         ResponseBuf, (DWORD)ResponseBufSize, RequestBuf, Bytes, | ||||
|         &Bytes, 0)) | ||||
|     { | ||||
|         Result = FspNtStatusFromWin32(GetLastError()); | ||||
|         goto exit; | ||||
|     } | ||||
|  | ||||
|     *PRequestBufSize = Bytes; | ||||
|     if (0 != *PRequestBufSize) | ||||
|         *PRequestBufSize = Bytes; | ||||
|  | ||||
| exit: | ||||
|     return Result; | ||||
|   | ||||
| @@ -9,7 +9,6 @@ | ||||
|  | ||||
| #define WINFSP_DLL_INTERNAL | ||||
| #include <winfsp/winfsp.h> | ||||
| #include <winfsp/fsctl.h> | ||||
| #include <strsafe.h> | ||||
|  | ||||
| #define LIBRARY_NAME                    "WinFsp" | ||||
|   | ||||
							
								
								
									
										144
									
								
								src/dll/loop.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								src/dll/loop.c
									
									
									
									
									
										Normal 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); | ||||
| } | ||||
| @@ -1,5 +1,4 @@ | ||||
| #include <winfsp/winfsp.h> | ||||
| #include <winfsp/fsctl.h> | ||||
| #include <tlib/testsuite.h> | ||||
| #include <process.h> | ||||
| #include <strsafe.h> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user