From 3684dc181c661eed8f1d5c3872d6be7874efeb3c Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 17 Apr 2007 22:07:07 +0200 Subject: [PATCH] server: Move the FSCTL_PIPE_WAIT ioctl implementation to the server. --- dlls/kernel32/tests/pipe.c | 3 + dlls/ntdll/file.c | 18 +----- include/wine/server_protocol.h | 20 +------ server/named_pipe.c | 104 +++++++++++++++++++-------------- server/protocol.def | 9 --- server/request.h | 2 - server/trace.c | 17 +----- 7 files changed, 69 insertions(+), 104 deletions(-) diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c index 6127c1329d1..81159ab7993 100644 --- a/dlls/kernel32/tests/pipe.c +++ b/dlls/kernel32/tests/pipe.c @@ -99,6 +99,9 @@ static void test_CreateNamedPipe(int pipemode) 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 0af36bb67b6..c2b3273c985 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -1105,27 +1105,15 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc 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 df2eeaa4d4c..f9f4bf27b3b 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -2720,21 +2720,6 @@ struct connect_named_pipe_reply }; - -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 @@ enum request 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 @@ union generic_request 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 @@ union generic_reply 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 @@ union generic_reply 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 a6871b79c6c..d4be777994d 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -215,6 +215,8 @@ static struct object *named_pipe_device_open_file( struct object *obj, unsigned 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 @@ static const struct fd_ops named_pipe_device_fd_ops = 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 @@ static struct object *named_pipe_open_file( struct object *obj, unsigned int acc 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 @@ DECL_HANDLER(connect_named_pipe) 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 9aff9e64e79..a5f91abd53a 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -2005,15 +2005,6 @@ enum message_type @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 63a7ee42b74..1b8da0ea2de 100644 --- a/server/request.h +++ b/server/request.h @@ -247,7 +247,6 @@ DECL_HANDLER(cancel_async); 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 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = (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 59cdf1db13b..3751cdf70db 100644 --- a/server/trace.c +++ b/server/trace.c @@ -90,6 +90,7 @@ static void dump_ioctl_code( const ioctl_code_t *code ) #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 @@ static void dump_connect_named_pipe_request( const struct connect_named_pipe_req 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 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { (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 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { (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 @@ static const char * const req_names[REQ_NB_REQUESTS] = { "ioctl", "create_named_pipe", "connect_named_pipe", - "wait_named_pipe", "get_named_pipe_info", "create_window", "destroy_window",