fsctl.h: FspFsctlTransact{Produce,Consume}{Request,Response}

This commit is contained in:
Bill Zissimopoulos 2015-11-26 00:06:10 -08:00
parent bafb947b9f
commit 4762f6d2e8
2 changed files with 50 additions and 20 deletions

View File

@ -31,7 +31,6 @@ extern const __declspec(selectany) GUID FspFsvrtDeviceClassGuid =
#define FSP_FSCTL_CREATE_BUFFER_SIZE 128 #define FSP_FSCTL_CREATE_BUFFER_SIZE 128
#define FSP_FSCTL_TRANSACT_BUFFER_SIZE 4096 #define FSP_FSCTL_TRANSACT_BUFFER_SIZE 4096
#define FSP_FSCTL_TRANSACT_REQ_SIZEMAX 1536
/* marshalling */ /* marshalling */
#pragma warning(push) #pragma warning(push)
@ -62,6 +61,36 @@ typedef struct
} Req; } Req;
} FSP_TRANSACT_RSP; } FSP_TRANSACT_RSP;
#pragma warning(pop) #pragma warning(pop)
static inline FSP_TRANSACT_REQ *FspFsctlTransactProduceRequest(
FSP_TRANSACT_REQ *Request, SIZE_T RequestSize, PVOID RequestBufEnd)
{
PVOID NextRequest = (PUINT8)Request + RequestSize;
return NextRequest <= RequestBufEnd ? NextRequest : 0;
}
static inline const FSP_TRANSACT_REQ *FspFsctlTransactConsumeRequest(
const FSP_TRANSACT_REQ *Request, PVOID RequestBufEnd)
{
if ((PUINT8)Request + sizeof(Request->Size) > (PUINT8)RequestBufEnd ||
sizeof(FSP_TRANSACT_REQ) > Request->Size)
return 0;
PVOID NextRequest = (PUINT8)Request + Request->Size;
return NextRequest <= RequestBufEnd ? NextRequest : 0;
}
static inline FSP_TRANSACT_RSP *FspFsctlTransactProduceResponse(
FSP_TRANSACT_RSP *Response, SIZE_T ResponseSize, PVOID ResponseBufEnd)
{
PVOID NextResponse = (PUINT8)Response + ResponseSize;
return NextResponse <= ResponseBufEnd ? NextResponse : 0;
}
static inline const FSP_TRANSACT_RSP *FspFsctlTransactConsumeResponse(
const FSP_TRANSACT_RSP *Response, PVOID ResponseBufEnd)
{
if ((PUINT8)Response + sizeof(Response->Size) > (PUINT8)ResponseBufEnd ||
sizeof(FSP_TRANSACT_RSP) > Response->Size)
return 0;
PVOID NextResponse = (PUINT8)Response + Response->Size;
return NextResponse <= ResponseBufEnd ? NextResponse : 0;
}
#if !defined(WINFSP_SYS_DRIVER_H_INTERNAL) #if !defined(WINFSP_SYS_DRIVER_H_INTERNAL)
NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath, PSECURITY_DESCRIPTOR SecurityDescriptor, NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath, PSECURITY_DESCRIPTOR SecurityDescriptor,

View File

@ -120,9 +120,9 @@ static NTSTATUS FspFsvrtTransact(
NTSTATUS Result; NTSTATUS Result;
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(DeviceObject); FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(DeviceObject);
PUINT8 SystemBufferPtr, SystemBufferEnd; PUINT8 SystemBufferEnd;
FSP_TRANSACT_RSP *Response; const FSP_TRANSACT_RSP *Response, *NextResponse;
FSP_TRANSACT_REQ *Request; FSP_TRANSACT_REQ *Request, *NextRequest, *PendingIrpRequest;
PIRP ProcessIrp, PendingIrp; PIRP ProcessIrp, PendingIrp;
/* access check */ /* access check */
@ -136,19 +136,18 @@ static NTSTATUS FspFsvrtTransact(
SystemBufferEnd = (PUINT8)SystemBuffer + InputBufferLength; SystemBufferEnd = (PUINT8)SystemBuffer + InputBufferLength;
for (;;) for (;;)
{ {
if ((PUINT8)Response + sizeof(Response->Size) > SystemBufferEnd || NextResponse = FspFsctlTransactConsumeResponse(Response, SystemBufferEnd);
sizeof(FSP_TRANSACT_RSP) > Response->Size || if (0 == NextResponse)
(PUINT8)Response + Response->Size > SystemBufferEnd)
break; break;
ProcessIrp = FspIoqEndProcessingIrp(&FsvrtDeviceExtension->Ioq, Response->Hint); ProcessIrp = FspIoqEndProcessingIrp(&FsvrtDeviceExtension->Ioq, Response->Hint);
if (0 == ProcessIrp) if (0 == ProcessIrp)
/* either IRP was canceled or a bogus IrpHint was provided */ /* either IRP was canceled or a bogus Hint was provided */
continue; continue;
//FspDispatchProcessedIrp(ProcessIrp, Response); //FspDispatchProcessedIrp(ProcessIrp, Response);
Response = (PVOID)((PUINT8)Response + Response->Size); Response = NextResponse;
} }
/* wait for an IRP to arrive */ /* wait for an IRP to arrive */
@ -159,14 +158,21 @@ static NTSTATUS FspFsvrtTransact(
} }
/* send any pending IRP's to the user-mode file system */ /* send any pending IRP's to the user-mode file system */
SystemBufferPtr = SystemBuffer; Request = SystemBuffer;
SystemBufferEnd = (PUINT8)SystemBuffer + OutputBufferLength; SystemBufferEnd = (PUINT8)SystemBuffer + OutputBufferLength;
ASSERT(SystemBufferPtr + FSP_FSCTL_TRANSACT_REQ_SIZEMAX + sizeof(Request->Size) <= SystemBufferEnd); for (;;)
for (BOOLEAN LoopedOnce = FALSE;; LoopedOnce = TRUE)
{ {
if (SystemBufferPtr + FSP_FSCTL_TRANSACT_REQ_SIZEMAX + sizeof(Request->Size) > SystemBufferEnd) PendingIrpRequest = PendingIrp->Tail.Overlay.DriverContext[0];
NextRequest = FspFsctlTransactProduceRequest(
Request, PendingIrpRequest->Size, SystemBufferEnd);
ASSERT(0 != NextRequest || Request != SystemBuffer);
if (0 == NextRequest)
break; break;
RtlCopyMemory(Request, PendingIrpRequest, PendingIrpRequest->Size);
Request = NextRequest;
if (!FspIoqStartProcessingIrp(&FsvrtDeviceExtension->Ioq, PendingIrp)) if (!FspIoqStartProcessingIrp(&FsvrtDeviceExtension->Ioq, PendingIrp))
{ {
/* /*
@ -180,17 +186,12 @@ static NTSTATUS FspFsvrtTransact(
return STATUS_CANCELLED; return STATUS_CANCELLED;
} }
Request = PendingIrp->Tail.Overlay.DriverContext[0];
RtlCopyMemory(SystemBufferPtr, Request, Request->Size);
SystemBufferPtr += Request->Size;
PendingIrp = FspIoqNextPendingIrp(&FsvrtDeviceExtension->Ioq, 0); PendingIrp = FspIoqNextPendingIrp(&FsvrtDeviceExtension->Ioq, 0);
if (0 == PendingIrp) if (0 == PendingIrp)
break; break;
} }
ASSERT(SystemBufferPtr + sizeof(Request->Size) <= SystemBufferEnd); Irp->IoStatus.Information = (PUINT8)Request - (PUINT8)SystemBuffer;
RtlZeroMemory(SystemBufferPtr, SystemBufferEnd - SystemBufferPtr);
Irp->IoStatus.Information = SystemBufferPtr - (PUINT8)SystemBuffer;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }