server: Move the FSCTL_PIPE_WAIT ioctl implementation to the server.
diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c
index 6127c13..81159ab 100644
--- a/dlls/kernel32/tests/pipe.c
+++ b/dlls/kernel32/tests/pipe.c
@@ -99,6 +99,9 @@
     hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
     ok(hFile != INVALID_HANDLE_VALUE, "CreateFile failed (%d)\n", GetLastError());
 
+    ok(!WaitNamedPipeA(PIPENAME, 1000), "WaitNamedPipe succeeded\n");
+    ok(GetLastError() == ERROR_SEM_TIMEOUT, "wrong error %u\n", GetLastError());
+
     /* don't try to do i/o if one side couldn't be opened, as it hangs */
     if (hFile != INVALID_HANDLE_VALUE) {
         HANDLE hFile2;
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 0af36bb..c2b3273 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -1105,27 +1105,15 @@
     case FSCTL_PIPE_WAIT:
         {
             HANDLE internal_event = 0;
-            FILE_PIPE_WAIT_FOR_BUFFER *buff = in_buffer;
 
             if(!event && !apc)
             {
                 status = NtCreateEvent(&internal_event, EVENT_ALL_ACCESS, NULL, FALSE, FALSE);
                 if (status != STATUS_SUCCESS) break;
+                event = internal_event;
             }
-            SERVER_START_REQ(wait_named_pipe)
-            {
-                req->handle = handle;
-                req->timeout = buff->TimeoutSpecified ? buff->Timeout.QuadPart : 0;
-                req->async.callback = pipe_completion_wait;
-                req->async.iosb     = io;
-                req->async.arg      = NULL;
-                req->async.apc      = apc;
-                req->async.apc_arg  = apc_context;
-                req->async.event    = event ? event : internal_event;
-                wine_server_add_data( req, buff->Name, buff->NameLength );
-                status = wine_server_call( req );
-            }
-            SERVER_END_REQ;
+            status = server_ioctl_file( handle, event, apc, apc_context, io, code,
+                                        in_buffer, in_size, out_buffer, out_size );
 
             if (internal_event && status == STATUS_PENDING)
             {
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index df2eeaa..f9f4bf2 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -2720,21 +2720,6 @@
 };
 
 
-
-struct wait_named_pipe_request
-{
-    struct request_header __header;
-    obj_handle_t   handle;
-    async_data_t   async;
-    timeout_t      timeout;
-    /* VARARG(name,unicode_str); */
-};
-struct wait_named_pipe_reply
-{
-    struct reply_header __header;
-};
-
-
 struct get_named_pipe_info_request
 {
     struct request_header __header;
@@ -4133,7 +4118,6 @@
     REQ_ioctl,
     REQ_create_named_pipe,
     REQ_connect_named_pipe,
-    REQ_wait_named_pipe,
     REQ_get_named_pipe_info,
     REQ_create_window,
     REQ_destroy_window,
@@ -4356,7 +4340,6 @@
     struct ioctl_request ioctl_request;
     struct create_named_pipe_request create_named_pipe_request;
     struct connect_named_pipe_request connect_named_pipe_request;
-    struct wait_named_pipe_request wait_named_pipe_request;
     struct get_named_pipe_info_request get_named_pipe_info_request;
     struct create_window_request create_window_request;
     struct destroy_window_request destroy_window_request;
@@ -4577,7 +4560,6 @@
     struct ioctl_reply ioctl_reply;
     struct create_named_pipe_reply create_named_pipe_reply;
     struct connect_named_pipe_reply connect_named_pipe_reply;
-    struct wait_named_pipe_reply wait_named_pipe_reply;
     struct get_named_pipe_info_reply get_named_pipe_info_reply;
     struct create_window_reply create_window_reply;
     struct destroy_window_reply destroy_window_reply;
@@ -4658,6 +4640,6 @@
     struct allocate_locally_unique_id_reply allocate_locally_unique_id_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 296
+#define SERVER_PROTOCOL_VERSION 297
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/named_pipe.c b/server/named_pipe.c
index a6871b7..d4be777 100644
--- a/server/named_pipe.c
+++ b/server/named_pipe.c
@@ -215,6 +215,8 @@
                                                    unsigned int sharing, unsigned int options );
 static void named_pipe_device_destroy( struct object *obj );
 static enum server_fd_type named_pipe_device_get_fd_type( struct fd *fd );
+static void named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data,
+                                     const void *data, data_size_t size );
 
 static const struct object_ops named_pipe_device_ops =
 {
@@ -239,7 +241,7 @@
     default_poll_event,               /* poll_event */
     no_flush,                         /* flush */
     named_pipe_device_get_fd_type,    /* get_fd_type */
-    default_fd_ioctl,                 /* ioctl */
+    named_pipe_device_ioctl,          /* ioctl */
     default_fd_queue_async,           /* queue_async */
     default_fd_reselect_async,        /* reselect_async */
     default_fd_cancel_async           /* cancel_async */
@@ -765,6 +767,64 @@
     return &client->obj;
 }
 
+static void named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data,
+                                     const void *data, data_size_t size )
+{
+    struct named_pipe_device *device = get_fd_user( fd );
+
+    switch(code)
+    {
+    case FSCTL_PIPE_WAIT:
+        {
+            const FILE_PIPE_WAIT_FOR_BUFFER *buffer = data;
+            struct named_pipe *pipe;
+            struct pipe_server *server;
+            struct unicode_str name;
+
+            if (size < sizeof(*buffer) ||
+                size < FIELD_OFFSET(FILE_PIPE_WAIT_FOR_BUFFER, Name[buffer->NameLength/sizeof(WCHAR)]))
+            {
+                set_error( STATUS_INVALID_PARAMETER );
+                break;
+            }
+            name.str = buffer->Name;
+            name.len = (buffer->NameLength / sizeof(WCHAR)) * sizeof(WCHAR);
+            if (!(pipe = (struct named_pipe *)find_object( device->pipes, &name, OBJ_CASE_INSENSITIVE )))
+            {
+                set_error( STATUS_PIPE_NOT_AVAILABLE );
+                break;
+            }
+            if (!(server = find_available_server( pipe )))
+            {
+                struct async *async;
+
+                if (!pipe->waiters && !(pipe->waiters = create_async_queue( NULL )))
+                {
+                    release_object( pipe );
+                    break;
+                }
+
+                if ((async = create_async( current, pipe->waiters, async_data )))
+                {
+                    timeout_t when = buffer->TimeoutSpecified ? buffer->Timeout.QuadPart : pipe->timeout;
+                    async_set_timeout( async, when, STATUS_IO_TIMEOUT );
+                    release_object( async );
+                    set_error( STATUS_PENDING );
+                }
+            }
+            else release_object( server );
+
+            release_object( pipe );
+            break;
+        }
+
+    default:
+        default_fd_ioctl( fd, code, async_data, data, size );
+        break;
+    }
+}
+
+
 DECL_HANDLER(create_named_pipe)
 {
     struct named_pipe *pipe;
@@ -864,48 +924,6 @@
     release_object(server);
 }
 
-DECL_HANDLER(wait_named_pipe)
-{
-    struct named_pipe_device *device;
-    struct named_pipe *pipe;
-    struct pipe_server *server;
-    struct unicode_str name;
-
-    device = (struct named_pipe_device *)get_handle_obj( current->process, req->handle,
-                                                         FILE_READ_ATTRIBUTES, &named_pipe_device_ops );
-    if (!device) return;
-
-    get_req_unicode_str( &name );
-    pipe = (struct named_pipe *)find_object( device->pipes, &name, OBJ_CASE_INSENSITIVE );
-    release_object( device );
-    if (!pipe)
-    {
-        set_error( STATUS_PIPE_NOT_AVAILABLE );
-        return;
-    }
-    server = find_available_server( pipe );
-    if (!server)
-    {
-        struct async *async;
-
-        if (!pipe->waiters && !(pipe->waiters = create_async_queue( NULL )))
-        {
-            release_object( pipe );
-            return;
-        }
-
-        if ((async = create_async( current, pipe->waiters, &req->async )))
-        {
-            async_set_timeout( async, req->timeout ? req->timeout : pipe->timeout, STATUS_TIMEOUT );
-            release_object( async );
-            set_error( STATUS_PENDING );
-        }
-    }
-    else release_object( server );
-
-    release_object( pipe );
-}
-
 DECL_HANDLER(get_named_pipe_info)
 {
     struct pipe_server *server;
diff --git a/server/protocol.def b/server/protocol.def
index 9aff9e6..a5f91ab 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -2005,15 +2005,6 @@
 @END
 
 
-/* Wait for a named pipe */
-@REQ(wait_named_pipe)
-    obj_handle_t   handle;
-    async_data_t   async;        /* async I/O parameters */
-    timeout_t      timeout;
-    VARARG(name,unicode_str);    /* pipe name */
-@END
-
-
 @REQ(get_named_pipe_info)
     obj_handle_t   handle;
 @REPLY
diff --git a/server/request.h b/server/request.h
index 63a7ee4..1b8da0e 100644
--- a/server/request.h
+++ b/server/request.h
@@ -247,7 +247,6 @@
 DECL_HANDLER(ioctl);
 DECL_HANDLER(create_named_pipe);
 DECL_HANDLER(connect_named_pipe);
-DECL_HANDLER(wait_named_pipe);
 DECL_HANDLER(get_named_pipe_info);
 DECL_HANDLER(create_window);
 DECL_HANDLER(destroy_window);
@@ -469,7 +468,6 @@
     (req_handler)req_ioctl,
     (req_handler)req_create_named_pipe,
     (req_handler)req_connect_named_pipe,
-    (req_handler)req_wait_named_pipe,
     (req_handler)req_get_named_pipe_info,
     (req_handler)req_create_window,
     (req_handler)req_destroy_window,
diff --git a/server/trace.c b/server/trace.c
index 59cdf1d..3751cdf 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -90,6 +90,7 @@
 #define CASE(c) case c: fputs( #c, stderr ); break
         CASE(FSCTL_DISMOUNT_VOLUME);
         CASE(FSCTL_PIPE_DISCONNECT);
+        CASE(FSCTL_PIPE_WAIT);
         default: fprintf( stderr, "%08x", *code ); break;
 #undef CASE
     }
@@ -2449,19 +2450,6 @@
     dump_async_data( &req->async );
 }
 
-static void dump_wait_named_pipe_request( const struct wait_named_pipe_request *req )
-{
-    fprintf( stderr, " handle=%p,", req->handle );
-    fprintf( stderr, " async=" );
-    dump_async_data( &req->async );
-    fprintf( stderr, "," );
-    fprintf( stderr, " timeout=" );
-    dump_timeout( &req->timeout );
-    fprintf( stderr, "," );
-    fprintf( stderr, " name=" );
-    dump_varargs_unicode_str( cur_size );
-}
-
 static void dump_get_named_pipe_info_request( const struct get_named_pipe_info_request *req )
 {
     fprintf( stderr, " handle=%p", req->handle );
@@ -3614,7 +3602,6 @@
     (dump_func)dump_ioctl_request,
     (dump_func)dump_create_named_pipe_request,
     (dump_func)dump_connect_named_pipe_request,
-    (dump_func)dump_wait_named_pipe_request,
     (dump_func)dump_get_named_pipe_info_request,
     (dump_func)dump_create_window_request,
     (dump_func)dump_destroy_window_request,
@@ -3833,7 +3820,6 @@
     (dump_func)dump_ioctl_reply,
     (dump_func)dump_create_named_pipe_reply,
     (dump_func)0,
-    (dump_func)0,
     (dump_func)dump_get_named_pipe_info_reply,
     (dump_func)dump_create_window_reply,
     (dump_func)0,
@@ -4052,7 +4038,6 @@
     "ioctl",
     "create_named_pipe",
     "connect_named_pipe",
-    "wait_named_pipe",
     "get_named_pipe_info",
     "create_window",
     "destroy_window",