server: Implement the FSCTL_PIPE_DISCONNECT ioctl on the server side.

This commit is contained in:
Alexandre Julliard 2007-04-16 14:51:29 +02:00
parent 635714397f
commit 8c46095484
7 changed files with 52 additions and 81 deletions

View File

@ -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");
}

View File

@ -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)
status = server_ioctl_file( handle, event, apc, apc_context, io, code,
in_buffer, in_size, out_buffer, out_size );
if (!status)
{
req->handle = handle;
status = wine_server_call(req);
if (!status)
{
int fd = server_remove_fd_from_cache( handle );
if (fd != -1) close( fd );
}
int fd = server_remove_fd_from_cache( handle );
if (fd != -1) close( fd );
}
SERVER_END_REQ;
break;
case FSCTL_LOCK_VOLUME:

View File

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

View File

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

View File

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

View File

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

View File

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