Sebastian Lackner : server: Implement set_named_pipe_info wineserver call for NtSetInformationFile/ FilePipeInformation.
Alexandre Julliard
julliard at wine.codeweavers.com
Wed Aug 20 14:30:34 CDT 2014
Module: wine
Branch: master
Commit: 82ce3fdcfd1a5d8bfe24d58dcc51ddc3a1dea040
URL: http://source.winehq.org/git/wine.git/?a=commit;h=82ce3fdcfd1a5d8bfe24d58dcc51ddc3a1dea040
Author: Sebastian Lackner <sebastian at fds-team.de>
Date: Mon Aug 11 17:06:49 2014 +0200
server: Implement set_named_pipe_info wineserver call for NtSetInformationFile/FilePipeInformation.
Based on a patch by Adam Martinson.
---
dlls/ntdll/file.c | 23 +++++++++++++++++++++++
include/wine/server_protocol.h | 17 ++++++++++++++++-
server/named_pipe.c | 38 ++++++++++++++++++++++++++++++++++++++
server/protocol.def | 7 ++++++-
server/request.h | 5 +++++
server/trace.c | 9 +++++++++
6 files changed, 97 insertions(+), 2 deletions(-)
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/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 57ab839..cc966f2 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -3189,6 +3189,18 @@ struct get_named_pipe_info_reply
};
+struct set_named_pipe_info_request
+{
+ struct request_header __header;
+ obj_handle_t handle;
+ unsigned int flags;
+ char __pad_20[4];
+};
+struct set_named_pipe_info_reply
+{
+ struct reply_header __header;
+};
+
struct create_window_request
{
@@ -5203,6 +5215,7 @@ enum request
REQ_get_ioctl_result,
REQ_create_named_pipe,
REQ_get_named_pipe_info,
+ REQ_set_named_pipe_info,
REQ_create_window,
REQ_destroy_window,
REQ_get_desktop_window,
@@ -5464,6 +5477,7 @@ union generic_request
struct get_ioctl_result_request get_ioctl_result_request;
struct create_named_pipe_request create_named_pipe_request;
struct get_named_pipe_info_request get_named_pipe_info_request;
+ struct set_named_pipe_info_request set_named_pipe_info_request;
struct create_window_request create_window_request;
struct destroy_window_request destroy_window_request;
struct get_desktop_window_request get_desktop_window_request;
@@ -5723,6 +5737,7 @@ union generic_reply
struct get_ioctl_result_reply get_ioctl_result_reply;
struct create_named_pipe_reply create_named_pipe_reply;
struct get_named_pipe_info_reply get_named_pipe_info_reply;
+ struct set_named_pipe_info_reply set_named_pipe_info_reply;
struct create_window_reply create_window_reply;
struct destroy_window_reply destroy_window_reply;
struct get_desktop_window_reply get_desktop_window_reply;
@@ -5834,6 +5849,6 @@ union generic_reply
struct set_suspend_context_reply set_suspend_context_reply;
};
-#define SERVER_PROTOCOL_VERSION 456
+#define SERVER_PROTOCOL_VERSION 457
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/named_pipe.c b/server/named_pipe.c
index d864478..3750d25 100644
--- a/server/named_pipe.c
+++ b/server/named_pipe.c
@@ -1046,3 +1046,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 */
+ at REQ(set_named_pipe_info)
+ obj_handle_t handle;
+ unsigned int flags;
+ at END
/* Create a window */
@REQ(create_window)
diff --git a/server/request.h b/server/request.h
index e25e327..c75a636 100644
--- a/server/request.h
+++ b/server/request.h
@@ -251,6 +251,7 @@ DECL_HANDLER(ioctl);
DECL_HANDLER(get_ioctl_result);
DECL_HANDLER(create_named_pipe);
DECL_HANDLER(get_named_pipe_info);
+DECL_HANDLER(set_named_pipe_info);
DECL_HANDLER(create_window);
DECL_HANDLER(destroy_window);
DECL_HANDLER(get_desktop_window);
@@ -511,6 +512,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_get_ioctl_result,
(req_handler)req_create_named_pipe,
(req_handler)req_get_named_pipe_info,
+ (req_handler)req_set_named_pipe_info,
(req_handler)req_create_window,
(req_handler)req_destroy_window,
(req_handler)req_get_desktop_window,
@@ -1536,6 +1538,9 @@ C_ASSERT( FIELD_OFFSET(struct get_named_pipe_info_reply, instances) == 20 );
C_ASSERT( FIELD_OFFSET(struct get_named_pipe_info_reply, outsize) == 24 );
C_ASSERT( FIELD_OFFSET(struct get_named_pipe_info_reply, insize) == 28 );
C_ASSERT( sizeof(struct get_named_pipe_info_reply) == 32 );
+C_ASSERT( FIELD_OFFSET(struct set_named_pipe_info_request, handle) == 12 );
+C_ASSERT( FIELD_OFFSET(struct set_named_pipe_info_request, flags) == 16 );
+C_ASSERT( sizeof(struct set_named_pipe_info_request) == 24 );
C_ASSERT( FIELD_OFFSET(struct create_window_request, parent) == 12 );
C_ASSERT( FIELD_OFFSET(struct create_window_request, owner) == 16 );
C_ASSERT( FIELD_OFFSET(struct create_window_request, atom) == 20 );
diff --git a/server/trace.c b/server/trace.c
index 4834354..cb8da0c 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -2776,6 +2776,12 @@ static void dump_get_named_pipe_info_reply( const struct get_named_pipe_info_rep
fprintf( stderr, ", insize=%08x", req->insize );
}
+static void dump_set_named_pipe_info_request( const struct set_named_pipe_info_request *req )
+{
+ fprintf( stderr, " handle=%04x", req->handle );
+ fprintf( stderr, ", flags=%08x", req->flags );
+}
+
static void dump_create_window_request( const struct create_window_request *req )
{
fprintf( stderr, " parent=%08x", req->parent );
@@ -4226,6 +4232,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_get_ioctl_result_request,
(dump_func)dump_create_named_pipe_request,
(dump_func)dump_get_named_pipe_info_request,
+ (dump_func)dump_set_named_pipe_info_request,
(dump_func)dump_create_window_request,
(dump_func)dump_destroy_window_request,
(dump_func)dump_get_desktop_window_request,
@@ -4483,6 +4490,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_get_ioctl_result_reply,
(dump_func)dump_create_named_pipe_reply,
(dump_func)dump_get_named_pipe_info_reply,
+ NULL,
(dump_func)dump_create_window_reply,
NULL,
(dump_func)dump_get_desktop_window_reply,
@@ -4740,6 +4748,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"get_ioctl_result",
"create_named_pipe",
"get_named_pipe_info",
+ "set_named_pipe_info",
"create_window",
"destroy_window",
"get_desktop_window",
More information about the wine-cvs
mailing list