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;