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"
NTSTATUS
IopPrepareDeviceForRemoval(PDEVICE_OBJECT DeviceObject, BOOLEAN Force);
+PDEVICE_OBJECT
+IopGetDeviceObjectFromDeviceInstance(PUNICODE_STRING DeviceInstance);
+
PDEVICE_NODE
FASTCALL
IopGetDeviceNode(PDEVICE_OBJECT DeviceObject)
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);
}
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);
/*