Added anonymous pipe support

diff --git a/scheduler/Makefile.in b/scheduler/Makefile.in
index 26b91e0..c21919d 100644
--- a/scheduler/Makefile.in
+++ b/scheduler/Makefile.in
@@ -12,6 +12,7 @@
 	handle.c \
 	k32obj.c \
 	mutex.c \
+	pipe.c \
 	process.c \
 	semaphore.c \
 	synchro.c \
diff --git a/scheduler/k32obj.c b/scheduler/k32obj.c
index d191c12..d8aca63 100644
--- a/scheduler/k32obj.c
+++ b/scheduler/k32obj.c
@@ -26,6 +26,7 @@
 extern const K32OBJ_OPS SEMAPHORE_Ops;
 extern const K32OBJ_OPS EVENT_Ops;
 extern const K32OBJ_OPS MUTEX_Ops;
+extern const K32OBJ_OPS PIPE_Ops;
 
 static const K32OBJ_OPS K32OBJ_NullOps =
 {
@@ -54,7 +55,7 @@
     &MEM_MAPPED_FILE_Ops,   /* K32OBJ_MEM_MAPPED_FILE */
     &K32OBJ_NullOps,        /* K32OBJ_SERIAL */
     &DEVICE_Ops,            /* K32OBJ_DEVICE_IOCTL */
-    &K32OBJ_NullOps,        /* K32OBJ_PIPE */
+    &PIPE_Ops,              /* K32OBJ_PIPE */
     &K32OBJ_NullOps,        /* K32OBJ_MAILSLOT */
     &K32OBJ_NullOps,        /* K32OBJ_TOOLHELP_SNAPSHOT */
     &K32OBJ_NullOps         /* K32OBJ_SOCKET */
diff --git a/scheduler/pipe.c b/scheduler/pipe.c
new file mode 100644
index 0000000..8548013
--- /dev/null
+++ b/scheduler/pipe.c
@@ -0,0 +1,92 @@
+/*
+ * Win32 pipes
+ *
+ * Copyright 1998 Alexandre Julliard
+ */
+
+#include <assert.h>
+#include "windows.h"
+#include "winerror.h"
+#include "k32obj.h"
+#include "process.h"
+#include "thread.h"
+#include "heap.h"
+#include "server/request.h"
+#include "server.h"
+
+typedef struct _PIPE
+{
+    K32OBJ         header;
+} PIPE;
+
+static void PIPE_Destroy( K32OBJ *obj );
+
+const K32OBJ_OPS PIPE_Ops =
+{
+    NULL,             /* signaled */
+    NULL,             /* satisfied */
+    NULL,             /* add_wait */
+    NULL,             /* remove_wait */
+    NULL,             /* read */
+    NULL,             /* write */
+    PIPE_Destroy      /* destroy */
+};
+
+
+/***********************************************************************
+ *	CreatePipe    (KERNEL32.170)
+ */
+BOOL32 WINAPI CreatePipe( PHANDLE hReadPipe, PHANDLE hWritePipe,
+                          LPSECURITY_ATTRIBUTES sa, DWORD size )
+{
+    struct create_pipe_request req;
+    struct create_pipe_reply reply;
+    PIPE *read_pipe, *write_pipe;
+    int len;
+
+    req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
+    CLIENT_SendRequest( REQ_CREATE_PIPE, -1, 1, &req, sizeof(req) );
+    if (CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) ) != ERROR_SUCCESS)
+        return FALSE;
+
+    SYSTEM_LOCK();
+    if (!(read_pipe = (PIPE *)K32OBJ_Create( K32OBJ_PIPE, sizeof(*read_pipe),
+                                             NULL, reply.handle_read,
+                                             STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|GENERIC_READ,
+                                             sa, hReadPipe )))
+    {
+        CLIENT_CloseHandle( reply.handle_write );
+        /* handle_read already closed by K32OBJ_Create */
+        SYSTEM_UNLOCK();
+        return FALSE;
+    }
+    K32OBJ_DecCount( &read_pipe->header );
+    if (!(write_pipe = (PIPE *)K32OBJ_Create( K32OBJ_PIPE, sizeof(*write_pipe),
+                                              NULL, reply.handle_write,
+                                              STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|GENERIC_WRITE,
+                                              sa, hWritePipe )))
+    {
+        CloseHandle( *hReadPipe );
+        *hReadPipe = INVALID_HANDLE_VALUE32;
+        SYSTEM_UNLOCK();
+        return FALSE;
+    }
+    /* everything OK */
+    K32OBJ_DecCount( &write_pipe->header );
+    SetLastError(0); /* FIXME */
+    SYSTEM_UNLOCK();
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           PIPE_Destroy
+ */
+static void PIPE_Destroy( K32OBJ *obj )
+{
+    PIPE *pipe = (PIPE *)obj;
+    assert( obj->type == K32OBJ_PIPE );
+    obj->type = K32OBJ_UNKNOWN;
+    HeapFree( SystemHeap, 0, pipe );
+}
+