From 8ad93d934d7307b73b1888a516e7f8207ddc220f Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Mon, 4 Jan 2016 15:34:11 -0800 Subject: [PATCH] sys: IRP_MJ_CLOSE --- src/sys/cleanup.c | 6 +++--- src/sys/close.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/src/sys/cleanup.c b/src/sys/cleanup.c index f26ce532..1b469eab 100644 --- a/src/sys/cleanup.c +++ b/src/sys/cleanup.c @@ -80,9 +80,9 @@ static NTSTATUS FspFsvolCleanup( if (!NT_SUCCESS(Result)) { /* - * This really should NOT, but can theoretically happen. One way around it would be to - * preallocate the Request at IRP_MJ_CREATE time. Unfortunately this becomes more - * complicated because of the FileNameRequired functionality. + * This really should NOT fail, but can theoretically happen. One way around it would + * be to preallocate the Request at IRP_MJ_CREATE time. Unfortunately this becomes + * expensive (and complicated) because of the FileNameRequired functionality. */ #if DBG DEBUGLOG("FileObject=%p, UserContext=%llx, UserContext2=%llx: " diff --git a/src/sys/close.c b/src/sys/close.c index 30f50c58..88c9f4ad 100644 --- a/src/sys/close.c +++ b/src/sys/close.c @@ -42,10 +42,59 @@ static NTSTATUS FspFsvrtClose( } static NTSTATUS FspFsvolClose( - PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) + PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) { PAGED_CODE(); + /* is this a valid FileObject? */ + if (!FspFileContextIsValid(IrpSp->FileObject->FsContext)) + return STATUS_SUCCESS; + + NTSTATUS Result; + FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject); + BOOLEAN FileNameRequired = 0 != FsvolDeviceExtension->VolumeParams.FileNameRequired; + PFILE_OBJECT FileObject = IrpSp->FileObject; + FSP_FILE_CONTEXT *FsContext = FileObject->FsContext; + UINT64 UserContext = FsContext->UserContext; + UINT64 UserContext2 = (UINT_PTR)FileObject->FsContext2; + FSP_FSCTL_TRANSACT_REQ *Request; + + /* dereference the FsContext (and delete if no more references) */ + FspFileContextRelease(FsContext); + + /* create the user-mode file system request */ + Result = FspIopCreateRequest(Irp, FileNameRequired ? &FsContext->FileName : 0, 0, &Request); + if (!NT_SUCCESS(Result)) + { + /* + * This really should NOT fail, but can theoretically happen. One way around it would + * be to preallocate the Request at IRP_MJ_CREATE time. Unfortunately this becomes + * expensive (and complicated) because of the FileNameRequired functionality. + */ +#if DBG + DEBUGLOG("FileObject=%p, UserContext=%llx, UserContext2=%llx: " + "error: the user-mode file system handle will be leaked!", + FileObject, UserContext, UserContext2); +#endif + Irp->IoStatus.Information = 0; + return STATUS_SUCCESS; + } + + /* populate the Close request */ + Request->Kind = FspFsctlTransactCloseKind; + Request->Req.Close.UserContext = UserContext; + Request->Req.Close.UserContext2 = UserContext2; + + /* post as a work request; this allows us to complete our own IRP and return immediately! */ + if (!FspIopPostWorkRequest(FsvolDeviceObject, Request)) + { +#if DBG + DEBUGLOG("FileObject=%p, UserContext=%llx, UserContext2=%llx: " + "error: the user-mode file system handle will be leaked!", + FileObject, UserContext, UserContext2); +#endif + } + Irp->IoStatus.Information = 0; return STATUS_SUCCESS; }