dll: major overhaul of FSP_FILE_SYSTEM dispatching

This commit is contained in:
Bill Zissimopoulos
2016-02-16 17:03:00 -08:00
parent f8d5273e04
commit d8c35f26b0
13 changed files with 337 additions and 476 deletions

View File

@ -7,7 +7,7 @@
#include <dll/library.h>
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;
}

View File

@ -7,25 +7,11 @@
#include <dll/library.h>
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;
}

View File

@ -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;
}

184
src/dll/dispatch.c Normal file
View File

@ -0,0 +1,184 @@
/**
* @file dll/dispatch.c
*
* @copyright 2015 Bill Zissimopoulos
*/
#include <dll/library.h>
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);
}

View File

@ -7,25 +7,26 @@
#include <dll/library.h>
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;
}

View File

@ -1,194 +0,0 @@
/**
* @file dll/loop.c
*
* @copyright 2015 Bill Zissimopoulos
*/
#include <dll/library.h>
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);
}

View File

@ -7,33 +7,19 @@
#include <dll/library.h>
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;
}