From d21180cba079255d9349c0533ea03564bfdc0716 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Tue, 8 Dec 2015 15:25:41 -0800 Subject: [PATCH] sys: iop: FSP_FSCTL_TRANSACT_REQ_HEADER --- inc/winfsp/fsctl.h | 6 ++-- src/sys/driver.h | 12 +++++-- src/sys/fsctl.c | 2 +- src/sys/idevctl.c | 4 +-- src/sys/iop.c | 79 +++++++++++++++++++++++++++++++--------------- 5 files changed, 69 insertions(+), 34 deletions(-) diff --git a/inc/winfsp/fsctl.h b/inc/winfsp/fsctl.h index 6d1c1029..92bbd92f 100644 --- a/inc/winfsp/fsctl.h +++ b/inc/winfsp/fsctl.h @@ -36,11 +36,11 @@ extern const __declspec(selectany) GUID FspFsvrtDeviceClassGuid = CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'T', METHOD_BUFFERED, FILE_ANY_ACCESS) #define FSP_FSCTL_CREATE_BUFFER_SIZE 128 -#define FSP_FSCTL_TRANSACT_BUFFER_SIZE (16 * 1024) +#define FSP_FSCTL_TRANSACT_BUFFER_SIZE 16384 #define FSP_FSCTL_VOLUME_PARAMS_SIZE FSP_FSCTL_DEFAULT_ALIGN_UP(sizeof(FSP_FSCTL_VOLUME_PARAMS)) -#define FSP_FSCTL_TRANSACT_REQ_SIZEMAX (4 * 1024) -#define FSP_FSCTL_TRANSACT_RSP_SIZEMAX (4 * 1024) +#define FSP_FSCTL_TRANSACT_REQ_SIZEMAX (4096 - 64) /* 64: size for internal request header */ +#define FSP_FSCTL_TRANSACT_RSP_SIZEMAX (4096 - 64) /* symmetry! */ /* marshalling */ #pragma warning(push) diff --git a/src/sys/driver.h b/src/sys/driver.h index 2b802bff..75974a42 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -263,12 +263,18 @@ PIRP FspIoqEndProcessingIrp(FSP_IOQ *Ioq, UINT_PTR IrpHint); /* I/O processing */ #define FSP_FSCTL_WORK \ CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'W', METHOD_NEITHER, FILE_ANY_ACCESS) -#define FspIrpContextRequest(Irp) \ +#define FspIopRequest(Irp) \ (*(FSP_FSCTL_TRANSACT_REQ **)&(Irp)->Tail.Overlay.DriverContext[0]) +#define FspIopRequestContext(Request, I)\ + (*FspIopRequestContextAddress(Request, I)) #define FspIrpContextHandle(Irp) \ (*(HANDLE *)&(Irp)->Tail.Overlay.DriverContext[1]) -NTSTATUS FspIopCreateRequest( - PIRP Irp, PUNICODE_STRING FileName, ULONG ExtraSize, FSP_FSCTL_TRANSACT_REQ **PRequest); +#define FspIopCreateRequest(I, F, E, P) FspIopCreateRequestEx(I, F, E, 0, P) +typedef VOID FSP_IOP_REQUEST_FINI(PVOID Context[3]); +NTSTATUS FspIopCreateRequestEx( + PIRP Irp, PUNICODE_STRING FileName, ULONG ExtraSize, FSP_IOP_REQUEST_FINI *RequestFini, + FSP_FSCTL_TRANSACT_REQ **PRequest); +PVOID *FspIopRequestContextAddress(FSP_FSCTL_TRANSACT_REQ *Request, ULONG I); NTSTATUS FspIopPostWorkRequest(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_TRANSACT_REQ *Request); VOID FspIopCompleteIrpEx(PIRP Irp, NTSTATUS Result, BOOLEAN DeviceRelease); static inline diff --git a/src/sys/fsctl.c b/src/sys/fsctl.c index 37217994..afee2395 100644 --- a/src/sys/fsctl.c +++ b/src/sys/fsctl.c @@ -391,7 +391,7 @@ retry: ASSERT((PUINT8)Request + FSP_FSCTL_TRANSACT_REQ_SIZEMAX <= SystemBufferEnd); for (;;) { - PendingIrpRequest = FspIrpContextRequest(PendingIrp); + PendingIrpRequest = FspIopRequest(PendingIrp); Result = FspIopDispatchPrepare(PendingIrp, PendingIrpRequest); if (!NT_SUCCESS(Result)) diff --git a/src/sys/idevctl.c b/src/sys/idevctl.c index 1dcb6e45..f3bc98b1 100644 --- a/src/sys/idevctl.c +++ b/src/sys/idevctl.c @@ -42,7 +42,7 @@ static NTSTATUS FspFsvolInternalDeviceControl( /* associate the passed Request with our Irp; acquire ownership of the Request */ Request->Hint = (UINT_PTR)Irp; - FspIrpContextRequest(Irp) = Request; + FspIopRequest(Irp) = Request; if (!FspIoqPostIrp(&FsvrtDeviceExtension->Ioq, Irp)) { @@ -51,7 +51,7 @@ static NTSTATUS FspFsvolInternalDeviceControl( /* disocciate the Request from our Irp; release ownership back to caller */ Request->Hint = 0; - FspIrpContextRequest(Irp) = 0; + FspIopRequest(Irp) = 0; Result = STATUS_CANCELLED; goto exit; diff --git a/src/sys/iop.c b/src/sys/iop.c index 9b394413..893f6a44 100644 --- a/src/sys/iop.c +++ b/src/sys/iop.c @@ -6,25 +6,41 @@ #include -NTSTATUS FspIopCreateRequest( - PIRP Irp, PUNICODE_STRING FileName, ULONG ExtraSize, FSP_FSCTL_TRANSACT_REQ **PRequest); +NTSTATUS FspIopCreateRequestEx( + PIRP Irp, PUNICODE_STRING FileName, ULONG ExtraSize, FSP_IOP_REQUEST_FINI *RequestFini, + FSP_FSCTL_TRANSACT_REQ **PRequest); +static VOID FspIopDeleteRequest(FSP_FSCTL_TRANSACT_REQ *Request); +PVOID *FspIopRequestContextAddress(FSP_FSCTL_TRANSACT_REQ *Request, ULONG I); NTSTATUS FspIopPostWorkRequest(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_TRANSACT_REQ *Request); static IO_COMPLETION_ROUTINE FspIopPostWorkRequestCompletion; +VOID FspIopCompleteIrpEx(PIRP Irp, NTSTATUS Result, BOOLEAN DeviceRelease); NTSTATUS FspIopDispatchPrepare(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request); VOID FspIopDispatchComplete(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response); #ifdef ALLOC_PRAGMA -#pragma alloc_text(PAGE, FspIopCreateRequest) +#pragma alloc_text(PAGE, FspIopCreateRequestEx) +#pragma alloc_text(PAGE, FspIopDeleteRequest) +#pragma alloc_text(PAGE, FspIopRequestContextAddress) #pragma alloc_text(PAGE, FspIopPostWorkRequest) +#pragma alloc_text(PAGE, FspIopCompleteIrpEx) #pragma alloc_text(PAGE, FspIopDispatchPrepare) #pragma alloc_text(PAGE, FspIopDispatchComplete) #endif -NTSTATUS FspIopCreateRequest( - PIRP Irp, PUNICODE_STRING FileName, ULONG ExtraSize, FSP_FSCTL_TRANSACT_REQ **PRequest) +typedef struct +{ + FSP_IOP_REQUEST_FINI *RequestFini; + PVOID Context[3]; + __declspec(align(MEMORY_ALLOCATION_ALIGNMENT)) UINT8 RequestBuf[]; +} FSP_FSCTL_TRANSACT_REQ_HEADER; + +NTSTATUS FspIopCreateRequestEx( + PIRP Irp, PUNICODE_STRING FileName, ULONG ExtraSize, FSP_IOP_REQUEST_FINI *RequestFini, + FSP_FSCTL_TRANSACT_REQ **PRequest) { PAGED_CODE(); + FSP_FSCTL_TRANSACT_REQ_HEADER *RequestHeader; FSP_FSCTL_TRANSACT_REQ *Request; *PRequest = 0; @@ -35,39 +51,52 @@ NTSTATUS FspIopCreateRequest( if (FSP_FSCTL_TRANSACT_REQ_SIZEMAX < sizeof *Request + ExtraSize) return STATUS_INVALID_PARAMETER; - Request = ExAllocatePoolWithTag(PagedPool, - sizeof *Request + ExtraSize, FSP_TAG); - if (0 == Request) + RequestHeader = ExAllocatePoolWithTag(PagedPool, + sizeof *RequestHeader + sizeof *Request + ExtraSize, FSP_TAG); + if (0 == RequestHeader) return STATUS_INSUFFICIENT_RESOURCES; - RtlZeroMemory(Request, sizeof *Request + ExtraSize); + RtlZeroMemory(RequestHeader, sizeof *RequestHeader + sizeof *Request + ExtraSize); + RequestHeader->RequestFini = RequestFini; + + Request = (PVOID)RequestHeader->RequestBuf; Request->Size = (UINT16)(sizeof *Request + ExtraSize); Request->Hint = (UINT_PTR)Irp; if (0 != FileName) { RtlCopyMemory(Request->Buffer, FileName->Buffer, FileName->Length); - Request->Buffer[FileName->Length] = '\0'; - Request->Buffer[FileName->Length + 1] = '\0'; - Request->FileName.Offset = 0; + //Request->Buffer[FileName->Length] = '\0'; + //Request->Buffer[FileName->Length + 1] = '\0'; + //Request->FileName.Offset = 0; Request->FileName.Size = FileName->Length + sizeof(WCHAR); } - else - { - Request->FileName.Offset = 0; - Request->FileName.Size = 0; - } if (0 != Irp) - FspIrpContextRequest(Irp) = Request; + FspIopRequest(Irp) = Request; *PRequest = Request; return STATUS_SUCCESS; } -static inline -VOID FspIopDeleteRequest(FSP_FSCTL_TRANSACT_REQ *Request) +static VOID FspIopDeleteRequest(FSP_FSCTL_TRANSACT_REQ *Request) { - ExFreePoolWithTag(Request, FSP_TAG); + PAGED_CODE(); + + FSP_FSCTL_TRANSACT_REQ_HEADER *RequestHeader = (PVOID)((PUINT8)Request - sizeof *RequestHeader); + + if (0 != RequestHeader->RequestFini) + RequestHeader->RequestFini(RequestHeader->Context); + + ExFreePoolWithTag(RequestHeader, FSP_TAG); +} + +PVOID *FspIopRequestContextAddress(FSP_FSCTL_TRANSACT_REQ *Request, ULONG I) +{ + PAGED_CODE(); + + FSP_FSCTL_TRANSACT_REQ_HEADER *RequestHeader = (PVOID)((PUINT8)Request - sizeof *RequestHeader); + + return &RequestHeader->Context[I]; } NTSTATUS FspIopPostWorkRequest(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_TRANSACT_REQ *Request) @@ -120,15 +149,15 @@ static NTSTATUS FspIopPostWorkRequestCompletion( VOID FspIopCompleteIrpEx(PIRP Irp, NTSTATUS Result, BOOLEAN DeviceRelease) { - // !PAGED_CODE(); + PAGED_CODE(); ASSERT(STATUS_PENDING != Result); ASSERT(0 == Irp->Tail.Overlay.DriverContext[3]); - if (0 != FspIrpContextRequest(Irp)) + if (0 != FspIopRequest(Irp)) { - FspIopDeleteRequest(FspIrpContextRequest(Irp)); - FspIrpContextRequest(Irp) = 0; + FspIopDeleteRequest(FspIopRequest(Irp)); + FspIopRequest(Irp) = 0; } if (0 != FspIrpContextHandle(Irp))