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
|
ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL) == 0
|
||||||
&& GetLastError() == ERROR_PIPE_NOT_CONNECTED,
|
&& GetLastError() == ERROR_PIPE_NOT_CONNECTED,
|
||||||
"ReadFile from disconnected pipe with bytes waiting\n");
|
"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");
|
ok(CloseHandle(hFile), "CloseHandle\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1192,17 +1192,13 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FSCTL_PIPE_DISCONNECT:
|
case FSCTL_PIPE_DISCONNECT:
|
||||||
SERVER_START_REQ(disconnect_named_pipe)
|
status = server_ioctl_file( handle, event, apc, apc_context, io, code,
|
||||||
|
in_buffer, in_size, out_buffer, out_size );
|
||||||
|
if (!status)
|
||||||
{
|
{
|
||||||
req->handle = handle;
|
int fd = server_remove_fd_from_cache( handle );
|
||||||
status = wine_server_call(req);
|
if (fd != -1) close( fd );
|
||||||
if (!status)
|
|
||||||
{
|
|
||||||
int fd = server_remove_fd_from_cache( handle );
|
|
||||||
if (fd != -1) close( fd );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FSCTL_LOCK_VOLUME:
|
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 get_named_pipe_info_request
|
||||||
{
|
{
|
||||||
struct request_header __header;
|
struct request_header __header;
|
||||||
|
@ -4161,7 +4149,6 @@ enum request
|
||||||
REQ_create_named_pipe,
|
REQ_create_named_pipe,
|
||||||
REQ_connect_named_pipe,
|
REQ_connect_named_pipe,
|
||||||
REQ_wait_named_pipe,
|
REQ_wait_named_pipe,
|
||||||
REQ_disconnect_named_pipe,
|
|
||||||
REQ_get_named_pipe_info,
|
REQ_get_named_pipe_info,
|
||||||
REQ_create_window,
|
REQ_create_window,
|
||||||
REQ_destroy_window,
|
REQ_destroy_window,
|
||||||
|
@ -4386,7 +4373,6 @@ union generic_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 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 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;
|
||||||
|
@ -4609,7 +4595,6 @@ union generic_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 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 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;
|
||||||
|
@ -4690,6 +4675,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 293
|
#define SERVER_PROTOCOL_VERSION 294
|
||||||
|
|
||||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
#define WIN32_NO_STATUS
|
#define WIN32_NO_STATUS
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "winternl.h"
|
#include "winternl.h"
|
||||||
|
#include "winioctl.h"
|
||||||
|
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "handle.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_destroy( struct object *obj);
|
||||||
static void pipe_server_flush( struct fd *fd, struct event **event );
|
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 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 =
|
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 */
|
default_poll_event, /* poll_event */
|
||||||
pipe_server_flush, /* flush */
|
pipe_server_flush, /* flush */
|
||||||
pipe_server_get_fd_type, /* get_fd_type */
|
pipe_server_get_fd_type, /* get_fd_type */
|
||||||
default_fd_ioctl, /* ioctl */
|
pipe_server_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 */
|
||||||
|
@ -567,6 +570,46 @@ static enum server_fd_type pipe_client_get_fd_type( struct fd *fd )
|
||||||
return FD_TYPE_PIPE;
|
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,
|
static struct named_pipe *create_named_pipe( struct directory *root, const struct unicode_str *name,
|
||||||
unsigned int attr )
|
unsigned int attr )
|
||||||
{
|
{
|
||||||
|
@ -874,45 +917,6 @@ DECL_HANDLER(wait_named_pipe)
|
||||||
release_object( 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)
|
DECL_HANDLER(get_named_pipe_info)
|
||||||
{
|
{
|
||||||
struct pipe_server *server;
|
struct pipe_server *server;
|
||||||
|
|
|
@ -2021,12 +2021,6 @@ enum message_type
|
||||||
@END
|
@END
|
||||||
|
|
||||||
|
|
||||||
/* Disconnect a named pipe */
|
|
||||||
@REQ(disconnect_named_pipe)
|
|
||||||
obj_handle_t handle;
|
|
||||||
@END
|
|
||||||
|
|
||||||
|
|
||||||
@REQ(get_named_pipe_info)
|
@REQ(get_named_pipe_info)
|
||||||
obj_handle_t handle;
|
obj_handle_t handle;
|
||||||
@REPLY
|
@REPLY
|
||||||
|
|
|
@ -249,7 +249,6 @@ 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(wait_named_pipe);
|
||||||
DECL_HANDLER(disconnect_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);
|
||||||
|
@ -473,7 +472,6 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
|
||||||
(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_wait_named_pipe,
|
||||||
(req_handler)req_disconnect_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,
|
||||||
|
|
|
@ -2456,11 +2456,6 @@ static void dump_wait_named_pipe_request( const struct wait_named_pipe_request *
|
||||||
dump_varargs_unicode_str( cur_size );
|
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 )
|
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 );
|
||||||
|
@ -3611,7 +3606,6 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
||||||
(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_wait_named_pipe_request,
|
||||||
(dump_func)dump_disconnect_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,
|
||||||
|
@ -3832,7 +3826,6 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
||||||
(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)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,
|
||||||
|
@ -4053,7 +4046,6 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
|
||||||
"create_named_pipe",
|
"create_named_pipe",
|
||||||
"connect_named_pipe",
|
"connect_named_pipe",
|
||||||
"wait_named_pipe",
|
"wait_named_pipe",
|
||||||
"disconnect_named_pipe",
|
|
||||||
"get_named_pipe_info",
|
"get_named_pipe_info",
|
||||||
"create_window",
|
"create_window",
|
||||||
"destroy_window",
|
"destroy_window",
|
||||||
|
|
Loading…
Reference in New Issue