Hello All,
I am porting a USB WDM driver to WDF. I have some vendor specific
commands thats needs to submitted to lower device.
I get a bugcheck 0x7E at WdfIoTargetSendInternalIoctlSynchronously().
Can some one help me if im going wrong anywhere in the below code.
Here are the WDM and WDF code snippets.
WDM
--------
NTSTATUS SubmitUSB()
{
usUrbSize = (USHORT)sizeof(struct
_URB_CONTROL_VENDOR_OR_CLASS_REQUEST);
pUrb = (PURB)ExAllocatePoolWithTag(NonPagedPool, usUrbSize,
'BSUD');
if (pUrb == NULL)
{
DbgPrint(1, ("ExAllocatePool Failed.. No Memory\n"));
return STATUS_NO_MEMORY;
}
UsbBuildVendorRequest(pUrb, URB_FUNCTION_VENDOR_DEVICE, usUrbSize,
USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK, 0,
ucRequest, usValue, usIndex,
pBuffer, NULL, ulTransferLen, NULL);
KeWaitForSingleObject( &KeSyncSubmitUrb, Executive, KernelMode,
FALSE, NULL );
KeInitializeEvent(&kEvent, NotificationEvent, FALSE);
// Build an IRP
pIrp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_SUBMIT_URB,
pdoNext, NULL, 0, NULL, 0, TRUE, &kEvent, &ioStatus);
if (pIrp == NULL)
{
DbgPrint(1, ("IoBuildDeviceIoControlRequest() failed!\n"));
status = STATUS_INSUFFICIENT_RESOURCES;
}
else
{
PIO_STACK_LOCATION pStack = IoGetNextIrpStackLocation(pIrp);
pStack->Parameters.Others.Argument1 = pUrb;
IoSetCancelRoutine(pIrp, NULL);
// Call the USBD
status = IoCallDriver(pdoNext, pIrp);
if (status == STATUS_PENDING)
{
LARGE_INTEGER TimeOut = { (ULONG)(-10000 * 1000), -1 };
while ( status != STATUS_SUCCESS )
{
// Wait for completion
status = KeWaitForSingleObject(&kEvent, Executive, KernelMode,
FALSE, &TimeOut);
if ( status != STATUS_SUCCESS )
{
DbgPrint(1, ("KeWaitForSingleObject failed\n");
if ( status == STATUS_TIMEOUT )
{
IoCancelIrp( pIrp );
}
}
}
status = ioStatus.Status;
}
}
KeSetEvent( &KeSyncSubmitUrb, 0, FALSE );
}
WDF Equivalent
-----------------------
NTSTATUS SubmitURB()
{
PURB pUrb = NULL;
WDFMEMORY urbMemory;
WDF_OBJECT_ATTRIBUTES objectAttribs;
WDF_MEMORY_DESCRIPTOR memoryDesc;
usUrbSize = (USHORT)sizeof(struct
_URB_CONTROL_VENDOR_OR_CLASS_REQUEST);
WDF_OBJECT_ATTRIBUTES_INIT(&objectAttribs);
objectAttribs.ParentObject = Device;
status = WdfMemoryCreate(
&objectAttribs,
NonPagedPool,
POOL_TAG,
usUrbSize,
&urbMemory,
(PVOID*) &pUrb);
if (!NT_SUCCESS(status)) {
DbgPrint(1, ("Failed to alloc mem for urb\n"));
status = STATUS_INSUFFICIENT_RESOURCES;
return status;
}
UsbBuildVendorRequest(pUrb, URB_FUNCTION_VENDOR_DEVICE, usUrbSize,
USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK, 0,
ucRequest, usValue, usIndex,
pBuffer, NULL, ulTransferLen, NULL);
WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&memoryDesc, urbMemory,
(USHORT)sizeof(URB));
status =
WdfIoTargetSendInternalIoctlSynchronously(WdfDeviceGetIoTarget(Device),
NULL, IOCTL_INTERNAL_USB_SUBMIT_URB, &memoryDesc, NULL, NULL, NULL);
if (!NT_SUCCESS(status)) {
DbgPrint(1, ("WdfIoTargetSendInternalIoctlSynchronously Failed
with error 0x%x\n",status));
return status;
}
}
Thank You.
Regards,
uba