diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index 02a175bd26b..c41d387308d 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -1075,28 +1075,6 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc if (!status) status = DIR_unmount_device( handle ); break; - case FSCTL_PIPE_WAIT: - { - HANDLE internal_event = 0; - - if(!event && !apc) - { - status = NtCreateEvent(&internal_event, EVENT_ALL_ACCESS, NULL, FALSE, FALSE); - if (status != STATUS_SUCCESS) break; - event = internal_event; - } - 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) - { - while (NtWaitForSingleObject(internal_event, TRUE, NULL) == STATUS_USER_APC) /*nothing*/ ; - status = io->u.Status; - } - if (internal_event) NtClose(internal_event); - } - break; - case FSCTL_PIPE_PEEK: { FILE_PIPE_PEEK_BUFFER *buffer = out_buffer; @@ -1173,6 +1151,7 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc break; case FSCTL_PIPE_LISTEN: + case FSCTL_PIPE_WAIT: default: status = server_ioctl_file( handle, event, apc, apc_context, io, code, in_buffer, in_size, out_buffer, out_size ); diff --git a/server/named_pipe.c b/server/named_pipe.c index a0344366508..6dba1f35d46 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -846,6 +846,7 @@ static obj_handle_t named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, c case FSCTL_PIPE_WAIT: { const FILE_PIPE_WAIT_FOR_BUFFER *buffer = data; + obj_handle_t wait_handle = 0; struct named_pipe *pipe; struct pipe_server *server; struct unicode_str name; @@ -867,13 +868,22 @@ static obj_handle_t named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, c { struct async *async; - if (!pipe->waiters && !(pipe->waiters = create_async_queue( NULL ))) - { - release_object( pipe ); - return 0; - } + if (!pipe->waiters && !(pipe->waiters = create_async_queue( NULL ))) goto done; - if ((async = create_async( current, pipe->waiters, async_data ))) + if (!async_data->event && !async_data->apc) + { + async_data_t new_data = *async_data; + if (!(wait_handle = alloc_wait_event( current->process ))) goto done; + new_data.event = wait_handle; + if (!(async = create_async( current, pipe->waiters, &new_data ))) + { + close_handle( current->process, wait_handle ); + wait_handle = 0; + } + } + else async = create_async( current, pipe->waiters, async_data ); + + if (async) { timeout_t when = buffer->TimeoutSpecified ? buffer->Timeout.QuadPart : pipe->timeout; async_set_timeout( async, when, STATUS_IO_TIMEOUT ); @@ -883,8 +893,9 @@ static obj_handle_t named_pipe_device_ioctl( struct fd *fd, ioctl_code_t code, c } else release_object( server ); + done: release_object( pipe ); - return 0; + return wait_handle; } default: