- 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;
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"

View file

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

View file

@ -50,6 +50,9 @@ IopCancelPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject);
NTSTATUS
IopPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject, BOOLEAN Force);
PDEVICE_OBJECT
IopGetDeviceObjectFromDeviceInstance(PUNICODE_STRING DeviceInstance);
PDEVICE_NODE
FASTCALL
IopGetDeviceNode(PDEVICE_OBJECT DeviceObject)
@ -1850,7 +1853,9 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
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,12 +1996,26 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
}
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);
/*