server: Move the FSCTL_PIPE_WAIT ioctl implementation to the server.
This commit is contained in:
parent
737148c57b
commit
3684dc181c
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in New Issue