Hello,
I’m going to implement a filter driver which is to be layered above a FSD.
I need to queue all incoming irps and pass them later on to the FSD
(from a worker thread created by the filter driver). In addition I need
to pass the requests in a synchronus way. I did the following:
Queue the irps, mark them pending, copy the current Irp location to
the next stack location and return STATUS_PENDING.
From the worker thread I dequeue the irps and call down to the
FSD. I set a completion routine which signals an event I’m waiting for.
The following is a code snippet for processing the deqeued irps:
// this routine is called from inside the worker thread
void WorkerRoutine(PIRP pIrp, PDEVICE_OBJECT pFileSystem)
{
KEVENT event;
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
IoSetCompletionRoutine(pIrp, Completion, &event, TRUE, TRUE, TRUE );
IoCallDriver(pFileSystem, pIrp);
KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0);
}
NTSTATUS Completion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp,
IN PVOID Context )
{
KEVENT *pEvent = (KEVENT *)Context;
//
// Now we have to mark Irp as pending if necessary
//
if( Irp->PendingReturned )
{
IoMarkIrpPending( Irp );
}
KeSetEvent(pEvent, 0, FALSE);
return Irp->IoStatus.Status;
}
The code works for a few irps only, then the call to IoCallDriver()
does not return any more.
Waiting on the event does not seem to be the problem, even when
not waiting I get the same results.
Any suggestions what is wrong here?
Is it possible to queue all irps to a FSD and process them later on from
a system worker thread?
The background is that I’m having a SCSI-miniport which needs the calling
process context. So my intention is to store the context together with the
irp
and when the worker thread calls down to the FSD passing the context to
the
miniport
on a private communication route.
Any other way to get the initiator context in the miniport?
Kind regards,
Bernd