Fix some cancellation race conditions.

svn path=/trunk/; revision=13851
This commit is contained in:
Filip Navara 2005-03-06 12:37:31 +00:00
parent fb22000d1c
commit ca4d8c0923
2 changed files with 22 additions and 8 deletions

View file

@ -54,10 +54,15 @@ NpfsFindListeningServerInstance(PNPFS_PIPE Pipe)
while (CurrentEntry != &Pipe->WaiterListHead) while (CurrentEntry != &Pipe->WaiterListHead)
{ {
Waiter = CONTAINING_RECORD(CurrentEntry, NPFS_WAITER_ENTRY, Entry); 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); DPRINT("Server found! Fcb %p\n", Waiter->Fcb);
return Waiter->Fcb;
if (IoSetCancelRoutine(Waiter->Irp, NULL) != NULL)
{
return Waiter->Fcb;
}
} }
CurrentEntry = CurrentEntry->Flink; CurrentEntry = CurrentEntry->Flink;

View file

@ -25,18 +25,26 @@ NpfsListeningCancelRoutine(IN PDEVICE_OBJECT DeviceObject,
PNPFS_WAITER_ENTRY Waiter; PNPFS_WAITER_ENTRY Waiter;
DPRINT1("NpfsListeningCancelRoutine() called\n"); DPRINT1("NpfsListeningCancelRoutine() called\n");
/* FIXME: Not tested. */ /* FIXME: Not tested. */
IoReleaseCancelSpinLock(Irp->CancelIrql);
Waiter = Irp->Tail.Overlay.DriverContext[0]; Waiter = Irp->Tail.Overlay.DriverContext[0];
KeLockMutex(&Waiter->Pipe->FcbListLock);
RemoveEntryList(&Waiter->Entry); RemoveEntryList(&Waiter->Entry);
ExFreePool(Waiter); if (IoSetCancelRoutine(Waiter->Irp, NULL) == NULL)
{
IoReleaseCancelSpinLock(Irp->CancelIrql); KeUnlockMutex(&Waiter->Pipe->FcbListLock);
return;
}
KeUnlockMutex(&Waiter->Pipe->FcbListLock);
Irp->IoStatus.Status = STATUS_CANCELLED; Irp->IoStatus.Status = STATUS_CANCELLED;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
ExFreePool(Waiter);
} }
@ -53,7 +61,7 @@ NpfsAddListeningServerInstance(PIRP Irp,
Entry->Irp = Irp; Entry->Irp = Irp;
Entry->Fcb = Fcb; Entry->Fcb = Fcb;
InsertTailList(&Fcb->Pipe->WaiterListHead, &Entry->Entry); Entry->Pipe = Fcb->Pipe;
IoAcquireCancelSpinLock(&OldIrql); IoAcquireCancelSpinLock(&OldIrql);
if (!Irp->Cancel) if (!Irp->Cancel)
@ -61,14 +69,15 @@ NpfsAddListeningServerInstance(PIRP Irp,
Irp->Tail.Overlay.DriverContext[0] = Entry; Irp->Tail.Overlay.DriverContext[0] = Entry;
IoMarkIrpPending(Irp); IoMarkIrpPending(Irp);
IoSetCancelRoutine(Irp, NpfsListeningCancelRoutine); IoSetCancelRoutine(Irp, NpfsListeningCancelRoutine);
KeLockMutex(&Fcb->Pipe->FcbListLock);
InsertTailList(&Fcb->Pipe->WaiterListHead, &Entry->Entry);
KeUnlockMutex(&Fcb->Pipe->FcbListLock);
IoReleaseCancelSpinLock(OldIrql); IoReleaseCancelSpinLock(OldIrql);
return STATUS_PENDING; return STATUS_PENDING;
} }
/* IRP has already been cancelled */ /* IRP has already been cancelled */
IoReleaseCancelSpinLock(OldIrql); IoReleaseCancelSpinLock(OldIrql);
DPRINT1("FIXME: Remove waiter entry!\n");
RemoveEntryList(&Entry->Entry);
ExFreePool(Entry); ExFreePool(Entry);
return STATUS_CANCELLED; return STATUS_CANCELLED;