server: Move the FSCTL_PIPE_WAIT ioctl implementation to the server.

oldstable
Alexandre Julliard 2007-04-17 22:07:07 +02:00
parent 737148c57b
commit 3684dc181c
7 changed files with 69 additions and 104 deletions

View File

@ -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;

View File

@ -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)
{

View File

@ -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 */

View File

@ -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;

View File

@ -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

View File

@ -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,

View File

@ -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",