- Fix PeekNamedPipe. Now only 14 winetests fail for pipetest.
authorAlex Ionescu <aionescu@gmail.com>
Wed, 9 Nov 2005 04:32:44 +0000 (04:32 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Wed, 9 Nov 2005 04:32:44 +0000 (04:32 +0000)
- Cleanup DisconnectNamedPipe and fix a small bug in it.

svn path=/trunk/; revision=19088

reactos/lib/kernel32/file/npipe.c

index 7048002..1ba72cf 100644 (file)
@@ -760,43 +760,42 @@ CallNamedPipeW(LPCWSTR lpNamedPipeName,
 /*
  * @implemented
  */
-BOOL STDCALL
+BOOL 
+WINAPI
 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)
+    /* Send the FSCTL to the driver */
+    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);
-       }
+        /* Wait on NPFS to finish and get updated status */
+        Status = NtWaitForSingleObject(hNamedPipe, FALSE, NULL);
+        if (NT_SUCCESS(Status)) Status = Iosb.Status;
     }
 
-  if (!NT_SUCCESS(Status))
+    /* Check for error */
+    if (!NT_SUCCESS(Status))
     {
-      SetLastErrorByStatus(Status);
-      return(FALSE);
-    }
-  return(TRUE);
+        /* Fail */
+        SetLastErrorByStatus(Status);
+        return FALSE;
+       }
+    
+    return TRUE;
 }
 
-
 /*
  * @unimplemented
  */
@@ -989,91 +988,92 @@ GetNamedPipeInfo(HANDLE hNamedPipe,
   return(TRUE);
 }
 
-
 /*
  * @implemented
  */
-BOOL STDCALL
+BOOL
+WINAPI
 PeekNamedPipe(HANDLE hNamedPipe,
-             LPVOID lpBuffer,
-             DWORD nBufferSize,
-             LPDWORD lpBytesRead,
-             LPDWORD lpTotalBytesAvail,
-             LPDWORD lpBytesLeftThisMessage)
+              LPVOID lpBuffer,
+              DWORD nBufferSize,
+              LPDWORD lpBytesRead,
+              LPDWORD lpTotalBytesAvail,
+              LPDWORD lpBytesLeftThisMessage)
 {
-  PFILE_PIPE_PEEK_BUFFER Buffer;
-  IO_STATUS_BLOCK Iosb;
-  ULONG BufferSize;
-  NTSTATUS Status;
+    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;
-    }
+    /* Calculate the buffer space that we'll need and allocate it */
+    BufferSize = nBufferSize + FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0]);
+    Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferSize);
 
-  if (Status == STATUS_BUFFER_OVERFLOW)
+    /* Tell the driver to seek */
+    Status = NtFsControlFile(hNamedPipe,
+                             NULL,
+                             NULL,
+                             NULL,
+                             &Iosb,
+                             FSCTL_PIPE_PEEK,
+                             NULL,
+                             0,
+                             Buffer,
+                             BufferSize);
+    if (Status == STATUS_PENDING)
     {
-      Status = STATUS_SUCCESS;
+        /* Wait for npfs to be done, and update the status */
+        Status = NtWaitForSingleObject(hNamedPipe, FALSE, NULL);
+        if (NT_SUCCESS(Status)) Status = Iosb.Status;
     }
 
-  if (!NT_SUCCESS(Status))
-    {
-      RtlFreeHeap(RtlGetProcessHeap(),
-                 0,
-                 Buffer);
-      SetLastErrorByStatus(Status);
-      return(FALSE);
-    }
+    /* Overflow is success for us */
+    if (Status == STATUS_BUFFER_OVERFLOW) Status = STATUS_SUCCESS;
 
-  if (lpTotalBytesAvail != NULL)
+    /* If we failed */
+    if (!NT_SUCCESS(Status))
     {
-      *lpTotalBytesAvail = Buffer->ReadDataAvailable;
+        /* Free the buffer and return failure */
+        RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
+        SetLastErrorByStatus(Status);
+        return FALSE;
     }
 
-  if (lpBytesRead != NULL)
+    /* Check if caller requested bytes available */
+    if (lpTotalBytesAvail) *lpTotalBytesAvail = Buffer->ReadDataAvailable;
+
+    /* Check if caller requested bytes read */
+    if (lpBytesRead)
     {
-      *lpBytesRead = Iosb.Information - sizeof(FILE_PIPE_PEEK_BUFFER);
+        /* Calculate the bytes returned, minus our structure overhead */
+        *lpBytesRead = (ULONG)(Iosb.Information -
+                               FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0]));
     }
 
-  if (lpBytesLeftThisMessage != NULL)
+    /* Check if caller requested bytes left */
+    if (lpBytesLeftThisMessage)
     {
-      *lpBytesLeftThisMessage = Buffer->MessageLength -
-       (Iosb.Information - sizeof(FILE_PIPE_PEEK_BUFFER));
+        /* Calculate total minus what we returned and our structure overhead */
+        *lpBytesLeftThisMessage = Buffer->MessageLength -
+                                  (ULONG)(Iosb.Information -
+                                          FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0]));
     }
 
-  if (lpBuffer != NULL)
+    /* Check if the caller wanted to see the actual data */
+    if (lpBuffer)
     {
-      memcpy(lpBuffer, Buffer->Data,
-            min(nBufferSize, Iosb.Information - sizeof(FILE_PIPE_PEEK_BUFFER)));
+        /* Give him what he wants */
+        RtlCopyMemory(lpBuffer,
+                      Buffer->Data,
+                         Iosb.Information -
+                      FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0]));
     }
 
-  RtlFreeHeap(RtlGetProcessHeap(),
-             0,
-             Buffer);
-
-  return(TRUE);
+    /* Free the buffer and return success */
+    RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
+    return TRUE;
 }
 
-
 /*
  * @implemented
  */