Use the share disposition to detect the direction of a pipe.
[reactos.git] / reactos / lib / kernel32 / file / npipe.c
index daba363..f926dc4 100644 (file)
@@ -72,7 +72,6 @@ CreateNamedPipeW(LPCWSTR lpName,
    HANDLE PipeHandle;
    ACCESS_MASK DesiredAccess;
    ULONG CreateOptions;
-   ULONG CreateDisposition;
    ULONG WriteModeMessage;
    ULONG ReadModeMessage;
    ULONG NonBlocking;
@@ -81,6 +80,12 @@ CreateNamedPipeW(LPCWSTR lpName,
    LARGE_INTEGER DefaultTimeOut;
    PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
 
+   if (nMaxInstances == 0 || nMaxInstances > PIPE_UNLIMITED_INSTANCES)
+   {
+      SetLastError(ERROR_INVALID_PARAMETER);
+      return INVALID_HANDLE_VALUE;
+   }
+
    Result = RtlDosPathNameToNtPathName_U((LPWSTR)lpName,
                                         &NamedPipeName,
                                         NULL,
@@ -108,77 +113,40 @@ CreateNamedPipeW(LPCWSTR lpName,
                              NULL,
                              SecurityDescriptor);
 
-   DesiredAccess = 0;
+   DesiredAccess = SYNCHRONIZE | (dwOpenMode & (WRITE_DAC | WRITE_OWNER | ACCESS_SYSTEM_SECURITY));
    ShareAccess = 0;
-   CreateDisposition = FILE_OPEN_IF;
    CreateOptions = 0;
+
    if (dwOpenMode & FILE_FLAG_WRITE_THROUGH)
-     {
-       CreateOptions = CreateOptions | FILE_WRITE_THROUGH;
-     }
+      CreateOptions = CreateOptions | FILE_WRITE_THROUGH;
+
    if (!(dwOpenMode & FILE_FLAG_OVERLAPPED))
-     {
-       CreateOptions = CreateOptions | FILE_SYNCHRONOUS_IO_NONALERT;
-     }
-   if (dwOpenMode & PIPE_ACCESS_DUPLEX)
-     {
-       CreateOptions = CreateOptions | FILE_PIPE_FULL_DUPLEX;
-       DesiredAccess |= (FILE_GENERIC_READ | FILE_GENERIC_WRITE);
-     }
-   else if (dwOpenMode & PIPE_ACCESS_INBOUND)
-     {
-       CreateOptions = CreateOptions | FILE_PIPE_INBOUND;
-       DesiredAccess |= FILE_GENERIC_READ;
-     }
-   else if (dwOpenMode & PIPE_ACCESS_OUTBOUND)
-     {
-       CreateOptions = CreateOptions | FILE_PIPE_OUTBOUND;
-       DesiredAccess |= FILE_GENERIC_WRITE;
-     }
+      CreateOptions = CreateOptions | FILE_SYNCHRONOUS_IO_NONALERT;
 
-   if (dwPipeMode & PIPE_TYPE_BYTE)
+   if (dwOpenMode & PIPE_ACCESS_OUTBOUND)
      {
-       WriteModeMessage = FILE_PIPE_BYTE_STREAM_MODE;
+       ShareAccess |= FILE_SHARE_READ;
+       DesiredAccess |= GENERIC_WRITE;
      }
-   else if (dwPipeMode & PIPE_TYPE_MESSAGE)
+   if (dwOpenMode & PIPE_ACCESS_INBOUND)
      {
-       WriteModeMessage = FILE_PIPE_MESSAGE_MODE;
+       ShareAccess |= FILE_SHARE_WRITE;
+       DesiredAccess |= GENERIC_READ;
      }
+   if (dwPipeMode & PIPE_TYPE_MESSAGE)
+      WriteModeMessage = FILE_PIPE_MESSAGE_MODE;
    else
-     {
-       WriteModeMessage = FILE_PIPE_BYTE_STREAM_MODE;
-     }
+      WriteModeMessage = FILE_PIPE_BYTE_STREAM_MODE;
 
-   if (dwPipeMode & PIPE_READMODE_BYTE)
-     {
-       ReadModeMessage = FILE_PIPE_BYTE_STREAM_MODE;
-     }
-   else if (dwPipeMode & PIPE_READMODE_MESSAGE)
-     {
-       ReadModeMessage = FILE_PIPE_MESSAGE_MODE;
-     }
+   if (dwPipeMode & PIPE_READMODE_MESSAGE)
+      ReadModeMessage = FILE_PIPE_MESSAGE_MODE;
    else
-     {
-       ReadModeMessage = FILE_PIPE_BYTE_STREAM_MODE;
-     }
+      ReadModeMessage = FILE_PIPE_BYTE_STREAM_MODE;
 
-   if (dwPipeMode & PIPE_WAIT)
-     {
-       NonBlocking = FILE_PIPE_QUEUE_OPERATION;
-     }
-   else if (dwPipeMode & PIPE_NOWAIT)
-     {
-       NonBlocking = FILE_PIPE_COMPLETE_OPERATION;
-     }
+   if (dwPipeMode & PIPE_NOWAIT)
+       NonBlocking = FILE_PIPE_COMPLETE_OPERATION;
    else
-     {
-       NonBlocking = FILE_PIPE_QUEUE_OPERATION;
-     }
-
-   if (nMaxInstances >= PIPE_UNLIMITED_INSTANCES)
-     {
-       nMaxInstances = ULONG_MAX;
-     }
+      NonBlocking = FILE_PIPE_QUEUE_OPERATION;
 
    DefaultTimeOut.QuadPart = nDefaultTimeOut * -10000LL;
 
@@ -187,7 +155,7 @@ CreateNamedPipeW(LPCWSTR lpName,
                                  &ObjectAttributes,
                                  &Iosb,
                                  ShareAccess,
-                                 CreateDisposition,
+                                 FILE_OPEN_IF,
                                  CreateOptions,
                                  WriteModeMessage,
                                  ReadModeMessage,
@@ -243,7 +211,7 @@ WaitNamedPipeW(LPCWSTR lpNamedPipeName,
    BOOL r;
    NTSTATUS Status;
    OBJECT_ATTRIBUTES ObjectAttributes;
-   NPFS_WAIT_PIPE WaitPipe;
+   FILE_PIPE_WAIT_FOR_BUFFER WaitPipe;
    HANDLE FileHandle;
    IO_STATUS_BLOCK Iosb;
 
@@ -262,7 +230,7 @@ WaitNamedPipeW(LPCWSTR lpNamedPipeName,
                              NULL,
                              NULL);
    Status = NtOpenFile(&FileHandle,
-                      FILE_GENERIC_READ,
+                      FILE_READ_ATTRIBUTES | SYNCHRONIZE,
                       &ObjectAttributes,
                       &Iosb,
                       FILE_SHARE_READ | FILE_SHARE_WRITE,
@@ -371,112 +339,93 @@ ConnectNamedPipe(IN HANDLE hNamedPipe,
 /*
  * @implemented
  */
-BOOL STDCALL
+BOOL
+STDCALL
 SetNamedPipeHandleState(HANDLE hNamedPipe,
-                       LPDWORD lpMode,
-                       LPDWORD lpMaxCollectionCount,
-                       LPDWORD lpCollectDataTimeout)
+                        LPDWORD lpMode,
+                        LPDWORD lpMaxCollectionCount,
+                        LPDWORD lpCollectDataTimeout)
 {
-   NPFS_GET_STATE GetState;
-   NPFS_SET_STATE SetState;
-   IO_STATUS_BLOCK Iosb;
-   NTSTATUS Status;
-
-   Status = NtFsControlFile(hNamedPipe,
-                           NULL,
-                           NULL,
-                           NULL,
-                           &Iosb,
-                           FSCTL_PIPE_GET_STATE,
-                           NULL,
-                           0,
-                           &GetState,
-                           sizeof(NPFS_GET_STATE));
-   if (Status == STATUS_PENDING)
-     {
-       Status = NtWaitForSingleObject(hNamedPipe,
-                                      FALSE,
-                                      NULL);
-       if (!NT_SUCCESS(Status))
-         {
-            SetLastErrorByStatus(Status);
-            return(FALSE);
-         }
-     }
-
-   if (lpMode != NULL)
-     {
-       if ((*lpMode) & PIPE_READMODE_MESSAGE)
-         {
-            SetState.ReadModeMessage = TRUE;
-         }
-       else
-         {
-            SetState.ReadModeMessage = FALSE;
-         }
-       if ((*lpMode) & PIPE_NOWAIT)
-         {
-            SetState.NonBlocking = TRUE;
-         }
-       else
-         {
-            SetState.NonBlocking = FALSE;
-         }
-       SetState.WriteModeMessage = GetState.WriteModeMessage;
-     }
-   else
-     {
-       SetState.ReadModeMessage = GetState.ReadModeMessage;
-       SetState.WriteModeMessage = GetState.WriteModeMessage;
-       SetState.NonBlocking = SetState.NonBlocking;
-     }
+    IO_STATUS_BLOCK Iosb;
+    NTSTATUS Status;
 
-   if (lpMaxCollectionCount != NULL)
-     {
-       SetState.InBufferSize = *lpMaxCollectionCount;
-     }
-   else
-     {
-       SetState.InBufferSize = GetState.InBufferSize;
-     }
-
-   SetState.OutBufferSize = GetState.OutBufferSize;
+    /* Check if the Mode is being changed */
+    if (lpMode)
+    {
+        FILE_PIPE_INFORMATION Settings;
+
+        /* Set the Completion Mode */
+        Settings.CompletionMode = (*lpMode & PIPE_NOWAIT) ?
+                                  FILE_PIPE_COMPLETE_OPERATION : FILE_PIPE_QUEUE_OPERATION;
+
+        /* Set the Read Mode */
+        Settings.ReadMode = (*lpMode & PIPE_READMODE_MESSAGE) ?
+                            FILE_PIPE_MESSAGE_MODE: FILE_PIPE_BYTE_STREAM_MODE;
+
+        /* Send the changes to the Driver */
+        Status = NtSetInformationFile(hNamedPipe,
+                                      &Iosb,
+                                      &Settings,
+                                      sizeof(FILE_PIPE_INFORMATION),
+                                      FilePipeInformation);
+        if (!NT_SUCCESS(Status))
+        {
+            SetLastErrorByStatus(Status);
+            return(FALSE);
+        }
+    }
 
-   if (lpCollectDataTimeout != NULL)
-     {
-       SetState.Timeout.QuadPart = (*lpCollectDataTimeout) * -10000LL;
-     }
-   else
-     {
-       SetState.Timeout = GetState.Timeout;
-     }
+    /* Check if the Collection count or Timeout are being changed */
+    if (lpMaxCollectionCount || lpCollectDataTimeout)
+    {
+        FILE_PIPE_REMOTE_INFORMATION RemoteSettings;
+
+        /* Setting one without the other would delete it, so we read old one */
+        if (!lpMaxCollectionCount || !lpCollectDataTimeout)
+        {
+            Status = NtQueryInformationFile(hNamedPipe,
+                                            &Iosb,
+                                            &RemoteSettings,
+                                            sizeof(FILE_PIPE_REMOTE_INFORMATION),
+                                            FilePipeRemoteInformation);
+
+            if (!NT_SUCCESS(Status))
+            {
+                SetLastErrorByStatus(Status);
+                return(FALSE);
+            }
+        }
+
+        /* Now set the new settings */
+        RemoteSettings.MaximumCollectionCount = (lpMaxCollectionCount) ?
+                                                *lpMaxCollectionCount :
+                                                RemoteSettings.MaximumCollectionCount;
+        if (lpCollectDataTimeout)
+        {
+            /* Convert it to Quad */
+            RemoteSettings.CollectDataTime.QuadPart = -(LONGLONG)
+                                                       UInt32x32To64(10000,
+                                                                     *lpCollectDataTimeout);
+        }
+
+        /* Tell the driver to change them */
+        Status = NtSetInformationFile(hNamedPipe,
+                                      &Iosb,
+                                      &RemoteSettings,
+                                      sizeof(FILE_PIPE_REMOTE_INFORMATION),
+                                      FilePipeRemoteInformation);
 
-   Status = NtFsControlFile(hNamedPipe,
-                           NULL,
-                           NULL,
-                           NULL,
-                           &Iosb,
-                           FSCTL_PIPE_SET_STATE,
-                           &SetState,
-                           sizeof(NPFS_SET_STATE),
-                           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);
+    /* All done */
+    return TRUE;
 }
 
-
 /*
  * @implemented
  */