Bug check in WdfRequestSend Call back

Hello All,
I am a newbie developing a WDF-USB miniport driver , I have a couple of queries :

-> In my call back for RequestSend , I am trying to retrieve memory handle for the request that I get but I get a bug-check. I get the same Request handle that I created (in the send routine).

//Start of Code
Status = WdfRequestRetrieveInputMemory(Request, &hMemory);
//EO code

//Start of Bug Check
******************************************************************************
* *
* 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: 00000006, memory referenced
Arg2: 00000002, IRQL
Arg3: 00000000, value 0 = read operation, 1 = write operation
Arg4: a9132adc, address which referenced memory

Debugging Details:

READ_ADDRESS: 00000006

CURRENT_IRQL: 2

FAULTING_IP:
wdf01000!FxRequest::GetMemoryObject+2a9
a9132adc 6683780600 cmp word ptr [eax+6],0

DEFAULT_BUCKET_ID: DRIVER_FAULT

BUGCHECK_STR: 0xD1

PROCESS_NAME: System

TRAP_FRAME: f792ccd0 – (.trap 0xfffffffff792ccd0)
ErrCode = 00000000
eax=00000000 ebx=86f0c7e8 ecx=78f99d28 edx=00000000 esi=870662d0 edi=a9169b98
eip=a9132adc esp=f792cd44 ebp=f792cd68 iopl=0 nv up ei pl nz na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010206
wdf01000!FxRequest::GetMemoryObject+0x2a9:
a9132adc 6683780600 cmp word ptr [eax+6],0 ds:0023:00000006=???
Resetting default scope

LAST_CONTROL_TRANSFER: from 804f8e09 to 8052b60c

STACK_TEXT:
f792c884 804f8e09 00000003 f792cbe0 00000000 nt!RtlpBreakWithStatusInstruction
f792c8d0 804f99f4 00000003 00000006 a9132adc nt!KiBugCheckDebugBreak+0x19
f792ccb0 80544728 0000000a 00000006 00000002 nt!KeBugCheck2+0x574
f792ccb0 a9132adc 0000000a 00000006 00000002 nt!KiTrap0E+0x238
f792cd68 a91251f0 f792cd8c f792cd84 f792cd88 wdf01000!FxRequest::GetMemoryObject+0x2a9
f792cd90 a97933da 870662d0 00000000 f792cdc4 wdf01000!imp_WdfRequestRetrieveInputMemory+0xb3
f792cda4 a9792fd6 78f99d28 f792cdc4 866e7d48 GesNdisUsb!WdfRequestRetrieveInputMemory+0x1a [c:\winddk\7600.16385.1\inc\wdf\kmdf\1.9\wdfrequest.h @ 1098]
f792cdd4 a9136317 78f99d28 7991de90 87170864 XexNdisUsb!WriteCmplteCb+0x76 [c:\code_on_25\ndiscbs_5.c @ 1263]
f792ce00 a911ac36 86f0c7c7 866e2168 00000000 wdf01000!FxRequestBase::CompleteSubmitted+0xf6
f792ce1c a911acde 010662d0 871bbed8 f792ce48 wdf01000!FxIoTarget::RequestCompletionRoutine+0x12d
f792ce2c 804f081d 00000000 86f0c6e8 870662d0 wdf01000!FxIoTarget::_RequestCompletionRoutine+0x35
f792ce48 804f16c0 00000000 86f0c6e8 871bbed8 nt!IopUnloadSafeCompletion+0x1d
f792ce78 f6b8b0d5 86f0c6e8 8693c578 87130028 nt!IopfCompleteRequest+0xa2
f792cee0 f6b8bd47 871708ac 00000000 871307d8 USBPORT!USBPORT_CompleteTransfer+0x373
f792cf10 f6b8c944 026e6f44 871300e0 871300e0 USBPORT!USBPORT_DoneTransfer+0x137
f792cf48 f6b8e13a 87130028 80546b0c 87130230 USBPORT!USBPORT_FlushDoneTransferList+0x16c
f792cf74 f6b9c24b 87130028 80546b0c 87130028 USBPORT!USBPORT_DpcWorker+0x224
f792cfb0 f6b9c3c2 87130028 00000001 87034e18 USBPORT!USBPORT_IsrDpcWorker+0x38f
f792cfcc 80545ebf 8713064c 6b755044 00000000 USBPORT!USBPORT_IsrDpc+0x166
f792cff4 80545a2b a996a8c8 00000000 00000000 nt!KiRetireDpcList+0x61
f792cff8 a996a8c8 00000000 00000000 00000000 nt!KiDispatchInterrupt+0x2b
WARNING: Frame IP not in any known module. Following frames may be wrong.
80545a2b 00000000 00000009 0081850f bb830000 0xa996a8c8

STACK_COMMAND: kb

FOLLOWUP_IP:
XexNdisUsb!WdfRequestRetrieveInputMemory+1a [c:\winddk\7600.16385.1\inc\wdf\kmdf\1.9\wdfrequest.h @ 1098]
a97933da 5d pop ebp

FAULTING_SOURCE_CODE:
1094: WDFMEMORY* Memory
1095: )
1096: {
1097: return ((PFN_WDFREQUESTRETRIEVEINPUTMEMORY) WdfFunctions[WdfRequestRetrieveInputMemoryTableIndex])(WdfDriverGlobals, Request, Memory);

1098: }
1099:
1100: //
1101: // WDF Function: WdfRequestRetrieveOutputMemory
1102: //
1103: typedef

SYMBOL_STACK_INDEX: 6

SYMBOL_NAME: XexNdisUsb!WdfRequestRetrieveInputMemory+1a

FOLLOWUP_NAME: MachineOwner

MODULE_NAME: XexNdisUsb

IMAGE_NAME: XexNdisUsb.sys

DEBUG_FLR_IMAGE_TIMESTAMP: 4cf3c566

FAILURE_BUCKET_ID: 0xD1_XexNdisUsb!WdfRequestRetrieveInputMemory+1a

BUCKET_ID: 0xD1_XexNdisUsb!WdfRequestRetrieveInputMemory+1a

//EO Bug Check

-> I am trying to preallocate Request and Memory handles for Send , but when I give the parent object of Request handle as WdfDevice or Bulk Write Pipe Iotarget , I get STATUS_INVALID_DEVICE_REQUEST when I use WdfRequestRetrieveInputMemory() if I do not assign any parent object , I am getting a bug check on the same call .

Am I doing Something wrong here :

//Start of Code

WDF_REQUEST_SEND_OPTIONS_INIT(&RequestOptions_g, 0x0000001);
WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&RequestOptions_g, WDF_REL_TIMEOUT_IN_SEC(50));

pWriteResources->nTotalWrites = nTotalWrites ;
pWriteResources->NxtAvlblWriteIndex = nTotalWrites ;

IoTarget = WdfUsbTargetPipeGetIoTarget(pUsbContext->bulkWPipe);
WDF_OBJECT_ATTRIBUTES_INIT(&ObjAttr);

//ReqAttr.ParentObject = WdfIoTargetGetDevice(pUsbContext->bulkWPipeIoTarget);
ReqAttr.ParentObject = pUsbContext->bulkWPipeIoTarget;
WDF_OBJECT_ATTRIBUTES_INIT(&ReqAttr);

for (i = 0; i < pWriteResources->nTotalWrites; i++) {

Status = WdfRequestCreate(&ReqAttr, IoTarget, &pWriteResources->WReqArray[i]);
if (!NT_SUCCESS(Status)) {
DPF(D_ERR,(“Could not create request: status(0x%08X)”, Status));
pWriteResources->nTotalWrites = i;
pWriteResources->NxtAvlblWriteIndex = i;
DPF(D_ALL, (“OUT %s\n”, FUNCTION));
return Status;
}
DPF(D_ERR, (“Create Request %p\n”, pWriteResources->WReqArray[i]));

#if 1
WDF_OBJECT_ATTRIBUTES_INIT(&ObjAttr);
ObjAttr.ParentObject = pWriteResources->WReqArray[i];

hBuffer = ExAllocatePoolWithTag(
NonPagedPool,
DEF_BULK_PIPE_SZ,
‘LSEG’
);
if (hBuffer == NULL){
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlMoveMemory(hBuffer, “Hello”, sizeof(“Hello”));
Status = WdfMemoryCreatePreallocated( &ObjAttr, hBuffer,
DEF_BULK_PIPE_SZ,
&hMemory
);
DPF(D_ERR,("In %s, WdfMemoryCreatePreallocated Status=%08x\n ", FUNCTION, Status));
#endif

if (!NT_SUCCESS(Status) && !hMemory) {
DPF(D_ERR,("In %s, Could not create request lock: status = ", FUNCTION, Status));
pWriteResources->nTotalWrites = i;
pWriteResources->NxtAvlblWriteIndex = i;
DPF(D_ALL, (“OUT %s\n”, FUNCTION));
return Status;
}

DPF(D_ERR, (“Create Memory %p\n”, hMemory));
Status = WdfUsbTargetPipeFormatRequestForWrite(pUsbContext->bulkWPipe, pWriteResources->WReqArray[i], hMemory, NULL);

if(!NT_SUCCESS(Status)) {
DPF(D_ERR,(“\n\nWdfUsbTargetPipeFormatRequestForWrite Failed , Status %08x\n\n”,Status));
}
}
#if DBG_ALL
for(i = 0; i < pWriteResources->nTotalWrites; i++) {
Status = WdfRequestRetrieveInputMemory(pWriteResources->WReqArray[i], &hMemory);
if(hMemory) {
DPF(D_ERR, (“Memory Handle = %p\n”, hMemory));
DataBuff = WdfMemoryGetBuffer(hMemory, &Length);
DPF(D_ERR, (“Memory Length= %d\n”, Length));
DPF(D_ERR, (“Data Buffer = %s\n”, (PUCHAR)DataBuff));
}
hMemory = NULL;
}
Status = STATUS_SUCCESS;
#endif
DPF(D_ALL, (“OUT %s\n”, FUNCTION));
return Status;

//EO Code

–> If i assign a Request Object as the parent of a memory object , Do I explictly need to Delete both the objects or is deleting Parent(Request) enough ?

–> Last One , Is wdldr loaded only when a WDF driver is loaded ?

Sorry for a lengthy post !

TIA,
Venkatesh D N

If you’re a newbie, then the first things you should learn are how to: (a) enable KMDF Verifier, (b) Enable verbose output, (c) use the WDFLOGDUMP command in the debugger to get KMDF debugging and tracing information.

See “Ten Things You Need To Know About KMDF”: http://www.osronline.com/article.cfm?article=496 (some of which is a tad dated, but still pretty accurate).

Peter
OSR

WdfRequestRetrieveInput/OutputMemory only work for the current stack location. If you create a request, there is no current stack location. In other words, WdfRequestRetrieveInput/OuputMemory only work for requests that are presented to you by a WDFQUEUE io callback, they don’t work for requests you create yourself. If you want to get the WDFMEMORY you allocated, store it in the pre allocated requests content area

Why would you do this?
hBuffer = ExAllocatePoolWithTag(
NonPagedPool,
DEF_BULK_PIPE_SZ,
‘LSEG’
);

Status = WdfMemoryCreatePreallocated( &ObjAttr, hBuffer,
DEF_BULK_PIPE_SZ,
&hMemory
);

Instead, just create a WDFMEMORY (WdfMemoryCreate) with a size of DEF_BULK_PIPE_SZ and then the WDFMEMORY can manage the lifetime of the allocation;

–> If i assign a Request Object as the parent of a memory object , Do I explictly need to Delete both the objects or is deleting Parent(Request) enough ?

Deleting the parent is enough, it works this way for all KMDF objects

–> Last One , Is wdldr loaded only when a WDF driver is loaded ?

Yes

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Monday, November 29, 2010 8:15 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Bug check in WdfRequestSend Call back

Hello All,
I am a newbie developing a WDF-USB miniport driver , I have a couple of queries :

-> In my call back for RequestSend , I am trying to retrieve memory handle for the request that I get but I get a bug-check. I get the same Request handle that I created (in the send routine).

//Start of Code
Status = WdfRequestRetrieveInputMemory(Request, &hMemory); //EO code

//Start of Bug Check
******************************************************************************
* *
* 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: 00000006, memory referenced
Arg2: 00000002, IRQL
Arg3: 00000000, value 0 = read operation, 1 = write operation
Arg4: a9132adc, address which referenced memory

Debugging Details:

READ_ADDRESS: 00000006

CURRENT_IRQL: 2

FAULTING_IP:
wdf01000!FxRequest::GetMemoryObject+2a9
a9132adc 6683780600 cmp word ptr [eax+6],0

DEFAULT_BUCKET_ID: DRIVER_FAULT

BUGCHECK_STR: 0xD1

PROCESS_NAME: System

TRAP_FRAME: f792ccd0 – (.trap 0xfffffffff792ccd0) ErrCode = 00000000
eax=00000000 ebx=86f0c7e8 ecx=78f99d28 edx=00000000 esi=870662d0 edi=a9169b98
eip=a9132adc esp=f792cd44 ebp=f792cd68 iopl=0 nv up ei pl nz na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010206
wdf01000!FxRequest::GetMemoryObject+0x2a9:
a9132adc 6683780600 cmp word ptr [eax+6],0 ds:0023:00000006=???
Resetting default scope

LAST_CONTROL_TRANSFER: from 804f8e09 to 8052b60c

STACK_TEXT:
f792c884 804f8e09 00000003 f792cbe0 00000000 nt!RtlpBreakWithStatusInstruction
f792c8d0 804f99f4 00000003 00000006 a9132adc nt!KiBugCheckDebugBreak+0x19
f792ccb0 80544728 0000000a 00000006 00000002 nt!KeBugCheck2+0x574
f792ccb0 a9132adc 0000000a 00000006 00000002 nt!KiTrap0E+0x238
f792cd68 a91251f0 f792cd8c f792cd84 f792cd88 wdf01000!FxRequest::GetMemoryObject+0x2a9
f792cd90 a97933da 870662d0 00000000 f792cdc4 wdf01000!imp_WdfRequestRetrieveInputMemory+0xb3
f792cda4 a9792fd6 78f99d28 f792cdc4 866e7d48 GesNdisUsb!WdfRequestRetrieveInputMemory+0x1a [c:\winddk\7600.16385.1\inc\wdf\kmdf\1.9\wdfrequest.h @ 1098]
f792cdd4 a9136317 78f99d28 7991de90 87170864 XexNdisUsb!WriteCmplteCb+0x76 [c:\code_on_25\ndiscbs_5.c @ 1263]
f792ce00 a911ac36 86f0c7c7 866e2168 00000000 wdf01000!FxRequestBase::CompleteSubmitted+0xf6
f792ce1c a911acde 010662d0 871bbed8 f792ce48 wdf01000!FxIoTarget::RequestCompletionRoutine+0x12d
f792ce2c 804f081d 00000000 86f0c6e8 870662d0 wdf01000!FxIoTarget::_RequestCompletionRoutine+0x35
f792ce48 804f16c0 00000000 86f0c6e8 871bbed8 nt!IopUnloadSafeCompletion+0x1d
f792ce78 f6b8b0d5 86f0c6e8 8693c578 87130028 nt!IopfCompleteRequest+0xa2
f792cee0 f6b8bd47 871708ac 00000000 871307d8 USBPORT!USBPORT_CompleteTransfer+0x373
f792cf10 f6b8c944 026e6f44 871300e0 871300e0 USBPORT!USBPORT_DoneTransfer+0x137
f792cf48 f6b8e13a 87130028 80546b0c 87130230 USBPORT!USBPORT_FlushDoneTransferList+0x16c
f792cf74 f6b9c24b 87130028 80546b0c 87130028 USBPORT!USBPORT_DpcWorker+0x224
f792cfb0 f6b9c3c2 87130028 00000001 87034e18 USBPORT!USBPORT_IsrDpcWorker+0x38f
f792cfcc 80545ebf 8713064c 6b755044 00000000 USBPORT!USBPORT_IsrDpc+0x166
f792cff4 80545a2b a996a8c8 00000000 00000000 nt!KiRetireDpcList+0x61
f792cff8 a996a8c8 00000000 00000000 00000000 nt!KiDispatchInterrupt+0x2b
WARNING: Frame IP not in any known module. Following frames may be wrong.
80545a2b 00000000 00000009 0081850f bb830000 0xa996a8c8

STACK_COMMAND: kb

FOLLOWUP_IP:
XexNdisUsb!WdfRequestRetrieveInputMemory+1a [c:\winddk\7600.16385.1\inc\wdf\kmdf\1.9\wdfrequest.h @ 1098]
a97933da 5d pop ebp

FAULTING_SOURCE_CODE:
1094: WDFMEMORY* Memory
1095: )
1096: {
1097: return ((PFN_WDFREQUESTRETRIEVEINPUTMEMORY) WdfFunctions[WdfRequestRetrieveInputMemoryTableIndex])(WdfDriverGlobals, Request, Memory);

1098: }
1099:
1100: //
1101: // WDF Function: WdfRequestRetrieveOutputMemory
1102: //
1103: typedef

SYMBOL_STACK_INDEX: 6

SYMBOL_NAME: XexNdisUsb!WdfRequestRetrieveInputMemory+1a

FOLLOWUP_NAME: MachineOwner

MODULE_NAME: XexNdisUsb

IMAGE_NAME: XexNdisUsb.sys

DEBUG_FLR_IMAGE_TIMESTAMP: 4cf3c566

FAILURE_BUCKET_ID: 0xD1_XexNdisUsb!WdfRequestRetrieveInputMemory+1a

BUCKET_ID: 0xD1_XexNdisUsb!WdfRequestRetrieveInputMemory+1a

//EO Bug Check

-> I am trying to preallocate Request and Memory handles for Send , but when I give the parent object of Request handle as WdfDevice or Bulk Write Pipe Iotarget , I get STATUS_INVALID_DEVICE_REQUEST when I use WdfRequestRetrieveInputMemory() if I do not assign any parent object , I am getting a bug check on the same call .

Am I doing Something wrong here :

//Start of Code

WDF_REQUEST_SEND_OPTIONS_INIT(&RequestOptions_g, 0x0000001); WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&RequestOptions_g, WDF_REL_TIMEOUT_IN_SEC(50));

pWriteResources->nTotalWrites = nTotalWrites ;
pWriteResources->NxtAvlblWriteIndex = nTotalWrites ;

IoTarget = WdfUsbTargetPipeGetIoTarget(pUsbContext->bulkWPipe);
WDF_OBJECT_ATTRIBUTES_INIT(&ObjAttr);

//ReqAttr.ParentObject = WdfIoTargetGetDevice(pUsbContext->bulkWPipeIoTarget);
ReqAttr.ParentObject = pUsbContext->bulkWPipeIoTarget; WDF_OBJECT_ATTRIBUTES_INIT(&ReqAttr);

for (i = 0; i < pWriteResources->nTotalWrites; i++) {

Status = WdfRequestCreate(&ReqAttr, IoTarget, &pWriteResources->WReqArray[i]);
if (!NT_SUCCESS(Status)) {
DPF(D_ERR,(“Could not create request: status(0x%08X)”, Status));
pWriteResources->nTotalWrites = i;
pWriteResources->NxtAvlblWriteIndex = i;
DPF(D_ALL, (“OUT %s\n”, FUNCTION));
return Status;
}
DPF(D_ERR, (“Create Request %p\n”, pWriteResources->WReqArray[i]));

#if 1
WDF_OBJECT_ATTRIBUTES_INIT(&ObjAttr);
ObjAttr.ParentObject = pWriteResources->WReqArray[i];

hBuffer = ExAllocatePoolWithTag(
NonPagedPool,
DEF_BULK_PIPE_SZ,
‘LSEG’
);
if (hBuffer == NULL){
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlMoveMemory(hBuffer, “Hello”, sizeof(“Hello”));
Status = WdfMemoryCreatePreallocated( &ObjAttr, hBuffer,
DEF_BULK_PIPE_SZ,
&hMemory
);
DPF(D_ERR,("In %s, WdfMemoryCreatePreallocated Status=%08x\n ", FUNCTION, Status)); #endif

if (!NT_SUCCESS(Status) && !hMemory) {
DPF(D_ERR,("In %s, Could not create request lock: status = ", FUNCTION, Status));
pWriteResources->nTotalWrites = i;
pWriteResources->NxtAvlblWriteIndex = i;
DPF(D_ALL, (“OUT %s\n”, FUNCTION));
return Status;
}

DPF(D_ERR, (“Create Memory %p\n”, hMemory));
Status = WdfUsbTargetPipeFormatRequestForWrite(pUsbContext->bulkWPipe, pWriteResources->WReqArray[i], hMemory, NULL);

if(!NT_SUCCESS(Status)) {
DPF(D_ERR,(“\n\nWdfUsbTargetPipeFormatRequestForWrite Failed , Status %08x\n\n”,Status));
}
}
#if DBG_ALL
for(i = 0; i < pWriteResources->nTotalWrites; i++) {
Status = WdfRequestRetrieveInputMemory(pWriteResources->WReqArray[i], &hMemory);
if(hMemory) {
DPF(D_ERR, (“Memory Handle = %p\n”, hMemory));
DataBuff = WdfMemoryGetBuffer(hMemory, &Length);
DPF(D_ERR, (“Memory Length= %d\n”, Length));
DPF(D_ERR, (“Data Buffer = %s\n”, (PUCHAR)DataBuff));
}
hMemory = NULL;
}
Status = STATUS_SUCCESS;
#endif
DPF(D_ALL, (“OUT %s\n”, FUNCTION));
return Status;

//EO Code

–> If i assign a Request Object as the parent of a memory object , Do I explictly need to Delete both the objects or is deleting Parent(Request) enough ?

–> Last One , Is wdldr loaded only when a WDF driver is loaded ?

Sorry for a lengthy post !

TIA,
Venkatesh D N


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