mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-15 01:49:16 +00:00
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);
|
hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
|
||||||
ok(hFile != INVALID_HANDLE_VALUE, "CreateFile failed (%d)\n", GetLastError());
|
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 */
|
/* don't try to do i/o if one side couldn't be opened, as it hangs */
|
||||||
if (hFile != INVALID_HANDLE_VALUE) {
|
if (hFile != INVALID_HANDLE_VALUE) {
|
||||||
HANDLE hFile2;
|
HANDLE hFile2;
|
||||||
|
|
|
@ -1105,27 +1105,15 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
|
||||||
case FSCTL_PIPE_WAIT:
|
case FSCTL_PIPE_WAIT:
|
||||||
{
|
{
|
||||||
HANDLE internal_event = 0;
|
HANDLE internal_event = 0;
|
||||||
FILE_PIPE_WAIT_FOR_BUFFER *buff = in_buffer;
|
|
||||||
|
|
||||||
if(!event && !apc)
|
if(!event && !apc)
|
||||||
{
|
{
|
||||||
status = NtCreateEvent(&internal_event, EVENT_ALL_ACCESS, NULL, FALSE, FALSE);
|
status = NtCreateEvent(&internal_event, EVENT_ALL_ACCESS, NULL, FALSE, FALSE);
|
||||||
if (status != STATUS_SUCCESS) break;
|
if (status != STATUS_SUCCESS) break;
|
||||||
|
event = internal_event;
|
||||||
}
|
}
|
||||||
SERVER_START_REQ(wait_named_pipe)
|
status = server_ioctl_file( handle, event, apc, apc_context, io, code,
|
||||||
{
|
in_buffer, in_size, out_buffer, out_size );
|
||||||
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;
|
|
||||||
|
|
||||||
if (internal_event && status == STATUS_PENDING)
|
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 get_named_pipe_info_request
|
||||||
{
|
{
|
||||||
struct request_header __header;
|
struct request_header __header;
|
||||||
|
@ -4133,7 +4118,6 @@ enum request
|
||||||
REQ_ioctl,
|
REQ_ioctl,
|
||||||
REQ_create_named_pipe,
|
REQ_create_named_pipe,
|
||||||
REQ_connect_named_pipe,
|
REQ_connect_named_pipe,
|
||||||
REQ_wait_named_pipe,
|
|
||||||
REQ_get_named_pipe_info,
|
REQ_get_named_pipe_info,
|
||||||
REQ_create_window,
|
REQ_create_window,
|
||||||
REQ_destroy_window,
|
REQ_destroy_window,
|
||||||
|
@ -4356,7 +4340,6 @@ union generic_request
|
||||||
struct ioctl_request ioctl_request;
|
struct ioctl_request ioctl_request;
|
||||||
struct create_named_pipe_request create_named_pipe_request;
|
struct create_named_pipe_request create_named_pipe_request;
|
||||||
struct connect_named_pipe_request connect_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 get_named_pipe_info_request get_named_pipe_info_request;
|
||||||
struct create_window_request create_window_request;
|
struct create_window_request create_window_request;
|
||||||
struct destroy_window_request destroy_window_request;
|
struct destroy_window_request destroy_window_request;
|
||||||
|
@ -4577,7 +4560,6 @@ union generic_reply
|
||||||
struct ioctl_reply ioctl_reply;
|
struct ioctl_reply ioctl_reply;
|
||||||
struct create_named_pipe_reply create_named_pipe_reply;
|
struct create_named_pipe_reply create_named_pipe_reply;
|
||||||
struct connect_named_pipe_reply connect_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 get_named_pipe_info_reply get_named_pipe_info_reply;
|
||||||
struct create_window_reply create_window_reply;
|
struct create_window_reply create_window_reply;
|
||||||
struct destroy_window_reply destroy_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;
|
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 */
|
#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 );
|
unsigned int sharing, unsigned int options );
|
||||||
static void named_pipe_device_destroy( struct object *obj );
|
static void named_pipe_device_destroy( struct object *obj );
|
||||||
static enum server_fd_type named_pipe_device_get_fd_type( struct fd *fd );
|
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 =
|
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 */
|
default_poll_event, /* poll_event */
|
||||||
no_flush, /* flush */
|
no_flush, /* flush */
|
||||||
named_pipe_device_get_fd_type, /* get_fd_type */
|
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_queue_async, /* queue_async */
|
||||||
default_fd_reselect_async, /* reselect_async */
|
default_fd_reselect_async, /* reselect_async */
|
||||||
default_fd_cancel_async /* cancel_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;
|
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)
|
DECL_HANDLER(create_named_pipe)
|
||||||
{
|
{
|
||||||
struct named_pipe *pipe;
|
struct named_pipe *pipe;
|
||||||
|
@ -864,48 +924,6 @@ DECL_HANDLER(connect_named_pipe)
|
||||||
release_object(server);
|
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)
|
DECL_HANDLER(get_named_pipe_info)
|
||||||
{
|
{
|
||||||
struct pipe_server *server;
|
struct pipe_server *server;
|
||||||
|
|
|
@ -2005,15 +2005,6 @@ enum message_type
|
||||||
@END
|
@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)
|
@REQ(get_named_pipe_info)
|
||||||
obj_handle_t handle;
|
obj_handle_t handle;
|
||||||
@REPLY
|
@REPLY
|
||||||
|
|
|
@ -247,7 +247,6 @@ DECL_HANDLER(cancel_async);
|
||||||
DECL_HANDLER(ioctl);
|
DECL_HANDLER(ioctl);
|
||||||
DECL_HANDLER(create_named_pipe);
|
DECL_HANDLER(create_named_pipe);
|
||||||
DECL_HANDLER(connect_named_pipe);
|
DECL_HANDLER(connect_named_pipe);
|
||||||
DECL_HANDLER(wait_named_pipe);
|
|
||||||
DECL_HANDLER(get_named_pipe_info);
|
DECL_HANDLER(get_named_pipe_info);
|
||||||
DECL_HANDLER(create_window);
|
DECL_HANDLER(create_window);
|
||||||
DECL_HANDLER(destroy_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_ioctl,
|
||||||
(req_handler)req_create_named_pipe,
|
(req_handler)req_create_named_pipe,
|
||||||
(req_handler)req_connect_named_pipe,
|
(req_handler)req_connect_named_pipe,
|
||||||
(req_handler)req_wait_named_pipe,
|
|
||||||
(req_handler)req_get_named_pipe_info,
|
(req_handler)req_get_named_pipe_info,
|
||||||
(req_handler)req_create_window,
|
(req_handler)req_create_window,
|
||||||
(req_handler)req_destroy_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
|
#define CASE(c) case c: fputs( #c, stderr ); break
|
||||||
CASE(FSCTL_DISMOUNT_VOLUME);
|
CASE(FSCTL_DISMOUNT_VOLUME);
|
||||||
CASE(FSCTL_PIPE_DISCONNECT);
|
CASE(FSCTL_PIPE_DISCONNECT);
|
||||||
|
CASE(FSCTL_PIPE_WAIT);
|
||||||
default: fprintf( stderr, "%08x", *code ); break;
|
default: fprintf( stderr, "%08x", *code ); break;
|
||||||
#undef CASE
|
#undef CASE
|
||||||
}
|
}
|
||||||
|
@ -2449,19 +2450,6 @@ static void dump_connect_named_pipe_request( const struct connect_named_pipe_req
|
||||||
dump_async_data( &req->async );
|
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 )
|
static void dump_get_named_pipe_info_request( const struct get_named_pipe_info_request *req )
|
||||||
{
|
{
|
||||||
fprintf( stderr, " handle=%p", req->handle );
|
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_ioctl_request,
|
||||||
(dump_func)dump_create_named_pipe_request,
|
(dump_func)dump_create_named_pipe_request,
|
||||||
(dump_func)dump_connect_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_get_named_pipe_info_request,
|
||||||
(dump_func)dump_create_window_request,
|
(dump_func)dump_create_window_request,
|
||||||
(dump_func)dump_destroy_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_ioctl_reply,
|
||||||
(dump_func)dump_create_named_pipe_reply,
|
(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_get_named_pipe_info_reply,
|
||||||
(dump_func)dump_create_window_reply,
|
(dump_func)dump_create_window_reply,
|
||||||
(dump_func)0,
|
(dump_func)0,
|
||||||
|
@ -4052,7 +4038,6 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
|
||||||
"ioctl",
|
"ioctl",
|
||||||
"create_named_pipe",
|
"create_named_pipe",
|
||||||
"connect_named_pipe",
|
"connect_named_pipe",
|
||||||
"wait_named_pipe",
|
|
||||||
"get_named_pipe_info",
|
"get_named_pipe_info",
|
||||||
"create_window",
|
"create_window",
|
||||||
"destroy_window",
|
"destroy_window",
|
||||||
|
|
Loading…
Reference in a new issue