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