From a quick look, first thing you need is to return STATUS_MORE_PROCESSING_REQUIRED in Bus_PDOInternalIoctlCompletionRoutine.
Now since you are mixing WDM completion routine with WDFREQUEST completion, IRP is actually getting double completed. Using status_more_processing_reqd will prevent that.
If it was a WDF completion routine, it would have been safe to complete WDFREQUEST.
Also you are skipping the current stack location and setting completion routine, this would overwrite any completion routine the last guy had. You need to increase the child device stack size by 1 instead and use CopyStackLocation. You cannot use skip if you make any changes to the stack location including setting a completion routine. Please check IoSkipCurrentIrpStackLocation documentation.
Praveen
-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Dharmaraju, Vidyadhari
Sent: Wednesday, May 06, 2009 11:36 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] WdfRequestComplete is crashing
Thank you all!
Here is code. I appreciate your looking into it.
I will also try the WDF verifier and will set the .tmf file to get the correct log dump.
VOID
Bus_EvtInternalIoDeviceControl(
IN WDFQUEUE Queue,
IN WDFREQUEST Request,
IN size_t OutputBufferLength,
IN size_t InputBufferLength,
IN ULONG IoControlCode
)
{
PBUS_FDO_EXTENSION pFdoEx;
PPDO_EXTENSION pPdoEx;
NTSTATUS ntStatus=STATUS_SUCCESS;
WDFDEVICE hDevice;
hDevice = WdfIoQueueGetDevice(Queue);
//
// These macros will only return the extension
// for the appropriate device:
// if it is a PDO, pFdoEx == NULL
// if it is a FDO, pPdoEx == NULL
pFdoEx = BusFdoGetData(hDevice);
pPdoEx = PdoGetData(hDevice);
TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PORT, “==> Bus_EvtInternalIoDeviceControl\n”);
if( NULL == pFdoEx )
{
//
// For PDOs we created
//
Bus_PDOInternalIoControl(Queue,
Request,
OutputBufferLength,
InputBufferLength,
IoControlCode);
}
else {
TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PORT, “Bus_EvtInternalIoDeviceControl not handling IOCTL because this is for the FDO\n”);
}
//
// Else don’t need to do anything for those we are not handling from Fdo
//
return;
}
VOID
Bus_PDOInternalIoControl(
IN WDFQUEUE Queue,
IN WDFREQUEST Request,
IN size_t OutputBufferLength,
IN size_t InputBufferLength,
IN ULONG IoControlCode
)
{
NTSTATUS ntStatus=STATUS_SUCCESS;
PPDO_EXTENSION pPdoEx, BusPdoData;
WDFDEVICE hDevice;
WDF_REQUEST_PARAMETERS params;
PIRP pIrp;
PDEVICE_OBJECT Pdo, BusPdo;
PBUS_FDO_EXTENSION busFdoData;
WDF_REQUEST_SEND_OPTIONS options;
BOOLEAN ret;
hDevice = WdfIoQueueGetDevice(Queue);
pPdoEx = PdoGetData(hDevice);
TraceEvents(TRACE_LEVEL_VERBOSE, DBG_BUS, “==> Bus_PDOInternalIoControl\n”);
// Get Bus FdoData
busFdoData = (PBUS_FDO_EXTENSION)pPdoEx->pParentFDO;
WDF_REQUEST_PARAMETERS_INIT(¶ms);
WdfRequestGetParameters(
Request,
¶ms
);
// Currently WDF way of sending IRP is not working
// this request crashes with a bug check: " No more I/O stack locations
// are available to format the underlying IRP"
//
// WDK says this formats a specified I/O request so that the driver can forward
// it, unmodified, to the driver’s local I/O target.
// TO DO:
// 1. Try without WdfRequestFormatRequestUsingCurrentType, use forget_and_Send option - no completion routine
// 2. Try by setting completion routine and do WdfRequestComplete
//WdfRequestFormatRequestUsingCurrentType(Request);
//WDF_REQUEST_SEND_OPTIONS_INIT(
// &options,
// WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET
// );
//ret = WdfRequestSend (
// Request,
// busFdoData->saveIoTarget,
// &options
// );
//if (!ret) {
// ntStatus = WdfRequestGetStatus(Request);
// WdfRequestComplete(
// Request,
// ntStatus
// );
//}
//
// Pass the Irp down
//
pIrp = WdfRequestWdmGetIrp(Request);
BusPdo = WdfDeviceWdmGetDeviceObject(pPdoEx->pCommon->WdfDevice);
TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IRP,
“@ Bus WDFREQUEST(sent): 0x%x IRP(sent): 0x%x\n”, Request, pIrp);
IoSkipCurrentIrpStackLocation (pIrp);
// This is actually not working, my completion routine is not getting called!!
//// WdfRequestSetCompletionRoutine( Request, Bus_PDOInternalIoctlCompletionRoutine, NULL );
// Set Completion routine in WDM way
// for now!
IoSetCompletionRoutine(
pIrp,
Bus_PDOInternalIoctlCompletionRoutine,
Request, // and pass the Request as Context
TRUE,
TRUE,
TRUE
);
// This goes down to the Port/lower level driver
ntStatus = IoCallDriver(BusPdo, pIrp );
TraceEvents(TRACE_LEVEL_VERBOSE, DBG_BUS, “<== Bus_PDOInternalIoControl, ntStatus %X\n”, ntStatus);
return;
}
NTSTATUS
Bus_PDOInternalIoctlCompletionRoutine(
IN PDEVICE_OBJECT pDeviceObject,
IN PIRP pIrp,
IN PVOID Context
)
{
NTSTATUS status =STATUS_SUCCESS;
KIRQL Irql;
WDFREQUEST Request;
Irql = KeGetCurrentIrql();
if(Irql <= DISPATCH_LEVEL)
{
TraceEvents(TRACE_LEVEL_VERBOSE, DBG_BUS,
“Irql < = DISPATCH_LEVEL\n” );
}
else{
TraceEvents(TRACE_LEVEL_VERBOSE, DBG_BUS,
“Irql =%d\n”, Irql );
}
Request = (WDFREQUEST)Context;
// This crashes! Verified that it is the
// same request that comes in Bus_PDOInternalIoControl()
WdfRequestComplete(Request, status);
return status; // Return Success always
}
// TO DO: Not getting called, find out why
//NTSTATUS
//Bus_PDOInternalIoctlCompletionRoutine(
// IN WDFREQUEST Request,
// IN WDFIOTARGET Target,
// IN PWDF_REQUEST_COMPLETION_PARAMS Params,
// IN WDFCONTEXT Context
// )
//{
// NTSTATUS status =STATUS_SUCCESS;
// KIRQL Irql;
//
// Irql = KeGetCurrentIrql();
//
// if(Irql <= DISPATCH_LEVEL)
// {
// TraceEvents(TRACE_LEVEL_VERBOSE, DBG_BUS,
// “Irql < = DISPATCH_LEVEL\n” );
// }
// else{
// TraceEvents(TRACE_LEVEL_VERBOSE, DBG_BUS,
// “Irql =%d\n”, Irql );
// }
//
// WdfRequestComplete(Request, status);
// return status;
//}
-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Doron Holan
Sent: Wednesday, May 06, 2009 10:21 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] WdfRequestComplete is crashing
You need to set the tmf file so that you can get the correct output from wdflogdump. Post your code for the dispatch routine where you process the irp, send it and then the completion routine where complete it
d
-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Dharmaraju, Vidyadhari
Sent: Wednesday, May 06, 2009 10:13 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] WdfRequestComplete is crashing
I am trying to do a WdfRequestComplete on a WDFREQUEST object in the completion routine that I registered. I am using the same request Object that got passed to me in my dispatch routine.
I have no clue why the framework thinks that it is not a valid Request and gives me this bug check.
!wdfkd.wdflogdump [DriverName] did not releave much information.
Any help?
Thanks!
Vidya
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: 00001028, memory referenced
Arg2: 00000002, IRQL
Arg3: 00000000, value 0 = read operation, 1 = write operation
Arg4: b64001f5, address which referenced memory
Debugging Details:
READ_ADDRESS: 00001028
CURRENT_IRQL: 2
FAULTING_IP:
wdf01000!FxRequest::Complete+97
b64001f5 8b4028 mov eax,dword ptr [eax+28h]
DEFAULT_BUCKET_ID: DRIVER_FAULT
BUGCHECK_STR: 0xD1
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