From de065afe8d6ae33bf71fc991c08c56cdefcf46bb Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Thu, 10 Dec 2015 21:31:02 -0800 Subject: [PATCH] sys: FsContext now maintains reference to its DeviceObject --- src/sys/cleanup.c | 84 +++++++++++++++++++++++------------------------ src/sys/close.c | 20 +++++------ src/sys/create.c | 10 +++--- src/sys/driver.h | 4 ++- src/sys/fileobj.c | 10 ++++-- 5 files changed, 68 insertions(+), 60 deletions(-) diff --git a/src/sys/cleanup.c b/src/sys/cleanup.c index 7273350b..861709bf 100644 --- a/src/sys/cleanup.c +++ b/src/sys/cleanup.c @@ -50,56 +50,56 @@ static NTSTATUS FspFsvolCleanup( NTSTATUS Result; FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject); - PDEVICE_OBJECT FsvrtDeviceObject = FsvolDeviceExtension->FsvrtDeviceObject; + PFILE_OBJECT FileObject = IrpSp->FileObject; + FSP_FILE_CONTEXT *FsContext = FileObject->FsContext; + UINT64 UserContext = FsContext->UserContext; + UINT64 UserContext2 = (UINT_PTR)FileObject->FsContext2; + BOOLEAN DeletePending; + LONG OpenCount; + /* lock the FsContext */ + ExAcquireResourceExclusiveLite(FsContext->Header.Resource, TRUE); + + /* propagate the FsContext DeleteOnClose to DeletePending */ + if (FsContext->DeleteOnClose) + FsContext->DeletePending = TRUE; + DeletePending = FsContext->DeletePending; + + /* all handles on this FileObject are gone; decrement its FsContext->OpenCount */ + OpenCount = FspFileContextClose(FsContext); + + /* unlock the FsContext */ + ExReleaseResourceLite(FsContext->Header.Resource); + + /* is the FsContext going away as well? */ + if (0 == OpenCount) + { + /* + * The following must be done under the file system volume device Resource, + * because we are manipulating its GenericTable. + */ + ExAcquireResourceExclusiveLite(&FsvolDeviceExtension->Base.Resource, TRUE); + try + { + /* remove the FsContext from the file system volume device generic table */ + FspFsvolDeviceDeleteContext(DeviceObject, FsContext->UserContext, 0); + } + finally + { + ExReleaseResourceLite(&FsvolDeviceExtension->Base.Resource); + } + } + + PDEVICE_OBJECT FsvrtDeviceObject = FsvolDeviceExtension->FsvrtDeviceObject; if (!FspDeviceRetain(FsvrtDeviceObject)) return STATUS_CANCELLED; + try { - FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = - FspFsvrtDeviceExtension(FsvrtDeviceObject); - PFILE_OBJECT FileObject = IrpSp->FileObject; - FSP_FILE_CONTEXT *FsContext = FileObject->FsContext; - UINT64 UserContext = FsContext->UserContext; - UINT64 UserContext2 = (UINT_PTR)FileObject->FsContext2; + FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(FsvrtDeviceObject); BOOLEAN FileNameRequired = 0 != FsvrtDeviceExtension->VolumeParams.FileNameRequired; - BOOLEAN DeletePending; - LONG OpenCount; FSP_FSCTL_TRANSACT_REQ *Request; - /* lock the FsContext */ - ExAcquireResourceExclusiveLite(FsContext->Header.Resource, TRUE); - - /* propagate the FsContext DeleteOnClose to DeletePending */ - if (FsContext->DeleteOnClose) - FsContext->DeletePending = TRUE; - DeletePending = FsContext->DeletePending; - - /* all handles on this FileObject are gone; decrement its FsContext->OpenCount */ - OpenCount = FspFileContextClose(FsContext); - - /* unlock the FsContext */ - ExReleaseResourceLite(FsContext->Header.Resource); - - /* is the FsContext going away as well? */ - if (0 == OpenCount) - { - /* - * The following must be done under the file system volume device Resource, - * because we are manipulating its GenericTable. - */ - ExAcquireResourceExclusiveLite(&FsvolDeviceExtension->Base.Resource, TRUE); - try - { - /* remove the FsContext from the file system volume device generic table */ - FspFsvolDeviceDeleteContext(DeviceObject, FsContext->UserContext, 0); - } - finally - { - ExReleaseResourceLite(&FsvolDeviceExtension->Base.Resource); - } - } - /* create the user-mode file system request */ Result = FspIopCreateRequest(Irp, FileNameRequired ? &FsContext->FileName : 0, 0, &Request); if (!NT_SUCCESS(Result)) diff --git a/src/sys/close.c b/src/sys/close.c index bfa0b7dd..f67b5162 100644 --- a/src/sys/close.c +++ b/src/sys/close.c @@ -50,24 +50,24 @@ static NTSTATUS FspFsvolClose( NTSTATUS Result; FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject); - PDEVICE_OBJECT FsvrtDeviceObject = FsvolDeviceExtension->FsvrtDeviceObject; + PFILE_OBJECT FileObject = IrpSp->FileObject; + FSP_FILE_CONTEXT *FsContext = FileObject->FsContext; + UINT64 UserContext = FsContext->UserContext; + UINT64 UserContext2 = (UINT_PTR)FileObject->FsContext2; + /* dereference the FsContext (and delete if no more references) */ + FspFileContextRelease(FsContext); + + PDEVICE_OBJECT FsvrtDeviceObject = FsvolDeviceExtension->FsvrtDeviceObject; if (!FspDeviceRetain(FsvrtDeviceObject)) return STATUS_CANCELLED; + try { - FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = - FspFsvrtDeviceExtension(FsvrtDeviceObject); - PFILE_OBJECT FileObject = IrpSp->FileObject; - FSP_FILE_CONTEXT *FsContext = FileObject->FsContext; - UINT64 UserContext = FsContext->UserContext; - UINT64 UserContext2 = (UINT_PTR)FileObject->FsContext2; + FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(FsvrtDeviceObject); BOOLEAN FileNameRequired = 0 != FsvrtDeviceExtension->VolumeParams.FileNameRequired; 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(0, FileNameRequired ? &FsContext->FileName : 0, 0, &Request); if (!NT_SUCCESS(Result)) diff --git a/src/sys/create.c b/src/sys/create.c index 75236079..7cb23ae0 100644 --- a/src/sys/create.c +++ b/src/sys/create.c @@ -63,14 +63,14 @@ static NTSTATUS FspFsvolCreate( NTSTATUS Result; FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject); - PDEVICE_OBJECT FsvrtDeviceObject = FsvolDeviceExtension->FsvrtDeviceObject; + PDEVICE_OBJECT FsvrtDeviceObject = FsvolDeviceExtension->FsvrtDeviceObject; if (!FspDeviceRetain(FsvrtDeviceObject)) return STATUS_CANCELLED; + try { - FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = - FspFsvrtDeviceExtension(FsvrtDeviceObject); + FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(FsvrtDeviceObject); PFILE_OBJECT FileObject = IrpSp->FileObject; PFILE_OBJECT RelatedFileObject = FileObject->RelatedFileObject; UNICODE_STRING FileName = FileObject->FileName; @@ -223,7 +223,7 @@ static NTSTATUS FspFsvolCreate( BOOLEAN AppendBackslash = sizeof(WCHAR) * 2/* not empty or root */ <= RelatedFsContext->FileName.Length && sizeof(WCHAR) <= FileName.Length && L':' != FileName.Buffer[0]; - Result = FspFileContextCreate( + Result = FspFileContextCreate(DeviceObject, RelatedFsContext->FileName.Length + AppendBackslash * sizeof(WCHAR) + FileName.Length, &FsContext); if (!NT_SUCCESS(Result)) @@ -254,7 +254,7 @@ static NTSTATUS FspFsvolCreate( goto exit; } - Result = FspFileContextCreate( + Result = FspFileContextCreate(DeviceObject, FileName.Length, &FsContext); if (!NT_SUCCESS(Result)) diff --git a/src/sys/driver.h b/src/sys/driver.h index b3b899d2..cb0af273 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -398,11 +398,13 @@ typedef struct BOOLEAN DeleteOnClose; /* FILE_DELETE_ON_CLOSE */ /* read-only after creation */ FSP_DEVICE_GENERIC_TABLE_ELEMENT ElementStorage; + PDEVICE_OBJECT FsvolDeviceObject; UINT64 UserContext; UNICODE_STRING FileName; WCHAR FileNameBuf[]; } FSP_FILE_CONTEXT; -NTSTATUS FspFileContextCreate(ULONG ExtraSize, FSP_FILE_CONTEXT **PContext); +NTSTATUS FspFileContextCreate(PDEVICE_OBJECT DeviceObject, + ULONG ExtraSize, FSP_FILE_CONTEXT **PFsContext); VOID FspFileContextDelete(FSP_FILE_CONTEXT *Context); static inline VOID FspFileContextOpen(FSP_FILE_CONTEXT *Context) diff --git a/src/sys/fileobj.c b/src/sys/fileobj.c index 015ed7d8..2e214d46 100644 --- a/src/sys/fileobj.c +++ b/src/sys/fileobj.c @@ -6,7 +6,8 @@ #include -NTSTATUS FspFileContextCreate(ULONG ExtraSize, FSP_FILE_CONTEXT **PContext); +NTSTATUS FspFileContextCreate(PDEVICE_OBJECT DeviceObject, + ULONG ExtraSize, FSP_FILE_CONTEXT **PFsContext); VOID FspFileContextDelete(FSP_FILE_CONTEXT *Context); #ifdef ALLOC_PRAGMA @@ -14,7 +15,8 @@ VOID FspFileContextDelete(FSP_FILE_CONTEXT *Context); #pragma alloc_text(PAGE, FspFileContextDelete) #endif -NTSTATUS FspFileContextCreate(ULONG ExtraSize, FSP_FILE_CONTEXT **PFsContext) +NTSTATUS FspFileContextCreate(PDEVICE_OBJECT DeviceObject, + ULONG ExtraSize, FSP_FILE_CONTEXT **PFsContext) { PAGED_CODE(); @@ -45,6 +47,8 @@ NTSTATUS FspFileContextCreate(ULONG ExtraSize, FSP_FILE_CONTEXT **PFsContext) FsRtlSetupAdvancedHeader(&FsContext->Header, &NonPaged->HeaderFastMutex); FsContext->NonPaged = NonPaged; FsContext->RefCount = 1; + FsContext->FsvolDeviceObject = DeviceObject; + FspDeviceRetain(FsContext->FsvolDeviceObject); RtlInitEmptyUnicodeString(&FsContext->FileName, FsContext->FileNameBuf, (USHORT)ExtraSize); *PFsContext = FsContext; @@ -58,6 +62,8 @@ VOID FspFileContextDelete(FSP_FILE_CONTEXT *FsContext) FsRtlTeardownPerStreamContexts(&FsContext->Header); + FspDeviceRelease(FsContext->FsvolDeviceObject); + ExDeleteResourceLite(&FsContext->NonPaged->PagingIoResource); ExDeleteResourceLite(&FsContext->NonPaged->Resource); FspFree(FsContext->NonPaged);