a callstack of where it is crashing in DeviceIoControl would help. which IOCTL is it blowing up on? also, is your user mode code handling the async completion of the request correctly?
d
From: xxxxx@lists.osr.com [xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com [xxxxx@gmail.com]
Sent: Tuesday, August 26, 2008 9:39 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] I/O request not able to complete - return
Hi…
I am a real newbie to usb driver programming…so most of the time i am not able to explain the problem i am facing …please excuse me for that.
Well i figured out that there was no completion routine that i registered and so the therad was waiting. Now i am not facing that problem any more. But new problem has occured.
My application which is calling DeviceIoControl is crashing. I checked with WinDbg and my EvtDeviceIoControl is getting existed , my completion routine is getting called and getting existed but even after that the application is crashing. Dont know why it is happeing.
Here is the code for my EvtDeviceIoControl :
VOID
USBDrvEvtIoDeviceControl(
IN WDFQUEUE Queue,
IN WDFREQUEST Request,
IN size_t OutputBufferLength,
IN size_t InputBufferLength,
IN ULONG IoControlCode
)
{
WDFDEVICE device;
PVOID ioBuffer;
size_t w;
NTSTATUS status;
PDEVICE_CONTEXT pDevContext;
PFILE_CONTEXT pFileContext;
ULONG length = 0;
WDFMEMORY memory;
UCHAR pipe;
UCHAR deleteme;
WDFUSBPIPE pipeNo;
int bufLength;
WDF_USB_PIPE_INFORMATION pipeInfo;
PVOID virtualAddress = 0;
WDF_OBJECT_ATTRIBUTES objectAttribs;
WDFMEMORY reqMemory;
WDFMEMORY_OFFSET offset;
char *pChar = NULL;
ULONG ulUrbFlags = ZERO;
ULONG_PTR ulpVirtualAddress = ZERO;
PMDL pNewMdl = NULL;
PMDL pRequestMdl = NULL;
PURB pUrb = NULL;
WDFMEMORY wdfUrbMemory;
USBD_PIPE_HANDLE usbdPipeHandle;
NTSTATUS ntstatus;
UNREFERENCED_PARAMETER(OutputBufferLength);
UNREFERENCED_PARAMETER(InputBufferLength);
UsbSamp_DbgPrint(3, (“Entered UsbSamp_DispatchDevCtrl\n”));
//
// initialize variables
//
device = WdfIoQueueGetDevice(Queue);
pDevContext = GetDeviceContext(device);
switch(IoControlCode)
{
case IOCTL_RESET_PIPE:
pFileContext = GetFileContext(WdfRequestGetFileObject(Request));
if (pFileContext->Pipe == NULL) {
status = STATUS_INVALID_PARAMETER;
}
else {
status = ResetPipe(pFileContext->Pipe);
}
break;
case IOCTL_GET_CONFIG_DESCRIPTOR:
if (pDevContext->UsbConfigurationDescriptor) {
length = pDevContext->UsbConfigurationDescriptor->wTotalLength;
status = WdfRequestRetrieveOutputBuffer(Request, length, &ioBuffer, &bufLength);
if(!NT_SUCCESS(status)){
UsbSamp_DbgPrint(3, (“WdfRequestRetrieveInputBuffer failed\n”));
break;
}
RtlCopyMemory(ioBuffer,
pDevContext->UsbConfigurationDescriptor,
length);
status = STATUS_SUCCESS;
}
else {
status = STATUS_INVALID_DEVICE_STATE;
}
break;
case IOCTL_RESET_DEVICE:
status = ResetDevice(device);
break;
case IOCTL_BULK_WRITE:
UsbSamp_DbgPrint(3, (“IOCTL_BULK_WRITE case - Starts \n”));
// Get the pipe associate with this request.
pFileContext = GetFileContext(WdfRequestGetFileObject(Request));
status = WdfRequestRetrieveInputBuffer(
Request,
InputBufferLength,
&ioBuffer,
&InputBufferLength
);
if(!NT_SUCCESS(status))
{
UsbSamp_DbgPrint(3, (“WdfRequestRetrieveInputBuffer -failed = %d\n”, status));
break;
}
pipe = *((UCHAR*)ioBuffer);
UsbSamp_DbgPrint(3, (“Out Pipe Assigned = %d \n”,pipe));
pipeNo = WdfUsbInterfaceGetConfiguredPipe(
pDevContext->UsbInterface,
pipe,
NULL
);
pFileContext->Pipe = pipeNo;
WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pipeNo);
WDF_USB_PIPE_INFORMATION_INIT(&pipeInfo);
WdfUsbTargetPipeGetInformation(pipeNo, &pipeInfo);
if((WdfUsbPipeTypeBulk == pipeInfo.PipeType) || (WdfUsbPipeTypeInterrupt == pipeInfo.PipeType))
{
// To retrieve a memory descriptor list (MDL) that represents an I/O request’s output buffer.
ntstatus = WdfRequestRetrieveOutputWdmMdl(Request, &pRequestMdl);
if(!NT_SUCCESS(ntstatus))
{
// Debug trace
UsbSamp_DbgPrint (3 , (“WdfRequestRetrieveOutputWdmMdl failed %x\n”, ntstatus));
break;
}
ulUrbFlags |= USBD_TRANSFER_DIRECTION_OUT;
ulUrbFlags |= USBD_SHORT_TRANSFER_OK;
ulpVirtualAddress = (ULONG_PTR) MmGetMdlVirtualAddress(pRequestMdl);
pNewMdl = IoAllocateMdl((PVOID) ulpVirtualAddress,
OutputBufferLength,
FALSE,
FALSE,
NULL);
if (pNewMdl == NULL)
{
// Debug trace
UsbSamp_DbgPrint (3 , (“Failed to alloc memory for mdl\n”));
ntstatus = STATUS_INSUFFICIENT_RESOURCES;
break;
}
// Map the portion of user-buffer described by an mdl to another mdl
IoBuildPartialMdl( pRequestMdl,
pNewMdl,
(PVOID) ulpVirtualAddress,
OutputBufferLength);
// create a framework memory object and allocates a memory buffer
// of a specified size.
ntstatus = WdfMemoryCreate( WDF_NO_OBJECT_ATTRIBUTES,
NonPagedPool,
POOL_TAG,
sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
&wdfUrbMemory,
(PVOID*) &pUrb);
if (!NT_SUCCESS(ntstatus))
{
// Debug trace
UsbSamp_DbgPrint (3 , (“Failed to alloc memory for urb\n”));
ntstatus = STATUS_INSUFFICIENT_RESOURCES;
break;
}
usbdPipeHandle = WdfUsbTargetPipeWdmGetPipeHandle(pipeNo);
UsbBuildInterruptOrBulkTransferRequest
( pUrb,
sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
usbdPipeHandle,
NULL,
pNewMdl,
OutputBufferLength,
ulUrbFlags,
NULL );
// builds an USB request for a specified USB pipe,
// using request parameters that a specified URB describes
ntstatus = WdfUsbTargetPipeFormatRequestForUrb(pipeNo, Request, wdfUrbMemory, NULL );
if (!NT_SUCCESS(ntstatus))
{
// Debug trace
UsbSamp_DbgPrint (3 ,(“Failed to format requset for urb\n”));
ntstatus = STATUS_INSUFFICIENT_RESOURCES;
break;
}
WdfRequestSetCompletionRoutine( Request,
EvtIoWriteComplete,
NULL);
if (!WdfRequestSend(Request,WdfUsbTargetPipeGetIoTarget(pipeNo),WDF_NO_SEND_OPTIONS))
{
ntstatus = WdfRequestGetStatus(Request);
UsbSamp_DbgPrint(3, (“WdfRequestSend failed\n”));
break;
}
UsbSamp_DbgPrint(3, (“Bulk Write Operation Completed Successfully \n”));
status = STATUS_SUCCESS;
}
status = STATUS_SUCCESS;
break;
default :
status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
UsbSamp_DbgPrint(3, (“status = %d \n”,status));
UsbSamp_DbgPrint(3, (“Exit UsbSamp_DispatchDevCtrl\n”));
return;
}
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