Implemented read/write.
authorEric Kohl <eric.kohl@reactos.org>
Tue, 20 Nov 2001 20:35:10 +0000 (20:35 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Tue, 20 Nov 2001 20:35:10 +0000 (20:35 +0000)
svn path=/trunk/; revision=2383

reactos/drivers/fs/np/create.c
reactos/drivers/fs/np/finfo.c
reactos/drivers/fs/np/fsctrl.c
reactos/drivers/fs/np/npfs.c
reactos/drivers/fs/np/npfs.h
reactos/drivers/fs/np/rw.c
reactos/include/napi/npipe.h
reactos/lib/kernel32/file/npipe.c

index 5a81934..382fcf4 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: create.c,v 1.10 2001/10/21 18:58:31 chorns Exp $
+/* $Id: create.c,v 1.11 2001/11/20 20:34:29 ekohl Exp $
  *
  * COPYRIGHT:  See COPYING in the top level directory
  * PROJECT:    ReactOS kernel
@@ -53,6 +53,7 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
        Irp->IoStatus.Information = 0;
        
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+       DPRINT("No memory!\n");
        
        return(STATUS_NO_MEMORY);
      }
@@ -96,10 +97,18 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
    ClientFcb->OtherSide = NULL;
    ClientFcb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
    
+   /* initialize data list */
+   InitializeListHead(&ClientFcb->DataListHead);
+   KeInitializeSpinLock(&ClientFcb->DataListLock);
+   
    KeInitializeEvent(&ClientFcb->ConnectEvent,
                     SynchronizationEvent,
                     FALSE);
    
+   KeInitializeEvent(&ClientFcb->ReadEvent,
+                    SynchronizationEvent,
+                    FALSE);
+   
    KeAcquireSpinLock(&Pipe->FcbListLock, &oldIrql);
    InsertTailList(&Pipe->ClientFcbListHead, &ClientFcb->FcbListEntry);
    KeReleaseSpinLock(&Pipe->FcbListLock, oldIrql);
@@ -108,7 +117,8 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
    
    KeUnlockMutex(&DeviceExt->PipeListLock);
 
-  if (Disposition == FILE_OPEN)
+#if 0
+  if (Disposition == OPEN_EXISTING)
     {
       /* do not connect to listening servers */
       FileObject->FsContext = ClientFcb;
@@ -117,9 +127,11 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
       Irp->IoStatus.Information = 0;
 
       IoCompleteRequest(Irp, IO_NO_INCREMENT);
+      DPRINT("Success!\n");
 
       return(STATUS_SUCCESS);
     }
+#endif
 
    /* search for disconnected or listening server fcb */
    current_entry = Pipe->ServerFcbListHead.Flink;
@@ -167,6 +179,7 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
    Irp->IoStatus.Information = 0;
    
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+   DPRINT("Success!\n");
    
    return(STATUS_SUCCESS);
 }
@@ -238,11 +251,6 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
    InitializeListHead(&Pipe->ClientFcbListHead);
    KeInitializeSpinLock(&Pipe->FcbListLock);
 
-   InitializeListHead(&Pipe->ServerDataListHead);
-   KeInitializeSpinLock(&Pipe->ServerDataListLock);
-   InitializeListHead(&Pipe->ClientDataListHead);
-   KeInitializeSpinLock(&Pipe->ClientDataListLock);
-
    Pipe->PipeType = Buffer->WriteModeMessage;
    Pipe->PipeWriteMode = Buffer->WriteModeMessage;
    Pipe->PipeReadMode = Buffer->ReadModeMessage;
@@ -294,13 +302,20 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
    Fcb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
    Fcb->ReadDataAvailable = 0;
    Fcb->WriteQuotaAvailable = 0;
-//   Fcb->InBuffer = NULL;
-//   Fcb->OutBuffer = NULL;
+
+   /* initialize data list */
+   InitializeListHead(&Fcb->DataListHead);
+   KeInitializeSpinLock(&Fcb->DataListLock);
 
    KeInitializeEvent(&Fcb->ConnectEvent,
                     SynchronizationEvent,
                     FALSE);
    
+   KeInitializeEvent(&Fcb->ReadEvent,
+                    SynchronizationEvent,
+                    FALSE);
+
+
    KeUnlockMutex(&DeviceExt->PipeListLock);
    
    FileObject->FsContext = Fcb;
index e512c36..549987e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: finfo.c,v 1.2 2001/07/29 16:40:20 ekohl Exp $
+/* $Id: finfo.c,v 1.3 2001/11/20 20:34:29 ekohl Exp $
  *
  * COPYRIGHT:  See COPYING in the top level directory
  * PROJECT:    ReactOS kernel
@@ -12,7 +12,7 @@
 #include <ddk/ntddk.h>
 #include "npfs.h"
 
-//#define NDEBUG
+#define NDEBUG
 #include <debug.h>
 
 
 /* FUNCTIONS *****************************************************************/
 
 static NTSTATUS
-NpfsQueryLocalInformation(PDEVICE_OBJECT DeviceObject,
-                         PNPFS_FCB Fcb,
-                         PFILE_PIPE_LOCAL_INFORMATION Info,
-                         PULONG BufferLength)
+NpfsQueryPipeInformation(PDEVICE_OBJECT DeviceObject,
+                        PNPFS_FCB Fcb,
+                        PFILE_PIPE_INFORMATION Info,
+                        PULONG BufferLength)
 {
   PNPFS_PIPE Pipe;
 
-  DPRINT("NpfsQueryLocalInformation()\n");
+  DPRINT("NpfsQueryPipeInformation()\n");
+
+  Pipe = Fcb->Pipe;
+
+  RtlZeroMemory(Info,
+               sizeof(FILE_PIPE_INFORMATION));
+
+//  Info->PipeMode = 
+//  Info->CompletionMode = 
+
+  *BufferLength -= sizeof(FILE_PIPE_INFORMATION);
+  return(STATUS_SUCCESS);
+}
+
+
+static NTSTATUS
+NpfsQueryLocalPipeInformation(PDEVICE_OBJECT DeviceObject,
+                             PNPFS_FCB Fcb,
+                             PFILE_PIPE_LOCAL_INFORMATION Info,
+                             PULONG BufferLength)
+{
+  PNPFS_PIPE Pipe;
+
+  DPRINT("NpfsQueryLocalPipeInformation()\n");
 
   Pipe = Fcb->Pipe;
 
@@ -64,63 +87,66 @@ NTSTATUS STDCALL
 NpfsQueryInformation(PDEVICE_OBJECT DeviceObject,
                     PIRP Irp)
 {
-   PIO_STACK_LOCATION IoStack;
-   FILE_INFORMATION_CLASS FileInformationClass;
-   PFILE_OBJECT FileObject;
-   PNPFS_DEVICE_EXTENSION DeviceExtension;
-   PNPFS_FCB Fcb;
-   PNPFS_PIPE Pipe;
-   PVOID SystemBuffer;
-   ULONG BufferLength;
-   NTSTATUS Status;
-   
-   DPRINT("NpfsQueryInformation(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
-   
-   IoStack = IoGetCurrentIrpStackLocation (Irp);
-   FileInformationClass = IoStack->Parameters.QueryFile.FileInformationClass;
-   DeviceExtension = DeviceObject->DeviceExtension;
-   FileObject = IoStack->FileObject;
-   Fcb = (PNPFS_FCB)FileObject->FsContext;
-   Pipe = Fcb->Pipe;
-   
-   SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
-   BufferLength = IoStack->Parameters.QueryFile.Length;
-   
-   DPRINT("Pipe name: %wZ\n", &Pipe->PipeName);
-   DPRINT("FileInformationClass %d\n", FileInformationClass);
-   DPRINT("SystemBuffer %x\n", SystemBuffer);
-   DPRINT("BufferLength %lu\n", BufferLength);
-   
-   switch (FileInformationClass)
-     {
-     case FilePipeInformation:
-       Status = STATUS_NOT_IMPLEMENTED;
+  PIO_STACK_LOCATION IoStack;
+  FILE_INFORMATION_CLASS FileInformationClass;
+  PFILE_OBJECT FileObject;
+  PNPFS_DEVICE_EXTENSION DeviceExtension;
+  PNPFS_FCB Fcb;
+  PNPFS_PIPE Pipe;
+  PVOID SystemBuffer;
+  ULONG BufferLength;
+  NTSTATUS Status;
+  
+  DPRINT("NpfsQueryInformation(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
+  
+  IoStack = IoGetCurrentIrpStackLocation (Irp);
+  FileInformationClass = IoStack->Parameters.QueryFile.FileInformationClass;
+  DeviceExtension = DeviceObject->DeviceExtension;
+  FileObject = IoStack->FileObject;
+  Fcb = (PNPFS_FCB)FileObject->FsContext;
+  Pipe = Fcb->Pipe;
+  
+  SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
+  BufferLength = IoStack->Parameters.QueryFile.Length;
+  
+  DPRINT("Pipe name: %wZ\n", &Pipe->PipeName);
+  DPRINT("FileInformationClass %d\n", FileInformationClass);
+  DPRINT("SystemBuffer %p\n", SystemBuffer);
+  DPRINT("BufferLength %lu\n", BufferLength);
+  
+  switch (FileInformationClass)
+    {
+      case FilePipeInformation:
+       Status = NpfsQueryPipeInformation(DeviceObject,
+                                         Fcb,
+                                         SystemBuffer,
+                                         &BufferLength);
        break;
 
-     case FilePipeLocalInformation:
-       Status = NpfsQueryLocalInformation(DeviceObject,
-                                          Fcb,
-                                          SystemBuffer,
-                                          &BufferLength);
+      case FilePipeLocalInformation:
+       Status = NpfsQueryLocalPipeInformation(DeviceObject,
+                                              Fcb,
+                                              SystemBuffer,
+                                              &BufferLength);
        break;
 
-     case FilePipeRemoteInformation:
+      case FilePipeRemoteInformation:
        Status = STATUS_NOT_IMPLEMENTED;
        break;
 
-     default:
+      default:
        Status = STATUS_NOT_SUPPORTED;
-     }
-   
-   Irp->IoStatus.Status = Status;
-   if (NT_SUCCESS(Status))
-     Irp->IoStatus.Information =
-       IoStack->Parameters.QueryFile.Length - BufferLength;
-   else
-     Irp->IoStatus.Information = 0;
-   IoCompleteRequest (Irp, IO_NO_INCREMENT);
-   
-   return(Status);
+    }
+  
+  Irp->IoStatus.Status = Status;
+  if (NT_SUCCESS(Status))
+    Irp->IoStatus.Information =
+      IoStack->Parameters.QueryFile.Length - BufferLength;
+  else
+    Irp->IoStatus.Information = 0;
+  IoCompleteRequest (Irp, IO_NO_INCREMENT);
+  
+  return(Status);
 }
 
 
@@ -128,52 +154,52 @@ NTSTATUS STDCALL
 NpfsSetInformation(PDEVICE_OBJECT DeviceObject,
                   PIRP Irp)
 {
-   PIO_STACK_LOCATION IoStack;
-   FILE_INFORMATION_CLASS FileInformationClass;
-   PFILE_OBJECT FileObject;
-   PNPFS_FCB Fcb;
-   PNPFS_PIPE Pipe;
-   PVOID SystemBuffer;
-   ULONG BufferLength;
-   NTSTATUS Status;
-   
-   DPRINT("NpfsSetInformation(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
-   
-   IoStack = IoGetCurrentIrpStackLocation (Irp);
-   FileInformationClass = IoStack->Parameters.QueryFile.FileInformationClass;
-   FileObject = IoStack->FileObject;
-   Fcb = (PNPFS_FCB)FileObject->FsContext;
-   Pipe = Fcb->Pipe;
-   
-   SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
-   BufferLength = IoStack->Parameters.QueryFile.Length;
-   
-   DPRINT("Pipe name: %wZ\n", &Pipe->PipeName);
-   DPRINT("FileInformationClass %d\n", FileInformationClass);
-   DPRINT("SystemBuffer %x\n", SystemBuffer);
-   DPRINT("BufferLength %lu\n", BufferLength);
-   
-   switch (FileInformationClass)
-     {
-     case FilePipeInformation:
+  PIO_STACK_LOCATION IoStack;
+  FILE_INFORMATION_CLASS FileInformationClass;
+  PFILE_OBJECT FileObject;
+  PNPFS_FCB Fcb;
+  PNPFS_PIPE Pipe;
+  PVOID SystemBuffer;
+  ULONG BufferLength;
+  NTSTATUS Status;
+
+  DPRINT("NpfsSetInformation(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
+
+  IoStack = IoGetCurrentIrpStackLocation (Irp);
+  FileInformationClass = IoStack->Parameters.QueryFile.FileInformationClass;
+  FileObject = IoStack->FileObject;
+  Fcb = (PNPFS_FCB)FileObject->FsContext;
+  Pipe = Fcb->Pipe;
+
+  SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
+  BufferLength = IoStack->Parameters.QueryFile.Length;
+
+  DPRINT("Pipe name: %wZ\n", &Pipe->PipeName);
+  DPRINT("FileInformationClass %d\n", FileInformationClass);
+  DPRINT("SystemBuffer %p\n", SystemBuffer);
+  DPRINT("BufferLength %lu\n", BufferLength);
+
+  switch (FileInformationClass)
+    {
+      case FilePipeInformation:
        Status = STATUS_NOT_IMPLEMENTED;
        break;
-     case FilePipeLocalInformation:
+      case FilePipeLocalInformation:
        Status = STATUS_NOT_IMPLEMENTED;
        break;
-     case FilePipeRemoteInformation:
+      case FilePipeRemoteInformation:
        Status = STATUS_NOT_IMPLEMENTED;
        break;
-     default:
+      default:
        Status = STATUS_NOT_SUPPORTED;
-     }
-   
-   Irp->IoStatus.Status = Status;
-   Irp->IoStatus.Information = 0;
-   IoCompleteRequest(Irp,
-                    IO_NO_INCREMENT);
-   
-   return(Status);
+    }
+
+  Irp->IoStatus.Status = Status;
+  Irp->IoStatus.Information = 0;
+  IoCompleteRequest(Irp,
+                   IO_NO_INCREMENT);
+
+  return(Status);
 }
 
 /* EOF */
index 24d225d..a4f60e4 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: fsctrl.c,v 1.7 2001/10/21 18:58:31 chorns Exp $
+/* $Id: fsctrl.c,v 1.8 2001/11/20 20:34:29 ekohl Exp $
  *
  * COPYRIGHT:  See COPYING in the top level directory
  * PROJECT:    ReactOS kernel
@@ -351,123 +351,163 @@ NpfsSetState(
 }
 
 
+static NTSTATUS
+NpfsPeekPipe(PIRP Irp,
+            PIO_STACK_LOCATION IoStack)
+/*
+ * FUNCTION: Peek at a pipe (get information about messages)
+ * ARGUMENTS:
+ *     Irp = Pointer to I/O request packet
+ *     IoStack = Pointer to current stack location of Irp
+ * RETURNS:
+ *     Status of operation
+ */
+{
+  ULONG OutputBufferLength;
+  PNPFS_PIPE Pipe;
+  PFILE_PIPE_PEEK_BUFFER Reply;
+  PNPFS_FCB Fcb;
+  NTSTATUS Status;
+
+  DPRINT("NpfsPeekPipe\n");
+
+  OutputBufferLength = IoStack->Parameters.DeviceIoControl.OutputBufferLength;
+
+  /* Validate parameters */
+  if (OutputBufferLength < sizeof(FILE_PIPE_PEEK_BUFFER))
+    {
+      DPRINT("Buffer too small\n");
+      return(STATUS_INVALID_PARAMETER);
+    }
+
+  Fcb = IoStack->FileObject->FsContext;
+  Reply = (PFILE_PIPE_PEEK_BUFFER)Irp->AssociatedIrp.SystemBuffer;
+  Pipe = Fcb->Pipe;
+
+  Status = STATUS_NOT_IMPLEMENTED;
+
+  return(Status);
+}
+
+
+
 NTSTATUS STDCALL
 NpfsFileSystemControl(PDEVICE_OBJECT DeviceObject,
                      PIRP Irp)
 {
-   PIO_STACK_LOCATION IoStack;
-   PFILE_OBJECT FileObject;
-   NTSTATUS Status;
-   PNPFS_DEVICE_EXTENSION DeviceExt;
-   PNPFS_PIPE Pipe;
-   PNPFS_FCB Fcb;
-   
-   DPRINT("NpfsFileSystemContol(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
-   
-   DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-   IoStack = IoGetCurrentIrpStackLocation(Irp);
-   DPRINT("IoStack: %p\n", IoStack);
-   FileObject = IoStack->FileObject;
-   DPRINT("FileObject: %p\n", FileObject);
-   Fcb = FileObject->FsContext;
-   DPRINT("Fcb: %p\n", Fcb);
-   Pipe = Fcb->Pipe;
-   DPRINT("Pipe: %p\n", Pipe);
-   DPRINT("PipeName: %wZ\n", &Pipe->PipeName);
-   
-   switch (IoStack->Parameters.FileSystemControl.IoControlCode)
-     {
+  PIO_STACK_LOCATION IoStack;
+  PFILE_OBJECT FileObject;
+  NTSTATUS Status;
+  PNPFS_DEVICE_EXTENSION DeviceExt;
+  PNPFS_PIPE Pipe;
+  PNPFS_FCB Fcb;
+
+  DPRINT("NpfsFileSystemContol(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
+
+  DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+  IoStack = IoGetCurrentIrpStackLocation(Irp);
+  DPRINT("IoStack: %p\n", IoStack);
+  FileObject = IoStack->FileObject;
+  DPRINT("FileObject: %p\n", FileObject);
+  Fcb = FileObject->FsContext;
+  DPRINT("Fcb: %p\n", Fcb);
+  Pipe = Fcb->Pipe;
+  DPRINT("Pipe: %p\n", Pipe);
+  DPRINT("PipeName: %wZ\n", &Pipe->PipeName);
+
+  switch (IoStack->Parameters.FileSystemControl.IoControlCode)
+    {
       case FSCTL_PIPE_ASSIGN_EVENT:
-       DPRINT("Assign event\n");
-        Status = STATUS_NOT_IMPLEMENTED; 
-        break;
+       DPRINT("Assign event\n");
+       Status = STATUS_NOT_IMPLEMENTED;
+       break;
 
       case FSCTL_PIPE_DISCONNECT:
-             DPRINT("Disconnecting pipe %wZ\n", &Pipe->PipeName);
-             Status = NpfsDisconnectPipe(Fcb);
-             break;
+       DPRINT("Disconnecting pipe %wZ\n", &Pipe->PipeName);
+       Status = NpfsDisconnectPipe(Fcb);
+       break;
 
       case FSCTL_PIPE_LISTEN:
-             DPRINT("Connecting pipe %wZ\n", &Pipe->PipeName);
-             Status = NpfsConnectPipe(Fcb);
-             break;
+       DPRINT("Connecting pipe %wZ\n", &Pipe->PipeName);
+       Status = NpfsConnectPipe(Fcb);
+       break;
 
       case FSCTL_PIPE_PEEK:
-       DPRINT("Peek\n");
-        Status = STATUS_NOT_IMPLEMENTED; 
-        break;
+       DPRINT("Peeking pipe %wZ\n", &Pipe->PipeName);
+       Status = NpfsPeekPipe(Irp, IoStack);
+       break;
 
       case FSCTL_PIPE_QUERY_EVENT:
-       DPRINT("Query event\n");
-        Status = STATUS_NOT_IMPLEMENTED; 
-        break;
+       DPRINT("Query event\n");
+       Status = STATUS_NOT_IMPLEMENTED;
+       break;
 
       case FSCTL_PIPE_TRANSCEIVE:
-       DPRINT("Transceive\n");
-        Status = STATUS_NOT_IMPLEMENTED; 
-        break;
+       DPRINT("Transceive\n");
+       Status = STATUS_NOT_IMPLEMENTED;
+       break;
 
       case FSCTL_PIPE_WAIT:
-             DPRINT("Waiting for pipe %wZ\n", &Pipe->PipeName);
-             Status = NpfsWaitPipe(Irp, Fcb);
-             break;
+       DPRINT("Waiting for pipe %wZ\n", &Pipe->PipeName);
+       Status = NpfsWaitPipe(Irp, Fcb);
+       break;
 
       case FSCTL_PIPE_IMPERSONATE:
-       DPRINT("Impersonate\n");
-        Status = STATUS_NOT_IMPLEMENTED; 
-        break;
+       DPRINT("Impersonate\n");
+       Status = STATUS_NOT_IMPLEMENTED;
+       break;
 
       case FSCTL_PIPE_SET_CLIENT_PROCESS:
-       DPRINT("Set client process\n");
-        Status = STATUS_NOT_IMPLEMENTED; 
-        break;
+       DPRINT("Set client process\n");
+       Status = STATUS_NOT_IMPLEMENTED;
+       break;
 
       case FSCTL_PIPE_QUERY_CLIENT_PROCESS:
-       DPRINT("Query client process\n");
-        Status = STATUS_NOT_IMPLEMENTED; 
-        break;
+       DPRINT("Query client process\n");
+       Status = STATUS_NOT_IMPLEMENTED;
+       break;
 
       case FSCTL_PIPE_GET_STATE:
-       DPRINT("Get state\n");
-        Status = NpfsGetState(Irp, IoStack); 
-        break;
+       DPRINT("Get state\n");
+       Status = NpfsGetState(Irp, IoStack);
+       break;
 
       case FSCTL_PIPE_SET_STATE:
-       DPRINT("Set state\n");
-        Status = NpfsSetState(Irp, IoStack); 
-        break;
+       DPRINT("Set state\n");
+       Status = NpfsSetState(Irp, IoStack);
+       break;
 
       case FSCTL_PIPE_INTERNAL_READ:
-       DPRINT("Internal read\n");
-        Status = STATUS_NOT_IMPLEMENTED; 
-        break;
+       DPRINT("Internal read\n");
+       Status = STATUS_NOT_IMPLEMENTED;
+       break;
 
       case FSCTL_PIPE_INTERNAL_WRITE:
-       DPRINT("Internal write\n");
-        Status = STATUS_NOT_IMPLEMENTED; 
-        break;
+       DPRINT("Internal write\n");
+       Status = STATUS_NOT_IMPLEMENTED;
+       break;
 
       case FSCTL_PIPE_INTERNAL_TRANSCEIVE:
-       DPRINT("Internal transceive\n");
-        Status = STATUS_NOT_IMPLEMENTED; 
-        break;
+       DPRINT("Internal transceive\n");
+       Status = STATUS_NOT_IMPLEMENTED;
+       break;
 
       case FSCTL_PIPE_INTERNAL_READ_OVFLOW:
-       DPRINT("Internal read overflow\n");
-        Status = STATUS_NOT_IMPLEMENTED; 
-        break;
+       DPRINT("Internal read overflow\n");
+       Status = STATUS_NOT_IMPLEMENTED;
+       break;
 
       default:
-        DPRINT("IoControlCode: %x\n", IoStack->Parameters.FileSystemControl.IoControlCode)
-        Status = STATUS_UNSUCCESSFUL;
-     }
-   
-   Irp->IoStatus.Status = Status;
-   Irp->IoStatus.Information = 0;
-   
-   IoCompleteRequest(Irp, IO_NO_INCREMENT);
-   
-   return(Status);
+       DPRINT("IoControlCode: %x\n", IoStack->Parameters.FileSystemControl.IoControlCode)
+       Status = STATUS_UNSUCCESSFUL;
+    }
+
+  Irp->IoStatus.Status = Status;
+  Irp->IoStatus.Information = 0;
+
+  IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+  return(Status);
 }
 
 /* EOF */
index ef487dd..f472444 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: npfs.c,v 1.2 2001/10/21 18:58:31 chorns Exp $
+/* $Id: npfs.c,v 1.3 2001/11/20 20:34:29 ekohl Exp $
  *
  * COPYRIGHT:  See COPYING in the top level directory
  * PROJECT:    ReactOS kernel
@@ -30,7 +30,6 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
    
    DbgPrint("Named Pipe FSD 0.0.2\n");
    
-   DeviceObject->Flags = 0;
    DriverObject->MajorFunction[IRP_MJ_CREATE] = NpfsCreate;
    DriverObject->MajorFunction[IRP_MJ_CREATE_NAMED_PIPE] =
      NpfsCreateNamedPipe;
@@ -70,6 +69,9 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
        return(Status);
      }
    
+   /* initialize the device object */
+   DeviceObject->Flags = DO_DIRECT_IO;
+   
    /* initialize the device extension */
    DeviceExtension = DeviceObject->DeviceExtension;
    InitializeListHead(&DeviceExtension->PipeListHead);
index 12380a3..b8f2697 100644 (file)
@@ -4,8 +4,8 @@
 
 typedef struct
 {
-   LIST_ENTRY PipeListHead;
-   KMUTEX PipeListLock;
+  LIST_ENTRY PipeListHead;
+  KMUTEX PipeListLock;
 } NPFS_DEVICE_EXTENSION, *PNPFS_DEVICE_EXTENSION;
 
 typedef struct
@@ -18,40 +18,38 @@ typedef struct
 
 typedef struct
 {
-   UNICODE_STRING PipeName;
-   LIST_ENTRY PipeListEntry;
-   KSPIN_LOCK FcbListLock;
-   LIST_ENTRY ServerFcbListHead;
-   LIST_ENTRY ClientFcbListHead;
-   /* Server posted data */
-   LIST_ENTRY ServerDataListHead;
-   KSPIN_LOCK ServerDataListLock;
-   /* Client posted data */
-   LIST_ENTRY ClientDataListHead;
-   KSPIN_LOCK ClientDataListLock;
-   ULONG ReferenceCount;
-   ULONG PipeType;
-   ULONG PipeReadMode;
-   ULONG PipeWriteMode;
-   ULONG PipeBlockMode;
-   ULONG PipeConfiguration;
-   ULONG MaximumInstances;
-   ULONG CurrentInstances;
-   ULONG InboundQuota;
-   ULONG OutboundQuota;
-   LARGE_INTEGER TimeOut;
+  UNICODE_STRING PipeName;
+  LIST_ENTRY PipeListEntry;
+  KSPIN_LOCK FcbListLock;
+  LIST_ENTRY ServerFcbListHead;
+  LIST_ENTRY ClientFcbListHead;
+  ULONG ReferenceCount;
+  ULONG PipeType;
+  ULONG PipeReadMode;
+  ULONG PipeWriteMode;
+  ULONG PipeBlockMode;
+  ULONG PipeConfiguration;
+  ULONG MaximumInstances;
+  ULONG CurrentInstances;
+  ULONG InboundQuota;
+  ULONG OutboundQuota;
+  LARGE_INTEGER TimeOut;
 } NPFS_PIPE, *PNPFS_PIPE;
 
 typedef struct _NPFS_FCB
 {
-   LIST_ENTRY FcbListEntry;
-   struct _NPFS_FCB* OtherSide;
-   PNPFS_PIPE Pipe;
-   KEVENT ConnectEvent;
-   ULONG PipeEnd;
-   ULONG PipeState;
-   ULONG ReadDataAvailable;
-   ULONG WriteQuotaAvailable;
+  LIST_ENTRY FcbListEntry;
+  struct _NPFS_FCB* OtherSide;
+  PNPFS_PIPE Pipe;
+  KEVENT ConnectEvent;
+  KEVENT ReadEvent;
+  ULONG PipeEnd;
+  ULONG PipeState;
+  ULONG ReadDataAvailable;
+  ULONG WriteQuotaAvailable;
+
+  LIST_ENTRY DataListHead;     /* Data queue */
+  KSPIN_LOCK DataListLock;     /* Data queue lock */
 } NPFS_FCB, *PNPFS_FCB;
 
 
index 21882b3..00e2c7b 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: rw.c,v 1.4 2001/10/21 18:58:32 chorns Exp $
+/* $Id: rw.c,v 1.5 2001/11/20 20:34:29 ekohl Exp $
  *
  * COPYRIGHT:  See COPYING in the top level directory
  * PROJECT:    ReactOS kernel
 
 /* FUNCTIONS *****************************************************************/
 
-static inline VOID NpfsFreePipeData(
-  PNPFS_PIPE_DATA PipeData)
+static inline VOID
+NpfsFreePipeData(PNPFS_PIPE_DATA PipeData)
 {
   if (PipeData->Data)
-  {
-    ExFreePool(PipeData->Data);
-  }
+    {
+      ExFreePool(PipeData->Data);
+    }
 
   ExFreeToNPagedLookasideList(&NpfsPipeDataLookasideList, PipeData);
 }
 
 
 static inline PNPFS_PIPE_DATA
-NpfsAllocatePipeData(
-  PVOID Data,
-  ULONG Size)
+NpfsAllocatePipeData(PVOID Data,
+                    ULONG Size)
 {
   PNPFS_PIPE_DATA PipeData;
 
   PipeData = ExAllocateFromNPagedLookasideList(&NpfsPipeDataLookasideList);
   if (!PipeData)
-  {
-    return NULL;
-  }
+    {
+      return NULL;
+    }
 
   PipeData->Data = Data;
   PipeData->Size = Size;
@@ -90,93 +89,134 @@ NpfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
   PNPFS_PIPE_DATA Current;
   ULONG Information;
   PNPFS_FCB Fcb;
+  PNPFS_FCB ReadFcb;
   PNPFS_PIPE Pipe;
-       ULONG Length;
-       PVOID Buffer;
+  ULONG Length;
+  PVOID Buffer;
   ULONG CopyLength;
+  BOOLEAN DataListEmpty;
 
   DPRINT("NpfsRead(DeviceObject %p  Irp %p)\n", DeviceObject, Irp);
-   
+  
   DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
   IoStack = IoGetCurrentIrpStackLocation(Irp);
   FileObject = IoStack->FileObject;
   Fcb = FileObject->FsContext;
   Pipe = Fcb->Pipe;
-  Status = STATUS_SUCCESS;
-  Length = IoStack->Parameters.Read.Length;
+  ReadFcb = Fcb->OtherSide;
 
-  DPRINT("Irp->MdlAddress %p\n", Irp->MdlAddress);
-
-  Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
-  KeAcquireSpinLock(&Pipe->ServerDataListLock, &OldIrql);
+  if (ReadFcb == NULL)
+    {
+      DPRINT("Pipe is NOT connected!\n");
+      Status = STATUS_UNSUCCESSFUL;
+      Length = 0;
+      goto done;
+    }
 
-  if (Pipe->PipeReadMode & FILE_PIPE_BYTE_STREAM_MODE)
-  {
-    DPRINT("Byte stream mode\n");
+  if (Irp->MdlAddress == NULL)
+    {
+      DPRINT("Irp->MdlAddress == NULL\n");
+      Status = STATUS_UNSUCCESSFUL;
+      Length = 0;
+      goto done;
+    }
 
-    /* Byte stream mode */
-    Information = 0;
-         CurrentEntry = Pipe->ServerDataListHead.Flink;
-         while ((Length > 0) && (CurrentEntry = RemoveHeadList(&Pipe->ServerDataListHead)))
-         {
-           Current = CONTAINING_RECORD(CurrentEntry, NPFS_PIPE_DATA, ListEntry);
+  Status = STATUS_SUCCESS;
+  Length = IoStack->Parameters.Read.Length;
 
-      DPRINT("Took pipe data at %p off the queue\n", Current);
+  Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
+  DPRINT("Length %d Buffer %x\n",Length,Buffer);
 
-      CopyLength = RtlMin(Current->Size, Length);
-           RtlCopyMemory(Buffer,
-        ((PVOID)((ULONG_PTR)Current->Data + Current->Offset)),
-        CopyLength);
-           Buffer += CopyLength;
-           Length -= CopyLength;
-           Information += CopyLength;
+  KeAcquireSpinLock(&ReadFcb->DataListLock, &OldIrql);
+  DataListEmpty = IsListEmpty(&ReadFcb->DataListHead);
+  KeReleaseSpinLock(&ReadFcb->DataListLock, OldIrql);
 
-      /* Update the data buffer */
-      Current->Offset += CopyLength;
-      Current->Size -= CopyLength;
+  /* FIXME: check if in blocking mode */
+  if (DataListEmpty == TRUE)
+    {
+      /* Wait for ReadEvent to become signaled */
+      DPRINT("Waiting for readable data\n");
+      Status = KeWaitForSingleObject(&Fcb->ReadEvent,
+                                    UserRequest,
+                                    KernelMode,
+                                    FALSE,
+                                    NULL);
+      DPRINT("Finished waiting! Status: %x\n", Status);
+    }
 
-           CurrentEntry = CurrentEntry->Flink;
-         }
+  KeAcquireSpinLock(&ReadFcb->DataListLock, &OldIrql);
 
-    if ((CurrentEntry != &Pipe->ServerDataListHead) && (Current->Offset != Current->Size))
+  if (Pipe->PipeReadMode & FILE_PIPE_BYTE_STREAM_MODE)
     {
-      DPRINT("Putting pipe data at %p back in queue\n", Current);
-
-      /* The caller's buffer could not contain the complete message,
-         so put it back on the queue */
-      InsertHeadList(&Pipe->ServerDataListHead, &Current->ListEntry);
+      DPRINT("Byte stream mode\n");
+
+      /* Byte stream mode */
+      Information = 0;
+      CurrentEntry = ReadFcb->DataListHead.Flink;
+       while ((Length > 0) && (CurrentEntry = RemoveHeadList(&ReadFcb->DataListHead)))
+       {
+         Current = CONTAINING_RECORD(CurrentEntry, NPFS_PIPE_DATA, ListEntry);
+
+         DPRINT("Took pipe data at %p off the queue\n", Current);
+
+         CopyLength = RtlMin(Current->Size, Length);
+         RtlCopyMemory(Buffer,
+                       ((PVOID)((ULONG_PTR)Current->Data + Current->Offset)),
+                       CopyLength);
+         Buffer += CopyLength;
+         Length -= CopyLength;
+         Information += CopyLength;
+
+         /* Update the data buffer */
+         Current->Offset += CopyLength;
+         Current->Size -= CopyLength;
+
+         CurrentEntry = CurrentEntry->Flink;
+       }
+
+      if ((CurrentEntry != &ReadFcb->DataListHead) && (Current->Offset != Current->Size))
+       {
+         DPRINT("Putting pipe data at %p back in queue\n", Current);
+
+         /* The caller's buffer could not contain the complete message,
+            so put it back on the queue */
+         InsertHeadList(&ReadFcb->DataListHead, &Current->ListEntry);
+       }
     }
-  }
   else
-  {
-    DPRINT("Message mode\n");
+    {
+      DPRINT("Message mode\n");
 
-    /* Message mode */
-         CurrentEntry = Pipe->ServerDataListHead.Flink;
-         if (CurrentEntry = RemoveHeadList(&Pipe->ServerDataListHead))
-         {
-           Current = CONTAINING_RECORD(CurrentEntry, NPFS_PIPE_DATA, ListEntry);
+      /* Message mode */
+      CurrentEntry = ReadFcb->DataListHead.Flink;
+      if (CurrentEntry = RemoveHeadList(&ReadFcb->DataListHead))
+       {
+         Current = CONTAINING_RECORD(CurrentEntry, NPFS_PIPE_DATA, ListEntry);
 
-      DPRINT("Took pipe data at %p off the queue\n", Current);
+         DPRINT("Took pipe data at %p off the queue\n", Current);
 
-      /* Truncate the message if the receive buffer is too small */
-      CopyLength = RtlMin(Current->Size, Length);
-      RtlCopyMemory(Buffer, Current->Data, CopyLength);
-           Information = CopyLength;
+         /* Truncate the message if the receive buffer is too small */
+         CopyLength = RtlMin(Current->Size, Length);
+         RtlCopyMemory(Buffer, Current->Data, CopyLength);
+         Information = CopyLength;
 
-      Current->Offset += CopyLength;
+         Current->Offset += CopyLength;
 
-           CurrentEntry = CurrentEntry->Flink;
+         CurrentEntry = CurrentEntry->Flink;
+       }
     }
-  }
 
-  KeReleaseSpinLock(&Pipe->ServerDataListLock, OldIrql);
+  KeReleaseSpinLock(&ReadFcb->DataListLock, OldIrql);
 
+  /* reset ReaderEvent */
+  KeResetEvent(&Fcb->ReadEvent);
+
+done:
   Irp->IoStatus.Status = Status;
   Irp->IoStatus.Information = Information;
-   
+
   IoCompleteRequest(Irp, IO_NO_INCREMENT);
-   
+
   return(Status);
 }
 
@@ -207,26 +247,46 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
   Pipe = Fcb->Pipe;
 
   Length = IoStack->Parameters.Write.Length;
-  Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress);
   Offset = IoStack->Parameters.Write.ByteOffset.u.LowPart;
 
+  if (Irp->MdlAddress == NULL)
+    {
+      DbgPrint ("Irp->MdlAddress == NULL\n");
+      Status = STATUS_UNSUCCESSFUL;
+      Length = 0;
+      goto done;
+    }
+
+  if (Fcb->OtherSide == NULL)
+    {
+      DPRINT("Pipe is NOT connected!\n");
+      Status = STATUS_UNSUCCESSFUL;
+      Length = 0;
+      goto done;
+    }
+
+  Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress);
+  DPRINT("Length %d Buffer %x Offset %x\n",Length,Buffer,Offset);
+
   PipeData = NpfsInitializePipeData(Buffer, Length);
   if (PipeData)
-  {
-    DPRINT("Attaching pipe data at %p (%d bytes)\n", PipeData, Length);
-
-    KeAcquireSpinLock(&Pipe->ServerDataListLock, &OldIrql);
+    {
+      DPRINT("Attaching pipe data at %p (%d bytes)\n", PipeData, Length);
 
-    InsertTailList(&Pipe->ServerDataListHead, &PipeData->ListEntry);
+      KeAcquireSpinLock(&Fcb->DataListLock, &OldIrql);
+      InsertTailList(&Fcb->DataListHead, &PipeData->ListEntry);
+      KeReleaseSpinLock(&Fcb->DataListLock, OldIrql);
 
-    KeReleaseSpinLock(&Pipe->ServerDataListLock, OldIrql);
-  }
+      /* signal the readers ReadEvent */
+      KeSetEvent(&Fcb->OtherSide->ConnectEvent, IO_NO_INCREMENT, FALSE);
+    }
   else
-  {
-    Length = 0;
-    Status = STATUS_INSUFFICIENT_RESOURCES;
-  }
+    {
+      Length = 0;
+      Status = STATUS_INSUFFICIENT_RESOURCES;
+    }
 
+done:
   Irp->IoStatus.Status = Status;
   Irp->IoStatus.Information = Length;
   
index 7610101..b89972f 100644 (file)
@@ -159,6 +159,14 @@ typedef struct _NPFS_GET_STATE
    LARGE_INTEGER Timeout;
 } NPFS_GET_STATE, *PNPFS_GET_STATE;
 
+typedef struct _FILE_PIPE_PEEK_BUFFER
+{
+  ULONG NamedPipeState;
+  ULONG ReadDataAvailable;
+  ULONG NumberOfMessages;
+  ULONG MessageLength;
+  CHAR Data[1];
+} FILE_PIPE_PEEK_BUFFER, *PFILE_PIPE_PEEK_BUFFER;
 
 #define FILE_PIPE_BYTE_STREAM_TYPE     0x00000000
 #define FILE_PIPE_MESSAGE_TYPE         0x00000001
index 24249e5..eb2503b 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: npipe.c,v 1.8 2001/10/21 19:06:42 chorns Exp $
+/* $Id: npipe.c,v 1.9 2001/11/20 20:35:10 ekohl Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
@@ -441,7 +441,7 @@ SetNamedPipeHandleState(HANDLE hNamedPipe,
 }
 
 
-WINBOOL STDCALL
+BOOL STDCALL
 CallNamedPipeA(LPCSTR lpNamedPipeName,
               LPVOID lpInBuffer,
               DWORD nInBufferSize,
@@ -450,12 +450,27 @@ CallNamedPipeA(LPCSTR lpNamedPipeName,
               LPDWORD lpBytesRead,
               DWORD nTimeOut)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+  UNICODE_STRING PipeName;
+  BOOL Result;
+  
+  RtlCreateUnicodeStringFromAsciiz(&PipeName,
+                                  (LPSTR)lpNamedPipeName);
+  
+  Result = CallNamedPipeW(PipeName.Buffer,
+                         lpInBuffer,
+                         nInBufferSize,
+                         lpOutBuffer,
+                         nOutBufferSize,
+                         lpBytesRead,
+                         nTimeOut);
+  
+  RtlFreeUnicodeString(&PipeName);
+  
+  return(Result);
 }
 
 
-WINBOOL STDCALL
+BOOL STDCALL
 CallNamedPipeW(LPCWSTR lpNamedPipeName,
               LPVOID lpInBuffer,
               DWORD nInBufferSize,
@@ -464,45 +479,45 @@ CallNamedPipeW(LPCWSTR lpNamedPipeName,
               LPDWORD lpBytesRead,
               DWORD nTimeOut)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
 }
 
 
-WINBOOL STDCALL
+BOOL STDCALL
 DisconnectNamedPipe(HANDLE hNamedPipe)
 {
-   IO_STATUS_BLOCK Iosb;
-   NTSTATUS Status;
+  IO_STATUS_BLOCK Iosb;
+  NTSTATUS Status;
 
-   Status = NtFsControlFile(hNamedPipe,
-                           NULL,
-                           NULL,
-                           NULL,
-                           &Iosb,
-                           FSCTL_PIPE_DISCONNECT,
-                           NULL,
-                           0,
-                           NULL,
-                           0);
-   if (Status == STATUS_PENDING)
-     {
-       Status = NtWaitForSingleObject(hNamedPipe,
-                                      FALSE,
-                                      NULL);
-       if (!NT_SUCCESS(Status))
-         {
-            SetLastErrorByStatus(Status);
-            return(FALSE);
-         }
-     }
+  Status = NtFsControlFile(hNamedPipe,
+                          NULL,
+                          NULL,
+                          NULL,
+                          &Iosb,
+                          FSCTL_PIPE_DISCONNECT,
+                          NULL,
+                          0,
+                          NULL,
+                          0);
+  if (Status == STATUS_PENDING)
+    {
+      Status = NtWaitForSingleObject(hNamedPipe,
+                                    FALSE,
+                                    NULL);
+      if (!NT_SUCCESS(Status))
+       {
+         SetLastErrorByStatus(Status);
+         return(FALSE);
+       }
+    }
 
-   if (!NT_SUCCESS(Status))
-     {
-       SetLastErrorByStatus(Status);
-       return(FALSE);
-     }
-   return(TRUE);
+  if (!NT_SUCCESS(Status))
+    {
+      SetLastErrorByStatus(Status);
+      return(FALSE);
+    }
+  return(TRUE);
 }
 
 
@@ -515,8 +530,46 @@ GetNamedPipeHandleStateW(HANDLE hNamedPipe,
                         LPWSTR lpUserName,
                         DWORD nMaxUserNameSize)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+  FILE_PIPE_LOCAL_INFORMATION LocalInfo;
+  FILE_PIPE_INFORMATION PipeInfo;
+  IO_STATUS_BLOCK StatusBlock;
+  NTSTATUS Status;
+
+  if (lpState != NULL)
+    {
+      Status = NtQueryInformationFile(hNamedPipe,
+                                     &StatusBlock,
+                                     &PipeInfo,
+                                     sizeof(FILE_PIPE_INFORMATION),
+                                     FilePipeInformation);
+      if (!NT_SUCCESS(Status))
+       {
+         SetLastErrorByStatus(Status);
+         return(FALSE);
+       }
+      *lpState = 0; /* FIXME */
+    }
+
+  if (lpCurInstances != NULL)
+    {
+      Status = NtQueryInformationFile(hNamedPipe,
+                                     &StatusBlock,
+                                     &LocalInfo,
+                                     sizeof(FILE_PIPE_LOCAL_INFORMATION),
+                                     FilePipeLocalInformation);
+      if (!NT_SUCCESS(Status))
+       {
+         SetLastErrorByStatus(Status);
+         return(FALSE);
+       }
+      *lpCurInstances = min(LocalInfo.CurrentInstances, 255);
+    }
+
+
+  /* FIXME: retrieve remaining information */
+
+
+  return(TRUE);
 }
 
 
@@ -580,7 +633,7 @@ GetNamedPipeInfo(HANDLE hNamedPipe,
 }
 
 
-WINBOOL STDCALL
+BOOL STDCALL
 PeekNamedPipe(HANDLE hNamedPipe,
              LPVOID lpBuffer,
              DWORD nBufferSize,
@@ -588,12 +641,80 @@ PeekNamedPipe(HANDLE hNamedPipe,
              LPDWORD lpTotalBytesAvail,
              LPDWORD lpBytesLeftThisMessage)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+  PFILE_PIPE_PEEK_BUFFER Buffer;
+  IO_STATUS_BLOCK Iosb;
+  ULONG BufferSize;
+  NTSTATUS Status;
+
+  BufferSize = nBufferSize + sizeof(FILE_PIPE_PEEK_BUFFER);
+  Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
+                          0,
+                          BufferSize);
+
+  Status = NtFsControlFile(hNamedPipe,
+                          NULL,
+                          NULL,
+                          NULL,
+                          &Iosb,
+                          FSCTL_PIPE_PEEK,
+                          NULL,
+                          0,
+                          Buffer,
+                          BufferSize);
+  if (Status == STATUS_PENDING)
+    {
+      Status = NtWaitForSingleObject(hNamedPipe,
+                                    FALSE,
+                                    NULL);
+      if (NT_SUCCESS(Status))
+       Status = Iosb.Status;
+    }
+
+  if (Status == STATUS_BUFFER_OVERFLOW)
+    {
+      Status = STATUS_SUCCESS;
+    }
+
+  if (!NT_SUCCESS(Status))
+    {
+      RtlFreeHeap(RtlGetProcessHeap(),
+                 0,
+                 Buffer);
+      SetLastErrorByStatus(Status);
+      return(FALSE);
+    }
+
+  if (lpTotalBytesAvail != NULL)
+    {
+      *lpTotalBytesAvail = Buffer->ReadDataAvailable;
+    }
+
+  if (lpBytesRead != NULL)
+    {
+      *lpBytesRead = Iosb.Information - sizeof(FILE_PIPE_PEEK_BUFFER);
+    }
+
+  if (lpBytesLeftThisMessage != NULL)
+    {
+      *lpBytesLeftThisMessage = Buffer->MessageLength -
+       (Iosb.Information - sizeof(FILE_PIPE_PEEK_BUFFER));
+    }
+
+  if (lpBuffer != NULL)
+    {
+      memcpy(lpBuffer, Buffer->Data,
+            min(nBufferSize, Iosb.Information - sizeof(FILE_PIPE_PEEK_BUFFER)));
+    }
+
+  RtlFreeHeap(RtlGetProcessHeap(),
+             0,
+             Buffer);
+
+  return(TRUE);
 }
 
 
-WINBOOL STDCALL
+BOOL STDCALL
 TransactNamedPipe(HANDLE hNamedPipe,
                  LPVOID lpInBuffer,
                  DWORD nInBufferSize,