From f24aa3981dd032137679056f8fccc2293bcfd53f Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Tue, 23 Oct 2012 05:42:17 +0000 Subject: [PATCH] [NTOSKRNL] - Unregister dope (device object power extension) from volume list when device object is deleted - Core-6691 #resolve svn path=/trunk/; revision=57599 --- reactos/ntoskrnl/include/internal/po.h | 5 +++ reactos/ntoskrnl/io/iomgr/device.c | 3 ++ reactos/ntoskrnl/po/povolume.c | 47 +++++++++++++++++++++++++- 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/reactos/ntoskrnl/include/internal/po.h b/reactos/ntoskrnl/include/internal/po.h index dcc4d0dbcbb..11891202787 100644 --- a/reactos/ntoskrnl/include/internal/po.h +++ b/reactos/ntoskrnl/include/internal/po.h @@ -285,6 +285,11 @@ PoVolumeDevice( IN PDEVICE_OBJECT DeviceObject ); +VOID +NTAPI +PoRemoveVolumeDevice( + IN PDEVICE_OBJECT DeviceObject); + // // Power State routines // diff --git a/reactos/ntoskrnl/io/iomgr/device.c b/reactos/ntoskrnl/io/iomgr/device.c index 0b1a8861fb4..a0e19615056 100644 --- a/reactos/ntoskrnl/io/iomgr/device.c +++ b/reactos/ntoskrnl/io/iomgr/device.c @@ -1035,6 +1035,9 @@ IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject) /* Set the pending delete flag */ IoGetDevObjExtension(DeviceObject)->ExtensionFlags |= DOE_DELETE_PENDING; + /* Unlink with the power manager */ + if (DeviceObject->Vpb) PoRemoveVolumeDevice(DeviceObject); + /* Check if the device object can be unloaded */ if (!DeviceObject->ReferenceCount) IopUnloadDevice(DeviceObject); } diff --git a/reactos/ntoskrnl/po/povolume.c b/reactos/ntoskrnl/po/povolume.c index 15aaebf7586..77003029a43 100644 --- a/reactos/ntoskrnl/po/povolume.c +++ b/reactos/ntoskrnl/po/povolume.c @@ -97,7 +97,52 @@ PoVolumeDevice(IN PDEVICE_OBJECT DeviceObject) KeReleaseGuardedMutex(&PopVolumeLock); } } - + +VOID +NTAPI +PoRemoveVolumeDevice(IN PDEVICE_OBJECT DeviceObject) +{ + PDEVICE_OBJECT_POWER_EXTENSION Dope; + PEXTENDED_DEVOBJ_EXTENSION DeviceExtension; + KIRQL OldIrql; + PAGED_CODE(); + + /* If the device already has the dope, return it */ + DeviceExtension = IoGetDevObjExtension(DeviceObject); + if (!DeviceExtension->Dope) + { + /* no dope */ + return; + } + + /* Make sure we can flush safely */ + KeAcquireGuardedMutex(&PopVolumeLock); + + /* Get dope from device */ + Dope = (PDEVICE_OBJECT_POWER_EXTENSION)DeviceExtension->Dope; + + if (Dope->Volume.Flink) + { + /* Remove from volume from list */ + RemoveEntryList(&Dope->Volume); + } + + /* Allow flushes to go through */ + KeReleaseGuardedMutex(&PopVolumeLock); + + /* Now remove dope from device object */ + KeAcquireSpinLock(&PopDopeGlobalLock, &OldIrql); + + /* remove from dev obj */ + DeviceExtension->Dope = NULL; + + /* Release lock */ + KeReleaseSpinLock(&PopDopeGlobalLock, OldIrql); + + /* Free dope */ + ExFreePoolWithTag(Dope, 'Dope'); +} + VOID NTAPI PopFlushVolumeWorker(IN PVOID Context) -- 2.17.1