diff --git a/src/sys/create.c b/src/sys/create.c index 6925bdd9..977871b0 100644 --- a/src/sys/create.c +++ b/src/sys/create.c @@ -70,6 +70,7 @@ static NTSTATUS FspFsvolCreate( BOOLEAN HasTraversePrivilege = BooleanFlagOn(AccessState->Flags, TOKEN_HAS_TRAVERSE_PRIVILEGE); BOOLEAN HasTrailingBackslash = FALSE; FSP_FILE_CONTEXT *FsContext = 0; + FSP_FSCTL_TRANSACT_REQ *Request; /* cannot open the volume object */ if (0 == RelatedFileObject && 0 == FileName.Length) @@ -164,6 +165,28 @@ static NTSTATUS FspFsvolCreate( * From this point forward we MUST remember to delete the FsContext on error. */ + /* create the user-mode file system request */ + Result = FspIopCreateRequest(Irp, FsContext->FileName.Length, &Request); + if (!NT_SUCCESS(Result)) + { + FspFileContextDelete(FsContext); + return Result; + } + + /* !!!: populate the request */ + + /* + * Post the IRP to our Ioq; we do this here instead of at FSP_LEAVE_MJ time, + * so that we can FspFileContextDelete() on failure. + */ + if (!FspIoqPostIrp(&FsvrtDeviceExtension->Ioq, Irp)) + { + /* this can only happen if the Ioq was stopped */ + ASSERT(FspIoqStopped(&FsvrtDeviceExtension->Ioq)); + FspFileContextDelete(FsContext); + return STATUS_CANCELLED; + } + return STATUS_PENDING; } diff --git a/src/sys/driver.h b/src/sys/driver.h index bd5d8022..ffdafe2b 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -246,6 +246,7 @@ BOOLEAN FspIoqStartProcessingIrp(FSP_IOQ *Ioq, PIRP Irp); PIRP FspIoqEndProcessingIrp(FSP_IOQ *Ioq, UINT_PTR IrpHint); /* I/O processing */ +NTSTATUS FspIopCreateRequest(PIRP Irp, ULONG ExtraSize, FSP_FSCTL_TRANSACT_REQ **PRequest); VOID FspIopCompleteRequest(PIRP Irp, NTSTATUS Result); VOID FspIopDispatchComplete(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response); @@ -337,7 +338,7 @@ typedef struct UNICODE_STRING FileName; WCHAR FileNameBuf[]; } FSP_FILE_CONTEXT; -NTSTATUS FspFileContextCreate(SIZE_T ExtraSize, FSP_FILE_CONTEXT **PContext); +NTSTATUS FspFileContextCreate(ULONG ExtraSize, FSP_FILE_CONTEXT **PContext); VOID FspFileContextDelete(FSP_FILE_CONTEXT *Context); /* misc */ diff --git a/src/sys/fileobj.c b/src/sys/fileobj.c index 5d83ec36..e08ff131 100644 --- a/src/sys/fileobj.c +++ b/src/sys/fileobj.c @@ -6,7 +6,7 @@ #include -NTSTATUS FspFileContextCreate(SIZE_T ExtraSize, FSP_FILE_CONTEXT **PContext); +NTSTATUS FspFileContextCreate(ULONG ExtraSize, FSP_FILE_CONTEXT **PContext); VOID FspFileContextDelete(FSP_FILE_CONTEXT *Context); #ifdef ALLOC_PRAGMA @@ -14,7 +14,7 @@ VOID FspFileContextDelete(FSP_FILE_CONTEXT *Context); #pragma alloc_text(PAGE, FspFileContextDelete) #endif -NTSTATUS FspFileContextCreate(SIZE_T ExtraSize, FSP_FILE_CONTEXT **PFsContext) +NTSTATUS FspFileContextCreate(ULONG ExtraSize, FSP_FILE_CONTEXT **PFsContext) { PAGED_CODE(); diff --git a/src/sys/iop.c b/src/sys/iop.c index 38b35c81..a6c7b119 100644 --- a/src/sys/iop.c +++ b/src/sys/iop.c @@ -6,12 +6,35 @@ #include +NTSTATUS FspIopCreateRequest(PIRP Irp, ULONG ExtraSize, FSP_FSCTL_TRANSACT_REQ **PRequest); VOID FspIopDispatchComplete(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response); #ifdef ALLOC_PRAGMA +#pragma alloc_text(PAGE, FspIopCreateRequest) #pragma alloc_text(PAGE, FspIopDispatchComplete) #endif +NTSTATUS FspIopCreateRequest(PIRP Irp, ULONG ExtraSize, FSP_FSCTL_TRANSACT_REQ **PRequest) +{ + PAGED_CODE(); + + *PRequest = 0; + + FSP_FSCTL_TRANSACT_REQ *Request = ExAllocatePoolWithTag(PagedPool, + sizeof *Request + ExtraSize, FSP_TAG); + if (0 == Request) + return STATUS_INSUFFICIENT_RESOURCES; + + RtlZeroMemory(Request, sizeof *Request + ExtraSize); + Request->Size = (UINT16)(sizeof *Request + ExtraSize); + Request->Hint = (UINT_PTR)Irp; + + Irp->Tail.Overlay.DriverContext[0] = Request; + *PRequest = Request; + + return STATUS_SUCCESS; +} + VOID FspIopCompleteRequest(PIRP Irp, NTSTATUS Result) { // !PAGED_CODE();