[Wine-patches] [eter-2.1 4/6] server: Implement set_named_pipe_info wineserver call for NtSetInformationFile/FilePipeInformation.

Dmitry Timoshkov dtimoshkov на etersoft.ru
Пн Июн 26 12:24:13 MSK 2017


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                 | 10 ++++++++++
 6 files changed, 98 insertions(+), 2 deletions(-)

diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 13ad6947d3..7d89394269 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -2264,6 +2264,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 ad4f4254fe..2a26f33dcf 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -3106,6 +3106,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
 {
@@ -5150,6 +5162,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,
@@ -5410,6 +5423,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;
@@ -5668,6 +5682,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;
@@ -5782,6 +5797,6 @@ union generic_reply
     struct set_suspend_context_reply set_suspend_context_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 439
+#define SERVER_PROTOCOL_VERSION 440
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/named_pipe.c b/server/named_pipe.c
index ac58ce858d..b348813d7d 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 c524c5ddca..95ca011991 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -2237,7 +2237,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
@@ -2249,6 +2249,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)
diff --git a/server/request.h b/server/request.h
index ec8702bfd4..c9b1c742c1 100644
--- a/server/request.h
+++ b/server/request.h
@@ -252,6 +252,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,
@@ -1512,6 +1514,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 6f6bc8b94a..d9d8d32010 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -2701,6 +2701,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 );
@@ -4168,6 +4174,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,
@@ -4424,6 +4431,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,
@@ -4680,6 +4688,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",
@@ -4854,6 +4863,7 @@ static const struct
     { "IO_TIMEOUT",                  STATUS_IO_TIMEOUT },
     { "KEY_DELETED",                 STATUS_KEY_DELETED },
     { "MAPPED_FILE_SIZE_ZERO",       STATUS_MAPPED_FILE_SIZE_ZERO },
+    { "MORE_PROCESSING_REQUIRED",    STATUS_MORE_PROCESSING_REQUIRED },
     { "MUTANT_NOT_OWNED",            STATUS_MUTANT_NOT_OWNED },
     { "NAME_TOO_LONG",               STATUS_NAME_TOO_LONG },
     { "NETWORK_BUSY",                STATUS_NETWORK_BUSY },
-- 
2.13.1

-- 
Dmitry.


Подробная информация о списке рассылки Wine-patches