You have to look at the internal logic.
If the lower-level driver is capable of finishing the IRP immediately,
without any queueing, then it will return some kind of status, such as
STATUS_SUCCESS or STATUS_WORLD_HAS_GONE_BAD or something else. But if it
has to queue it, then it will return STATUS_PENDING. In that case, such as
in the IRP_MJ_PNP prototype handler, you do something of the form
NSTATUS status;
KEVENT event;
KeInitializeEvent(&event);
IoSetCompletionRoutine(Irp, MyCompletion, &event, TRUE, TRUE, TRUE);
status = IoCallDriver(lowerlevel, Irp);
if(status == STATUS_PENDING)
{
KeWaitForSingleObject(&event, …other parameters here…, NULL);
status = Irp.IoStatus.Status;
}
if(!NT_SUCCESS(status))
{
…deal with failure
}
else
{
…IRP has been processed, either synchronously or asynchronously
}
NTSTATUS MyCompletion(PDEVICE_OBJECT device, PIRP Irp, PVOID context)
{
PKEVENT event = (PKEVENT)context;
…stuff
KeSetEvent(event, …);
return STATUS_MORE_PROCESSING_REQUIRED;
}
If the lower level queues up the IRP, then the event becomes signaled, and
the thread which is waiting resumes, using whatever status was set in the
IoStatus.Status field by the lower-level driver.
There is nothing that says when the thread which is released starts running.
It may even be running before the KeSetEvent returns, and you must not do
anything to the IRP after that KeSetEvent. Any race conditions that might
arise in the I/O Manager will be dealt with by the I/O Manager, and from
your viewpoint this happens by Magic. But once you do the KeSetEvent, you
should assume the IRP is no longer under your control. The thread which has
resumed might call IoCompleteRequest, which may result in the I/O Manager
freeing up the IRP before the KeSetEvent returns. Therefore, it shouldn’t
matter to you what precisely happens, or what order it happens in. You have
to assume that there is potential concurrency everywhere.
joe
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
workingmailing@163.com
Sent: Monday, August 08, 2011 10:25 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Waiting for lower level driver to complete IRP
in completion routine: we set the event, and return SMPR.
in dispatch routine, we waiting on the event.
when the event is set, the dispatch routine should have two case:
one is immediately dispatch routine will run, and the other not.
I have question here, if it is immediately dispatch routine will run, does
the return SMPR will running after it?
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