Context = (PMSFS_DPC_CTX)DeferredContext;
+ /* Try to get the IRP */
Irp = IoCsqRemoveIrp(Context->Csq, &Context->CsqContext);
if (Irp != NULL)
{
+ /* It timed out, complete it (it's ours) and free context */
Irp->IoStatus.Status = STATUS_IO_TIMEOUT;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ ExFreePoolWithTag(Context, 'NFsM');
+ }
+ else
+ {
+ /* We were racing with writing and failed, signal we're done */
+ KeSetEvent(&Context->Event, IO_NO_INCREMENT, FALSE);
}
-
- ExFreePool(Context);
}
/* EOF */
return STATUS_INSUFFICIENT_RESOURCES;
}
+ KeInitializeEvent(&Context->Event, SynchronizationEvent, FALSE);
IoCsqInsertIrp(&Fcb->CancelSafeQueue, Irp, &Context->CsqContext);
Timer = &Context->Timer;
Dpc = &Context->Dpc;
Context->Csq = &Fcb->CancelSafeQueue;
+ Irp->Tail.Overlay.DriverContext[0] = Context;
/* No timer for INFINITY_WAIT */
if (Timeout.QuadPart != -1)
ULONG Length;
PVOID Buffer;
PIRP CsqIrp;
+ PMSFS_DPC_CTX Context;
DPRINT("MsfsWrite(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
CsqIrp = IoCsqRemoveNextIrp(&Fcb->CancelSafeQueue, NULL);
if (CsqIrp != NULL)
{
- /* FIXME: It is necessary to reset the timers. */
+ /* Get the context */
+ Context = CsqIrp->Tail.Overlay.DriverContext[0];
+ /* DPC was queued, wait for it to fail (IRP is ours) */
+ if (Fcb->TimeOut.QuadPart != -1 && !KeCancelTimer(&Context->Timer))
+ {
+ KeWaitForSingleObject(&Context->Event, Executive, KernelMode, FALSE, NULL);
+ }
+
+ /* Free context & attempt read */
+ ExFreePoolWithTag(Context, 'NFsM');
MsfsRead(DeviceObject, CsqIrp);
}