mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-15 02:04:46 +00:00
server: Implement the open_file method for named pipes.
Get rid of the open_named_pipe request, we can now use a normal open_file_object.
This commit is contained in:
parent
806bb49eda
commit
de1866d4fd
|
@ -142,7 +142,6 @@ NTSTATUS WINAPI NtCreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATTRIB
|
||||||
ULONG attributes, ULONG sharing, ULONG disposition,
|
ULONG attributes, ULONG sharing, ULONG disposition,
|
||||||
ULONG options, PVOID ea_buffer, ULONG ea_length )
|
ULONG options, PVOID ea_buffer, ULONG ea_length )
|
||||||
{
|
{
|
||||||
static const WCHAR pipeW[] = {'\\','?','?','\\','p','i','p','e','\\'};
|
|
||||||
ANSI_STRING unix_name;
|
ANSI_STRING unix_name;
|
||||||
int created = FALSE;
|
int created = FALSE;
|
||||||
|
|
||||||
|
@ -156,28 +155,6 @@ NTSTATUS WINAPI NtCreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATTRIB
|
||||||
|
|
||||||
if (alloc_size) FIXME( "alloc_size not supported\n" );
|
if (alloc_size) FIXME( "alloc_size not supported\n" );
|
||||||
|
|
||||||
/* check for named pipe */
|
|
||||||
|
|
||||||
if (attr->ObjectName->Length > sizeof(pipeW) &&
|
|
||||||
!memicmpW( attr->ObjectName->Buffer, pipeW, sizeof(pipeW)/sizeof(WCHAR) ))
|
|
||||||
{
|
|
||||||
if (attr->SecurityQualityOfService)
|
|
||||||
FIXME("SecurityQualityOfService ignored\n");
|
|
||||||
SERVER_START_REQ( open_named_pipe )
|
|
||||||
{
|
|
||||||
req->access = access;
|
|
||||||
req->attributes = attr->Attributes;
|
|
||||||
req->rootdir = attr->RootDirectory;
|
|
||||||
req->flags = options;
|
|
||||||
wine_server_add_data( req, attr->ObjectName->Buffer,
|
|
||||||
attr->ObjectName->Length );
|
|
||||||
io->u.Status = wine_server_call( req );
|
|
||||||
*handle = reply->handle;
|
|
||||||
}
|
|
||||||
SERVER_END_REQ;
|
|
||||||
return io->u.Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attr->RootDirectory)
|
if (attr->RootDirectory)
|
||||||
{
|
{
|
||||||
FIXME( "RootDirectory %p not supported\n", attr->RootDirectory );
|
FIXME( "RootDirectory %p not supported\n", attr->RootDirectory );
|
||||||
|
|
|
@ -2698,23 +2698,6 @@ struct create_named_pipe_reply
|
||||||
#define NAMED_PIPE_SERVER_END 0x8000
|
#define NAMED_PIPE_SERVER_END 0x8000
|
||||||
|
|
||||||
|
|
||||||
struct open_named_pipe_request
|
|
||||||
{
|
|
||||||
struct request_header __header;
|
|
||||||
unsigned int access;
|
|
||||||
unsigned int attributes;
|
|
||||||
obj_handle_t rootdir;
|
|
||||||
unsigned int flags;
|
|
||||||
/* VARARG(name,unicode_str); */
|
|
||||||
};
|
|
||||||
struct open_named_pipe_reply
|
|
||||||
{
|
|
||||||
struct reply_header __header;
|
|
||||||
obj_handle_t handle;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct connect_named_pipe_request
|
struct connect_named_pipe_request
|
||||||
{
|
{
|
||||||
struct request_header __header;
|
struct request_header __header;
|
||||||
|
@ -4150,7 +4133,6 @@ enum request
|
||||||
REQ_register_async,
|
REQ_register_async,
|
||||||
REQ_cancel_async,
|
REQ_cancel_async,
|
||||||
REQ_create_named_pipe,
|
REQ_create_named_pipe,
|
||||||
REQ_open_named_pipe,
|
|
||||||
REQ_connect_named_pipe,
|
REQ_connect_named_pipe,
|
||||||
REQ_wait_named_pipe,
|
REQ_wait_named_pipe,
|
||||||
REQ_disconnect_named_pipe,
|
REQ_disconnect_named_pipe,
|
||||||
|
@ -4374,7 +4356,6 @@ union generic_request
|
||||||
struct register_async_request register_async_request;
|
struct register_async_request register_async_request;
|
||||||
struct cancel_async_request cancel_async_request;
|
struct cancel_async_request cancel_async_request;
|
||||||
struct create_named_pipe_request create_named_pipe_request;
|
struct create_named_pipe_request create_named_pipe_request;
|
||||||
struct open_named_pipe_request open_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 wait_named_pipe_request wait_named_pipe_request;
|
||||||
struct disconnect_named_pipe_request disconnect_named_pipe_request;
|
struct disconnect_named_pipe_request disconnect_named_pipe_request;
|
||||||
|
@ -4596,7 +4577,6 @@ union generic_reply
|
||||||
struct register_async_reply register_async_reply;
|
struct register_async_reply register_async_reply;
|
||||||
struct cancel_async_reply cancel_async_reply;
|
struct cancel_async_reply cancel_async_reply;
|
||||||
struct create_named_pipe_reply create_named_pipe_reply;
|
struct create_named_pipe_reply create_named_pipe_reply;
|
||||||
struct open_named_pipe_reply open_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 wait_named_pipe_reply wait_named_pipe_reply;
|
||||||
struct disconnect_named_pipe_reply disconnect_named_pipe_reply;
|
struct disconnect_named_pipe_reply disconnect_named_pipe_reply;
|
||||||
|
@ -4680,6 +4660,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 287
|
#define SERVER_PROTOCOL_VERSION 288
|
||||||
|
|
||||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||||
|
|
|
@ -108,6 +108,8 @@ struct named_pipe_device
|
||||||
|
|
||||||
static void named_pipe_dump( struct object *obj, int verbose );
|
static void named_pipe_dump( struct object *obj, int verbose );
|
||||||
static unsigned int named_pipe_map_access( struct object *obj, unsigned int access );
|
static unsigned int named_pipe_map_access( struct object *obj, unsigned int access );
|
||||||
|
static struct object *named_pipe_open_file( struct object *obj, unsigned int access,
|
||||||
|
unsigned int sharing, unsigned int options );
|
||||||
static void named_pipe_destroy( struct object *obj );
|
static void named_pipe_destroy( struct object *obj );
|
||||||
|
|
||||||
static const struct object_ops named_pipe_ops =
|
static const struct object_ops named_pipe_ops =
|
||||||
|
@ -122,7 +124,7 @@ static const struct object_ops named_pipe_ops =
|
||||||
no_get_fd, /* get_fd */
|
no_get_fd, /* get_fd */
|
||||||
named_pipe_map_access, /* map_access */
|
named_pipe_map_access, /* map_access */
|
||||||
no_lookup_name, /* lookup_name */
|
no_lookup_name, /* lookup_name */
|
||||||
no_open_file, /* open_file */
|
named_pipe_open_file, /* open_file */
|
||||||
no_close_handle, /* close_handle */
|
no_close_handle, /* close_handle */
|
||||||
named_pipe_destroy /* destroy */
|
named_pipe_destroy /* destroy */
|
||||||
};
|
};
|
||||||
|
@ -688,6 +690,69 @@ static inline struct pipe_server *find_server2( struct named_pipe *pipe,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct object *named_pipe_open_file( struct object *obj, unsigned int access,
|
||||||
|
unsigned int sharing, unsigned int options )
|
||||||
|
{
|
||||||
|
struct named_pipe *pipe = (struct named_pipe *)obj;
|
||||||
|
struct pipe_server *server;
|
||||||
|
struct pipe_client *client;
|
||||||
|
int fds[2];
|
||||||
|
|
||||||
|
if (!(server = find_server2( pipe, ps_idle_server, ps_wait_open )))
|
||||||
|
{
|
||||||
|
set_error( STATUS_PIPE_NOT_AVAILABLE );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((client = create_pipe_client( options )))
|
||||||
|
{
|
||||||
|
if (!socketpair( PF_UNIX, SOCK_STREAM, 0, fds ))
|
||||||
|
{
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
|
assert( !client->fd );
|
||||||
|
assert( !server->fd );
|
||||||
|
|
||||||
|
/* for performance reasons, only set nonblocking mode when using
|
||||||
|
* overlapped I/O. Otherwise, we will be doing too much busy
|
||||||
|
* looping */
|
||||||
|
if (is_overlapped( options ))
|
||||||
|
res = fcntl( fds[1], F_SETFL, O_NONBLOCK );
|
||||||
|
if ((res != -1) && is_overlapped( server->options ))
|
||||||
|
res = fcntl( fds[0], F_SETFL, O_NONBLOCK );
|
||||||
|
|
||||||
|
if (pipe->insize)
|
||||||
|
{
|
||||||
|
setsockopt( fds[0], SOL_SOCKET, SO_RCVBUF, &pipe->insize, sizeof(pipe->insize) );
|
||||||
|
setsockopt( fds[1], SOL_SOCKET, SO_RCVBUF, &pipe->insize, sizeof(pipe->insize) );
|
||||||
|
}
|
||||||
|
if (pipe->outsize)
|
||||||
|
{
|
||||||
|
setsockopt( fds[0], SOL_SOCKET, SO_SNDBUF, &pipe->outsize, sizeof(pipe->outsize) );
|
||||||
|
setsockopt( fds[1], SOL_SOCKET, SO_SNDBUF, &pipe->outsize, sizeof(pipe->outsize) );
|
||||||
|
}
|
||||||
|
|
||||||
|
client->fd = create_anonymous_fd( &pipe_client_fd_ops,
|
||||||
|
fds[1], &client->obj );
|
||||||
|
server->fd = create_anonymous_fd( &pipe_server_fd_ops,
|
||||||
|
fds[0], &server->obj );
|
||||||
|
if (client->fd && server->fd && res != 1)
|
||||||
|
{
|
||||||
|
if (server->state == ps_wait_open)
|
||||||
|
async_terminate_head( &server->wait_q, STATUS_SUCCESS );
|
||||||
|
assert( list_empty( &server->wait_q ) );
|
||||||
|
server->state = ps_connected_server;
|
||||||
|
server->client = client;
|
||||||
|
client->server = server;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
file_set_error();
|
||||||
|
}
|
||||||
|
release_object( server );
|
||||||
|
return &client->obj;
|
||||||
|
}
|
||||||
|
|
||||||
DECL_HANDLER(create_named_pipe)
|
DECL_HANDLER(create_named_pipe)
|
||||||
{
|
{
|
||||||
struct named_pipe *pipe;
|
struct named_pipe *pipe;
|
||||||
|
@ -747,85 +812,6 @@ DECL_HANDLER(create_named_pipe)
|
||||||
release_object( pipe );
|
release_object( pipe );
|
||||||
}
|
}
|
||||||
|
|
||||||
DECL_HANDLER(open_named_pipe)
|
|
||||||
{
|
|
||||||
struct pipe_server *server;
|
|
||||||
struct pipe_client *client;
|
|
||||||
struct unicode_str name;
|
|
||||||
struct directory *root = NULL;
|
|
||||||
struct named_pipe *pipe;
|
|
||||||
int fds[2];
|
|
||||||
|
|
||||||
get_req_unicode_str( &name );
|
|
||||||
if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 )))
|
|
||||||
return;
|
|
||||||
|
|
||||||
pipe = open_object_dir( root, &name, req->attributes, &named_pipe_ops );
|
|
||||||
|
|
||||||
if (root) release_object( root );
|
|
||||||
if (!pipe) return;
|
|
||||||
|
|
||||||
server = find_server2( pipe, ps_idle_server, ps_wait_open );
|
|
||||||
release_object( pipe );
|
|
||||||
|
|
||||||
if (!server)
|
|
||||||
{
|
|
||||||
set_error( STATUS_PIPE_NOT_AVAILABLE );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
client = create_pipe_client( req->flags );
|
|
||||||
if (client)
|
|
||||||
{
|
|
||||||
if (!socketpair( PF_UNIX, SOCK_STREAM, 0, fds ))
|
|
||||||
{
|
|
||||||
int res = 0;
|
|
||||||
|
|
||||||
assert( !client->fd );
|
|
||||||
assert( !server->fd );
|
|
||||||
|
|
||||||
/* for performance reasons, only set nonblocking mode when using
|
|
||||||
* overlapped I/O. Otherwise, we will be doing too much busy
|
|
||||||
* looping */
|
|
||||||
if (is_overlapped( req->flags ))
|
|
||||||
res = fcntl( fds[1], F_SETFL, O_NONBLOCK );
|
|
||||||
if ((res != -1) && is_overlapped( server->options ))
|
|
||||||
res = fcntl( fds[0], F_SETFL, O_NONBLOCK );
|
|
||||||
|
|
||||||
if (pipe->insize)
|
|
||||||
{
|
|
||||||
setsockopt( fds[0], SOL_SOCKET, SO_RCVBUF, &pipe->insize, sizeof(pipe->insize) );
|
|
||||||
setsockopt( fds[1], SOL_SOCKET, SO_RCVBUF, &pipe->insize, sizeof(pipe->insize) );
|
|
||||||
}
|
|
||||||
if (pipe->outsize)
|
|
||||||
{
|
|
||||||
setsockopt( fds[0], SOL_SOCKET, SO_SNDBUF, &pipe->outsize, sizeof(pipe->outsize) );
|
|
||||||
setsockopt( fds[1], SOL_SOCKET, SO_SNDBUF, &pipe->outsize, sizeof(pipe->outsize) );
|
|
||||||
}
|
|
||||||
|
|
||||||
client->fd = create_anonymous_fd( &pipe_client_fd_ops,
|
|
||||||
fds[1], &client->obj );
|
|
||||||
server->fd = create_anonymous_fd( &pipe_server_fd_ops,
|
|
||||||
fds[0], &server->obj );
|
|
||||||
if (client->fd && server->fd && res != 1)
|
|
||||||
{
|
|
||||||
if (server->state == ps_wait_open)
|
|
||||||
async_terminate_head( &server->wait_q, STATUS_SUCCESS );
|
|
||||||
assert( list_empty( &server->wait_q ) );
|
|
||||||
server->state = ps_connected_server;
|
|
||||||
server->client = client;
|
|
||||||
client->server = server;
|
|
||||||
reply->handle = alloc_handle( current->process, client, req->access, req->attributes );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
file_set_error();
|
|
||||||
|
|
||||||
release_object( client );
|
|
||||||
}
|
|
||||||
release_object( server );
|
|
||||||
}
|
|
||||||
|
|
||||||
DECL_HANDLER(connect_named_pipe)
|
DECL_HANDLER(connect_named_pipe)
|
||||||
{
|
{
|
||||||
struct pipe_server *server;
|
struct pipe_server *server;
|
||||||
|
|
|
@ -1992,18 +1992,6 @@ enum message_type
|
||||||
#define NAMED_PIPE_NONBLOCKING_MODE 0x0004
|
#define NAMED_PIPE_NONBLOCKING_MODE 0x0004
|
||||||
#define NAMED_PIPE_SERVER_END 0x8000
|
#define NAMED_PIPE_SERVER_END 0x8000
|
||||||
|
|
||||||
/* Open an existing named pipe */
|
|
||||||
@REQ(open_named_pipe)
|
|
||||||
unsigned int access;
|
|
||||||
unsigned int attributes; /* object attributes */
|
|
||||||
obj_handle_t rootdir; /* root directory */
|
|
||||||
unsigned int flags; /* file flags */
|
|
||||||
VARARG(name,unicode_str); /* pipe name */
|
|
||||||
@REPLY
|
|
||||||
obj_handle_t handle; /* handle to the pipe */
|
|
||||||
@END
|
|
||||||
|
|
||||||
|
|
||||||
/* Connect to a named pipe */
|
/* Connect to a named pipe */
|
||||||
@REQ(connect_named_pipe)
|
@REQ(connect_named_pipe)
|
||||||
obj_handle_t handle;
|
obj_handle_t handle;
|
||||||
|
|
|
@ -245,7 +245,6 @@ DECL_HANDLER(set_serial_info);
|
||||||
DECL_HANDLER(register_async);
|
DECL_HANDLER(register_async);
|
||||||
DECL_HANDLER(cancel_async);
|
DECL_HANDLER(cancel_async);
|
||||||
DECL_HANDLER(create_named_pipe);
|
DECL_HANDLER(create_named_pipe);
|
||||||
DECL_HANDLER(open_named_pipe);
|
|
||||||
DECL_HANDLER(connect_named_pipe);
|
DECL_HANDLER(connect_named_pipe);
|
||||||
DECL_HANDLER(wait_named_pipe);
|
DECL_HANDLER(wait_named_pipe);
|
||||||
DECL_HANDLER(disconnect_named_pipe);
|
DECL_HANDLER(disconnect_named_pipe);
|
||||||
|
@ -468,7 +467,6 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
|
||||||
(req_handler)req_register_async,
|
(req_handler)req_register_async,
|
||||||
(req_handler)req_cancel_async,
|
(req_handler)req_cancel_async,
|
||||||
(req_handler)req_create_named_pipe,
|
(req_handler)req_create_named_pipe,
|
||||||
(req_handler)req_open_named_pipe,
|
|
||||||
(req_handler)req_connect_named_pipe,
|
(req_handler)req_connect_named_pipe,
|
||||||
(req_handler)req_wait_named_pipe,
|
(req_handler)req_wait_named_pipe,
|
||||||
(req_handler)req_disconnect_named_pipe,
|
(req_handler)req_disconnect_named_pipe,
|
||||||
|
|
|
@ -2415,21 +2415,6 @@ static void dump_create_named_pipe_reply( const struct create_named_pipe_reply *
|
||||||
fprintf( stderr, " handle=%p", req->handle );
|
fprintf( stderr, " handle=%p", req->handle );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dump_open_named_pipe_request( const struct open_named_pipe_request *req )
|
|
||||||
{
|
|
||||||
fprintf( stderr, " access=%08x,", req->access );
|
|
||||||
fprintf( stderr, " attributes=%08x,", req->attributes );
|
|
||||||
fprintf( stderr, " rootdir=%p,", req->rootdir );
|
|
||||||
fprintf( stderr, " flags=%08x,", req->flags );
|
|
||||||
fprintf( stderr, " name=" );
|
|
||||||
dump_varargs_unicode_str( cur_size );
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dump_open_named_pipe_reply( const struct open_named_pipe_reply *req )
|
|
||||||
{
|
|
||||||
fprintf( stderr, " handle=%p", req->handle );
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dump_connect_named_pipe_request( const struct connect_named_pipe_request *req )
|
static void dump_connect_named_pipe_request( const struct connect_named_pipe_request *req )
|
||||||
{
|
{
|
||||||
fprintf( stderr, " handle=%p,", req->handle );
|
fprintf( stderr, " handle=%p,", req->handle );
|
||||||
|
@ -3599,7 +3584,6 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
||||||
(dump_func)dump_register_async_request,
|
(dump_func)dump_register_async_request,
|
||||||
(dump_func)dump_cancel_async_request,
|
(dump_func)dump_cancel_async_request,
|
||||||
(dump_func)dump_create_named_pipe_request,
|
(dump_func)dump_create_named_pipe_request,
|
||||||
(dump_func)dump_open_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_wait_named_pipe_request,
|
||||||
(dump_func)dump_disconnect_named_pipe_request,
|
(dump_func)dump_disconnect_named_pipe_request,
|
||||||
|
@ -3819,7 +3803,6 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
||||||
(dump_func)0,
|
(dump_func)0,
|
||||||
(dump_func)0,
|
(dump_func)0,
|
||||||
(dump_func)dump_create_named_pipe_reply,
|
(dump_func)dump_create_named_pipe_reply,
|
||||||
(dump_func)dump_open_named_pipe_reply,
|
|
||||||
(dump_func)0,
|
(dump_func)0,
|
||||||
(dump_func)0,
|
(dump_func)0,
|
||||||
(dump_func)0,
|
(dump_func)0,
|
||||||
|
@ -4039,7 +4022,6 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
|
||||||
"register_async",
|
"register_async",
|
||||||
"cancel_async",
|
"cancel_async",
|
||||||
"create_named_pipe",
|
"create_named_pipe",
|
||||||
"open_named_pipe",
|
|
||||||
"connect_named_pipe",
|
"connect_named_pipe",
|
||||||
"wait_named_pipe",
|
"wait_named_pipe",
|
||||||
"disconnect_named_pipe",
|
"disconnect_named_pipe",
|
||||||
|
|
Loading…
Reference in a new issue