[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

svn path=/trunk/; revision=52034
This commit is contained in:
Cameron Gutman 2011-06-01 06:22:54 +00:00
parent 47328a7510
commit 9048ea9dcf
2 changed files with 14 additions and 21 deletions

View file

@ -48,9 +48,12 @@ NTAPI
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)

View file

@ -3936,24 +3936,16 @@ IopPrepareDeviceForRemoval(IN PDEVICE_OBJECT DeviceObject)
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;
goto cleanup;
}
else
{
IopSendRemoveDevice(DeviceRelations->Objects[i]);
IopQueueTargetDeviceEvent(&GUID_DEVICE_SAFE_REMOVAL,
&RelationsDeviceNode->InstancePath);
ObDereferenceObject(DeviceRelations->Objects[i]);
DeviceRelations->Objects[i] = NULL;
@ -3995,9 +3987,15 @@ IopRemoveDevice(PDEVICE_NODE DeviceNode)
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 @@ IoRequestDeviceEject(IN PDEVICE_OBJECT PhysicalDeviceObject)
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;