Crash due to multiple device plugins.

I get the following error, when plugging in a device:

PNP_DETECTED_FATAL_ERROR (ca)
PnP encountered a severe error, either as a result of a problem in a driver or
a problem in PnP itself. The first argument describes the nature of the
problem, the second argument is the address of the PDO. The other arguments
vary depending on argument 1.
Arguments:
Arg1: 00000001, Duplicate PDO
A specific instance of a driver has enumerated multiple PDOs with
identical device id and unique ids.
Arg2: 81973410, Newly reported PDO.
Arg3: 8191b6d8, PDO of which it is a duplicate.
Arg4: 00000000

It is because I get plugin/unplug ioctls and issue WdfChildListUpdateChildDescriptionAsMissing and WdfChildListAddOrUpdateChildDescriptionAsPresent in quick succession.

Is there a way for me to wait till a device is torn down before I issue the WdfChildListAddOrUpdateChildDescriptionAsPresent, a synchronous WdfChildListUpdateChildDescriptionAsMissing as it were.

Thanks,

Kevin.

Are you correctly implementing the compare callback?

Mark Roddy

On Tue, Feb 8, 2011 at 10:42 AM, wrote:
> I get the following error, when plugging in a device:
>
> PNP_DETECTED_FATAL_ERROR (ca)
> PnP encountered a severe error, either as a result of a problem in a driver or
> a problem in PnP itself. ?The first argument describes the nature of the
> problem, the second argument is the address of the PDO. ?The other arguments
> vary depending on argument 1.
> Arguments:
> Arg1: 00000001, Duplicate PDO
> ? ? ? ?A specific instance of a driver has enumerated multiple PDOs with
> ? ? ? ?identical device id and unique ids.
> Arg2: 81973410, Newly reported PDO.
> Arg3: 8191b6d8, PDO of which it is a duplicate.
> Arg4: 00000000
>
> It is because I get plugin/unplug ?ioctls and issue WdfChildListUpdateChildDescriptionAsMissing and WdfChildListAddOrUpdateChildDescriptionAsPresent in quick succession.
>
> Is there a way for me to wait till a device is torn down before I issue the WdfChildListAddOrUpdateChildDescriptionAsPresent, a synchronous WdfChildListUpdateChildDescriptionAsMissing as it were.
>
> Thanks,
>
> Kevin.
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
>

It’s a simple compare of device ids:

BOOLEAN EvtUtSrDtuBusChildListIdentificationDescriptionCompare(WDFCHILDLIST ChildList, PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER pFirstIdentificationDescription, PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER pSecondIdentificationDescription)
{
PUTSRUSBDEVICE_IDDESC pFirstContext = CONTAINING_RECORD(pFirstIdentificationDescription, UTSRUSBDEVICE_IDDESC, IdHeader);
PUTSRUSBDEVICE_IDDESC pSecondContext = CONTAINING_RECORD(pSecondIdentificationDescription, UTSRUSBDEVICE_IDDESC, IdHeader);

return (pFirstContext->devid == pSecondContext->devid);
}

These deviceids are integers?

So assuming that you are following the rest of the dynamic enumeration
rules, this should work. So perhaps you want to show us the rest of
your dynamic enumeration code?

Mark Roddy

On Tue, Feb 8, 2011 at 11:44 AM, wrote:
> It’s a simple compare of device ids:
>
> BOOLEAN EvtUtSrDtuBusChildListIdentificationDescriptionCompare(WDFCHILDLIST ChildList, PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER pFirstIdentificationDescription, PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER pSecondIdentificationDescription)
> {
> ? ?PUTSRUSBDEVICE_IDDESC pFirstContext = CONTAINING_RECORD(pFirstIdentificationDescription, UTSRUSBDEVICE_IDDESC, IdHeader);
> ? ?PUTSRUSBDEVICE_IDDESC pSecondContext = CONTAINING_RECORD(pSecondIdentificationDescription, UTSRUSBDEVICE_IDDESC, IdHeader);
>
> ? ?return (pFirstContext->devid == pSecondContext->devid);
> }
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
>

Devid is an integer.

#pragma region AddDeviceId
status = RtlUnicodeStringPrintf(&StringBuffer, L"USB\VID_%04X&PID_%04X\0\0", pDeviceDescriptor->idVendor, pDeviceDescriptor->idProduct);
if (!NT_SUCCESS(status)) {
DebugPrint(TRACE_ERRORS, (“AddDeviceId RtlUnicodeStringPrintf failed (%X)\n”, status));
goto RETURN;
}
status = WdfPdoInitAssignDeviceID(ChildInit, &StringBuffer);
if (!NT_SUCCESS(status)) {
DebugPrint(TRACE_ERRORS, (“WdfPdoInitAssignDeviceID failed (%X)\n”, status));
goto RETURN;
}

DebugPrint(TRACE_EVENTS, (“Device id: %wZ\n”, &StringBuffer));
#pragma endregion AddDeviceId

#pragma region AddInstanceId
pSerialNumberString = NULL;
if (pDeviceDescriptor->iSerialNumber > 0 && pSerialNumberString != NULL) {
UCHAR LengthBytes = pSerialNumberString->bLength - sizeof(pSerialNumberString->bLength) - sizeof(pSerialNumberString->bDescriptorType);

RtlInitUnicodeString(&StringBuffer, pSerialNumberString->bString);
StringBuffer.Length = StringBuffer.MaximumLength = LengthBytes;

status = WdfPdoInitAssignInstanceID(ChildInit, &StringBuffer);
if (!NT_SUCCESS(status)) {
DebugPrint(TRACE_ERRORS, (“AddInstanceId WdfPdoInitAssignInstanceID 1 failed (%X)\n”, status));
goto RETURN;
}

DebugPrint(TRACE_EVENTS, (“Instance id: %wZ\n”, &StringBuffer));
} else {
status = RtlUnicodeStringPrintf(&StringBuffer, L"%02d", pSrUsbDeviceDescription->Port);
if (!NT_SUCCESS(status)) {
DebugPrint(TRACE_ERRORS, (“AddInstanceId RtlUnicodeStringPrintf failed (%X)\n”, status));
goto RETURN;
}
status = WdfPdoInitAssignInstanceID(ChildInit, &StringBuffer);
if (!NT_SUCCESS(status)) {
DebugPrint(TRACE_ERRORS, (“AddInstanceId WdfPdoInitAssignInstanceID 2 failed (%X)\n”, status));
goto RETURN;
}

DebugPrint(TRACE_EVENTS, (“Instance id: %wZ\n”, &StringBuffer));
}
#pragma endregion AddInstanceId

But since I don’t use devid, maybe this is the problem