mirror of
https://github.com/reactos/wine.git
synced 2024-11-24 20:30:01 +00:00
server: Implement the FSCTL_PIPE_DISCONNECT ioctl on the server side.
This commit is contained in:
parent
635714397f
commit
8c46095484
@ -744,6 +744,8 @@ static int test_DisconnectNamedPipe(void)
|
||||
ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL) == 0
|
||||
&& GetLastError() == ERROR_PIPE_NOT_CONNECTED,
|
||||
"ReadFile from disconnected pipe with bytes waiting\n");
|
||||
ok(!DisconnectNamedPipe(hnp) && GetLastError() == ERROR_PIPE_NOT_CONNECTED,
|
||||
"DisconnectNamedPipe worked twice\n");
|
||||
ok(CloseHandle(hFile), "CloseHandle\n");
|
||||
}
|
||||
|
||||
|
@ -1192,17 +1192,13 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_DISCONNECT:
|
||||
SERVER_START_REQ(disconnect_named_pipe)
|
||||
{
|
||||
req->handle = handle;
|
||||
status = wine_server_call(req);
|
||||
status = server_ioctl_file( handle, event, apc, apc_context, io, code,
|
||||
in_buffer, in_size, out_buffer, out_size );
|
||||
if (!status)
|
||||
{
|
||||
int fd = server_remove_fd_from_cache( handle );
|
||||
if (fd != -1) close( fd );
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
break;
|
||||
|
||||
case FSCTL_LOCK_VOLUME:
|
||||
|
@ -2749,18 +2749,6 @@ struct wait_named_pipe_reply
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct disconnect_named_pipe_request
|
||||
{
|
||||
struct request_header __header;
|
||||
obj_handle_t handle;
|
||||
};
|
||||
struct disconnect_named_pipe_reply
|
||||
{
|
||||
struct reply_header __header;
|
||||
};
|
||||
|
||||
|
||||
struct get_named_pipe_info_request
|
||||
{
|
||||
struct request_header __header;
|
||||
@ -4161,7 +4149,6 @@ enum request
|
||||
REQ_create_named_pipe,
|
||||
REQ_connect_named_pipe,
|
||||
REQ_wait_named_pipe,
|
||||
REQ_disconnect_named_pipe,
|
||||
REQ_get_named_pipe_info,
|
||||
REQ_create_window,
|
||||
REQ_destroy_window,
|
||||
@ -4386,7 +4373,6 @@ union generic_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 disconnect_named_pipe_request disconnect_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;
|
||||
@ -4609,7 +4595,6 @@ union generic_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 disconnect_named_pipe_reply disconnect_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;
|
||||
@ -4690,6 +4675,6 @@ union generic_reply
|
||||
struct allocate_locally_unique_id_reply allocate_locally_unique_id_reply;
|
||||
};
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 293
|
||||
#define SERVER_PROTOCOL_VERSION 294
|
||||
|
||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||
|
@ -46,6 +46,7 @@
|
||||
#define WIN32_NO_STATUS
|
||||
#include "windef.h"
|
||||
#include "winternl.h"
|
||||
#include "winioctl.h"
|
||||
|
||||
#include "file.h"
|
||||
#include "handle.h"
|
||||
@ -138,6 +139,8 @@ static struct fd *pipe_server_get_fd( struct object *obj );
|
||||
static void pipe_server_destroy( struct object *obj);
|
||||
static void pipe_server_flush( struct fd *fd, struct event **event );
|
||||
static enum server_fd_type pipe_server_get_fd_type( struct fd *fd );
|
||||
static void pipe_server_ioctl( struct fd *fd, unsigned int code, const async_data_t *async,
|
||||
const void *data, data_size_t size );
|
||||
|
||||
static const struct object_ops pipe_server_ops =
|
||||
{
|
||||
@ -162,7 +165,7 @@ static const struct fd_ops pipe_server_fd_ops =
|
||||
default_poll_event, /* poll_event */
|
||||
pipe_server_flush, /* flush */
|
||||
pipe_server_get_fd_type, /* get_fd_type */
|
||||
default_fd_ioctl, /* ioctl */
|
||||
pipe_server_ioctl, /* ioctl */
|
||||
default_fd_queue_async, /* queue_async */
|
||||
default_fd_reselect_async, /* reselect_async */
|
||||
default_fd_cancel_async, /* cancel_async */
|
||||
@ -567,6 +570,46 @@ static enum server_fd_type pipe_client_get_fd_type( struct fd *fd )
|
||||
return FD_TYPE_PIPE;
|
||||
}
|
||||
|
||||
static void pipe_server_ioctl( struct fd *fd, unsigned int code, const async_data_t *async,
|
||||
const void *data, data_size_t size )
|
||||
{
|
||||
struct pipe_server *server = get_fd_user( fd );
|
||||
|
||||
switch(code)
|
||||
{
|
||||
case FSCTL_PIPE_DISCONNECT:
|
||||
switch(server->state)
|
||||
{
|
||||
case ps_connected_server:
|
||||
assert( server->client );
|
||||
assert( server->client->fd );
|
||||
|
||||
notify_empty( server );
|
||||
|
||||
/* dump the client and server fds, but keep the pointers
|
||||
around - client loses all waiting data */
|
||||
server->state = ps_disconnected_server;
|
||||
do_disconnect( server );
|
||||
break;
|
||||
case ps_wait_disconnect:
|
||||
assert( !server->client );
|
||||
do_disconnect( server );
|
||||
server->state = ps_wait_connect;
|
||||
break;
|
||||
case ps_idle_server:
|
||||
case ps_wait_open:
|
||||
case ps_disconnected_server:
|
||||
case ps_wait_connect:
|
||||
assert(0); /* shouldn't even get an fd */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
default_fd_ioctl( fd, code, async, data, size );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static struct named_pipe *create_named_pipe( struct directory *root, const struct unicode_str *name,
|
||||
unsigned int attr )
|
||||
{
|
||||
@ -874,45 +917,6 @@ DECL_HANDLER(wait_named_pipe)
|
||||
release_object( pipe );
|
||||
}
|
||||
|
||||
DECL_HANDLER(disconnect_named_pipe)
|
||||
{
|
||||
struct pipe_server *server;
|
||||
|
||||
server = get_pipe_server_obj( current->process, req->handle, 0 );
|
||||
if (!server)
|
||||
return;
|
||||
switch(server->state)
|
||||
{
|
||||
case ps_connected_server:
|
||||
assert( server->fd );
|
||||
assert( server->client );
|
||||
assert( server->client->fd );
|
||||
|
||||
notify_empty( server );
|
||||
|
||||
/* Dump the client and server fds, but keep the pointers
|
||||
around - client loses all waiting data */
|
||||
server->state = ps_disconnected_server;
|
||||
do_disconnect( server );
|
||||
break;
|
||||
|
||||
case ps_wait_disconnect:
|
||||
assert( !server->client );
|
||||
assert( server->fd );
|
||||
do_disconnect( server );
|
||||
server->state = ps_wait_connect;
|
||||
break;
|
||||
|
||||
case ps_idle_server:
|
||||
case ps_wait_open:
|
||||
case ps_disconnected_server:
|
||||
case ps_wait_connect:
|
||||
set_error( STATUS_PIPE_DISCONNECTED );
|
||||
break;
|
||||
}
|
||||
release_object( server );
|
||||
}
|
||||
|
||||
DECL_HANDLER(get_named_pipe_info)
|
||||
{
|
||||
struct pipe_server *server;
|
||||
|
@ -2021,12 +2021,6 @@ enum message_type
|
||||
@END
|
||||
|
||||
|
||||
/* Disconnect a named pipe */
|
||||
@REQ(disconnect_named_pipe)
|
||||
obj_handle_t handle;
|
||||
@END
|
||||
|
||||
|
||||
@REQ(get_named_pipe_info)
|
||||
obj_handle_t handle;
|
||||
@REPLY
|
||||
|
@ -249,7 +249,6 @@ DECL_HANDLER(ioctl);
|
||||
DECL_HANDLER(create_named_pipe);
|
||||
DECL_HANDLER(connect_named_pipe);
|
||||
DECL_HANDLER(wait_named_pipe);
|
||||
DECL_HANDLER(disconnect_named_pipe);
|
||||
DECL_HANDLER(get_named_pipe_info);
|
||||
DECL_HANDLER(create_window);
|
||||
DECL_HANDLER(destroy_window);
|
||||
@ -473,7 +472,6 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
|
||||
(req_handler)req_create_named_pipe,
|
||||
(req_handler)req_connect_named_pipe,
|
||||
(req_handler)req_wait_named_pipe,
|
||||
(req_handler)req_disconnect_named_pipe,
|
||||
(req_handler)req_get_named_pipe_info,
|
||||
(req_handler)req_create_window,
|
||||
(req_handler)req_destroy_window,
|
||||
|
@ -2456,11 +2456,6 @@ static void dump_wait_named_pipe_request( const struct wait_named_pipe_request *
|
||||
dump_varargs_unicode_str( cur_size );
|
||||
}
|
||||
|
||||
static void dump_disconnect_named_pipe_request( const struct disconnect_named_pipe_request *req )
|
||||
{
|
||||
fprintf( stderr, " handle=%p", req->handle );
|
||||
}
|
||||
|
||||
static void dump_get_named_pipe_info_request( const struct get_named_pipe_info_request *req )
|
||||
{
|
||||
fprintf( stderr, " handle=%p", req->handle );
|
||||
@ -3611,7 +3606,6 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
||||
(dump_func)dump_create_named_pipe_request,
|
||||
(dump_func)dump_connect_named_pipe_request,
|
||||
(dump_func)dump_wait_named_pipe_request,
|
||||
(dump_func)dump_disconnect_named_pipe_request,
|
||||
(dump_func)dump_get_named_pipe_info_request,
|
||||
(dump_func)dump_create_window_request,
|
||||
(dump_func)dump_destroy_window_request,
|
||||
@ -3832,7 +3826,6 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
||||
(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_create_window_reply,
|
||||
(dump_func)0,
|
||||
@ -4053,7 +4046,6 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
|
||||
"create_named_pipe",
|
||||
"connect_named_pipe",
|
||||
"wait_named_pipe",
|
||||
"disconnect_named_pipe",
|
||||
"get_named_pipe_info",
|
||||
"create_window",
|
||||
"destroy_window",
|
||||
|
Loading…
Reference in New Issue
Block a user