all,
i am reviewing a sample driver where I find that the folks have tried to
serialize IRP completion.
So this code, when it gets an IRP_MJ_WRITE, goes ahead and spawns another
IRP to write some meta data on the disk corresponding to the original IRP.
So, in essence one write becomes into two writes (on the same disk).
This is done in the main write handler, and these folks are calling their
IRP rolling function from inside the write handler of the main IRP.
To make these two IOs synchronous and so that the original IRP is blocked
till they update their own meta data, they do the following:
KEVENT event;
KeInitializeEvent(&event, NotificationEvent, FALSE);
irp = IoAllocateIrp( TopOfDeviceStack->StackSize, FALSE );
IoSetCompletionRoutine(irp,
CompRoutine,
(PVOID ) &event,
TRUE,
TRUE,
TRUE);
status =IoCallDriver(TopOfDeviceStack, irp);
if (status == STATUS_PENDING)
{
// wait for the result
(void) KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
// set the final result of this Write IRP
status = irp->IoStatus.Status;
}
IoFreeIrp(irp);
Now in the completion routine CompRoutine() they are sending a varaible
allocated from teh stack of this function, the event, I am not sure if that
is valid. is there a possibility that the irp they roll will be completed
in a different thread context?
here is the code of the completion routine, which seems to be a only
setting the event for this the original thread is waiting in the
KeWaitForSingleObject…
NTSTATUS
CompRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{
PKEVENT pEvent= (PKEVENT)Context;
PDEVICE_OBJECT VDev= DeviceObject;
if(VDev==NULL || Irp ==NULL)
{
}
if(NULL == Context)
{
//Something looks to be gone bad ,lets hang the system to findout what.
}else
{
KeSetEvent(pEvent, (KPRIORITY) 0, FALSE);
}
return STATUS_MORE_PROCESSING_REQUIRED;
}
//