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",