diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c index 0cbcafc991..6127c1329d 100644 --- a/dlls/kernel32/tests/pipe.c +++ b/dlls/kernel32/tests/pipe.c @@ -744,6 +744,8 @@ static int test_DisconnectNamedPipe(void) ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL) == 0 && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "ReadFile from disconnected pipe with bytes waiting\n"); + ok(!DisconnectNamedPipe(hnp) && GetLastError() == ERROR_PIPE_NOT_CONNECTED, + "DisconnectNamedPipe worked twice\n"); ok(CloseHandle(hFile), "CloseHandle\n"); } diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index b29bb1370a..9e46548ce4 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -1192,17 +1192,13 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc break; case FSCTL_PIPE_DISCONNECT: - SERVER_START_REQ(disconnect_named_pipe) + status = server_ioctl_file( handle, event, apc, apc_context, io, code, + in_buffer, in_size, out_buffer, out_size ); + if (!status) { - req->handle = handle; - status = wine_server_call(req); - if (!status) - { - int fd = server_remove_fd_from_cache( handle ); - if (fd != -1) close( fd ); - } + int fd = server_remove_fd_from_cache( handle ); + if (fd != -1) close( fd ); } - SERVER_END_REQ; break; case FSCTL_LOCK_VOLUME: diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index a4ee09188d..b134513d1e 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -2749,18 +2749,6 @@ struct wait_named_pipe_reply }; - -struct disconnect_named_pipe_request -{ - struct request_header __header; - obj_handle_t handle; -}; -struct disconnect_named_pipe_reply -{ - struct reply_header __header; -}; - - struct get_named_pipe_info_request { struct request_header __header; @@ -4161,7 +4149,6 @@ enum request REQ_create_named_pipe, REQ_connect_named_pipe, REQ_wait_named_pipe, - REQ_disconnect_named_pipe, REQ_get_named_pipe_info, REQ_create_window, REQ_destroy_window, @@ -4386,7 +4373,6 @@ union generic_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 disconnect_named_pipe_request disconnect_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; @@ -4609,7 +4595,6 @@ union generic_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 disconnect_named_pipe_reply disconnect_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; @@ -4690,6 +4675,6 @@ union generic_reply struct allocate_locally_unique_id_reply allocate_locally_unique_id_reply; }; -#define SERVER_PROTOCOL_VERSION 293 +#define SERVER_PROTOCOL_VERSION 294 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/named_pipe.c b/server/named_pipe.c index 62c30c4aab..680e7db13e 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -46,6 +46,7 @@ #define WIN32_NO_STATUS #include "windef.h" #include "winternl.h" +#include "winioctl.h" #include "file.h" #include "handle.h" @@ -138,6 +139,8 @@ static struct fd *pipe_server_get_fd( struct object *obj ); static void pipe_server_destroy( struct object *obj); static void pipe_server_flush( struct fd *fd, struct event **event ); static enum server_fd_type pipe_server_get_fd_type( struct fd *fd ); +static void pipe_server_ioctl( struct fd *fd, unsigned int code, const async_data_t *async, + const void *data, data_size_t size ); static const struct object_ops pipe_server_ops = { @@ -162,7 +165,7 @@ static const struct fd_ops pipe_server_fd_ops = default_poll_event, /* poll_event */ pipe_server_flush, /* flush */ pipe_server_get_fd_type, /* get_fd_type */ - default_fd_ioctl, /* ioctl */ + pipe_server_ioctl, /* ioctl */ default_fd_queue_async, /* queue_async */ default_fd_reselect_async, /* reselect_async */ default_fd_cancel_async, /* cancel_async */ @@ -567,6 +570,46 @@ static enum server_fd_type pipe_client_get_fd_type( struct fd *fd ) return FD_TYPE_PIPE; } +static void pipe_server_ioctl( struct fd *fd, unsigned int code, const async_data_t *async, + const void *data, data_size_t size ) +{ + struct pipe_server *server = get_fd_user( fd ); + + switch(code) + { + case FSCTL_PIPE_DISCONNECT: + switch(server->state) + { + case ps_connected_server: + assert( server->client ); + assert( server->client->fd ); + + notify_empty( server ); + + /* dump the client and server fds, but keep the pointers + around - client loses all waiting data */ + server->state = ps_disconnected_server; + do_disconnect( server ); + break; + case ps_wait_disconnect: + assert( !server->client ); + do_disconnect( server ); + server->state = ps_wait_connect; + break; + case ps_idle_server: + case ps_wait_open: + case ps_disconnected_server: + case ps_wait_connect: + assert(0); /* shouldn't even get an fd */ + break; + } + break; + default: + default_fd_ioctl( fd, code, async, data, size ); + break; + } +} + static struct named_pipe *create_named_pipe( struct directory *root, const struct unicode_str *name, unsigned int attr ) { @@ -874,45 +917,6 @@ DECL_HANDLER(wait_named_pipe) release_object( pipe ); } -DECL_HANDLER(disconnect_named_pipe) -{ - struct pipe_server *server; - - server = get_pipe_server_obj( current->process, req->handle, 0 ); - if (!server) - return; - switch(server->state) - { - case ps_connected_server: - assert( server->fd ); - assert( server->client ); - assert( server->client->fd ); - - notify_empty( server ); - - /* Dump the client and server fds, but keep the pointers - around - client loses all waiting data */ - server->state = ps_disconnected_server; - do_disconnect( server ); - break; - - case ps_wait_disconnect: - assert( !server->client ); - assert( server->fd ); - do_disconnect( server ); - server->state = ps_wait_connect; - break; - - case ps_idle_server: - case ps_wait_open: - case ps_disconnected_server: - case ps_wait_connect: - set_error( STATUS_PIPE_DISCONNECTED ); - break; - } - release_object( server ); -} - DECL_HANDLER(get_named_pipe_info) { struct pipe_server *server; diff --git a/server/protocol.def b/server/protocol.def index 3ca7241270..8cc44fc6c5 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -2021,12 +2021,6 @@ enum message_type @END -/* Disconnect a named pipe */ -@REQ(disconnect_named_pipe) - obj_handle_t handle; -@END - - @REQ(get_named_pipe_info) obj_handle_t handle; @REPLY diff --git a/server/request.h b/server/request.h index 3424fb3fb1..fe0e87dd5a 100644 --- a/server/request.h +++ b/server/request.h @@ -249,7 +249,6 @@ DECL_HANDLER(ioctl); DECL_HANDLER(create_named_pipe); DECL_HANDLER(connect_named_pipe); DECL_HANDLER(wait_named_pipe); -DECL_HANDLER(disconnect_named_pipe); DECL_HANDLER(get_named_pipe_info); DECL_HANDLER(create_window); DECL_HANDLER(destroy_window); @@ -473,7 +472,6 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = (req_handler)req_create_named_pipe, (req_handler)req_connect_named_pipe, (req_handler)req_wait_named_pipe, - (req_handler)req_disconnect_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 84c409e7bd..de24553b6c 100644 --- a/server/trace.c +++ b/server/trace.c @@ -2456,11 +2456,6 @@ static void dump_wait_named_pipe_request( const struct wait_named_pipe_request * dump_varargs_unicode_str( cur_size ); } -static void dump_disconnect_named_pipe_request( const struct disconnect_named_pipe_request *req ) -{ - fprintf( stderr, " handle=%p", req->handle ); -} - static void dump_get_named_pipe_info_request( const struct get_named_pipe_info_request *req ) { fprintf( stderr, " handle=%p", req->handle ); @@ -3611,7 +3606,6 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_create_named_pipe_request, (dump_func)dump_connect_named_pipe_request, (dump_func)dump_wait_named_pipe_request, - (dump_func)dump_disconnect_named_pipe_request, (dump_func)dump_get_named_pipe_info_request, (dump_func)dump_create_window_request, (dump_func)dump_destroy_window_request, @@ -3832,7 +3826,6 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_create_named_pipe_reply, (dump_func)0, (dump_func)0, - (dump_func)0, (dump_func)dump_get_named_pipe_info_reply, (dump_func)dump_create_window_reply, (dump_func)0, @@ -4053,7 +4046,6 @@ static const char * const req_names[REQ_NB_REQUESTS] = { "create_named_pipe", "connect_named_pipe", "wait_named_pipe", - "disconnect_named_pipe", "get_named_pipe_info", "create_window", "destroy_window",