Implemented waiting for server pipe (WaitNamedPipe()).
authorEric Kohl <eric.kohl@reactos.org>
Sat, 20 Oct 2001 15:30:07 +0000 (15:30 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Sat, 20 Oct 2001 15:30:07 +0000 (15:30 +0000)
svn path=/trunk/; revision=2305

reactos/drivers/fs/np/create.c
reactos/drivers/fs/np/fsctrl.c

index 6431bc3..d3379a0 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: create.c,v 1.8 2001/07/29 16:40:20 ekohl Exp $
+/* $Id: create.c,v 1.9 2001/10/20 15:30:07 ekohl Exp $
  *
  * COPYRIGHT:  See COPYING in the top level directory
  * PROJECT:    ReactOS kernel
@@ -28,7 +28,6 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
 {
    PIO_STACK_LOCATION IoStack;
    PFILE_OBJECT FileObject;
-   NTSTATUS Status;
    PNPFS_PIPE Pipe;
    PNPFS_FCB ClientFcb;
    PNPFS_FCB ServerFcb;
@@ -36,13 +35,16 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
    PLIST_ENTRY current_entry;
    PNPFS_DEVICE_EXTENSION DeviceExt;
    KIRQL oldIrql;
+   ULONG Disposition;
    
    DPRINT("NpfsCreate(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
    
    DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
    IoStack = IoGetCurrentIrpStackLocation(Irp);
    FileObject = IoStack->FileObject;
+   Disposition = ((IoStack->Parameters.Create.Options >> 24) & 0xff);
    DPRINT("FileObject %p\n", FileObject);
+   DPRINT("FileName %wZ\n", &FileObject->FileName);
    
    ClientFcb = ExAllocatePool(NonPagedPool, sizeof(NPFS_FCB));
    if (ClientFcb == NULL)
@@ -63,7 +65,7 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
                                    NPFS_PIPE,
                                    PipeListEntry);
        
-       if (RtlCompareUnicodeString(&Pipe->PipeName,
+       if (RtlCompareUnicodeString(&FileObject->FileName,
                                    &current->PipeName,
                                    TRUE) == 0)
          {
@@ -82,8 +84,9 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
        Irp->IoStatus.Information = 0;
        
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+       DPRINT("No pipe found!\n");
        
-       return(STATUS_UNSUCCESSFUL);
+       return(STATUS_OBJECT_NAME_NOT_FOUND);
      }
    
    Pipe = current;
@@ -104,7 +107,20 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
    Pipe->ReferenceCount++;
    
    KeUnlockMutex(&DeviceExt->PipeListLock);
-   
+
+  if (Disposition == FILE_OPEN)
+    {
+      /* do not connect to listening servers */
+      FileObject->FsContext = ClientFcb;
+
+      Irp->IoStatus.Status = STATUS_SUCCESS;
+      Irp->IoStatus.Information = 0;
+
+      IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+      return(STATUS_SUCCESS);
+    }
+
    /* search for disconnected or listening server fcb */
    current_entry = Pipe->ServerFcbListHead.Flink;
    while (current_entry != &Pipe->ServerFcbListHead)
@@ -124,12 +140,14 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
    if (current_entry == &Pipe->ServerFcbListHead)
      {
        DPRINT("No server fcb found!\n");
-       
+
+       FileObject->FsContext = ClientFcb;
+
        Irp->IoStatus.Status = STATUS_SUCCESS;
        Irp->IoStatus.Information = 0;
-       
+
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
-       
+
        return(STATUS_SUCCESS);
      }
    
@@ -145,12 +163,12 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
    
    FileObject->FsContext = ClientFcb;
    
-   Irp->IoStatus.Status = Status;
+   Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;
    
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    
-   return(Status);
+   return(STATUS_SUCCESS);
 }
 
 
@@ -295,63 +313,76 @@ 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;
-   KIRQL oldIrql;
+  PNPFS_DEVICE_EXTENSION DeviceExt;
+  PIO_STACK_LOCATION IoStack;
+  PFILE_OBJECT FileObject;
+  PNPFS_FCB Fcb;
+  PNPFS_PIPE Pipe;
+  KIRQL oldIrql;
 
-   DPRINT("NpfsClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
+  DPRINT("NpfsClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
 
-   IoStack = IoGetCurrentIrpStackLocation(Irp);
-   DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-   FileObject = IoStack->FileObject;
-   Fcb =  FileObject->FsContext;
-   Pipe = Fcb->Pipe;
+  IoStack = IoGetCurrentIrpStackLocation(Irp);
+  DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+  FileObject = IoStack->FileObject;
+  Fcb =  FileObject->FsContext;
 
-   DPRINT("Closing pipe %wZ\n", &Pipe->PipeName);
+  if (Fcb == NULL)
+    {
+      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(&DeviceExt->PipeListLock);
 
-   KeLockMutex(&DeviceExt->PipeListLock);
 
    if (Fcb->PipeEnd == FILE_PIPE_SERVER_END)
-     {
-       /* FIXME: Clean up existing connections here ?? */
-       Pipe->CurrentInstances--;
-     }
-   Pipe->ReferenceCount--;
+    {
+      /* FIXME: Clean up existing connections here ?? */
+      Pipe->CurrentInstances--;
+    }
+  Pipe->ReferenceCount--;
 
-   if ((Fcb->PipeEnd == FILE_PIPE_CLIENT_END)
-       && (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE))
-     {
-       Fcb->OtherSide->PipeState = FILE_PIPE_CLOSING_STATE;
-       Fcb->OtherSide->OtherSide = NULL;
-       Fcb->OtherSide = NULL;
-       Fcb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
-     }
+  if ((Fcb->PipeEnd == FILE_PIPE_CLIENT_END)
+      && (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE))
+    {
+      Fcb->OtherSide->PipeState = FILE_PIPE_CLOSING_STATE;
+      Fcb->OtherSide->OtherSide = NULL;
+      Fcb->OtherSide = NULL;
+      Fcb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
+    }
 
-   KeAcquireSpinLock(&Pipe->FcbListLock, &oldIrql);
-   RemoveEntryList(&Fcb->FcbListEntry);
-   KeReleaseSpinLock(&Pipe->FcbListLock, oldIrql);
-   
-   ExFreePool(Fcb);
-   FileObject->FsContext = NULL;
+  KeAcquireSpinLock(&Pipe->FcbListLock, &oldIrql);
+  RemoveEntryList(&Fcb->FcbListEntry);
+  KeReleaseSpinLock(&Pipe->FcbListLock, oldIrql);
 
-   if (Pipe->ReferenceCount == 0)
-     {
-       RtlFreeUnicodeString(&Pipe->PipeName);
-       RemoveEntryList(&Pipe->PipeListEntry);
-       ExFreePool(Pipe);
-     }
+  ExFreePool(Fcb);
+  FileObject->FsContext = NULL;
 
-   KeUnlockMutex(&DeviceExt->PipeListLock);
+  if (Pipe->ReferenceCount == 0)
+    {
+      RtlFreeUnicodeString(&Pipe->PipeName);
+      RemoveEntryList(&Pipe->PipeListEntry);
+      ExFreePool(Pipe);
+    }
 
-   Irp->IoStatus.Status = STATUS_SUCCESS;
-   Irp->IoStatus.Information = 0;
-   
-   IoCompleteRequest(Irp, IO_NO_INCREMENT);
-   
-   return(STATUS_SUCCESS);
+  KeUnlockMutex(&DeviceExt->PipeListLock);
+
+  Irp->IoStatus.Status = STATUS_SUCCESS;
+  Irp->IoStatus.Information = 0;
+
+  IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+  return(STATUS_SUCCESS);
 }
 
 /* EOF */
index 02b09fd..915737b 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: fsctrl.c,v 1.5 2001/07/29 16:40:20 ekohl Exp $
+/* $Id: fsctrl.c,v 1.6 2001/10/20 15:30:07 ekohl Exp $
  *
  * COPYRIGHT:  See COPYING in the top level directory
  * PROJECT:    ReactOS kernel
@@ -55,7 +55,8 @@ NpfsConnectPipe(PNPFS_FCB Fcb)
                                      NPFS_FCB,
                                      FcbListEntry);
        
-       if (ClientFcb->PipeState == FILE_PIPE_LISTENING_STATE)
+       if ((ClientFcb->PipeState == FILE_PIPE_LISTENING_STATE)
+           || (ClientFcb->PipeState == FILE_PIPE_DISCONNECTED_STATE))
          {
             break;
          }
@@ -63,7 +64,8 @@ NpfsConnectPipe(PNPFS_FCB Fcb)
        current_entry = current_entry->Flink;
      }
    
-   if (current_entry != &Pipe->ClientFcbListHead)
+   if ((current_entry != &Pipe->ClientFcbListHead)
+       && (ClientFcb->PipeState == FILE_PIPE_LISTENING_STATE))
      {
        /* found a listening client fcb */
        DPRINT("Listening client fcb found -- connecting\n");
@@ -82,6 +84,15 @@ NpfsConnectPipe(PNPFS_FCB Fcb)
        KeSetEvent(&ClientFcb->ConnectEvent, IO_NO_INCREMENT, FALSE);
 
      }
+   else if ((current_entry != &Pipe->ClientFcbListHead)
+           && (ClientFcb->PipeState == FILE_PIPE_DISCONNECTED_STATE))
+     {
+       /* found a disconnected client fcb */
+       DPRINT("Disconnected client fcb found - notifying client\n");
+
+       /* signal client's connect event */
+       KeSetEvent(&ClientFcb->ConnectEvent, IO_NO_INCREMENT, FALSE);
+     }
    else
      {
        /* no listening client fcb found */
@@ -141,10 +152,54 @@ NpfsDisconnectPipe(PNPFS_FCB Fcb)
 
 
 static NTSTATUS
-NpfsWaitPipe(PNPFS_FCB Fcb)
+NpfsWaitPipe(PIRP Irp,
+            PNPFS_FCB Fcb)
 {
+  PNPFS_PIPE Pipe;
+  PLIST_ENTRY current_entry;
+  PNPFS_FCB ServerFcb;
+  PNPFS_WAIT_PIPE WaitPipe;
+  NTSTATUS Status;
+
   DPRINT("NpfsWaitPipe\n");
-  return STATUS_NOT_IMPLEMENTED;
+
+  WaitPipe = (PNPFS_WAIT_PIPE)Irp->AssociatedIrp.SystemBuffer;
+  Pipe = Fcb->Pipe;
+
+  /* search for listening server */
+  current_entry = Pipe->ServerFcbListHead.Flink;
+  while (current_entry != &Pipe->ServerFcbListHead)
+    {
+      ServerFcb = CONTAINING_RECORD(current_entry,
+                                   NPFS_FCB,
+                                   FcbListEntry);
+
+      if (ServerFcb->PipeState == FILE_PIPE_LISTENING_STATE)
+       break;
+
+      current_entry = current_entry->Flink;
+    }
+
+  if (current_entry != &Pipe->ServerFcbListHead)
+    {
+      /* found a listening server fcb */
+      DPRINT("Listening server fcb found -- connecting\n");
+
+      Status = STATUS_SUCCESS;
+    }
+  else
+    {
+      /* no listening server fcb found -- wait for one */
+      Fcb->PipeState = FILE_PIPE_LISTENING_STATE;
+
+      Status = KeWaitForSingleObject(&Fcb->ConnectEvent,
+                                    UserRequest,
+                                    KernelMode,
+                                    FALSE,
+                                    &WaitPipe->Timeout);
+    }
+
+  return(Status);
 }
 
 
@@ -186,7 +241,7 @@ NpfsFileSystemControl(PDEVICE_OBJECT DeviceObject,
 
       case FSCTL_PIPE_WAIT:
        DPRINT("Waiting for pipe %wZ\n", &Pipe->PipeName);
-       Status = NpfsWaitPipe(Fcb);
+       Status = NpfsWaitPipe(Irp, Fcb);
        break;
 
       default: