Fix some cancellation race conditions. Modified: trunk/reactos/drivers/fs/np/create.c Modified: trunk/reactos/drivers/fs/np/fsctrl.c _____
Modified: trunk/reactos/drivers/fs/np/create.c --- trunk/reactos/drivers/fs/np/create.c 2005-03-06 12:36:05 UTC (rev 13850) +++ trunk/reactos/drivers/fs/np/create.c 2005-03-06 12:37:31 UTC (rev 13851) @@ -54,10 +54,15 @@
while (CurrentEntry != &Pipe->WaiterListHead) { Waiter = CONTAINING_RECORD(CurrentEntry, NPFS_WAITER_ENTRY, Entry); - if (Waiter->Fcb->PipeState == FILE_PIPE_LISTENING_STATE) + if (Waiter->Fcb->PipeState == FILE_PIPE_LISTENING_STATE && + !Waiter->Irp->Cancel) { DPRINT("Server found! Fcb %p\n", Waiter->Fcb); - return Waiter->Fcb; + + if (IoSetCancelRoutine(Waiter->Irp, NULL) != NULL) + { + return Waiter->Fcb; + } }
CurrentEntry = CurrentEntry->Flink; _____
Modified: trunk/reactos/drivers/fs/np/fsctrl.c --- trunk/reactos/drivers/fs/np/fsctrl.c 2005-03-06 12:36:05 UTC (rev 13850) +++ trunk/reactos/drivers/fs/np/fsctrl.c 2005-03-06 12:37:31 UTC (rev 13851) @@ -25,18 +25,26 @@
PNPFS_WAITER_ENTRY Waiter;
DPRINT1("NpfsListeningCancelRoutine() called\n"); + /* FIXME: Not tested. */
+ IoReleaseCancelSpinLock(Irp->CancelIrql); + Waiter = Irp->Tail.Overlay.DriverContext[0];
+ KeLockMutex(&Waiter->Pipe->FcbListLock); RemoveEntryList(&Waiter->Entry); - ExFreePool(Waiter); + if (IoSetCancelRoutine(Waiter->Irp, NULL) == NULL) + { + KeUnlockMutex(&Waiter->Pipe->FcbListLock); + return; + } + KeUnlockMutex(&Waiter->Pipe->FcbListLock);
- IoReleaseCancelSpinLock(Irp->CancelIrql); - Irp->IoStatus.Status = STATUS_CANCELLED; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); + ExFreePool(Waiter); }
@@ -53,7 +61,7 @@
Entry->Irp = Irp; Entry->Fcb = Fcb; - InsertTailList(&Fcb->Pipe->WaiterListHead, &Entry->Entry); + Entry->Pipe = Fcb->Pipe;
IoAcquireCancelSpinLock(&OldIrql); if (!Irp->Cancel) @@ -61,14 +69,15 @@ Irp->Tail.Overlay.DriverContext[0] = Entry; IoMarkIrpPending(Irp); IoSetCancelRoutine(Irp, NpfsListeningCancelRoutine); + KeLockMutex(&Fcb->Pipe->FcbListLock); + InsertTailList(&Fcb->Pipe->WaiterListHead, &Entry->Entry); + KeUnlockMutex(&Fcb->Pipe->FcbListLock); IoReleaseCancelSpinLock(OldIrql); return STATUS_PENDING; } /* IRP has already been cancelled */ IoReleaseCancelSpinLock(OldIrql);
- DPRINT1("FIXME: Remove waiter entry!\n"); - RemoveEntryList(&Entry->Entry); ExFreePool(Entry);
return STATUS_CANCELLED;