- fixed ConnectNamedPipe to properly wait on completion for synchronous operations 
- prevent completion port notification by not passing an APC context to the kernel when the low-order bit of the event handle is set (for asynchronous operations)
Modified: trunk/reactos/lib/kernel32/file/npipe.c

Modified: trunk/reactos/lib/kernel32/file/npipe.c
--- trunk/reactos/lib/kernel32/file/npipe.c	2005-05-06 16:05:37 UTC (rev 15047)
+++ trunk/reactos/lib/kernel32/file/npipe.c	2005-05-06 16:07:51 UTC (rev 15048)
@@ -300,55 +300,71 @@
  * @implemented
  */
 BOOL STDCALL
-ConnectNamedPipe(HANDLE hNamedPipe,
-		 LPOVERLAPPED lpOverlapped)
+ConnectNamedPipe(IN HANDLE hNamedPipe,
+                 IN LPOVERLAPPED lpOverlapped)
 {
-  PIO_STATUS_BLOCK IoStatusBlock;
-  IO_STATUS_BLOCK Iosb;
-  HANDLE hEvent;
-  NTSTATUS Status;
+   NTSTATUS Status;
+   
+   if (lpOverlapped != NULL)
+     {
+        PVOID ApcContext;
+        
+        lpOverlapped->Internal = STATUS_PENDING;
+        ApcContext = (((ULONG_PTR)lpOverlapped->hEvent & 0x1) ? NULL : lpOverlapped);
+        
+        Status = NtFsControlFile(hNamedPipe,
+                                 lpOverlapped->hEvent,
+                                 NULL,
+                                 ApcContext,
+                                 (PIO_STATUS_BLOCK)lpOverlapped,
+                                 FSCTL_PIPE_LISTEN,
+                                 NULL,
+                                 0,
+                                 NULL,
+                                 0);
 
-  if (lpOverlapped != NULL)
-    {
-      lpOverlapped->Internal = STATUS_PENDING;
-      hEvent = lpOverlapped->hEvent;
-      IoStatusBlock = (PIO_STATUS_BLOCK)lpOverlapped;
-    }
-  else
-    {
-      IoStatusBlock = &Iosb;
-      hEvent = NULL;
-    }
+        /* return FALSE in case of failure and pending operations! */
+        if (!NT_SUCCESS(Status) || Status == STATUS_PENDING)
+          {
+             SetLastErrorByStatus(Status);
+             return FALSE;
+          }
+     }
+   else
+     {
+        IO_STATUS_BLOCK Iosb;
+        
+        Status = NtFsControlFile(hNamedPipe,
+                                 NULL,
+                                 NULL,
+                                 NULL,
+                                 &Iosb,
+                                 FSCTL_PIPE_LISTEN,
+                                 NULL,
+                                 0,
+                                 NULL,
+                                 0);
 
-  Status = NtFsControlFile(hNamedPipe,
-			   hEvent,
-			   NULL,
-			   NULL,
-			   IoStatusBlock,
-			   FSCTL_PIPE_LISTEN,
-			   NULL,
-			   0,
-			   NULL,
-			   0);
-  if ((lpOverlapped == NULL) && (Status == STATUS_PENDING))
-    {
-      Status = NtWaitForSingleObject(hNamedPipe,
-				     FALSE,
-				     NULL);
-      if (NT_SUCCESS(Status))
-	{
-	  Status = Iosb.Status;
-	}
-    }
+        /* wait in case operation is pending */
+        if (Status == STATUS_PENDING)
+          {
+             Status = NtWaitForSingleObject(hNamedPipe,
+                                            FALSE,
+                                            NULL);
+             if (NT_SUCCESS(Status))
+               {
+                  Status = Iosb.Status;
+               }
+          }
 
-  if ((!NT_SUCCESS(Status) && Status != STATUS_PIPE_CONNECTED) ||
-      (Status == STATUS_PENDING))
-    {
-      SetLastErrorByStatus(Status);
-      return FALSE;
-    }
+        if (!NT_SUCCESS(Status))
+          {
+             SetLastErrorByStatus(Status);
+             return FALSE;
+          }
+     }
 
-  return TRUE;
+   return TRUE;
 }