Hi,
Below is some code that have to work but it does not… So what goes on:
IoCallDriver() returns immidiately (no STATUS_PENDING returned so no
KeWaitForSingleObject() initiated). Then TdiBrideOnComplete() is invoked.
I do return STATUS_MORE_PROCESSING_REQUIRED so the IRP is not freed. After
this I clear event explicitly by calling KeClearEvent(), call
IoCompleteRequest() with the address of the IRP i use to complete
processing of IRP and call KeWaitForSingleObject() to wait until the
completion of IRP processing/freeing. But this last call BLOCKS FOREVER!!
WHY??? WHAT AM I DOING WRONG? What’s the correct way to implement timeouts
in calling TDI?
Thanks for help,
Anton
NTSTATUS
TdiBrideOnComplete(
IN PDEVICE_OBJECT pDeviceObject,
IN PIRP pIrp,
IN PVOID pvoidContext
)
{
DbgPrint( “TdiBride:TdiBrideOnComplete(): ENTERed…\n” );
//
// set signalling event
//
KeSetEvent(
( PKEVENT )( pvoidContext ),
IO_NO_INCREMENT,
FALSE
);
DbgPrint( “TdiBride:TdiBrideOnComplete(): BEFORE exit…\n” );
//
// return correct status
//
return STATUS_MORE_PROCESSING_REQUIRED;
}
NTSTATUS
TdiBrideCallEx(
IN PDEVICE_OBJECT pDeviceObject,
IN PIRP pIrp,
IN PKEVENT pkEvent,
IN PIO_STATUS_BLOCK pIoStatusBlock
)
{
NTSTATUS ntStatus;
NTSTATUS ntStatusFinal;
LARGE_INTEGER largeIntegerTimeout;
DbgPrint( “TdiBride:TdiBrideCallEx(): ENTERed…\n” );
/*
DbgPrint(
“TdiBride:TdiBrideCallEx(): KIRQL == %u…\n”,
KeGetCurrentIrql()
);
*/
/*
//
// set completion routine on the IRP
//
IoSetCompletionRoutine(
pIrp,
TdiBrideOnComplete,
pkEvent,
TRUE,
TRUE,
TRUE
);
*/
//
// try to call underlying device object
//
ntStatus =
IoCallDriver(
pDeviceObject,
pIrp
);
//
// check for the status of IoCallDriver(…)
//
if ( ntStatus == STATUS_PENDING )
{
DbgPrint( “TdiBride:TdiBrideCallEx(): IoCallDriver() is pending…\n”
);
//
// prepare timeout…
//
largeIntegerTimeout.QuadPart = 10000L; // debug…
//10000000L; // in seconds…
largeIntegerTimeout.QuadPart *= DEFAULT_TIMEOUT_IN_SECONDS; // convert to
seconds…
largeIntegerTimeout.QuadPart = - ( largeIntegerTimeout.QuadPart ); //
relative time to wait…
//
// wait for async I/O completion
//
ntStatus =
KeWaitForSingleObject(
pkEvent,
//UserRequest,
Executive,
KernelMode,
FALSE,
&largeIntegerTimeout // our timeout
//NULL
);
//
// check if this is timeout
//
if ( ntStatus == STATUS_TIMEOUT )
{
DbgPrint( “TdiBride:TdiBrideCallEx(): call timeouted…\n” );
//
// cancel pending request
//
IoCancelIrp( pIrp );
//
// clear event
//
KeWaitForSingleObject(
pkEvent,
Executive,
KernelMode,
FALSE,
NULL
);
}
}
//
// check for the status of KeWaitForSingleObject() or IoCallDriver()
call…
//
if ( NT_SUCCESS( ntStatus ) == FALSE )
{
DbgPrint(
“TdiBride:TdiBrideCallEx(): KeWaitForSingleObject() or IoCallDriver()
failed, status == 0x%08X\n”,
ntStatus
);
//
// set final status to failed status
//
ntStatusFinal = ntStatus;
}
else
{
DbgPrint(
“TdiBride:TdiBrideCallEx(): KeWaitForSingleObject() or IoCallDriver()
OK, status == 0x%08X\n”,
pIoStatusBlock->Status
);
//
// set final status to IRP status
//
ntStatusFinal = pIoStatusBlock->Status;
}
//
// clear event
//
KeClearEvent( pkEvent );
//
// complete request in second time
//
IoCompleteRequest(
pIrp,
IO_NO_INCREMENT
);
//
// clear last wait
//
KeWaitForSingleObject(
pkEvent,
Executive,
KernelMode,
FALSE,
NULL
);
DbgPrint(
“TdiBride:TdiBrideCallEx(): EXITing with status == 0x%08X…\n”,
ntStatusFinal
);
//
// return final status
//
return ntStatusFinal;
}
You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com