WdfUsbTargetDeviceSelectConfig() blue screen under very specific circumstances

I’ve encountered a blue screen in WdfUsbTargetDeviceSelectConfig() that I don’t
understand. What’s especially odd is that it will only occur when all of the following
conditions are true:

  1. The device exposes a non-zero based, non-sequential list of interface descriptors
    (such as, interfaces 5, 6, and 8).

  2. The host OS is Windows 2000 (doesn’t occur on Windows XP, haven’t tried
    Vista).

  3. There is no USB hub between the machine and the device. Introducing a hub
    makes the problem disappears.

I’ve seen two different crash dumps from this problem, so I’ve given both below.

The WDF IFR log says:

— start of log —
1: FxPkgPnp::PnpEnterNewState - WDFDEVICE 0x7A94BFE8 !devobj 0x856B5840
entering PnP State WdfDevStatePnpInit from WdfDevStatePnpObjectCreated
2: FxPkgPnp::Dispatch - WDFDEVICE 0x7A94BFE8 !devobj 0x856B5840,
IRP_MJ_PNP, 0x00000000(IRP_MN_START_DEVICE) IRP 0x85781BC8
3: FxPkgPnp::PnpEnterNewState - WDFDEVICE 0x7A94BFE8 !devobj 0x856B5840
entering PnP State WdfDevStatePnpInitStarting from WdfDevStatePnpInit
4: FxPkgPnp::PnpEnterNewState - WDFDEVICE 0x7A94BFE8 !devobj 0x856B5840
entering PnP State WdfDevStatePnpHardwareAvailable from WdfDevStatePnpInitStarting
5: FxIoTarget::SubmitLocked - ignoring WDFIOTARGET 7A94A9C8 state,
sending WDFREQUEST BAF7CA08, state 1
6: FxIoTarget::SubmitLocked - ignoring WDFIOTARGET 7A94A9C8 state,
sending WDFREQUEST BAF7CA08, state 1
---- end of log ----

Blue screen #1 dump:

*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************

Use !analyze -v to get detailed debugging information.

BugCheck 1E, {c0000005, 8046ac64, 0, fffb}

Probably caused by : Pool_Corruption ( nt!ExFreePool+b )

Followup: Pool_corruption

kd> !analyze -v
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************

KMODE_EXCEPTION_NOT_HANDLED (1e)
This is a very common bugcheck. Usually the exception address pinpoints
the driver/function that caused the problem. Always note this address
as well as the link date of the driver/image that contains this address.
Arguments:
Arg1: c0000005, The exception code that was not handled
Arg2: 8046ac64, The address that the exception occurred at
Arg3: 00000000, Parameter 0 of the exception
Arg4: 0000fffb, Parameter 1 of the exception

Debugging Details:

EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at “0x%08lx” referenced memory at “0x%08lx”. The memory could not be “%s”.

FAULTING_IP:
nt!ExFreePoolWithTag+f2
8046ac64 8a47fa mov al,byte ptr [edi-6]

EXCEPTION_PARAMETER1: 00000000

EXCEPTION_PARAMETER2: 0000fffb

READ_ADDRESS: 0000fffb

DEFAULT_BUCKET_ID: DRIVER_FAULT

BUGCHECK_STR: 0x1E

PROCESS_NAME: System

EXCEPTION_RECORD: eb443714 – (.exr ffffffffeb443714)
ExceptionAddress: 8046ac64 (nt!ExFreePoolWithTag+0x000000f2)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 00000000
Parameter[1]: 0000fffb
Attempt to read from address 0000fffb

CONTEXT: eb44336c – (.cxr ffffffffeb44336c)
eax=00000000 ebx=00000000 ecx=00000000 edx=6e9c0000 esi=e2a9b448 edi=00010001
eip=8046ac64 esp=eb4437dc ebp=eb4437fc iopl=0 nv up ei pl nz na po nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010202
nt!ExFreePoolWithTag+0xf2:
8046ac64 8a47fa mov al,byte ptr [edi-6] ds:0023:0000fffb=??
Resetting default scope

LAST_CONTROL_TRANSFER: from 8046aaef to 8046ac64

STACK_TEXT:
eb4437fc 8046aaef 00010001 00000000 eb2caeec nt!ExFreePoolWithTag+0xf2
eb443808 eb2caeec 00010001 eb2cae0e 856dd3b0 nt!ExFreePool+0xb
eb443838 eb2c84d0 85e47030 856a32e8 00010001 USBD!USBD_SelectInterface+0xde
eb443864 eb2c99eb 85e47030 856a32e8 8579b828 USBD!USBD_ProcessURB+0x198
eb443898 eb2c8c38 85e47030 856a32e8 85e470e8 USBD!USBD_FdoDispatch+0x221
eb4438c0 eb2b0409 85e47030 856a32e8 eb4438ec USBD!USBD_Dispatch+0x76
eb4438f4 8041dded 85e47030 856a32e8 856a33bc uhcd!UHCD_Dispatch+0x23
eb443908 eb0c204b 856a32e8 8582c8c8 00220003 nt!IopfCallDriver+0x35
eb44391c eb0c228a 85d7ae28 856a32e8 8582c810 usbhub!USBH_PdoUrbFilter+0xdd
eb443938 eb0c069a 00020a00 856a32e8 eb443990 usbhub!USBH_PdoDispatch+0xd8
eb443948 8041dded 8582c810 856a32e8 bffde44a usbhub!USBH_HubDispatch+0x46
eb44395c bffde471 85e92008 bffde677 85729c50 nt!IopfCallDriver+0x35
eb443964 bffde677 85729c50 856a32e8 85729c50 ACPI!ACPIDispatchForwardIrp+0x27
eb443990 8041dded 85729c50 856a32e8 ba6d6a08 ACPI!ACPIDispatchIrp+0x123
eb4439a4 ba67dbd1 857e20f8 8569dd50 eb443ae4 nt!IopfCallDriver+0x35
eb4439ec ba687312 01443a08 eb443a98 00000000 Wdf01000!FxIoTarget::SubmitSync+0x1f2
eb443ae4 ba687bc0 00000000 857e20d0 eb443c8c Wdf01000!FxUsbDevice::SelectConfig+0x59b
eb443c24 ba681f3b 00000000 eb443c7c 00000000 Wdf01000!FxUsbDevice::SelectConfigMulti+0x2db
eb443c44 ba7bbd6d 8589cd20 7a9622a8 00000000 Wdf01000!imp_WdfUsbTargetDeviceSelectConfig+0x6c9
eb443c5c ba7bbb81 7a9622a8 00000000 eb443c7c xxxccgp!WdfUsbTargetDeviceSelectConfig+0x1d
eb443c90 ba6c207c 7a964fe8 7a872648 7a8725c8 xxxccgp!xxxCcgpEvtDevicePrepareHardware+0x101
eb443cb0 ba6c23ae eb443ccb 00000008 8569bd50 Wdf01000!FxPkgPnp::PnpPrepareHardware+0x7c
eb443ccc ba6c1245 8569bd50 ba6da260 8569bd50 Wdf01000!FxPkgPnp::PnpEventHardwareAvailable+0x6f
eb443cf4 ba6c1fa0 00000108 8569bdfc 8569bd50 Wdf01000!FxPkgPnp::PnpEnterNewState+0x15c
eb443d1c ba6c2323 eb443d4c 80062f58 8569bdf0 Wdf01000!FxPkgPnp::PnpProcessEventInner+0x1f5
eb443d30 ba6c5f34 8569bd50 eb443d4c 8569d8e8 Wdf01000!FxPkgPnp::_PnpProcessEventInner+0x26
eb443d5c ba6c5fa7 85729e50 eb443da8 8042040f Wdf01000!FxEventQueue::EventQueueWorker+0x47
eb443d68 8042040f 85729e50 8569bdf0 8047479c Wdf01000!FxWorkItemEventQueue::_WorkItemCallback+0x1a
eb443d78 80416bfa 8569d8e8 00000000 00000000 nt!IopProcessWorkItem+0xf
eb443da8 80454ab2 8569d8e8 00000000 00000000 nt!ExpWorkerThread+0xae
eb443ddc 804692a2 80416b4c 00000001 00000000 nt!PspSystemThreadStartup+0x54
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16

FOLLOWUP_IP:
nt!ExFreePool+b
8046aaef c20400 ret 4

SYMBOL_STACK_INDEX: 1

SYMBOL_NAME: nt!ExFreePool+b

FOLLOWUP_NAME: Pool_corruption

IMAGE_NAME: Pool_Corruption

DEBUG_FLR_IMAGE_TIMESTAMP: 0

MODULE_NAME: Pool_Corruption

STACK_COMMAND: .cxr 0xffffffffeb44336c ; kb

FAILURE_BUCKET_ID: 0x1E_nt!ExFreePool+b

BUCKET_ID: 0x1E_nt!ExFreePool+b

Followup: Pool_corruption

kd> lmvm Pool_Corruption
start end module name

Blue screen #2 dump:

*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************

Use !analyze -v to get detailed debugging information.

BugCheck 1E, {c0000005, eb2ca7ca, 0, 901b3}

Probably caused by : USBD.SYS ( USBD!USBD_InternalInterfaceBusy+e )

Followup: MachineOwner

kd> !analyze -v
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************

KMODE_EXCEPTION_NOT_HANDLED (1e)
This is a very common bugcheck. Usually the exception address pinpoints
the driver/function that caused the problem. Always note this address
as well as the link date of the driver/image that contains this address.
Arguments:
Arg1: c0000005, The exception code that was not handled
Arg2: eb2ca7ca, The address that the exception occurred at
Arg3: 00000000, Parameter 0 of the exception
Arg4: 000901b3, Parameter 1 of the exception

Debugging Details:

EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at “0x%08lx” referenced memory at “0x%08lx”. The memory could not be “%s”.

FAULTING_IP:
USBD!USBD_InternalInterfaceBusy+e
eb2ca7ca 385f0c cmp byte ptr [edi+0Ch],bl

EXCEPTION_PARAMETER1: 00000000

EXCEPTION_PARAMETER2: 000901b3

READ_ADDRESS: 000901b3

DEFAULT_BUCKET_ID: DRIVER_FAULT

BUGCHECK_STR: 0x1E

PROCESS_NAME: System

EXCEPTION_RECORD: eb43f720 – (.exr ffffffffeb43f720)
ExceptionAddress: eb2ca7ca (USBD!USBD_InternalInterfaceBusy+0x0000000e)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 00000000
Parameter[1]: 000901b3
Attempt to read from address 000901b3

CONTEXT: eb43f378 – (.cxr ffffffffeb43f378)
eax=00000006 ebx=00000000 ecx=00000000 edx=0000000c esi=e2a3b208 edi=000901a7
eip=eb2ca7ca esp=eb43f7e8 ebp=eb43f800 iopl=0 nv up ei pl zr na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00210246
USBD!USBD_InternalInterfaceBusy+0xe:
eb2ca7ca 385f0c cmp byte ptr [edi+0Ch],bl ds:0023:000901b3=??
Resetting default scope

LAST_CONTROL_TRANSFER: from eb2cae60 to eb2ca7ca

STACK_TEXT:
eb43f800 eb2cae60 857c6c68 85e8b030 000901a7 USBD!USBD_InternalInterfaceBusy+0xe
eb43f838 eb2c84d0 85e8b030 857376e8 856b0450 USBD!USBD_SelectInterface+0x52
eb43f864 eb2c99eb 85e8b030 857376e8 857c6c68 USBD!USBD_ProcessURB+0x198
eb43f898 eb2c8c38 85e8b030 857376e8 85e8b0e8 USBD!USBD_FdoDispatch+0x221
eb43f8c0 eb2b0409 85e8b030 857376e8 eb43f8ec USBD!USBD_Dispatch+0x76
eb43f8f4 8041dded 85e8b030 857376e8 857377bc uhcd!UHCD_Dispatch+0x23
eb43f908 eb0c204b 857376e8 857c05c8 00220003 nt!IopfCallDriver+0x35
eb43f91c eb0c228a 85d84e28 857376e8 857c0510 usbhub!USBH_PdoUrbFilter+0xdd
eb43f938 eb0c069a 00020a00 857376e8 eb43f990 usbhub!USBH_PdoDispatch+0xd8
eb43f948 8041dded 857c0510 857376e8 bffde44a usbhub!USBH_HubDispatch+0x46
eb43f95c bffde471 85e92008 bffde677 85bf3f10 nt!IopfCallDriver+0x35
eb43f964 bffde677 85bf3f10 857376e8 85bf3f10 ACPI!ACPIDispatchForwardIrp+0x27
eb43f990 8041dded 85bf3f10 857376e8 ba819a08 ACPI!ACPIDispatchIrp+0x123
eb43f9a4 ba7c0bd1 85817eb8 856adef0 eb43fae4 nt!IopfCallDriver+0x35
eb43f9ec ba7ca312 0143fa08 eb43fa98 00000000 Wdf01000!FxIoTarget::SubmitSync+0x1f2
eb43fae4 ba7cabc0 00000000 85817e90 eb43fc8c Wdf01000!FxUsbDevice::SelectConfig+0x59b
eb43fc24 ba7c4f3b 00000000 eb43fc7c 00000000 Wdf01000!FxUsbDevice::SelectConfigMulti+0x2db
eb43fc44 badd7d6d 8588d420 7a952108 00000000 Wdf01000!imp_WdfUsbTargetDeviceSelectConfig+0x6c9
eb43fc5c badd7b81 7a952108 00000000 eb43fc7c xxxccgp!WdfUsbTargetDeviceSelectConfig+0x1d
eb43fc90 ba80507c 7a950fe8 7a9503a8 7a950328 xxxccgp!xxxCcgpEvtDevicePrepareHardware+0x101
eb43fcb0 ba8053ae eb43fccb 00000008 856afd50 Wdf01000!FxPkgPnp::PnpPrepareHardware+0x7c
eb43fccc ba804245 856afd50 ba81d260 856afd50 Wdf01000!FxPkgPnp::PnpEventHardwareAvailable+0x6f
eb43fcf4 ba804fa0 00000108 856afdfc 856afd50 Wdf01000!FxPkgPnp::PnpEnterNewState+0x15c
eb43fd1c ba805323 eb43fd4c 80062f58 856afdf0 Wdf01000!FxPkgPnp::PnpProcessEventInner+0x1f5
eb43fd30 ba808f34 856afd50 eb43fd4c 857c98c8 Wdf01000!FxPkgPnp::_PnpProcessEventInner+0x26
eb43fd5c ba808fa7 85806cb0 eb43fda8 8042040f Wdf01000!FxEventQueue::EventQueueWorker+0x47
eb43fd68 8042040f 85806cb0 856afdf0 8047479c Wdf01000!FxWorkItemEventQueue::_WorkItemCallback+0x1a
eb43fd78 80416bfa 857c98c8 00000000 00000000 nt!IopProcessWorkItem+0xf
eb43fda8 80454ab2 857c98c8 00000000 00000000 nt!ExpWorkerThread+0xae
eb43fddc 804692a2 80416b4c 00000001 00000000 nt!PspSystemThreadStartup+0x54
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16

FOLLOWUP_IP:
USBD!USBD_InternalInterfaceBusy+e
eb2ca7ca 385f0c cmp byte ptr [edi+0Ch],bl

SYMBOL_STACK_INDEX: 0

FOLLOWUP_NAME: MachineOwner

MODULE_NAME: USBD

IMAGE_NAME: USBD.SYS

DEBUG_FLR_IMAGE_TIMESTAMP: 3e2ecf5d

SYMBOL_NAME: USBD!USBD_InternalInterfaceBusy+e

STACK_COMMAND: .cxr 0xffffffffeb43f378 ; kb

FAILURE_BUCKET_ID: 0x1E_USBD!USBD_InternalInterfaceBusy+e

BUCKET_ID: 0x1E_USBD!USBD_InternalInterfaceBusy+e

Followup: MachineOwner

-Chris

Just an update. I tried configuring the device by creating the select configuration URB myself, and then using WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_URB().

This too worked on XP, but it still crashes on Win2k, but it looks like it gets a little farther:

*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************

Use !analyze -v to get detailed debugging information.

BugCheck D1, {6f6974b4, 2, 0, eb2b22d4}

Probably caused by : uhcd.sys ( uhcd!UHCD_GetSetEndpointState_StartIo+2e )

Followup: MachineOwner

kd> !analyze -v
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************

DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)
An attempt was made to access a pageable (or completely invalid) address at an
interrupt request level (IRQL) that is too high. This is usually
caused by drivers using improper addresses.
If kernel debugger is available get stack backtrace.
Arguments:
Arg1: 6f6974b4, memory referenced
Arg2: 00000002, IRQL
Arg3: 00000000, value 0 = read operation, 1 = write operation
Arg4: eb2b22d4, address which referenced memory

Debugging Details:

READ_ADDRESS: 6f6974b4

CURRENT_IRQL: 2

FAULTING_IP:
uhcd!UHCD_GetSetEndpointState_StartIo+2e
eb2b22d4 3909 cmp dword ptr [ecx],ecx

DEFAULT_BUCKET_ID: DRIVER_FAULT

BUGCHECK_STR: 0xD1

PROCESS_NAME: System

TRAP_FRAME: eb43f76c – (.trap ffffffffeb43f76c)
ErrCode = 00000000
eax=00000002 ebx=00000000 ecx=6f6974b4 edx=00000000 esi=6f697470 edi=85702da8
eip=eb2b22d4 esp=eb43f7e0 ebp=eb43f7f4 iopl=0 nv up ei pl zr na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010246
uhcd!UHCD_GetSetEndpointState_StartIo+0x2e:
eb2b22d4 3909 cmp dword ptr [ecx],ecx ds:0023:6f6974b4=???
Resetting default scope

LAST_CONTROL_TRANSFER: from eb2b22d4 to 80467df7

STACK_TEXT:
eb43f76c eb2b22d4 00000000 80067fbe 00000000 nt!KiTrap0E+0x20b
eb43f7f4 eb2b1ba6 85e8aaf0 85775008 85e8aaf0 uhcd!UHCD_GetSetEndpointState_StartIo+0x2e
eb43f81c 8041f5ed 85e8aaf0 85775008 00000000 uhcd!UHCD_StartIo+0x166
eb43f840 eb2b175d 85e8aaf0 85775008 00000000 nt!IoStartPacket+0x6f
eb43f870 eb2b046e 85e8aaf0 85775008 85e8aaf0 uhcd!UHCD_URB_Dispatch+0x221
eb43f89c 8041dded 85e8aaf0 85775008 85702da8 uhcd!UHCD_Dispatch+0x88
eb43f8b0 eb2cb064 e22fb228 85702da8 00000000 nt!IopfCallDriver+0x35
eb43f8e8 eb2cb3b7 85702da8 85e8aaf0 85264328 USBD!USBD_SubmitSynchronousURB+0x134
eb43f904 eb2ca7f1 85264328 85e8aaf0 e22fb240 USBD!USBD_GetEndpointState+0x45
eb43f938 eb2cae60 85264328 85e8aaf0 e22fb228 USBD!USBD_InternalInterfaceBusy+0x35
eb43f970 eb2c84d0 85e8aaf0 8527b008 8571cdd0 USBD!USBD_SelectInterface+0x52
eb43f99c eb2c99eb 85e8aaf0 8527b008 85264328 USBD!USBD_ProcessURB+0x198
eb43f9d0 eb2c8c38 85e8aaf0 8527b008 85e8aba8 USBD!USBD_FdoDispatch+0x221
eb43f9f8 eb2b0409 85e8aaf0 8527b008 eb43fa24 USBD!USBD_Dispatch+0x76
eb43fa2c 8041dded 85e8aaf0 8527b008 8527b0dc uhcd!UHCD_Dispatch+0x23
eb43fa40 eb0c204b 8527b008 857510e8 00220003 nt!IopfCallDriver+0x35
eb43fa54 eb0c228a 85e16d08 8527b008 85751030 usbhub!USBH_PdoUrbFilter+0xdd
eb43fa70 eb0c069a 00020a00 8527b008 eb43fac8 usbhub!USBH_PdoDispatch+0xd8
eb43fa80 8041dded 85751030 8527b008 bffde44a usbhub!USBH_HubDispatch+0x46
eb43fa94 bffde471 85e928e8 bffde677 8575b970 nt!IopfCallDriver+0x35
eb43fa9c bffde677 8575b970 8527b008 8575b970 ACPI!ACPIDispatchForwardIrp+0x27
eb43fac8 8041dded 8575b970 8527b008 ba6b1a08 ACPI!ACPIDispatchIrp+0x123
eb43fadc ba658bd1 856b0170 85729590 eb43fc1c nt!IopfCallDriver+0x35
eb43fb24 ba662312 0143fb40 eb43fbd0 00000000 Wdf01000!FxIoTarget::SubmitSync+0x1f2
eb43fc1c ba65ce11 00000000 856b0148 00000000 Wdf01000!FxUsbDevice::SelectConfig+0x59b
eb43fc40 eb200dad 8527e8a0 7a8d6a68 00000000 Wdf01000!imp_WdfUsbTargetDeviceSelectConfig+0x59f
eb43fc58 eb200ba9 7a8d6a68 00000000 eb43fc7c xxxccgp!WdfUsbTargetDeviceSelectConfig+0x1d
eb43fc90 ba69d07c 7ad73fe8 7a850a08 7a79dfe8 xxxccgp!xxxCcgpEvtDevicePrepareHardware+0x129
eb43fcb0 ba69d3ae eb43fccb 00000008 8571ea90 Wdf01000!FxPkgPnp::PnpPrepareHardware+0x7c
eb43fccc ba69c245 8571ea90 ba6b5260 8571ea90 Wdf01000!FxPkgPnp::PnpEventHardwareAvailable+0x6f
eb43fcf4 ba69cfa0 00000108 8571eb3c 8571ea90 Wdf01000!FxPkgPnp::PnpEnterNewState+0x15c
eb43fd1c ba69d323 eb43fd4c 80062f58 8571eb30 Wdf01000!FxPkgPnp::PnpProcessEventInner+0x1f5
eb43fd30 ba6a0f34 8571ea90 eb43fd4c 85e70e08 Wdf01000!FxPkgPnp::_PnpProcessEventInner+0x26
eb43fd5c ba6a0fa7 852c5370 eb43fda8 8042040f Wdf01000!FxEventQueue::EventQueueWorker+0x47
eb43fd68 8042040f 852c5370 8571eb30 8047479c Wdf01000!FxWorkItemEventQueue::_WorkItemCallback+0x1a
eb43fd78 80416bfa 85e70e08 00000000 00000000 nt!IopProcessWorkItem+0xf
eb43fda8 80454ab2 85e70e08 00000000 00000000 nt!ExpWorkerThread+0xae
eb43fddc 804692a2 80416b4c 00000001 00000000 nt!PspSystemThreadStartup+0x54
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16

STACK_COMMAND: kb

FOLLOWUP_IP:
uhcd!UHCD_GetSetEndpointState_StartIo+2e
eb2b22d4 3909 cmp dword ptr [ecx],ecx

SYMBOL_STACK_INDEX: 1

FOLLOWUP_NAME: MachineOwner

MODULE_NAME: uhcd

IMAGE_NAME: uhcd.sys

DEBUG_FLR_IMAGE_TIMESTAMP: 3e25ba6e

SYMBOL_NAME: uhcd!UHCD_GetSetEndpointState_StartIo+2e

FAILURE_BUCKET_ID: 0xD1_uhcd!UHCD_GetSetEndpointState_StartIo+2e

BUCKET_ID: 0xD1_uhcd!UHCD_GetSetEndpointState_StartIo+2e

Followup: MachineOwner

-Chris

One last piece of information, and then I’m pretty much out of ideas:

If I take this same select configuration URB and send it down manually with WdfUsbTargetDeviceSendUrbSynchronously(), that works.

So it only crashes if I use WdfUsbTargetDeviceSelectConfig(). I also tried sending the URB manually first, and then doing …SelectConfig(), but that still crashed.

xxxxx@gmail.com wrote:

Just an update. I tried configuring the device by creating the select configuration URB myself, and then using WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_URB().

This too worked on XP, but it still crashes on Win2k, but it looks like it gets a little farther:

*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************

Use !analyze -v to get detailed debugging information.

BugCheck D1, {6f6974b4, 2, 0, eb2b22d4}

Note that the address being referenced includes the ASCII characters
“tio” (74 69 6f). Is it possible that you have a printf somewhere in
your driver that overflows a buffer? Do you have driver verifier turned on?


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Tim Roberts wrote:

Note that the address being referenced includes the ASCII characters
“tio” (74 69 6f). Is it possible that you have a printf somewhere in
your driver that overflows a buffer? Do you have driver verifier
turned on?

I noticed that too, but I don’t see how that’s possible. I turned on driver verifier just now on the 2K machine, and it still loads fine in a USB configuration other than the one I mentioned.

Similarly, if I do use the troublesome configuration, it crashes, and the bugcheck analysis is exactly the same.

The only thing I can think of now to do is develop a lower filter that watches for select-configuration from my driver, and then manually configures the device (since that appears to work).

Then it could fill out and complete the original select-configuration URB on its own without sending it to UHCD where everything crashes.

In addition to command line completion and what other people has
suggested, I would like to add:

1)selectively expand substruct field(s).
For instance,

typedef struct _a_t {
int a1;
int a2;
} a_t;

typedef struct _b_t {
int b1;
int b2;
a_t *sub;
} b_t;

dt -o _a_t 0xdeadbeef sub
I would expect to see b1 and b2 without showing the reset of fields in
struct _a_t.

  1. the syntax for conditional BP are counter intuitive and difficult to
    remember.

  2. performance for conditional BP is poor, not very practical for high
    occurrence functions. SI’s counterpart does a better job.

  3. single stepping is much slower than SI even on 1394 connection. This
    is understandable b/c each exception has to be sent to the host.

  4. improve ba to support break on physical address access.

  5. there should be a “.lsympath” for clients.

  6. while a source file of a specific revision is pulled out from source
    server (because of a source indexed PDB), please close the source
    windows of other revisions (if any) of the same file *automatically*.

  7. add command to retrieve the memory mapped PCI config space (if
    supported) of arbitrary PCI devices on newer systems.

  8. invent some command to do “break if called by function abc”.

Calvin Guan (DDK MVP)
Sr. Staff Engineer
NetXtreme NTX Miniport
Broadcom Corporation
Connecting Everything(r)

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:bounce-276116-
xxxxx@lists.osr.com] On Behalf Of Tim Roberts
Sent: Thursday, January 18, 2007 12:15 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] WdfUsbTargetDeviceSelectConfig() blue screen
under
very specific circumstances

xxxxx@gmail.com wrote:
> Just an update. I tried configuring the device by creating the
select
configuration URB myself, and then using
WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_URB().
>
> This too worked on XP, but it still crashes on Win2k, but it looks
like
it gets a little farther:
> …
>

************************************************************************
**

*****
> *
*
> * Bugcheck Analysis
*
> *
*
>

************************************************************************
**

*****
>
> Use !analyze -v to get detailed debugging information.
>
> BugCheck D1, {6f6974b4, 2, 0, eb2b22d4}
>

Note that the address being referenced includes the ASCII characters
“tio” (74 69 6f). Is it possible that you have a printf somewhere in
your driver that overflows a buffer? Do you have driver verifier
turned
on?


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Thinking about this a little more, maybe I can pose the question a little differently and hope that Doron, Eliyas, Peter, or someone responds (please!): how would I go about determining if this is a KMDF issue or not?

I’m only suspicious that it might be, for the following reasons:

  1. It only happens on Win2k, and there have been Win2k-only KMDF bugs before (not setting MaximumTransferSize on certain interfaces in 1.1, etc.) and in that same situation adding a hub also masked the problem.

  2. The API itself is very plain (SelectConfigMulti) and I don’t see how it’s possible to call it with bad data.

  3. Sending the same exact URB myself works normally.

  4. The configuration of the device is something of a “corner case” that may have eluded testing.

So, … I dunno.

-Chris

No, there are no known issues of this type with KMDF on win2k. A couple of questions for you

  1. What is the configuration you are trying to select?
  2. How did you build the select config URB that works? Using USBD functions or on your own?

One thing you can do is put a bp on wdf01000!FxUsbDevice::SelectConfig and look at the URB (it will be the 2nd parameter) that KMDF built for your request. How does it compare to your select config URB? Can you send your results?

I don’t think the usbhub in the middle does anyting with respect to the select config urb, it could change the behavior of your device on the bus during the select config process though.

d

NTSTATUS
FxUsbDevice::SelectConfig(
PWDF_OBJECT_ATTRIBUTES PipesAttributes,
PURB Urb,
PUCHAR NumConfiguredInterfaces
)

Doron,

For 1), I’m just trying to select the first configuration on the device with all interfaces at alternate setting 0. No frills – I’m just passing the number of interfaces to the …INIT_MULTIPLE_INTERFACES() macro and that’s it.

For 2), I’m using the USBD helper functions in usbdilib.h. In fact, I just pulled the code for doing this from SelectInterfaces() in the 3790 WDM bulkusb sample, and didn’t really touch it otherwise.

I’ll definitely compare the KMDF URB with the URB that I’m creating. The next thing I was going to do to resolve this was create a LowerFilter that intercepts the select configuration URB, sets it aside, and then reissues my working one. Once I get to that point I can post a hex dump of both.

For my device, once I issue select configuration, it starts drawing a full 500mA from the port, but otherwise doesn’t do anything else.

I am interested in the configuration you are selecting, what are the interfaces and EPs on each interface. For 2), are you using USBD_CreateConfigurationRequestEx?

d

Hi, Doron,

First, let me describe the device per your request:

Interface 5: no endpoints.
Interface 6: one BULK IN endpoint.
Interface 8: no endpoints.

For part 2 above, my sequence of calls looks like this:

  1. Allocate memory for URB based on number of interfaces + 1, based on bulkusb sample
  2. Loop on calling USBD_ParseConfigurationDescriptorEx() to find interface descriptors
  3. Call USBD_CreateConfigurationRequestEx() to get my URB
  4. Send it down synchronously with KMDF

I’ve got four dumps for you. This first one is from my URB that I am sending synchronously to configure the device. This is the dump of the SELECT_CONFIGURATION URB on the way down (with the memory zeroed out first), and then subsequently what it looks like on the way back up:

[xxxccgpfl] xxxCcgpFlInternalIoctl: begins.
[xxxccgpfl] xxxCcgpFlInternalIoctl: select configuration URB follows.
[xxxccgpfl] LogFrame: [00000000] <— 5C 00 00 00 88 AA FA 86 .…
[xxxccgpfl] LogFrame: [00000008] <— F4 2E DA B3 06 11 00 00 …
[xxxccgpfl] LogFrame: [00000010] <— A8 3F 27 87 88 AA FA 86 .?‘…
[xxxccgpfl] LogFrame: [00000018] <— 10 00 05 00 A4 47 58 87 …GX.
[xxxccgpfl] LogFrame: [00000020] <— A4 47 58 87 00 00 00 00 .GX…
[xxxccgpfl] LogFrame: [00000028] <— 24 00 06 00 B4 47 58 87 $…GX.
[xxxccgpfl] LogFrame: [00000030] <— B4 47 58 87 01 00 00 00 .GX…
[xxxccgpfl] LogFrame: [00000038] <— 00 00 00 00 30 F9 57 87 …0.W.
[xxxccgpfl] LogFrame: [00000040] <— C8 47 58 87 00 10 00 00 .GX…
[xxxccgpfl] LogFrame: [00000048] <— 00 00 00 00 10 00 08 00 …
[xxxccgpfl] LogFrame: [00000050] <— 00 00 00 00 00 00 00 00 …
[xxxccgpfl] LogFrame: [00000058] <— 00 00 00 00 …
[xxxccgpfl] xxxCcgpFlGenericCompletion: begins – IOCTL status is 0x00000000, information is 0x00000000.
[xxxccgpfl] xxxCcgpFlGenericCompletion: completed select configuration URB follows.
[xxxccgpfl] LogFrame: [00000000] —> 5C 00 00 00 00 00 00 00 .…
[xxxccgpfl] LogFrame: [00000008] —> 28 8A 8D 87 00 00 00 00 (…
[xxxccgpfl] LogFrame: [00000010] —> A8 3F 27 87 C8 03 62 E4 .?’…b.
[xxxccgpfl] LogFrame: [00000018] —> 10 00 05 00 FF 01 FF 00 …
[xxxccgpfl] LogFrame: [00000020] —> 28 14 88 87 00 00 00 00 (…
[xxxccgpfl] LogFrame: [00000028] —> 24 00 06 00 FF 02 FF 00 $…
[xxxccgpfl] LogFrame: [00000030] —> E8 F1 36 87 01 00 00 00 …6…
[xxxccgpfl] LogFrame: [00000038] —> 20 00 84 00 02 00 00 00 …
[xxxccgpfl] LogFrame: [00000040] —> 00 F2 36 87 00 10 00 00 …6…
[xxxccgpfl] LogFrame: [00000048] —> 00 00 00 00 10 00 08 00 …
[xxxccgpfl] LogFrame: [00000050] —> FF 03 00 00 08 A0 25 87 …
[xxxccgpfl] LogFrame: [00000058] —> 00 00 00 00 …
[xxxccgpfl] xxxCcgpFlGenericCompletion: ends.
[xxxccgpfl] xxxCcgpFlInternalIoctl: ends.
[xxxccgp] xxxCcgpEvtDevicePrepareHardware: ends.

This next one is from KMDF’s select-config function. Actually, what’s interesting to me is that the URB actually does come back, but the system crashes almost immediately after:

[xxxccgpfl] xxxCcgpFlInternalIoctl: begins.
[xxxccgpfl] xxxCcgpFlInternalIoctl: select configuration URB follows.
[xxxccgpfl] LogFrame: [00000000] <— 5C 00 00 00 00 00 00 00 .…
[xxxccgpfl] LogFrame: [00000008] <— 00 00 00 00 00 00 00 00 …
[xxxccgpfl] LogFrame: [00000010] <— 50 C3 18 87 00 00 00 00 P…
[xxxccgpfl] LogFrame: [00000018] <— 10 00 05 00 00 00 00 00 …
[xxxccgpfl] LogFrame: [00000020] <— 00 00 00 00 00 00 00 00 …
[xxxccgpfl] LogFrame: [00000028] <— 24 00 06 00 00 00 00 00 $…
[xxxccgpfl] LogFrame: [00000030] <— 00 00 00 00 01 00 00 00 …
[xxxccgpfl] LogFrame: [00000038] <— 00 00 00 00 00 00 00 00 …
[xxxccgpfl] LogFrame: [00000040] <— 00 00 00 00 00 10 00 00 …
[xxxccgpfl] LogFrame: [00000048] <— 00 00 00 00 10 00 08 00 …
[xxxccgpfl] LogFrame: [00000050] <— 00 00 00 00 00 00 00 00 …
[xxxccgpfl] LogFrame: [00000058] <— 00 00 00 00 …
[xxxccgpfl] xxxCcgpFlGenericCompletion: begins – IOCTL status is 0x00000000, information is 0x00000000.
[xxxccgpfl] xxxCcgpFlGenericCompletion: completed select configuration URB follows.
[xxxccgpfl] LogFrame: [00000000] —> 5C 00 00 00 00 00 00 00 .…
[xxxccgpfl] LogFrame: [00000008] —> 48 8C 20 87 00 00 00 00 H. …
[xxxccgpfl] LogFrame: [00000010] —> 50 C3 18 87 68 4A 0D E4 P…hJ…
[xxxccgpfl] LogFrame: [00000018] —> 10 00 05 00 FF 01 FF 00 …
[xxxccgpfl] LogFrame: [00000020] —> 28 51 58 87 00 00 00 00 (QX…
[xxxccgpfl] LogFrame: [00000028] —> 24 00 06 00 FF 02 FF 00 $…
[xxxccgpfl] LogFrame: [00000030] —> 28 AC 1E 87 01 00 00 00 (…
[xxxccgpfl] LogFrame: [00000038] —> 20 00 84 00 02 00 00 00 …
[xxxccgpfl] LogFrame: [00000040] —> 40 AC 1E 87 00 10 00 00 @…
[xxxccgpfl] LogFrame: [00000048] —> 00 00 00 00 10 00 08 00 …
[xxxccgpfl] LogFrame: [00000050] —> FF 03 00 00 A8 1C 2F 87 …/.
[xxxccgpfl] LogFrame: [00000058] —> 00 00 00 00 …
[xxxccgpfl] xxxCcgpFlGenericCompletion: ends.
[xxxccgpfl] xxxCcgpFlInternalIoctl: ends.
[xxxccgpfl] xxxCcgpFlInternalIoctl: begins.


Here’s the one from usbhub (the 2K generic parent, I mean), which also works.

[xxxccgpfl] xxxCcgpFlInternalIoctl: begins.
[xxxccgpfl] xxxCcgpFlInternalIoctl: select configuration URB follows.
[xxxccgpfl] LogFrame: [00000000] <— 5C 00 00 00 00 00 04 00 .…
[xxxccgpfl] LogFrame: [00000008] <— 00 00 00 00 F4 D8 81 87 …
[xxxccgpfl] LogFrame: [00000010] <— 08 F0 81 87 13 00 00 01 …
[xxxccgpfl] LogFrame: [00000018] <— 10 00 05 00 65 00 72 00 …e.r.
[xxxccgpfl] LogFrame: [00000020] <— F8 17 8F F6 00 00 00 00 …
[xxxccgpfl] LogFrame: [00000028] <— 24 00 06 00 39 00 36 00 $…9.6.
[xxxccgpfl] LogFrame: [00000030] <— 00 00 00 00 01 00 00 00 …
[xxxccgpfl] LogFrame: [00000038] <— 08 00 0A 00 00 00 00 00 …
[xxxccgpfl] LogFrame: [00000040] <— 28 D9 81 87 00 10 00 00 (…
[xxxccgpfl] LogFrame: [00000048] <— 00 00 00 00 10 00 08 00 …
[xxxccgpfl] LogFrame: [00000050] <— A0 2E 99 87 40 0F 48 80 …@.H.
[xxxccgpfl] LogFrame: [00000058] <— 00 00 00 00 …
[xxxccgpfl] xxxCcgpFlGenericCompletion: begins – IOCTL status is 0x00000000, information is 0x00000000.
[xxxccgpfl] xxxCcgpFlGenericCompletion: completed select configuration URB follows.
[xxxccgpfl] LogFrame: [00000000] —> 5C 00 00 00 00 00 00 00 .…
[xxxccgpfl] LogFrame: [00000008] —> C8 4C 7E 87 00 00 00 00 .L~…
[xxxccgpfl] LogFrame: [00000010] —> 08 F0 81 87 48 0B 49 E1 …H.I.
[xxxccgpfl] LogFrame: [00000018] —> 10 00 05 00 FF 01 FF 00 …
[xxxccgpfl] LogFrame: [00000020] —> C8 53 40 87 00 00 00 00 .S@…
[xxxccgpfl] LogFrame: [00000028] —> 24 00 06 00 FF 02 FF 00 $…
[xxxccgpfl] LogFrame: [00000030] —> 28 8D 8F 87 01 00 00 00 (…
[xxxccgpfl] LogFrame: [00000038] —> 20 00 84 00 02 00 00 00 …
[xxxccgpfl] LogFrame: [00000040] —> 40 8D 8F 87 00 10 00 00 @…
[xxxccgpfl] LogFrame: [00000048] —> 00 00 00 00 10 00 08 00 …
[xxxccgpfl] LogFrame: [00000050] —> FF 03 00 00 88 0F 9F 87 …
[xxxccgpfl] LogFrame: [00000058] —> 00 00 00 00 …
[xxxccgpfl] xxxCcgpFlGenericCompletion: ends.

Here’s the one from my driver on XP using the KMDF select-config, which works as well.

[xxxccgpfl] xxxCcgpFlInternalIoctl: begins.
[xxxccgpfl] xxxCcgpFlInternalIoctl: select configuration URB follows.
[xxxccgpfl] LogFrame: [00000000] <— 5C 00 00 00 00 00 00 00 .…
[xxxccgpfl] LogFrame: [00000008] <— 00 00 00 00 00 00 00 00 …
[xxxccgpfl] LogFrame: [00000010] <— 90 B9 09 86 00 00 00 00 …
[xxxccgpfl] LogFrame: [00000018] <— 10 00 05 00 00 00 00 00 …
[xxxccgpfl] LogFrame: [00000020] <— 00 00 00 00 00 00 00 00 …
[xxxccgpfl] LogFrame: [00000028] <— 24 00 06 00 00 00 00 00 $…
[xxxccgpfl] LogFrame: [00000030] <— 00 00 00 00 01 00 00 00 …
[xxxccgpfl] LogFrame: [00000038] <— 00 00 00 00 00 00 00 00 …
[xxxccgpfl] LogFrame: [00000040] <— 00 00 00 00 FF FF FF FF …
[xxxccgpfl] LogFrame: [00000048] <— 00 00 00 00 10 00 08 00 …
[xxxccgpfl] LogFrame: [00000050] <— 00 00 00 00 00 00 00 00 …
[xxxccgpfl] LogFrame: [00000058] <— 00 00 00 00 …
[xxxccgpfl] xxxCcgpFlGenericCompletion: begins – IOCTL status is 0x00000000, information is 0x00000000.
[xxxccgpfl] xxxCcgpFlGenericCompletion: completed select configuration URB follows.
[xxxccgpfl] LogFrame: [00000000] —> 5C 00 00 00 00 00 00 00 .…
[xxxccgpfl] LogFrame: [00000008] —> 08 C0 02 86 00 00 00 00 …
[xxxccgpfl] LogFrame: [00000010] —> 90 B9 09 86 00 F2 0D 86 …
[xxxccgpfl] LogFrame: [00000018] —> 10 00 05 00 FF 01 FF 00 …
[xxxccgpfl] LogFrame: [00000020] —> C0 41 53 86 00 00 00 00 .AS…
[xxxccgpfl] LogFrame: [00000028] —> 24 00 06 00 FF 02 FF 00 $…
[xxxccgpfl] LogFrame: [00000030] —> 98 52 0D 86 01 00 00 00 .R…
[xxxccgpfl] LogFrame: [00000038] —> 20 00 84 00 02 00 00 00 …
[xxxccgpfl] LogFrame: [00000040] —> B4 52 0D 86 FF FF FF FF .R…
[xxxccgpfl] LogFrame: [00000048] —> 00 00 00 00 10 00 08 00 …
[xxxccgpfl] LogFrame: [00000050] —> FF 03 00 00 E0 E1 07 86 …
[xxxccgpfl] LogFrame: [00000058] —> 00 00 00 00 …
[xxxccgpfl] xxxCcgpFlGenericCompletion: ends.

These were all collected with a simple KMDF lower filter on the stack, right below the generic parent.

I’m not sure what to make of it all, except that the URBs that KMDF is sending look somewhat more “sparse” than the ones that are being sent by usbhub or me manually.

-Chris

Sorry, those dumps got wrapped due to some whitespace at the end, maybe this is easier to read:

(My URB on 2K, OK):

[xxxccgpfl] xxxCcgpFlInternalIoctl: begins.
[xxxccgpfl] xxxCcgpFlInternalIoctl: select configuration URB follows.
[xxxccgpfl] LogFrame: [00000000] <— 5C 00 00 00 88 AA FA 86 .…
[xxxccgpfl] LogFrame: [00000008] <— F4 2E DA B3 06 11 00 00 …
[xxxccgpfl] LogFrame: [00000010] <— A8 3F 27 87 88 AA FA 86 .?‘…
[xxxccgpfl] LogFrame: [00000018] <— 10 00 05 00 A4 47 58 87 …GX.
[xxxccgpfl] LogFrame: [00000020] <— A4 47 58 87 00 00 00 00 .GX…
[xxxccgpfl] LogFrame: [00000028] <— 24 00 06 00 B4 47 58 87 $…GX.
[xxxccgpfl] LogFrame: [00000030] <— B4 47 58 87 01 00 00 00 .GX…
[xxxccgpfl] LogFrame: [00000038] <— 00 00 00 00 30 F9 57 87 …0.W.
[xxxccgpfl] LogFrame: [00000040] <— C8 47 58 87 00 10 00 00 .GX…
[xxxccgpfl] LogFrame: [00000048] <— 00 00 00 00 10 00 08 00 …
[xxxccgpfl] LogFrame: [00000050] <— 00 00 00 00 00 00 00 00 …
[xxxccgpfl] LogFrame: [00000058] <— 00 00 00 00 …
[xxxccgpfl] xxxCcgpFlGenericCompletion: begins – IOCTL status is 0x00000000,
information is 0x00000000.
[xxxccgpfl] xxxCcgpFlGenericCompletion: completed select configuration URB
follows.
[xxxccgpfl] LogFrame: [00000000] —> 5C 00 00 00 00 00 00 00 .…
[xxxccgpfl] LogFrame: [00000008] —> 28 8A 8D 87 00 00 00 00 (…
[xxxccgpfl] LogFrame: [00000010] —> A8 3F 27 87 C8 03 62 E4 .?’…b.
[xxxccgpfl] LogFrame: [00000018] —> 10 00 05 00 FF 01 FF 00 …
[xxxccgpfl] LogFrame: [00000020] —> 28 14 88 87 00 00 00 00 (…
[xxxccgpfl] LogFrame: [00000028] —> 24 00 06 00 FF 02 FF 00 $…
[xxxccgpfl] LogFrame: [00000030] —> E8 F1 36 87 01 00 00 00 …6…
[xxxccgpfl] LogFrame: [00000038] —> 20 00 84 00 02 00 00 00 …
[xxxccgpfl] LogFrame: [00000040] —> 00 F2 36 87 00 10 00 00 …6…
[xxxccgpfl] LogFrame: [00000048] —> 00 00 00 00 10 00 08 00 …
[xxxccgpfl] LogFrame: [00000050] —> FF 03 00 00 08 A0 25 87 …
[xxxccgpfl] LogFrame: [00000058] —> 00 00 00 00 …
[xxxccgpfl] xxxCcgpFlGenericCompletion: ends.
[xxxccgpfl] xxxCcgpFlInternalIoctl: ends.
[xxxccgp] xxxCcgpEvtDevicePrepareHardware: ends.

(KMDF select config on 2K, crash)

[xxxccgpfl] xxxCcgpFlInternalIoctl: begins.
[xxxccgpfl] xxxCcgpFlInternalIoctl: select configuration URB follows.
[xxxccgpfl] LogFrame: [00000000] <— 5C 00 00 00 00 00 00 00 .…
[xxxccgpfl] LogFrame: [00000008] <— 00 00 00 00 00 00 00 00 …
[xxxccgpfl] LogFrame: [00000010] <— 50 C3 18 87 00 00 00 00 P…
[xxxccgpfl] LogFrame: [00000018] <— 10 00 05 00 00 00 00 00 …
[xxxccgpfl] LogFrame: [00000020] <— 00 00 00 00 00 00 00 00 …
[xxxccgpfl] LogFrame: [00000028] <— 24 00 06 00 00 00 00 00 $…
[xxxccgpfl] LogFrame: [00000030] <— 00 00 00 00 01 00 00 00 …
[xxxccgpfl] LogFrame: [00000038] <— 00 00 00 00 00 00 00 00 …
[xxxccgpfl] LogFrame: [00000040] <— 00 00 00 00 00 10 00 00 …
[xxxccgpfl] LogFrame: [00000048] <— 00 00 00 00 10 00 08 00 …
[xxxccgpfl] LogFrame: [00000050] <— 00 00 00 00 00 00 00 00 …
[xxxccgpfl] LogFrame: [00000058] <— 00 00 00 00 …
[xxxccgpfl] xxxCcgpFlGenericCompletion: begins – IOCTL status is 0x00000000,
information is 0x00000000.
[xxxccgpfl] xxxCcgpFlGenericCompletion: completed select configuration URB
follows.
[xxxccgpfl] LogFrame: [00000000] —> 5C 00 00 00 00 00 00 00 .…
[xxxccgpfl] LogFrame: [00000008] —> 48 8C 20 87 00 00 00 00 H. …
[xxxccgpfl] LogFrame: [00000010] —> 50 C3 18 87 68 4A 0D E4 P…hJ…
[xxxccgpfl] LogFrame: [00000018] —> 10 00 05 00 FF 01 FF 00 …
[xxxccgpfl] LogFrame: [00000020] —> 28 51 58 87 00 00 00 00 (QX…
[xxxccgpfl] LogFrame: [00000028] —> 24 00 06 00 FF 02 FF 00 $…
[xxxccgpfl] LogFrame: [00000030] —> 28 AC 1E 87 01 00 00 00 (…
[xxxccgpfl] LogFrame: [00000038] —> 20 00 84 00 02 00 00 00 …
[xxxccgpfl] LogFrame: [00000040] —> 40 AC 1E 87 00 10 00 00 @…
[xxxccgpfl] LogFrame: [00000048] —> 00 00 00 00 10 00 08 00 …
[xxxccgpfl] LogFrame: [00000050] —> FF 03 00 00 A8 1C 2F 87 …/.
[xxxccgpfl] LogFrame: [00000058] —> 00 00 00 00 …
[xxxccgpfl] xxxCcgpFlGenericCompletion: ends.
[xxxccgpfl] xxxCcgpFlInternalIoctl: ends.
[xxxccgpfl] xxxCcgpFlInternalIoctl: begins.


(usbhub on 2k, OK):

[xxxccgpfl] xxxCcgpFlInternalIoctl: begins.
[xxxccgpfl] xxxCcgpFlInternalIoctl: select configuration URB follows.
[xxxccgpfl] LogFrame: [00000000] <— 5C 00 00 00 00 00 04 00 .…
[xxxccgpfl] LogFrame: [00000008] <— 00 00 00 00 F4 D8 81 87 …
[xxxccgpfl] LogFrame: [00000010] <— 08 F0 81 87 13 00 00 01 …
[xxxccgpfl] LogFrame: [00000018] <— 10 00 05 00 65 00 72 00 …e.r.
[xxxccgpfl] LogFrame: [00000020] <— F8 17 8F F6 00 00 00 00 …
[xxxccgpfl] LogFrame: [00000028] <— 24 00 06 00 39 00 36 00 $…9.6.
[xxxccgpfl] LogFrame: [00000030] <— 00 00 00 00 01 00 00 00 …
[xxxccgpfl] LogFrame: [00000038] <— 08 00 0A 00 00 00 00 00 …
[xxxccgpfl] LogFrame: [00000040] <— 28 D9 81 87 00 10 00 00 (…
[xxxccgpfl] LogFrame: [00000048] <— 00 00 00 00 10 00 08 00 …
[xxxccgpfl] LogFrame: [00000050] <— A0 2E 99 87 40 0F 48 80 …@.H.
[xxxccgpfl] LogFrame: [00000058] <— 00 00 00 00 …
[xxxccgpfl] xxxCcgpFlGenericCompletion: begins – IOCTL status is 0x00000000,
information is 0x00000000.
[xxxccgpfl] xxxCcgpFlGenericCompletion: completed select configuration URB
follows.
[xxxccgpfl] LogFrame: [00000000] —> 5C 00 00 00 00 00 00 00 .…
[xxxccgpfl] LogFrame: [00000008] —> C8 4C 7E 87 00 00 00 00 .L~…
[xxxccgpfl] LogFrame: [00000010] —> 08 F0 81 87 48 0B 49 E1 …H.I.
[xxxccgpfl] LogFrame: [00000018] —> 10 00 05 00 FF 01 FF 00 …
[xxxccgpfl] LogFrame: [00000020] —> C8 53 40 87 00 00 00 00 .S@…
[xxxccgpfl] LogFrame: [00000028] —> 24 00 06 00 FF 02 FF 00 $…
[xxxccgpfl] LogFrame: [00000030] —> 28 8D 8F 87 01 00 00 00 (…
[xxxccgpfl] LogFrame: [00000038] —> 20 00 84 00 02 00 00 00 …
[xxxccgpfl] LogFrame: [00000040] —> 40 8D 8F 87 00 10 00 00 @…
[xxxccgpfl] LogFrame: [00000048] —> 00 00 00 00 10 00 08 00 …
[xxxccgpfl] LogFrame: [00000050] —> FF 03 00 00 88 0F 9F 87 …
[xxxccgpfl] LogFrame: [00000058] —> 00 00 00 00 …
[xxxccgpfl] xxxCcgpFlGenericCompletion: ends.

(XP KMDF select config, OK)

[xxxccgpfl] xxxCcgpFlInternalIoctl: begins.
[xxxccgpfl] xxxCcgpFlInternalIoctl: select configuration URB follows.
[xxxccgpfl] LogFrame: [00000000] <— 5C 00 00 00 00 00 00 00 .…
[xxxccgpfl] LogFrame: [00000008] <— 00 00 00 00 00 00 00 00 …
[xxxccgpfl] LogFrame: [00000010] <— 90 B9 09 86 00 00 00 00 …
[xxxccgpfl] LogFrame: [00000018] <— 10 00 05 00 00 00 00 00 …
[xxxccgpfl] LogFrame: [00000020] <— 00 00 00 00 00 00 00 00 …
[xxxccgpfl] LogFrame: [00000028] <— 24 00 06 00 00 00 00 00 $…
[xxxccgpfl] LogFrame: [00000030] <— 00 00 00 00 01 00 00 00 …
[xxxccgpfl] LogFrame: [00000038] <— 00 00 00 00 00 00 00 00 …
[xxxccgpfl] LogFrame: [00000040] <— 00 00 00 00 FF FF FF FF …
[xxxccgpfl] LogFrame: [00000048] <— 00 00 00 00 10 00 08 00 …
[xxxccgpfl] LogFrame: [00000050] <— 00 00 00 00 00 00 00 00 …
[xxxccgpfl] LogFrame: [00000058] <— 00 00 00 00 …
[xxxccgpfl] xxxCcgpFlGenericCompletion: begins – IOCTL status is 0x00000000, information is 0x00000000.
[xxxccgpfl] xxxCcgpFlGenericCompletion: completed select configuration URB follows.
[xxxccgpfl] LogFrame: [00000000] —> 5C 00 00 00 00 00 00 00 .…
[xxxccgpfl] LogFrame: [00000008] —> 08 C0 02 86 00 00 00 00 …
[xxxccgpfl] LogFrame: [00000010] —> 90 B9 09 86 00 F2 0D 86 …
[xxxccgpfl] LogFrame: [00000018] —> 10 00 05 00 FF 01 FF 00 …
[xxxccgpfl] LogFrame: [00000020] —> C0 41 53 86 00 00 00 00 .AS…
[xxxccgpfl] LogFrame: [00000028] —> 24 00 06 00 FF 02 FF 00 $…
[xxxccgpfl] LogFrame: [00000030] —> 98 52 0D 86 01 00 00 00 .R…
[xxxccgpfl] LogFrame: [00000038] —> 20 00 84 00 02 00 00 00 …
[xxxccgpfl] LogFrame: [00000040] —> B4 52 0D 86 FF FF FF FF .R…
[xxxccgpfl] LogFrame: [00000048] —> 00 00 00 00 10 00 08 00 …
[xxxccgpfl] LogFrame: [00000050] —> FF 03 00 00 E0 E1 07 86 …
[xxxccgpfl] LogFrame: [00000058] —> 00 00 00 00 …
[xxxccgpfl] xxxCcgpFlGenericCompletion: ends.

-Chris

Any chance you want to annotate the output by breaking into the debugger and using dt to show the structure instead of me having to do a byte by byte reconstruction of the URB? :slight_smile:

Just to clarify, this is not a device sitting on usbgccp on the equivalent usbhub functionality on win2k. both of those drivers take your select config and turn them into something else (or don’t even send it down the stack)

d

This is a little tricky, because all of these structures are variable length,
but I think this is what you were looking for. This is what the URB that crashes
looks like on the way down.

And yes, my driver is sitting directly on the PDO that represents my actual device.
I’m not on usbhub or usbccgp. (But when I do use those as my driver for this device
instead, it’s okay. That’s why I showed the same dump from usbhub earlier).

(Setting the breakpoint)

kd> bp wdf01000!FxUsbDevice::SelectConfig
kd> g
Breakpoint 1 hit
Wdf01000!FxUsbDevice::SelectConfig:
b42bcd77 8bff mov edi,edi

(Hitting it and looking at the stack)

kd> kb
ChildEBP RetAddr Args to Child
b77fb920 b42bdbc0 00000000 878b4f10 b77fbacc Wdf01000!FxUsbDevice::SelectConfig
b77fba60 b42b7f3b 00000000 b77fbabc 00000000 Wdf01000!FxUsbDevice::SelectConfigMulti+0x2db
[…]

(Looking at the main part of the URB and interface 5)

kd> dt xxxccgp!_URB_SELECT_CONFIGURATION -b 0x878b4f10
+0x000 Hdr : _URB_HEADER
+0x000 Length : 0x5c
+0x002 Function : 0
+0x004 Status : 0
+0x008 UsbdDeviceHandle : (null)
+0x00c UsbdFlags : 0
+0x010 ConfigurationDescriptor : 0x879e99b0
+0x014 ConfigurationHandle : (null)
+0x018 Interface : _USBD_INTERFACE_INFORMATION
+0x000 Length : 0x10
+0x002 InterfaceNumber : 0x5 ‘’
+0x003 AlternateSetting : 0 ‘’
+0x004 Class : 0 ‘’
+0x005 SubClass : 0 ‘’
+0x006 Protocol : 0 ‘’
+0x007 Reserved : 0 ‘’
+0x008 InterfaceHandle : (null)
+0x00c NumberOfPipes : 0
+0x010 Pipes :
[00] _USBD_PIPE_INFORMATION
+0x000 MaximumPacketSize : 0x24
+0x002 EndpointAddress : 0x6 ‘’
+0x003 Interval : 0 ‘’
+0x004 PipeType : 0 ( UsbdPipeTypeControl )
+0x008 PipeHandle : (null)
+0x00c MaximumTransferSize : 1
+0x010 PipeFlags : 0

(Interface 6)

kd> dt xxxccgp!_USBD_INTERFACE_INFORMATION -b 0x878b4f38
+0x000 Length : 0x24
+0x002 InterfaceNumber : 0x6 ‘’
+0x003 AlternateSetting : 0 ‘’
+0x004 Class : 0 ‘’
+0x005 SubClass : 0 ‘’
+0x006 Protocol : 0 ‘’
+0x007 Reserved : 0 ‘’
+0x008 InterfaceHandle : (null)
+0x00c NumberOfPipes : 1
+0x010 Pipes :
[00] _USBD_PIPE_INFORMATION
+0x000 MaximumPacketSize : 0
+0x002 EndpointAddress : 0 ‘’
+0x003 Interval : 0 ‘’
+0x004 PipeType : 0 ( UsbdPipeTypeControl )
+0x008 PipeHandle : (null)
+0x00c MaximumTransferSize : 0x1000
+0x010 PipeFlags : 0

(Interface 8)

kd> dt xxxccgp!_USBD_INTERFACE_INFORMATION -b 0x878b4f5C
+0x000 Length : 0x10
+0x002 InterfaceNumber : 0x8 ‘’
+0x003 AlternateSetting : 0 ‘’
+0x004 Class : 0 ‘’
+0x005 SubClass : 0 ‘’
+0x006 Protocol : 0 ‘’
+0x007 Reserved : 0 ‘’
+0x008 InterfaceHandle : (null)
+0x00c NumberOfPipes : 0
+0x010 Pipes :
[00] _USBD_PIPE_INFORMATION
+0x000 MaximumPacketSize : 0
+0x002 EndpointAddress : 0 ‘’
+0x003 Interval : 0 ‘’
+0x004 PipeType : 0 ( UsbdPipeTypeControl )
+0x008 PipeHandle : (null)
+0x00c MaximumTransferSize : 0
+0x010 PipeFlags : 0

-Chris

Doron,

Ok. I think I’ve made some major progress here, so hopefully this can get the process moving again.

I thought about how these bugchecks were occuring in USBD!USBD_InternalInterfaceBusy. The third parameter was always a null pointer dereference, or close to it.

I set a breakpoint on that function, and then did a db on this address when usbhub was loaded for my device. When I removed the device (ONLY, not when I brought it up), I got three hits on this breakpoint. (Remember, my device has three interfaces, 5, 6, and 8).

Each time I did a dump on that memory (which was now valid, thus no blue screen), it looked like the word “FACX”, followed by some stuff I couldn’t parse, followed by the interface descriptor for that interface.

In the case of interface 6, which has one BULK IN endpoint, the word “BULK” also appeared after the above, with what appeared to be endpoint information (address, max packet size, etc.)

Now, I noticed when I did SelectConfigMulti() from KMDF, I was also getting hits on this breakpoint when I *brought up* the device. Thinking back to the call stack when this was happening…

eb43f800 eb2cae60 857c6c68 85e8b030 000901a7 USBD!USBD_InternalInterfaceBusy+0xe
eb43f838 eb2c84d0 85e8b030 857376e8 856b0450 USBD!USBD_SelectInterface+0x52

I remembered that in response to SelectConfigMulti(), KMDF will also issue SelectInterface on its own for any interfaces that have bulk endpoints, presumably to set the max transfer size.

Then it clicked why the crash dump I sent earlier looked like the select config URB succeeded, but the very next URB crashed everything. Because that’s what was happening!

So, realizing that it was actually the SELECT_INTERFACE URB from KMDF that was bringing everything down, I let SELECT_CONFIG go through in my LowerFilter but failed out SELECT_INTERFACE. So far, no blue screen.

I did a dump on the select interface URB from KMDF and it looks like this:

38 00 01 00 00 00 00 00
00 00 00 00 00 00 00 00
08 39 94 E3 24 00 06 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 10 00 00 00 00 00 00

Basically, it works out to length 38, function 1 (select interface URB), the 0xE3943908 is my USBD_CONFIGURATION_HANDLE, the 24 is length, 6 is my interface number, and the 00 10 00 00 is the 4K maximum transfer size, the rest is zero.

That URB seems to check out, so I was surprised that it was bringing everything down.

So what I did was succeeded it myself in my LowerFilter and passed in some bogus values as response data. KMDF took it, and away we went. No crash.

Here’s my question. What exactly is USBD_InternalInterfaceBusy? In particular, what is the third argument? In what cases would it be NULL or close to it?

My best theory is that it’s (supposed to be) some address in KMDF land, but because of the non-zero interface numbers, it’s looking for interface 6 in the “two” spot (second of 5, 6, 8), instead of the “6” spot, and getting a NULL. Then it tries to dereference, or free it, or something, and everything blows up.

What do you think??

-Chris

I thought of one more test case as further evidence. I tried this same setup on a different device. This time, it has interfaces 0, 1, 6, and 8:

0: one interrupt IN
1: one bulk IN, one bulk OUT
6: one bulk IN (same as last time)
8: no endpoints (same as last time)

Now, based on previous observation, I expected SelectConfigMulti() to issue one select configuration URB for the entire device, and then issue two more select interface URBs: one for interface 1, and one for interface 6, because they have bulk endpoints.

My hypothesis was that the select interface URB to interface 1 would be okay, because there are no gaps starting from the 0 interface, but the select interface to interface 6 would be bogus because of the gap between it and interface 1.

Here’s the breakpoint and call stack on the first select interface URB:

USBD!USBD_InternalInterfaceBusy:
eb6fa7bc 55 push ebp
kd> kb
ChildEBP RetAddr Args to Child
eb8376a0 eb6fae60 81d09c28 81ff4af0 81c364e8 USBD!USBD_InternalInterfaceBusy
eb8376d8 eb6f84d0 81ff4af0 81d04988 81d14430 USBD!USBD_SelectInterface+0x52
eb837704 eb6f99eb 81ff4af0 81d04988 81d09c28 USBD!USBD_ProcessURB+0x198
eb837738 eb6f8c38 81ff4af0 81d04988 81ff4ba8 USBD!USBD_FdoDispatch+0x221
eb837760 eb6e0409 81ff4af0 81d04988 eb83778c USBD!USBD_Dispatch+0x76
eb837794 8041dded 81ff4af0 81d04988 81d04a38 uhcd!UHCD_Dispatch+0x23
eb8377a8 eb51204b 81d04988 81c50aa8 00220003 nt!IopfCallDriver+0x35
eb8377bc eb51228a 81f514a8 81d04988 81c509f0 usbhub!USBH_PdoUrbFilter+0xdd
eb8377d8 eb51069a 00020a02 81d04988 eb837844 usbhub!USBH_PdoDispatch+0xd8
eb8377e8 8041dded 81c509f0 81d04988 bb9dca08 usbhub!USBH_HubDispatch+0x46
eb8377fc bb983bd1 81c33b4c 81c21810 eb837938 nt!IopfCallDriver+0x35
eb837844 bb98d312 01837860 eb8378f0 00000000 Wdf01000!FxIoTarget::SubmitSync+0x1f2
eb837938 bb98dbc0 00000000 81c33b10 eb837b08 Wdf01000!FxUsbDevice::SelectConfig+0x59b
eb837a78 bb987f3b 00000000 eb837af8 00000000 Wdf01000!FxUsbDevice::SelectConfigMulti+0x2db
eb837a98 bba31ecd 81c50260 7e3de7e8 00000000 Wdf01000!imp_WdfUsbTargetDeviceSelectConfig+0x6c9
eb837ab0 bba31b7e 7e3de7e8 00000000 eb837af8 xxxccgp!WdfUsbTargetDeviceSelectConfig+0x1d
eb837b0c bb9c807c 7e3befe8 7e3e1fe8 7e3b9b48 xxxccgp!XxxCcgpEvtDevicePrepareHardware+0xfe
eb837b2c bb9c83ae eb837b47 00000008 81c21c30 Wdf01000!FxPkgPnp::PnpPrepareHardware+0x7c
eb837b48 bb9c7245 81c21c30 bb9e0260 81c21c30 Wdf01000!FxPkgPnp::PnpEventHardwareAvailable+0x6f
eb837b70 bb9c7fa0 00000108 81c21cd0 81c21c30 Wdf01000!FxPkgPnp::PnpEnterNewState+0x15c

If I look at the third argument to USBD_InternalInterfaceBusy, I see:

kd> d 0x81c364e8
81c364e8 58 46 41 43 00 00 00 00-09 04 01 00 02 0a 00 00 XFAC…
81c364f8 04 00 00 00 38 65 c3 81-50 49 50 45 07 05 8a 02 …8e…PIPE…
81c36508 40 00 00 00 68 0b c5 81-00 10 00 00 00 00 00 00 @…h…
81c36518 00 00 00 00 50 49 50 45-07 05 0b 02 40 00 00 00 …PIPE…@…
81c36528 e8 07 c5 81 00 10 00 00-00 00 00 00 00 00 00 00 …
81c36538 38 00 01 00 0a 00 00 00-e8 64 c3 81 02 00 00 00 8…d…
81c36548 40 00 8a 00 02 00 00 00-00 65 c3 81 00 10 00 00 @…e…
81c36558 00 00 00 00 40 00 0b 00-02 00 00 00 1c 65 c3 81 …@…e…

Note the interface descriptor for interface 1 on the right half of the first line, and the two “PIPE” thingys as well (as I mentioned earlier). So far so good. I continue onward, and sure enough…

kd> g
Breakpoint 0 hit
USBD!USBD_InternalInterfaceBusy:
eb6fa7bc 55 push ebp
kd> kb
ChildEBP RetAddr Args to Child
eb8376a0 eb6fae60 81d09c28 81ff4af0 00720067 USBD!USBD_InternalInterfaceBusy
eb8376d8 eb6f84d0 81ff4af0 81d04988 81d14430 USBD!USBD_SelectInterface+0x52
eb837704 eb6f99eb 81ff4af0 81d04988 81d09c28 USBD!USBD_ProcessURB+0x198
eb837738 eb6f8c38 81ff4af0 81d04988 81ff4ba8 USBD!USBD_FdoDispatch+0x221
eb837760 eb6e0409 81ff4af0 81d04988 eb83778c USBD!USBD_Dispatch+0x76
eb837794 8041dded 81ff4af0 81d04988 81d04a38 uhcd!UHCD_Dispatch+0x23
eb8377a8 eb51204b 81d04988 81c50aa8 00220003 nt!IopfCallDriver+0x35
eb8377bc eb51228a 81f514a8 81d04988 81c509f0 usbhub!USBH_PdoUrbFilter+0xdd
eb8377d8 eb51069a 00020a02 81d04988 eb837844 usbhub!USBH_PdoDispatch+0xd8
eb8377e8 8041dded 81c509f0 81d04988 bb9dca08 usbhub!USBH_HubDispatch+0x46
eb8377fc bb983bd1 81c33b94 81c21810 eb837938 nt!IopfCallDriver+0x35
eb837844 bb98d312 01837860 eb8378f0 00000000 Wdf01000!FxIoTarget::SubmitSync+0x1f2
eb837938 bb98dbc0 00000000 81c33b10 eb837b08 Wdf01000!FxUsbDevice::SelectConfig+0x59b
eb837a78 bb987f3b 00000000 eb837af8 00000000 Wdf01000!FxUsbDevice::SelectConfigMulti+0x2db
eb837a98 bba31ecd 81c50260 7e3de7e8 00000000 Wdf01000!imp_WdfUsbTargetDeviceSelectConfig+0x6c9
eb837ab0 bba31b7e 7e3de7e8 00000000 eb837af8 xxxccgp!WdfUsbTargetDeviceSelectConfig+0x1d
eb837b0c bb9c807c 7e3befe8 7e3e1fe8 7e3b9b48 xxxccgp!XxxCcgpEvtDevicePrepareHardware+0xfe
eb837b2c bb9c83ae eb837b47 00000008 81c21c30 Wdf01000!FxPkgPnp::PnpPrepareHardware+0x7c
eb837b48 bb9c7245 81c21c30 bb9e0260 81c21c30 Wdf01000!FxPkgPnp::PnpEventHardwareAvailable+0x6f
eb837b70 bb9c7fa0 00000108 81c21cd0 81c21c30 Wdf01000!FxPkgPnp::PnpEnterNewState+0x15c

Uh oh. 0x00720067?

kd> d 0x00720067
00720067 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ???
00720077 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ???

Bonk.

So, at this point, I’m convinced that there is some bug here that is out of my control. I’d guess one of the following:

  1. Some issue in KMDF, but probably not since this doesn’t happen on XP.

  2. Some issue in the Win2k USB stack where select interface URBs crash on interfaces that follow “gaps”. I suppose this could be verified independently by issuing the URBs manually.

Anyway, the solution is clear now: in my lower filter, I’ll stash away the response to the initial select configuration URB, and then when select interface comes, I will just succeed them myself, pulling the response data from the individual USBD_INTERFACE_INFORMATION structs that were in the original select config URB response.

-Chris

Chris and I discussed this offline and I would like to bring closure to this thread

  1. The win2k USB stack requires that interface numbers on a multi interface be consecutive and start with zero for any select interface request
  2. You would only see this issue if you prevented the generic driver from loading on your device to split out your interfaces
  3. You send a select interface after the select config. KMDF does this automatically for multi interface devices to acquire the 2…N interface’s endpoints.
  4. XP and later do not have this issue

Nearly all devices have one interface so you would not see this normally. If you are creating a multi interface device that works on win2k, you should number your interface numbers consecutively and start with zero. A bug has been filed against KMDF to consider fixing this issue, the core Win2k issue will not be addressed since support for win2k has ended.

thx
d