Author: cgutman Date: Wed Mar 21 14:35:52 2012 New Revision: 56204
URL: http://svn.reactos.org/svn/reactos?rev=56204&view=rev Log: - 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
Modified: trunk/reactos/drivers/bus/acpi/acpienum.c trunk/reactos/ntoskrnl/io/pnpmgr/plugplay.c trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c
Modified: trunk/reactos/drivers/bus/acpi/acpienum.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/bus/acpi/acpienum.c... ============================================================================== --- trunk/reactos/drivers/bus/acpi/acpienum.c [iso-8859-1] (original) +++ trunk/reactos/drivers/bus/acpi/acpienum.c [iso-8859-1] Wed Mar 21 14:35:52 2012 @@ -45,10 +45,38 @@ for (entry = FdoData->ListOfPDOs.Flink; entry != &FdoData->ListOfPDOs; entry = entry->Flink) { - pdoData = CONTAINING_RECORD (entry, PDO_DEVICE_DATA, Link); - //dont duplicate devices - if(pdoData->AcpiHandle == Device->handle) + struct acpi_device *CurrentDevice; + + 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; + } + 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"
Modified: trunk/reactos/ntoskrnl/io/pnpmgr/plugplay.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/plugplay... ============================================================================== --- trunk/reactos/ntoskrnl/io/pnpmgr/plugplay.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/io/pnpmgr/plugplay.c [iso-8859-1] Wed Mar 21 14:35:52 2012 @@ -141,7 +141,7 @@ }
-static PDEVICE_OBJECT +PDEVICE_OBJECT IopGetDeviceObjectFromDeviceInstance(PUNICODE_STRING DeviceInstance) { if (IopRootDeviceNode == NULL)
Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c... ============================================================================== --- trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c [iso-8859-1] Wed Mar 21 14:35:52 2012 @@ -49,6 +49,9 @@
NTSTATUS IopPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject, BOOLEAN Force); + +PDEVICE_OBJECT +IopGetDeviceObjectFromDeviceInstance(PUNICODE_STRING DeviceInstance);
PDEVICE_NODE FASTCALL @@ -1850,7 +1853,9 @@ HANDLE InstanceKey = NULL; UNICODE_STRING ValueName; UNICODE_STRING ParentIdPrefix = { 0, 0, NULL }; + UNICODE_STRING InstancePathU; DEVICE_CAPABILITIES DeviceCapabilities; + PDEVICE_OBJECT OldDeviceObject;
DPRINT("IopActionInterrogateDeviceStack(%p, %p)\n", DeviceNode, Context); DPRINT("PDO 0x%p\n", DeviceNode->PhysicalDeviceObject); @@ -1991,11 +1996,25 @@ } RtlFreeUnicodeString(&ParentIdPrefix);
- if (!RtlCreateUnicodeString(&DeviceNode->InstancePath, InstancePath)) + if (!RtlCreateUnicodeString(&InstancePathU, InstancePath)) { DPRINT("No resources\n"); /* 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);