USB lower filter and blasted URB_FUNCTION_SELECT_CONFIGURATION completion

Apologies in advance for the “please do my homework for me” style question, but I am not seeing why this pretty standard (?) code is not working for me and would very much appreciate any insights/ hints. I have a USB lower filter driver which invokes this executive work item from the completion of handling URB_FUNCTION_SELECT_CONFIGURATION. What I see on a win7 box is that all appears well until the application attempts to access the device - it hangs, unless I set doSelectConfig to FALSE of course :slight_smile:

What I am expecting to happen is to pick up the pipe handles and *not* shaft the application!

Sigh… help!

Thanks,

Jolyon

VOID ConfigureUsbDeviceWorkItemWhichMayBeProblematic(__in WDFWORKITEM WorkItem)
{
NTSTATUS status;
WDF_USB_DEVICE_SELECT_CONFIG_PARAMS usbConfig;
WDF_USB_PIPE_INFORMATION pipeConfig;
WDFUSBPIPE pipe = NULL;
BYTE index = 0;
PURB pUrb = NULL;
PWORKITEM_CONTEXT pWorkItemContext = NULL;
WDFDEVICE device = NULL;
PDEVICE_CONTEXT pDeviceContext = NULL;
struct _URB_SELECT_CONFIGURATION* pTypedUrb;
BOOLEAN doSelectConfig = TRUE;

/*

our work item context looks like this:-

typedef struct _WORKITEM_CONTEXT
{
WDFREQUEST Request; // the request we need to complete
NTSTATUS RequestCompletionStatus; // the status to use
} WORKITEM_CONTEXT, *PWORKITEM_CONTEXT;

*/

pWorkItemContext = GetWorkItemContext(WorkItem);
ASSERT (pWorkItemContext != NULL );

device = WdfIoQueueGetDevice(WdfRequestGetIoQueue(pWorkItemContext->Request));
/*
0: kd> !devstack 8acb6130
!DevObj !DrvObj !DevExt ObjectName
8b386520 \Driver\usbprint 8b3865d8
87a75ee0 \DRIVER\VERIFIER_FILTER87a75f98

8acb6130 \Driver\jolyon 9856f198
8acb6428 \DRIVER\VERIFIER_FILTER8acb64e0
98400d70 *** ERROR: Module load completed but symbols could not be loaded for iusb3hub.sys
\Driver\iusb3hub 98400e28 000000a6
!DevNode aee548c8 :
DeviceInst is “USB\VID_0AA7&PID_030F\7&19fc8923&0&3”
ServiceName is “usbprint”
*/
pDeviceContext = GetDeviceContext(device);

pUrb = (PURB) IoGetCurrentIrpStackLocation(WdfRequestWdmGetIrp(pWorkItemContext->Request))->Parameters.Others.Argument1;
pTypedUrb = (struct _URB_SELECT_CONFIGURATION*) pUrb;

ASSERT(pUrb && pUrb->UrbSelectConfiguration.ConfigurationDescriptor);

WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_URB(&usbConfig, pUrb);

__debugbreak(); // whats going on?!

if (doSelectConfig == TRUE) // change the value in the debugger to skip this block
{
status = WdfUsbTargetDeviceSelectConfig(pDeviceContext->UsbDevice,
WDF_NO_OBJECT_ATTRIBUTES,
&usbConfig);
ASSERT(NT_SUCCESS(status));

pDeviceContext->UsbInterface = WdfUsbTargetDeviceGetInterface(pDeviceContext->UsbDevice, 0);

KdPrint((“NumSettings:%d\n”, WdfUsbInterfaceGetNumSettings(pDeviceContext->UsbInterface))); // gives me 1

WDF_USB_PIPE_INFORMATION_INIT(&pipeConfig);

index = 0;

do
{
pipe = WdfUsbInterfaceGetConfiguredPipe(pDeviceContext->UsbInterface,
index,
&pipeConfig);
if (NULL == pipe)
break;
WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pipe);

if (WdfUsbPipeTypeBulk == pipeConfig.PipeType)
{
if (TRUE == WdfUsbTargetPipeIsInEndpoint(pipe))
{
pDeviceContext->UsbBulkInPipe = pipe;
}
else if (TRUE == WdfUsbTargetPipeIsOutEndpoint(pipe))
{
pDeviceContext->UsbBulkOutPipe = pipe;
}
}
else if (WdfUsbPipeTypeInterrupt == pipeConfig.PipeType)
{
pDeviceContext->UsbInterruptPipe = pipe;
}
index++;
} while (NULL != pipe);
}

WdfRequestComplete(pWorkItemContext->Request,
pWorkItemContext->RequestCompletionStatus);
WdfObjectDelete(WorkItem);

return;
}

WdfUsbTargetDeviceSelectConfig will send the select config back down to the USB host again, not sure that is what you want. Instead, why not process the select config synchronously in the send path?

Bent from my phone


From: xxxxx@lists.osr.com on behalf of xxxxx@gmail.com
Sent: Thursday, June 22, 2017 6:38:55 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] USB lower filter and blasted URB_FUNCTION_SELECT_CONFIGURATION completion

Apologies in advance for the “please do my homework for me” style question, but I am not seeing why this pretty standard (?) code is not working for me and would very much appreciate any insights/ hints. I have a USB lower filter driver which invokes this executive work item from the completion of handling URB_FUNCTION_SELECT_CONFIGURATION. What I see on a win7 box is that all appears well until the application attempts to access the device - it hangs, unless I set doSelectConfig to FALSE of course :slight_smile:

What I am expecting to happen is to pick up the pipe handles and not shaft the application!

Sigh… help!

Thanks,

Jolyon

VOID ConfigureUsbDeviceWorkItemWhichMayBeProblematic(__in WDFWORKITEM WorkItem)
{
NTSTATUS status;
WDF_USB_DEVICE_SELECT_CONFIG_PARAMS usbConfig;
WDF_USB_PIPE_INFORMATION pipeConfig;
WDFUSBPIPE pipe = NULL;
BYTE index = 0;
PURB pUrb = NULL;
PWORKITEM_CONTEXT pWorkItemContext = NULL;
WDFDEVICE device = NULL;
PDEVICE_CONTEXT pDeviceContext = NULL;
struct _URB_SELECT_CONFIGURATION* pTypedUrb;
BOOLEAN doSelectConfig = TRUE;

/

our work item context looks like this:-

typedef struct _WORKITEM_CONTEXT
{
WDFREQUEST Request; // the request we need to complete
NTSTATUS RequestCompletionStatus; // the status to use
} WORKITEM_CONTEXT, PWORKITEM_CONTEXT;

/

pWorkItemContext = GetWorkItemContext(WorkItem);
ASSERT (pWorkItemContext != NULL );

device = WdfIoQueueGetDevice(WdfRequestGetIoQueue(pWorkItemContext->Request));
/

0: kd> !devstack 8acb6130
!DevObj !DrvObj !DevExt ObjectName
8b386520 \Driver\usbprint 8b3865d8
87a75ee0 \DRIVER\VERIFIER_FILTER87a75f98
> 8acb6130 \Driver\jolyon 9856f198
8acb6428 \DRIVER\VERIFIER_FILTER8acb64e0
98400d70 *** ERROR: Module load completed but symbols could not be loaded for iusb3hub.sys
\Driver\iusb3hub 98400e28 000000a6
!DevNode aee548c8 :
DeviceInst is “USB\VID_0AA7&PID_030F\7&19fc8923&0&3”
ServiceName is “usbprint”
/
pDeviceContext = GetDeviceContext(device);

pUrb = (PURB) IoGetCurrentIrpStackLocation(WdfRequestWdmGetIrp(pWorkItemContext->Request))->Parameters.Others.Argument1;
pTypedUrb = (struct _URB_SELECT_CONFIGURATION
) pUrb;

ASSERT(pUrb && pUrb->UrbSelectConfiguration.ConfigurationDescriptor);

WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_URB(&usbConfig, pUrb);

__debugbreak(); // whats going on?!

if (doSelectConfig == TRUE) // change the value in the debugger to skip this block
{
status = WdfUsbTargetDeviceSelectConfig(pDeviceContext->UsbDevice,
WDF_NO_OBJECT_ATTRIBUTES,
&usbConfig);
ASSERT(NT_SUCCESS(status));

pDeviceContext->UsbInterface = WdfUsbTargetDeviceGetInterface(pDeviceContext->UsbDevice, 0);

KdPrint((“NumSettings:%d\n”, WdfUsbInterfaceGetNumSettings(pDeviceContext->UsbInterface))); // gives me 1

WDF_USB_PIPE_INFORMATION_INIT(&pipeConfig);

index = 0;

do
{
pipe = WdfUsbInterfaceGetConfiguredPipe(pDeviceContext->UsbInterface,
index,
&pipeConfig);
if (NULL == pipe)
break;
WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pipe);

if (WdfUsbPipeTypeBulk == pipeConfig.PipeType)
{
if (TRUE == WdfUsbTargetPipeIsInEndpoint(pipe))
{
pDeviceContext->UsbBulkInPipe = pipe;
}
else if (TRUE == WdfUsbTargetPipeIsOutEndpoint(pipe))
{
pDeviceContext->UsbBulkOutPipe = pipe;
}
}
else if (WdfUsbPipeTypeInterrupt == pipeConfig.PipeType)
{
pDeviceContext->UsbInterruptPipe = pipe;
}
index++;
} while (NULL != pipe);
}

WdfRequestComplete(pWorkItemContext->Request,
pWorkItemContext->RequestCompletionStatus);
WdfObjectDelete(WorkItem);

return;
}


NTDEV is sponsored by OSR

Visit the list online at: https:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at https:

To unsubscribe, visit the List Server section of OSR Online at https:</https:></https:></https:>

thankyou, doron holan; that worked - you are a super star!