[NTOSKRNL]

- Implement IopRemoveDevice and IopStopDevice
- Do a graceful remove before installing new drivers (like Windows does)
- Debug log warnings abound (don't be alarmed ;)) because drivers aren't used to receiving IRP_MN_QUERY_REMOVE_DEVICE, IRP_MN_REMOVE_DEVICE and IRP_MN_QUERY_PNP_DEVICE_STATE from our (formly) crippled PnP manager

svn path=/trunk/; revision=52029
This commit is contained in:
Cameron Gutman
2011-05-31 19:34:08 +00:00
parent 3d472cf72f
commit 80d7517cde
3 changed files with 63 additions and 4 deletions
+10
View File
@@ -790,6 +790,16 @@ IopStartDevice(
IN PDEVICE_NODE DeviceNode
);
NTSTATUS
IopStopDevice(
IN PDEVICE_NODE DeviceNode
);
NTSTATUS
IopRemoveDevice(
IN PDEVICE_NODE DeviceNode
);
PVPB
NTAPI
IopCheckVpbMounted(
+11 -3
View File
@@ -551,10 +551,18 @@ IopResetDevice(PPLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData)
DeviceNode = IopGetDeviceNode(DeviceObject);
/* FIXME: we should stop the device, before starting it again */
/* Remove the device */
if (DeviceNode->Flags & DNF_ENUMERATED)
{
Status = IopRemoveDevice(DeviceNode);
if (!NT_SUCCESS(Status))
{
DPRINT1("WARNING: Ignoring failed IopRemoveDevice() for %wZ (likely a driver bug)\n", &DeviceNode->InstancePath);
}
}
/* Start the device */
IopDeviceNodeClearFlag(DeviceNode, DNF_DISABLED);
/* Reenumerate the device and its children */
DeviceNode->Flags &= ~DNF_DISABLED;
Status = IopActionConfigureChildServices(DeviceNode, DeviceNode->Parent);
if (NT_SUCCESS(Status))
+42 -1
View File
@@ -337,6 +337,24 @@ IopStartAndEnumerateDevice(IN PDEVICE_NODE DeviceNode)
return Status;
}
NTSTATUS
IopStopDevice(
PDEVICE_NODE DeviceNode)
{
NTSTATUS Status;
DPRINT("Stopping device: %wZ\n", &DeviceNode->InstancePath);
Status = IopQueryStopDevice(DeviceNode->PhysicalDeviceObject);
if (!NT_SUCCESS(Status))
{
IopSendStopDevice(DeviceNode->PhysicalDeviceObject);
return STATUS_SUCCESS;
}
return Status;
}
NTSTATUS
IopStartDevice(
PDEVICE_NODE DeviceNode)
@@ -420,7 +438,7 @@ IopQueryDeviceCapabilities(PDEVICE_NODE DeviceNode,
return Status;
}
DeviceNode->CapabilityFlags = *(PULONG)((ULONG_PTR)&DeviceCaps + 4);
DeviceNode->CapabilityFlags = *(PULONG)((ULONG_PTR)&DeviceCaps->Version + sizeof(DeviceCaps->Version));;
if (DeviceCaps->NoDisplayInUI)
DeviceNode->UserFlags |= DNUF_DONT_SHOW_IN_UI;
@@ -3873,6 +3891,12 @@ IopPrepareDeviceForRemoval(IN PDEVICE_OBJECT DeviceObject)
PDEVICE_RELATIONS DeviceRelations;
NTSTATUS Status;
ULONG i;
if (DeviceNode->UserFlags & DNUF_NOT_DISABLEABLE)
{
DPRINT1("Removal not allowed for %wZ\n", &DeviceNode->InstancePath);
return STATUS_UNSUCCESSFUL;
}
IopQueueTargetDeviceEvent(&GUID_DEVICE_REMOVE_PENDING,
&DeviceNode->InstancePath);
@@ -3958,6 +3982,23 @@ cleanup:
return Status;
}
NTSTATUS
IopRemoveDevice(PDEVICE_NODE DeviceNode)
{
NTSTATUS Status;
DPRINT("Removing device: %wZ\n", &DeviceNode->InstancePath);
Status = IopPrepareDeviceForRemoval(DeviceNode->PhysicalDeviceObject);
if (NT_SUCCESS(Status))
{
IopSendRemoveDevice(DeviceNode->PhysicalDeviceObject);
return STATUS_SUCCESS;
}
return Status;
}
/*
* @implemented
*/