- Implemented NpfsCleanup.  
- Moved most of the code from NpfsClose to NpfsCleanup.  
- If a pipe handle is closed, remove the fcb from the wait list and cancel a connecting irp if one is waiting.
Modified: trunk/reactos/drivers/fs/np/create.c
Modified: trunk/reactos/drivers/fs/np/npfs.c
Modified: trunk/reactos/drivers/fs/np/npfs.h

Modified: trunk/reactos/drivers/fs/np/create.c
--- trunk/reactos/drivers/fs/np/create.c	2005-03-25 13:02:35 UTC (rev 14309)
+++ trunk/reactos/drivers/fs/np/create.c	2005-03-25 13:40:33 UTC (rev 14310)
@@ -92,7 +92,7 @@
 	{
 	  DPRINT("Server found! Fcb %p\n", Waiter->Fcb);
 
-	  Waiter->Irp->IoStatus.Status = FILE_PIPE_CONNECTED_STATE;
+	  Waiter->Irp->IoStatus.Status = STATUS_PIPE_CONNECTED;
 	  Waiter->Irp->IoStatus.Information = 0;
 	  IoCompleteRequest(Waiter->Irp, IO_NO_INCREMENT);
 
@@ -467,10 +467,9 @@
 
            if (NewPipe)
              {
-               /* 
-                * FIXME:
-	        *   Lock the pipelist and remove the pipe from the list.
-	        */
+               KeLockMutex(&DeviceExt->PipeListLock);
+	       RemoveEntryList(&Pipe->PipeListEntry);
+               KeUnlockMutex(&DeviceExt->PipeListLock);
                RtlFreeUnicodeString(&Pipe->PipeName);
                ExFreePool(Pipe);
              }
@@ -494,10 +493,6 @@
 
    Pipe->CurrentInstances++;
 
-   KeLockMutex(&Pipe->FcbListLock);
-   InsertTailList(&Pipe->ServerFcbListHead, &Fcb->FcbListEntry);
-   KeUnlockMutex(&Pipe->FcbListLock);
-
    Fcb->Pipe = Pipe;
    Fcb->PipeEnd = FILE_PIPE_SERVER_END;
    Fcb->PipeState = FILE_PIPE_LISTENING_STATE;
@@ -511,6 +506,10 @@
 		     SynchronizationEvent,
 		     FALSE);
 
+   KeLockMutex(&Pipe->FcbListLock);
+   InsertTailList(&Pipe->ServerFcbListHead, &Fcb->FcbListEntry);
+   KeUnlockMutex(&Pipe->FcbListLock);
+
    FileObject->FsContext = Fcb;
 
    Irp->IoStatus.Status = STATUS_SUCCESS;
@@ -523,8 +522,8 @@
 
 
 NTSTATUS STDCALL
-NpfsClose(PDEVICE_OBJECT DeviceObject,
-          PIRP Irp)
+NpfsCleanup(PDEVICE_OBJECT DeviceObject,
+	    PIRP Irp)
 {
    PNPFS_DEVICE_EXTENSION DeviceExt;
    PIO_STACK_LOCATION IoStack;
@@ -533,7 +532,7 @@
    PNPFS_PIPE Pipe;
    BOOL Server;
 
-   DPRINT("NpfsClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
+   DPRINT("NpfsCleanup(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
 
    IoStack = IoGetCurrentIrpStackLocation(Irp);
    DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
@@ -552,7 +551,7 @@
    DPRINT("Fcb %x\n", Fcb);
    Pipe = Fcb->Pipe;
 
-   DPRINT("Closing pipe %wZ\n", &Pipe->PipeName);
+   DPRINT("Cleaning pipe %wZ\n", &Pipe->PipeName);
 
    KeLockMutex(&Pipe->FcbListLock);
 
@@ -562,7 +561,6 @@
    {
       /* FIXME: Clean up existing connections here ?? */
       DPRINT("Server\n");
-      Pipe->CurrentInstances--;
    }
    else
    {
@@ -573,7 +571,7 @@
    {
       if (Fcb->OtherSide)
       {
-         Fcb->OtherSide->PipeState = FILE_PIPE_CLOSING_STATE;
+         Fcb->OtherSide->PipeState = FILE_PIPE_DISCONNECTED_STATE;
          Fcb->OtherSide->OtherSide = NULL;
          /*
           * Signaling the write event. If is possible that an other
@@ -581,15 +579,119 @@
           */
          KeSetEvent(&Fcb->OtherSide->Event, IO_NO_INCREMENT, FALSE);
       }
+   }
+   else if (Fcb->PipeState == FILE_PIPE_LISTENING_STATE)
+   {
+      PLIST_ENTRY Entry;
+      PNPFS_WAITER_ENTRY WaitEntry = NULL;
+      BOOLEAN Complete = FALSE; 
+      KIRQL oldIrql;
 
-      Fcb->PipeState = 0;
+      Entry = Fcb->Pipe->WaiterListHead.Flink;
+      while (Entry != &Fcb->Pipe->WaiterListHead)
+      {
+         WaitEntry = CONTAINING_RECORD(Entry, NPFS_WAITER_ENTRY, Entry);
+	 if (WaitEntry->Fcb == Fcb)
+	 {
+            RemoveEntryList(Entry);
+	    IoAcquireCancelSpinLock(&oldIrql);
+	    if (!Irp->Cancel)
+	    {
+               IoSetCancelRoutine(WaitEntry->Irp, NULL);
+	       Complete = TRUE;
+	    }
+	    IoReleaseCancelSpinLock(oldIrql);
+	    break;
+	 }
+	 Entry = Entry->Flink;
+      }
+
+      if (Entry != &Fcb->Pipe->WaiterListHead)
+      {
+         if (Complete)
+	 {
+	    WaitEntry->Irp->IoStatus.Status = STATUS_PIPE_BROKEN;
+            WaitEntry->Irp->IoStatus.Information = 0;
+            IoCompleteRequest(WaitEntry->Irp, IO_NO_INCREMENT);
+	 }
+         ExFreePool(WaitEntry);
+      }
    }
+   Fcb->PipeState = FILE_PIPE_CLOSING_STATE;
 
+   KeUnlockMutex(&Pipe->FcbListLock);
+
+   ExAcquireFastMutex(&Fcb->DataListLock);
+   if (Fcb->Data)
+   {
+      ExFreePool(Fcb->Data);
+      Fcb->Data = NULL;
+      Fcb->ReadPtr = NULL;
+      Fcb->WritePtr = NULL;
+   }
+   ExReleaseFastMutex(&Fcb->DataListLock);
+
+   Irp->IoStatus.Status = STATUS_SUCCESS;
+   Irp->IoStatus.Information = 0;
+   IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+   DPRINT("Success!\n");
+
+   return STATUS_SUCCESS;
+}
+
+NTSTATUS STDCALL
+NpfsClose(PDEVICE_OBJECT DeviceObject,
+          PIRP Irp)
+{
+   PNPFS_DEVICE_EXTENSION DeviceExt;
+   PIO_STACK_LOCATION IoStack;
+   PFILE_OBJECT FileObject;
+   PNPFS_FCB Fcb;
+   PNPFS_PIPE Pipe;
+   BOOL Server;
+
+   DPRINT("NpfsClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
+
+   IoStack = IoGetCurrentIrpStackLocation(Irp);
+   DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+   FileObject = IoStack->FileObject;
+   Fcb = FileObject->FsContext;
+
+   if (Fcb == NULL)
+   {
+      DPRINT("Success!\n");
+      Irp->IoStatus.Status = STATUS_SUCCESS;
+      Irp->IoStatus.Information = 0;
+      IoCompleteRequest(Irp, IO_NO_INCREMENT);
+      return STATUS_SUCCESS;
+   }
+
+   DPRINT("Fcb %x\n", Fcb);
+   Pipe = Fcb->Pipe;
+
+   DPRINT("Closing pipe %wZ\n", &Pipe->PipeName);
+
+   KeLockMutex(&Pipe->FcbListLock);
+
+   Server = (Fcb->PipeEnd == FILE_PIPE_SERVER_END);
+
+   if (Server)
+   {
+      DPRINT("Server\n");
+      Pipe->CurrentInstances--;
+   }
+   else
+   {
+      DPRINT("Client\n");
+   }
+
+   ASSERT (Fcb->PipeState == FILE_PIPE_CLOSING_STATE);
+
    FileObject->FsContext = NULL;
 
    RemoveEntryList(&Fcb->FcbListEntry);
-   if (Fcb->Data)
-      ExFreePool(Fcb->Data);
+
    ExFreePool(Fcb);
 
    KeUnlockMutex(&Pipe->FcbListLock);

Modified: trunk/reactos/drivers/fs/np/npfs.c
--- trunk/reactos/drivers/fs/np/npfs.c	2005-03-25 13:02:35 UTC (rev 14309)
+++ trunk/reactos/drivers/fs/np/npfs.c	2005-03-25 13:40:33 UTC (rev 14310)
@@ -40,7 +40,7 @@
      NpfsSetInformation;
    DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = 
      NpfsQueryVolumeInformation;
-//   DriverObject->MajorFunction[IRP_MJ_CLEANUP] = NpfsCleanup;
+   DriverObject->MajorFunction[IRP_MJ_CLEANUP] = NpfsCleanup;
    DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = NpfsFlushBuffers;
 //   DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] =
 //     NpfsDirectoryControl;

Modified: trunk/reactos/drivers/fs/np/npfs.h
--- trunk/reactos/drivers/fs/np/npfs.h	2005-03-25 13:02:35 UTC (rev 14309)
+++ trunk/reactos/drivers/fs/np/npfs.h	2005-03-25 13:40:33 UTC (rev 14310)
@@ -99,6 +99,7 @@
 
 NTSTATUS STDCALL NpfsCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp);
 NTSTATUS STDCALL NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject, PIRP Irp);
+NTSTATUS STDCALL NpfsCleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp);
 NTSTATUS STDCALL NpfsClose(PDEVICE_OBJECT DeviceObject, PIRP Irp);
 
 NTSTATUS STDCALL NpfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp);