- Send removal IRPs to children and removal relations before sending to the device itself
svn path=/branches/usb-bringup-trunk/; revision=55079
IopCancelPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject);
NTSTATUS
IopCancelPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject);
NTSTATUS
-IopPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject);
+IopPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject, BOOLEAN Force);
NewList = ExAllocatePool(PagedPool, NewSize);
if (!NewList) {
NewList = ExAllocatePool(PagedPool, NewSize);
if (!NewList) {
- /* Fail */
- ExFreePool(PnpBusTypeGuidList);
- goto Quickie;
+ /* Fail */
+ ExFreePool(PnpBusTypeGuidList);
+ goto Quickie;
}
/* Now copy them, decrease the size too */
}
/* Now copy them, decrease the size too */
- * Creates a device node
+ * Creates a device node
*
* ARGUMENTS
* ParentNode = Pointer to parent device node
*
* ARGUMENTS
* ParentNode = Pointer to parent device node
* DeviceNode = Pointer to storage for created device node
*
* RETURN VALUE
* DeviceNode = Pointer to storage for created device node
*
* RETURN VALUE
*/
NTSTATUS
IopCreateDeviceNode(PDEVICE_NODE ParentNode,
*/
NTSTATUS
IopCreateDeviceNode(PDEVICE_NODE ParentNode,
RtlInitUnicodeString(&ValueName, L"HardwareID");
Status = ZwSetValueKey(InstanceKey,
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);
if (!NT_SUCCESS(Status))
{
DPRINT1("ZwSetValueKey() failed (Status %lx)\n", Status);
+ /* 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);
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);
}
IopSendRemoveDevice(Child->PhysicalDeviceObject);
}
-IopQueryRemoveChildDevices(PDEVICE_NODE ParentDeviceNode)
+IopQueryRemoveChildDevices(PDEVICE_NODE ParentDeviceNode, BOOLEAN Force)
{
PDEVICE_NODE ChildDeviceNode, NextDeviceNode, FailedRemoveDevice;
NTSTATUS Status;
{
PDEVICE_NODE ChildDeviceNode, NextDeviceNode, FailedRemoveDevice;
NTSTATUS Status;
NextDeviceNode = ChildDeviceNode->Sibling;
KeReleaseSpinLock(&IopDeviceTreeLock, OldIrql);
NextDeviceNode = ChildDeviceNode->Sibling;
KeReleaseSpinLock(&IopDeviceTreeLock, OldIrql);
- Status = IopPrepareDeviceForRemoval(ChildDeviceNode->PhysicalDeviceObject);
+ Status = IopPrepareDeviceForRemoval(ChildDeviceNode->PhysicalDeviceObject, Force);
if (!NT_SUCCESS(Status))
{
FailedRemoveDevice = ChildDeviceNode;
if (!NT_SUCCESS(Status))
{
FailedRemoveDevice = ChildDeviceNode;
-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 */
{
/* This function DOES NOT dereference the device objects on SUCCESS
* but it DOES dereference device objects on FAILURE */
for (i = 0; i < DeviceRelations->Count; i++)
{
for (i = 0; i < DeviceRelations->Count; i++)
{
- Status = IopPrepareDeviceForRemoval(DeviceRelations->Objects[i]);
+ Status = IopPrepareDeviceForRemoval(DeviceRelations->Objects[i], Force);
if (!NT_SUCCESS(Status))
{
j = i;
if (!NT_SUCCESS(Status))
{
j = i;
-IopPrepareDeviceForRemoval(IN PDEVICE_OBJECT DeviceObject)
+IopPrepareDeviceForRemoval(IN PDEVICE_OBJECT DeviceObject, BOOLEAN Force)
{
PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject);
IO_STACK_LOCATION Stack;
{
PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject);
IO_STACK_LOCATION Stack;
PDEVICE_RELATIONS DeviceRelations;
NTSTATUS Status;
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;
}
{
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");
{
DPRINT1("Removal vetoed by failing the query remove request\n");
- Status = IopQueryRemoveDeviceRelations(DeviceRelations);
+ Status = IopQueryRemoveDeviceRelations(DeviceRelations, Force);
if (!NT_SUCCESS(Status))
return Status;
}
if (!NT_SUCCESS(Status))
return Status;
}
-
- Status = IopQueryRemoveChildDevices(DeviceNode);
+
+ Status = IopQueryRemoveChildDevices(DeviceNode, Force);
if (!NT_SUCCESS(Status))
{
if (DeviceRelations)
IopCancelRemoveDeviceRelations(DeviceRelations);
return Status;
}
if (!NT_SUCCESS(Status))
{
if (DeviceRelations)
IopCancelRemoveDeviceRelations(DeviceRelations);
return Status;
}
if (DeviceRelations)
IopSendRemoveDeviceRelations(DeviceRelations);
IopSendRemoveChildDevices(DeviceNode);
if (DeviceRelations)
IopSendRemoveDeviceRelations(DeviceRelations);
IopSendRemoveChildDevices(DeviceNode);
DPRINT("Removing device: %wZ\n", &DeviceNode->InstancePath);
DPRINT("Removing device: %wZ\n", &DeviceNode->InstancePath);
- Status = IopPrepareDeviceForRemoval(DeviceNode->PhysicalDeviceObject);
+ Status = IopPrepareDeviceForRemoval(DeviceNode->PhysicalDeviceObject, FALSE);
if (NT_SUCCESS(Status))
{
IopSendRemoveDevice(DeviceNode->PhysicalDeviceObject);
if (NT_SUCCESS(Status))
{
IopSendRemoveDevice(DeviceNode->PhysicalDeviceObject);
- Status = IopQueryRemoveDeviceRelations(DeviceRelations);
+ Status = IopQueryRemoveDeviceRelations(DeviceRelations, FALSE);
if (!NT_SUCCESS(Status))
goto cleanup;
}
if (!NT_SUCCESS(Status))
goto cleanup;
}
- Status = IopQueryRemoveChildDevices(DeviceNode);
+ Status = IopQueryRemoveChildDevices(DeviceNode, FALSE);
if (!NT_SUCCESS(Status))
{
if (DeviceRelations)
if (!NT_SUCCESS(Status))
{
if (DeviceRelations)
- if (IopPrepareDeviceForRemoval(PhysicalDeviceObject) != STATUS_SUCCESS)
+ if (IopPrepareDeviceForRemoval(PhysicalDeviceObject, FALSE) != STATUS_SUCCESS)
{
if (DeviceRelations)
IopCancelRemoveDeviceRelations(DeviceRelations);
{
if (DeviceRelations)
IopCancelRemoveDeviceRelations(DeviceRelations);