Author: cgutman
Date: Sun Jan 22 21:50:29 2012
New Revision: 55079
URL:
http://svn.reactos.org/svn/reactos?rev=55079&view=rev
Log:
[USB-BRINGUP-TRUNK]
- Send removal IRPs to children and removal relations before sending to the device itself
Modified:
branches/usb-bringup-trunk/ntoskrnl/io/pnpmgr/pnpmgr.c
Modified: branches/usb-bringup-trunk/ntoskrnl/io/pnpmgr/pnpmgr.c
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/ntoskrnl/io/p…
==============================================================================
--- branches/usb-bringup-trunk/ntoskrnl/io/pnpmgr/pnpmgr.c [iso-8859-1] (original)
+++ branches/usb-bringup-trunk/ntoskrnl/io/pnpmgr/pnpmgr.c [iso-8859-1] Sun Jan 22
21:50:29 2012
@@ -48,7 +48,7 @@
IopCancelPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject);
NTSTATUS
-IopPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject);
+IopPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject, BOOLEAN Force);
PDEVICE_NODE
FASTCALL
@@ -588,9 +588,9 @@
NewList = ExAllocatePool(PagedPool, NewSize);
if (!NewList) {
- /* Fail */
- ExFreePool(PnpBusTypeGuidList);
- goto Quickie;
+ /* Fail */
+ ExFreePool(PnpBusTypeGuidList);
+ goto Quickie;
}
/* Now copy them, decrease the size too */
@@ -620,7 +620,7 @@
/*
* DESCRIPTION
- * Creates a device node
+ * Creates a device node
*
* ARGUMENTS
* ParentNode = Pointer to parent device node
@@ -630,7 +630,7 @@
* DeviceNode = Pointer to storage for created device node
*
* RETURN VALUE
- * Status
+ * Status
*/
NTSTATUS
IopCreateDeviceNode(PDEVICE_NODE ParentNode,
@@ -1369,11 +1369,11 @@
RtlInitUnicodeString(&ValueName, L"HardwareID");
Status = ZwSetValueKey(InstanceKey,
- &ValueName,
- 0,
- REG_MULTI_SZ,
- (PVOID)IoStatusBlock.Information,
- (TotalLength + 1) * sizeof(WCHAR));
+ &ValueName,
+ 0,
+ REG_MULTI_SZ,
+ (PVOID)IoStatusBlock.Information,
+ (TotalLength + 1) * sizeof(WCHAR));
if (!NT_SUCCESS(Status))
{
DPRINT1("ZwSetValueKey() failed (Status %lx)\n", Status);
@@ -1826,12 +1826,20 @@
if (!Found)
{
+ /* Send removal IRPs to all of its children */
+ IopPrepareDeviceForRemoval(Child->PhysicalDeviceObject, TRUE);
+
+ /* Set the flag */
+ Child->Flags |= DNF_WILL_BE_REMOVED;
+
+ /* Send the surprise removal IRP */
IopSendSurpriseRemoval(Child->PhysicalDeviceObject);
/* Tell the user-mode PnP manager that a device was removed */
IopQueueTargetDeviceEvent(&GUID_DEVICE_SURPRISE_REMOVAL,
&Child->InstancePath);
+ /* Send the remove device IRP */
IopSendRemoveDevice(Child->PhysicalDeviceObject);
}
@@ -3899,7 +3907,7 @@
static
NTSTATUS
-IopQueryRemoveChildDevices(PDEVICE_NODE ParentDeviceNode)
+IopQueryRemoveChildDevices(PDEVICE_NODE ParentDeviceNode, BOOLEAN Force)
{
PDEVICE_NODE ChildDeviceNode, NextDeviceNode, FailedRemoveDevice;
NTSTATUS Status;
@@ -3912,7 +3920,7 @@
NextDeviceNode = ChildDeviceNode->Sibling;
KeReleaseSpinLock(&IopDeviceTreeLock, OldIrql);
- Status = IopPrepareDeviceForRemoval(ChildDeviceNode->PhysicalDeviceObject);
+ Status = IopPrepareDeviceForRemoval(ChildDeviceNode->PhysicalDeviceObject,
Force);
if (!NT_SUCCESS(Status))
{
FailedRemoveDevice = ChildDeviceNode;
@@ -3998,7 +4006,7 @@
static
NTSTATUS
-IopQueryRemoveDeviceRelations(PDEVICE_RELATIONS DeviceRelations)
+IopQueryRemoveDeviceRelations(PDEVICE_RELATIONS DeviceRelations, BOOLEAN Force)
{
/* This function DOES NOT dereference the device objects on SUCCESS
* but it DOES dereference device objects on FAILURE */
@@ -4008,7 +4016,7 @@
for (i = 0; i < DeviceRelations->Count; i++)
{
- Status = IopPrepareDeviceForRemoval(DeviceRelations->Objects[i]);
+ Status = IopPrepareDeviceForRemoval(DeviceRelations->Objects[i], Force);
if (!NT_SUCCESS(Status))
{
j = i;
@@ -4104,7 +4112,7 @@
}
NTSTATUS
-IopPrepareDeviceForRemoval(IN PDEVICE_OBJECT DeviceObject)
+IopPrepareDeviceForRemoval(IN PDEVICE_OBJECT DeviceObject, BOOLEAN Force)
{
PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject);
IO_STACK_LOCATION Stack;
@@ -4112,13 +4120,13 @@
PDEVICE_RELATIONS DeviceRelations;
NTSTATUS Status;
- if (DeviceNode->UserFlags & DNUF_NOT_DISABLEABLE)
+ if ((DeviceNode->UserFlags & DNUF_NOT_DISABLEABLE) && !Force)
{
DPRINT1("Removal not allowed for %wZ\n",
&DeviceNode->InstancePath);
return STATUS_UNSUCCESSFUL;
}
- if (IopQueryRemoveDevice(DeviceObject) != STATUS_SUCCESS)
+ if (!Force && IopQueryRemoveDevice(DeviceObject) != STATUS_SUCCESS)
{
DPRINT1("Removal vetoed by failing the query remove request\n");
@@ -4145,19 +4153,19 @@
if (DeviceRelations)
{
- Status = IopQueryRemoveDeviceRelations(DeviceRelations);
+ Status = IopQueryRemoveDeviceRelations(DeviceRelations, Force);
if (!NT_SUCCESS(Status))
return Status;
}
-
- Status = IopQueryRemoveChildDevices(DeviceNode);
+
+ Status = IopQueryRemoveChildDevices(DeviceNode, Force);
if (!NT_SUCCESS(Status))
{
if (DeviceRelations)
IopCancelRemoveDeviceRelations(DeviceRelations);
return Status;
}
-
+
if (DeviceRelations)
IopSendRemoveDeviceRelations(DeviceRelations);
IopSendRemoveChildDevices(DeviceNode);
@@ -4172,7 +4180,7 @@
DPRINT("Removing device: %wZ\n", &DeviceNode->InstancePath);
- Status = IopPrepareDeviceForRemoval(DeviceNode->PhysicalDeviceObject);
+ Status = IopPrepareDeviceForRemoval(DeviceNode->PhysicalDeviceObject, FALSE);
if (NT_SUCCESS(Status))
{
IopSendRemoveDevice(DeviceNode->PhysicalDeviceObject);
@@ -4225,12 +4233,12 @@
if (DeviceRelations)
{
- Status = IopQueryRemoveDeviceRelations(DeviceRelations);
+ Status = IopQueryRemoveDeviceRelations(DeviceRelations, FALSE);
if (!NT_SUCCESS(Status))
goto cleanup;
}
- Status = IopQueryRemoveChildDevices(DeviceNode);
+ Status = IopQueryRemoveChildDevices(DeviceNode, FALSE);
if (!NT_SUCCESS(Status))
{
if (DeviceRelations)
@@ -4238,7 +4246,7 @@
goto cleanup;
}
- if (IopPrepareDeviceForRemoval(PhysicalDeviceObject) != STATUS_SUCCESS)
+ if (IopPrepareDeviceForRemoval(PhysicalDeviceObject, FALSE) != STATUS_SUCCESS)
{
if (DeviceRelations)
IopCancelRemoveDeviceRelations(DeviceRelations);