- Fix device manager view by connection in ACPI mode

[NTOSKRNL]
- Bugcheck if a driver reports a PDO with a non-unique instance ID
[ACPI]
- Check that we're not reporting the same device multiple times

svn path=/trunk/; revision=56204
This commit is contained in:
Cameron Gutman 2012-03-21 14:35:52 +00:00
parent a1de3e633b
commit e6c7846c3a
3 changed files with 52 additions and 5 deletions

View file

@ -45,10 +45,38 @@ Bus_PlugInDevice (
for (entry = FdoData->ListOfPDOs.Flink; for (entry = FdoData->ListOfPDOs.Flink;
entry != &FdoData->ListOfPDOs; entry = entry->Flink) entry != &FdoData->ListOfPDOs; entry = entry->Flink)
{ {
pdoData = CONTAINING_RECORD (entry, PDO_DEVICE_DATA, Link); struct acpi_device *CurrentDevice;
//dont duplicate devices
if(pdoData->AcpiHandle == Device->handle) pdoData = CONTAINING_RECORD (entry, PDO_DEVICE_DATA, Link);
//dont duplicate devices
if (pdoData->AcpiHandle == Device->handle)
return STATUS_SUCCESS;
//check everything but fixed feature devices
if (pdoData->AcpiHandle)
acpi_bus_get_device(pdoData->AcpiHandle, &CurrentDevice);
else
continue;
//check if the HID matches
if (strstr(Device->pnp.hardware_id, CurrentDevice->pnp.hardware_id))
{
//check if UID exists for both and matches
if (Device->flags.unique_id && CurrentDevice->flags.unique_id &&
strstr(Device->pnp.unique_id, CurrentDevice->pnp.unique_id))
{
/* We have a UID on both but they're the same so we have to ignore it */
DPRINT1("Detected duplicate device: %hs %hs\n", Device->pnp.hardware_id, Device->pnp.unique_id);
return STATUS_SUCCESS; return STATUS_SUCCESS;
}
else if (!Device->flags.unique_id && !CurrentDevice->flags.unique_id)
{
/* No UID so we can only legally have 1 of these devices */
DPRINT1("Detected duplicate device: %hs\n", Device->pnp.hardware_id);
return STATUS_SUCCESS;
}
}
} }
DPRINT("Exposing PDO\n" DPRINT("Exposing PDO\n"

View file

@ -141,7 +141,7 @@ IopTraverseDeviceNode(PDEVICE_NODE Node, PUNICODE_STRING DeviceInstance)
} }
static PDEVICE_OBJECT PDEVICE_OBJECT
IopGetDeviceObjectFromDeviceInstance(PUNICODE_STRING DeviceInstance) IopGetDeviceObjectFromDeviceInstance(PUNICODE_STRING DeviceInstance)
{ {
if (IopRootDeviceNode == NULL) if (IopRootDeviceNode == NULL)

View file

@ -50,6 +50,9 @@ IopCancelPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject);
NTSTATUS NTSTATUS
IopPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject, BOOLEAN Force); IopPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject, BOOLEAN Force);
PDEVICE_OBJECT
IopGetDeviceObjectFromDeviceInstance(PUNICODE_STRING DeviceInstance);
PDEVICE_NODE PDEVICE_NODE
FASTCALL FASTCALL
IopGetDeviceNode(PDEVICE_OBJECT DeviceObject) IopGetDeviceNode(PDEVICE_OBJECT DeviceObject)
@ -1850,7 +1853,9 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
HANDLE InstanceKey = NULL; HANDLE InstanceKey = NULL;
UNICODE_STRING ValueName; UNICODE_STRING ValueName;
UNICODE_STRING ParentIdPrefix = { 0, 0, NULL }; UNICODE_STRING ParentIdPrefix = { 0, 0, NULL };
UNICODE_STRING InstancePathU;
DEVICE_CAPABILITIES DeviceCapabilities; DEVICE_CAPABILITIES DeviceCapabilities;
PDEVICE_OBJECT OldDeviceObject;
DPRINT("IopActionInterrogateDeviceStack(%p, %p)\n", DeviceNode, Context); DPRINT("IopActionInterrogateDeviceStack(%p, %p)\n", DeviceNode, Context);
DPRINT("PDO 0x%p\n", DeviceNode->PhysicalDeviceObject); DPRINT("PDO 0x%p\n", DeviceNode->PhysicalDeviceObject);
@ -1991,12 +1996,26 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
} }
RtlFreeUnicodeString(&ParentIdPrefix); RtlFreeUnicodeString(&ParentIdPrefix);
if (!RtlCreateUnicodeString(&DeviceNode->InstancePath, InstancePath)) if (!RtlCreateUnicodeString(&InstancePathU, InstancePath))
{ {
DPRINT("No resources\n"); DPRINT("No resources\n");
/* FIXME: Cleanup and disable device */ /* FIXME: Cleanup and disable device */
} }
/* Verify that this is not a duplicate */
OldDeviceObject = IopGetDeviceObjectFromDeviceInstance(&InstancePathU);
if (OldDeviceObject != NULL)
{
DPRINT1("Duplicate device instance '%wZ'\n", &InstancePathU);
KeBugCheckEx(PNP_DETECTED_FATAL_ERROR,
0x01,
(ULONG_PTR)DeviceNode->PhysicalDeviceObject,
(ULONG_PTR)OldDeviceObject,
0);
}
DeviceNode->InstancePath = InstancePathU;
DPRINT("InstancePath is %S\n", DeviceNode->InstancePath.Buffer); DPRINT("InstancePath is %S\n", DeviceNode->InstancePath.Buffer);
/* /*