Author: cgutman Date: Wed Jun 1 06:22:54 2011 New Revision: 52034
URL: http://svn.reactos.org/svn/reactos?rev=52034&view=rev Log: [NTOSKRNL] - Remove the device node when the device object is destroyed to prevent PnP manager from crashing when manipulating device nodes with device objects that no longer exist - Move removal notifications into IopRemoveDevice and call it from IopPrepareDeviceForRemoval and IoRequestDeviceEject to manage all of the removal relations for each device removed
Modified: trunk/reactos/ntoskrnl/io/iomgr/device.c trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c
Modified: trunk/reactos/ntoskrnl/io/iomgr/device.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/device.c?... ============================================================================== --- trunk/reactos/ntoskrnl/io/iomgr/device.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/io/iomgr/device.c [iso-8859-1] Wed Jun 1 06:22:54 2011 @@ -48,9 +48,12 @@ IopDeleteDevice(IN PVOID ObjectBody) { PDEVICE_OBJECT DeviceObject = ObjectBody; + PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject); PAGED_CODE(); - - /* TODO: Delete Device Node */ + + /* Cleanup and free the device node */ + if (DeviceNode) + IopFreeDeviceNode(DeviceNode);
/* Dereference the driver object, referenced in IoCreateDevice */ if (DeviceObject->DriverObject)
Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c... ============================================================================== --- trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c [iso-8859-1] Wed Jun 1 06:22:54 2011 @@ -3936,12 +3936,9 @@ IopQueueTargetDeviceEvent(&GUID_DEVICE_REMOVE_PENDING, &RelationsDeviceNode->InstancePath);
- if (IopQueryRemoveDevice(DeviceRelations->Objects[i]) != STATUS_SUCCESS) + if (IopRemoveDevice(RelationsDeviceNode) != STATUS_SUCCESS) { DPRINT1("Device removal vetoed by failing a dependent query remove request\n"); - - IopQueueTargetDeviceEvent(&GUID_DEVICE_REMOVAL_VETOED, - &RelationsDeviceNode->InstancePath);
Status = STATUS_UNSUCCESSFUL;
@@ -3949,11 +3946,6 @@ } else { - IopSendRemoveDevice(DeviceRelations->Objects[i]); - - IopQueueTargetDeviceEvent(&GUID_DEVICE_SAFE_REMOVAL, - &RelationsDeviceNode->InstancePath); - ObDereferenceObject(DeviceRelations->Objects[i]);
DeviceRelations->Objects[i] = NULL; @@ -3995,8 +3987,14 @@ if (NT_SUCCESS(Status)) { IopSendRemoveDevice(DeviceNode->PhysicalDeviceObject); + IopQueueTargetDeviceEvent(&GUID_DEVICE_SAFE_REMOVAL, + &DeviceNode->InstancePath); + DeviceNode->Flags |= DNF_WILL_BE_REMOVED; return STATUS_SUCCESS; } + + IopQueueTargetDeviceEvent(&GUID_DEVICE_REMOVAL_VETOED, + &DeviceNode->InstancePath);
return Status; } @@ -4051,22 +4049,14 @@ IopQueueTargetDeviceEvent(&GUID_DEVICE_REMOVE_PENDING, &RelationsDeviceNode->InstancePath);
- if (IopQueryRemoveDevice(DeviceRelations->Objects[i]) != STATUS_SUCCESS) + if (IopRemoveDevice(RelationsDeviceNode) != STATUS_SUCCESS) { DPRINT1("Device removal vetoed by failing a query remove request (ejection relations)\n"); - - IopQueueTargetDeviceEvent(&GUID_DEVICE_REMOVAL_VETOED, - &RelationsDeviceNode->InstancePath); - + goto cleanup; } else { - IopSendRemoveDevice(DeviceRelations->Objects[i]); - - IopQueueTargetDeviceEvent(&GUID_DEVICE_SAFE_REMOVAL, - &RelationsDeviceNode->InstancePath); - ObDereferenceObject(DeviceRelations->Objects[i]);
DeviceRelations->Objects[i] = NULL;