From: Sebastian Lackner Subject: [3/4] server: Implement set_named_pipe_info wineserver call for NtSetInformationFile/FilePipeInformation. Message-Id: <53EA6B5A.6050009@fds-team.de> Date: Tue, 12 Aug 2014 21:30:34 +0200 Based on patch by Adam Martinson. This patch adds a new wineserver call set_named_pipe_info to change the properties stored in server->pipe_flags or client->pipe_flags. This request is then used to implement NtSetInformationFile(FilePipeInformation, ...) Invalid combinations (like requesting read message mode when using a byte mode pipe) are rejected with STATUS_INVALID_PARAMETER. Requires ./tools/make_requests --- dlls/ntdll/file.c | 23 +++++++++++++++++++++++ server/named_pipe.c | 38 ++++++++++++++++++++++++++++++++++++++ server/protocol.def | 7 ++++++- 3 files changed, 67 insertions(+), 1 deletion(-) From 91100e52dabb872a1f6c3dfdc98db015cba1d749 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Mon, 11 Aug 2014 17:06:49 +0200 Subject: server: Implement set_named_pipe_info wineserver call for NtSetInformationFile/FilePipeInformation. Based on patch by Adam Martinson. --- dlls/ntdll/file.c | 23 +++++++++++++++++++++++ server/named_pipe.c | 38 ++++++++++++++++++++++++++++++++++++++ server/protocol.def | 7 ++++++- 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index 2ae8bee..92d9829 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -2335,6 +2335,29 @@ NTSTATUS WINAPI NtSetInformationFile(HANDLE handle, PIO_STATUS_BLOCK io, else io->u.Status = STATUS_INVALID_PARAMETER_3; break; + case FilePipeInformation: + if (len >= sizeof(FILE_PIPE_INFORMATION)) + { + FILE_PIPE_INFORMATION *info = ptr; + + if ((info->CompletionMode | info->ReadMode) & ~1) + { + io->u.Status = STATUS_INVALID_PARAMETER; + break; + } + + SERVER_START_REQ( set_named_pipe_info ) + { + req->handle = wine_server_obj_handle( handle ); + req->flags = (info->CompletionMode ? NAMED_PIPE_NONBLOCKING_MODE : 0) | + (info->ReadMode ? NAMED_PIPE_MESSAGE_STREAM_READ : 0); + io->u.Status = wine_server_call( req ); + } + SERVER_END_REQ; + } + else io->u.Status = STATUS_INVALID_PARAMETER_3; + break; + case FileMailslotSetInformation: { FILE_MAILSLOT_SET_INFORMATION *info = ptr; diff --git a/server/named_pipe.c b/server/named_pipe.c index 59fb0ab..0ec069d 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -1045,3 +1045,41 @@ DECL_HANDLER(get_named_pipe_info) release_object(server); } } + +DECL_HANDLER(set_named_pipe_info) +{ + struct pipe_server *server; + struct pipe_client *client = NULL; + + server = get_pipe_server_obj( current->process, req->handle, FILE_WRITE_ATTRIBUTES ); + if (!server) + { + if (get_error() != STATUS_OBJECT_TYPE_MISMATCH) + return; + + clear_error(); + client = (struct pipe_client *)get_handle_obj( current->process, req->handle, + 0, &pipe_client_ops ); + if (!client) return; + server = client->server; + } + + if ((req->flags & ~(NAMED_PIPE_MESSAGE_STREAM_READ | NAMED_PIPE_NONBLOCKING_MODE)) || + ((req->flags & NAMED_PIPE_MESSAGE_STREAM_READ) && !(server->pipe->flags & NAMED_PIPE_MESSAGE_STREAM_WRITE))) + { + set_error( STATUS_INVALID_PARAMETER ); + } + else if (client) + { + client->pipe_flags = server->pipe->flags | req->flags; + } + else + { + server->pipe_flags = server->pipe->flags | req->flags; + } + + if (client) + release_object(client); + else + release_object(server); +} diff --git a/server/protocol.def b/server/protocol.def index a8c1fb9..c9270ea 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -2294,7 +2294,7 @@ enum message_type #define NAMED_PIPE_NONBLOCKING_MODE 0x0004 #define NAMED_PIPE_SERVER_END 0x8000 - +/* Get named pipe information by handle */ @REQ(get_named_pipe_info) obj_handle_t handle; @REPLY @@ -2306,6 +2306,11 @@ enum message_type unsigned int insize; @END +/* Set named pipe information by handle */ +@REQ(set_named_pipe_info) + obj_handle_t handle; + unsigned int flags; +@END /* Create a window */ @REQ(create_window) -- 1.7.9.5