[wing: 1/2] Add support for INBOUND/OUTBOUND named pipe access



commit c40e4375bf0bc7293ebf7c39b48a64db492168ab
Author: Marco Alesiani <alesiani amazon com>
Date:   Tue Aug 21 11:41:08 2018 +0200

    Add support for INBOUND/OUTBOUND named pipe access
    
    Adds support for INBOUND/OUTBOUND fashion access control
    for named pipes. The previous code would always cause a
    DUPLEX pipe to be opened and fail if remote server pipe
    permissions were INBOUND or OUTBOUND only.

 tests/named-pipe.c         | 10 ++++++++
 wing/wingnamedpipeclient.c | 61 ++++++++++++++++++++++++++++++++++++----------
 wing/wingnamedpipeclient.h | 32 +++++++++++++++---------
 3 files changed, 78 insertions(+), 25 deletions(-)
---
diff --git a/tests/named-pipe.c b/tests/named-pipe.c
index 7e83eaf..69bf8ee 100644
--- a/tests/named-pipe.c
+++ b/tests/named-pipe.c
@@ -105,6 +105,7 @@ test_connect_basic (void)
   client = wing_named_pipe_client_new ();
   wing_named_pipe_client_connect_async (client,
                                         "\\\\.\\pipe\\gtest-named-pipe-name",
+                                        WING_NAMED_PIPE_CLIENT_GENERIC_READ | 
WING_NAMED_PIPE_CLIENT_GENERIC_WRITE,
                                         NULL,
                                         connected_cb,
                                         &success_connected);
@@ -138,6 +139,7 @@ test_connect_before_accept (void)
   client = wing_named_pipe_client_new ();
   wing_named_pipe_client_connect_async (client,
                                         "\\\\.\\pipe\\gtest-named-pipe-name",
+                                        WING_NAMED_PIPE_CLIENT_GENERIC_READ | 
WING_NAMED_PIPE_CLIENT_GENERIC_WRITE,
                                         NULL,
                                         connected_cb,
                                         &success_connected);
@@ -175,6 +177,7 @@ test_connect_sync (void)
   client = wing_named_pipe_client_new ();
   connection = wing_named_pipe_client_connect (client,
                                                "\\\\.\\pipe\\gtest-connect-sync",
+                                               WING_NAMED_PIPE_CLIENT_GENERIC_READ | 
WING_NAMED_PIPE_CLIENT_GENERIC_WRITE,
                                                NULL,
                                                &error);
 
@@ -195,6 +198,7 @@ test_connect_sync_fails (void)
   client = wing_named_pipe_client_new ();
   connection = wing_named_pipe_client_connect (client,
                                                "\\\\.\\pipe\\gtest-connect-sync-fails",
+                                               WING_NAMED_PIPE_CLIENT_GENERIC_READ | 
WING_NAMED_PIPE_CLIENT_GENERIC_WRITE,
                                                NULL,
                                                &error);
 
@@ -291,6 +295,7 @@ test_connect_accept_cancel (void)
   client = wing_named_pipe_client_new ();
   wing_named_pipe_client_connect_async (client,
                                         "\\\\.\\pipe\\gtest-named-pipe-name-connect-then-cancel",
+                                        WING_NAMED_PIPE_CLIENT_GENERIC_READ | 
WING_NAMED_PIPE_CLIENT_GENERIC_WRITE,
                                         NULL,
                                         connected_cb,
                                         &success_connected);
@@ -345,6 +350,7 @@ test_multi_client_basic (void)
   client = wing_named_pipe_client_new ();
   wing_named_pipe_client_connect_async (client,
                                         "\\\\.\\pipe\\gtest-named-pipe-name-connect-multi-client",
+                                        WING_NAMED_PIPE_CLIENT_GENERIC_READ | 
WING_NAMED_PIPE_CLIENT_GENERIC_WRITE,
                                         NULL,
                                         connected_cb,
                                         &success_connected);
@@ -366,6 +372,7 @@ test_multi_client_basic (void)
   client = wing_named_pipe_client_new ();
   wing_named_pipe_client_connect_async (client,
                                         "\\\\.\\pipe\\gtest-named-pipe-name-connect-multi-client",
+                                        WING_NAMED_PIPE_CLIENT_GENERIC_READ | 
WING_NAMED_PIPE_CLIENT_GENERIC_WRITE,
                                         NULL,
                                         connected_cb,
                                         &success_connected);
@@ -553,6 +560,7 @@ test_read_write_basic (void)
   client = wing_named_pipe_client_new ();
   wing_named_pipe_client_connect_async (client,
                                         "\\\\.\\pipe\\gtest-named-pipe-name",
+                                        WING_NAMED_PIPE_CLIENT_GENERIC_READ | 
WING_NAMED_PIPE_CLIENT_GENERIC_WRITE,
                                         NULL,
                                         connected_read_write_cb,
                                         &conn_client);
@@ -600,6 +608,7 @@ test_read_write_several_connections (void)
       client = wing_named_pipe_client_new ();
       wing_named_pipe_client_connect_async (client,
                                             "\\\\.\\pipe\\gtest-named-pipe-name-read-write-several",
+                                            WING_NAMED_PIPE_CLIENT_GENERIC_READ | 
WING_NAMED_PIPE_CLIENT_GENERIC_WRITE,
                                             NULL,
                                             connected_read_write_cb,
                                             &conn_client);
@@ -654,6 +663,7 @@ test_read_write_same_time_several_connections (void)
       client = wing_named_pipe_client_new ();
       wing_named_pipe_client_connect_async (client,
                                             "\\\\.\\pipe\\gtest-named-pipe-name-read-write-several",
+                                            WING_NAMED_PIPE_CLIENT_GENERIC_READ | 
WING_NAMED_PIPE_CLIENT_GENERIC_WRITE,
                                             NULL,
                                             connected_read_write_cb,
                                             &conn_client);
diff --git a/wing/wingnamedpipeclient.c b/wing/wingnamedpipeclient.c
index 9524acf..2b57910 100644
--- a/wing/wingnamedpipeclient.c
+++ b/wing/wingnamedpipeclient.c
@@ -143,6 +143,7 @@ wing_named_pipe_client_new (void)
  * wing_named_pipe_client_connect:
  * @client: a #WingNamedPipeClient.
  * @pipe_name: a pipe name.
+ * @flags: requested access to the pipe (read, write, both or none).
  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
  * @error: #GError for error reporting, or %NULL to ignore.
  *
@@ -155,15 +156,17 @@ wing_named_pipe_client_new (void)
  * Returns: (transfer full): a #WingNamedPipeConnection on success, %NULL on error.
  */
 WingNamedPipeConnection *
-wing_named_pipe_client_connect (WingNamedPipeClient  *client,
-                                const gchar          *pipe_name,
-                                GCancellable         *cancellable,
-                                GError              **error)
+wing_named_pipe_client_connect (WingNamedPipeClient     *client,
+                                const gchar             *pipe_name,
+                                WingNamedPipeClientFlags flags,
+                                GCancellable            *cancellable,
+                                GError                  **error)
 {
   WingNamedPipeClientPrivate *priv;
   HANDLE handle = INVALID_HANDLE_VALUE;
   WingNamedPipeConnection *connection = NULL;
   gunichar2 *pipe_namew;
+  DWORD pipe_flags = 0;
 
   g_return_val_if_fail (WING_IS_NAMED_PIPE_CLIENT (client), NULL);
   g_return_val_if_fail (pipe_name != NULL, NULL);
@@ -181,8 +184,14 @@ wing_named_pipe_client_connect (WingNamedPipeClient  *client,
       if (g_cancellable_set_error_if_cancelled (cancellable, error))
         break;
 
+      if (flags & WING_NAMED_PIPE_CLIENT_GENERIC_READ)
+        pipe_flags |= GENERIC_READ;
+
+      if (flags & WING_NAMED_PIPE_CLIENT_GENERIC_WRITE)
+        pipe_flags |= GENERIC_WRITE;
+
       handle = CreateFileW (pipe_namew,
-                            GENERIC_READ | GENERIC_WRITE,
+                            pipe_flags,
                             FILE_SHARE_READ | FILE_SHARE_WRITE,
                             NULL,
                             OPEN_EXISTING,
@@ -235,6 +244,29 @@ wing_named_pipe_client_connect (WingNamedPipeClient  *client,
   return connection;
 }
 
+typedef struct
+{
+  gchar                      *pipe_name;
+  WingNamedPipeClientFlags    flags;
+} PipeAsyncTaskData;
+
+static PipeAsyncTaskData*
+create_pipe_async_task_data(const gchar                 *pipe_name,
+                            WingNamedPipeClientFlags     flags)
+{
+  PipeAsyncTaskData *task_data = g_new0(PipeAsyncTaskData, 1);
+  task_data->pipe_name = g_strdup(pipe_name);
+  task_data->flags = flags;
+  return task_data;
+}
+
+static void
+free_pipe_async_task_data(PipeAsyncTaskData *task_data)
+{
+  g_free(task_data->pipe_name);
+  g_free(task_data);
+}
+
 static void
 client_connect_thread (GTask        *task,
                        gpointer      source_object,
@@ -242,11 +274,12 @@ client_connect_thread (GTask        *task,
                        GCancellable *cancellable)
 {
   WingNamedPipeClient *client = WING_NAMED_PIPE_CLIENT (source_object);
-  const gchar *pipe_name = (const gchar *)task_data;
+  PipeAsyncTaskData *data = (PipeAsyncTaskData*)task_data;
   WingNamedPipeConnection *connection;
   GError *error = NULL;
 
-  connection = wing_named_pipe_client_connect (client, pipe_name,
+  connection = wing_named_pipe_client_connect (client, (const gchar *)data->pipe_name,
+                                               data->flags,
                                                cancellable, &error);
 
   if (connection == NULL)
@@ -272,11 +305,12 @@ client_connect_thread (GTask        *task,
  * the result of the operation.
  */
 void
-wing_named_pipe_client_connect_async (WingNamedPipeClient  *client,
-                                      const gchar          *pipe_name,
-                                      GCancellable         *cancellable,
-                                      GAsyncReadyCallback   callback,
-                                      gpointer              user_data)
+wing_named_pipe_client_connect_async (WingNamedPipeClient       *client,
+                                      const gchar               *pipe_name,
+                                      WingNamedPipeClientFlags   flags,
+                                      GCancellable              *cancellable,
+                                      GAsyncReadyCallback        callback,
+                                      gpointer                   user_data)
 {
   GTask *task;
 
@@ -284,7 +318,8 @@ wing_named_pipe_client_connect_async (WingNamedPipeClient  *client,
   g_return_if_fail (pipe_name != NULL);
 
   task = g_task_new (client, cancellable, callback, user_data);
-  g_task_set_task_data (task, g_strdup (pipe_name), g_free);
+  g_task_set_task_data (task, create_pipe_async_task_data(pipe_name, flags),
+                        (GDestroyNotify)free_pipe_async_task_data);
 
   g_task_run_in_thread (task, client_connect_thread);
 }
diff --git a/wing/wingnamedpipeclient.h b/wing/wingnamedpipeclient.h
index f55a373..46b4eab 100644
--- a/wing/wingnamedpipeclient.h
+++ b/wing/wingnamedpipeclient.h
@@ -48,6 +48,12 @@ struct _WingNamedPipeClientClass
   gpointer padding[10];
 };
 
+typedef enum
+{
+  WING_NAMED_PIPE_CLIENT_GENERIC_READ  = (1 << 0),
+  WING_NAMED_PIPE_CLIENT_GENERIC_WRITE = (1 << 1)
+} WingNamedPipeClientFlags;
+
 WING_AVAILABLE_IN_ALL
 GType                     wing_named_pipe_client_get_type         (void) G_GNUC_CONST;
 
@@ -55,22 +61,24 @@ WING_AVAILABLE_IN_ALL
 WingNamedPipeClient      *wing_named_pipe_client_new              (void);
 
 WING_AVAILABLE_IN_ALL
-WingNamedPipeConnection  *wing_named_pipe_client_connect          (WingNamedPipeClient  *client,
-                                                                   const gchar          *pipe_name,
-                                                                   GCancellable         *cancellable,
-                                                                   GError              **error);
+WingNamedPipeConnection  *wing_named_pipe_client_connect          (WingNamedPipeClient      *client,
+                                                                   const gchar              *pipe_name,
+                                                                   WingNamedPipeClientFlags  flags,
+                                                                   GCancellable             *cancellable,
+                                                                   GError                   **error);
 
 WING_AVAILABLE_IN_ALL
-void                      wing_named_pipe_client_connect_async    (WingNamedPipeClient  *client,
-                                                                   const gchar          *pipe_name,
-                                                                   GCancellable         *cancellable,
-                                                                   GAsyncReadyCallback   callback,
-                                                                   gpointer              user_data);
+void                      wing_named_pipe_client_connect_async    (WingNamedPipeClient      *client,
+                                                                   const gchar              *pipe_name,
+                                                                   WingNamedPipeClientFlags  flags,
+                                                                   GCancellable             *cancellable,
+                                                                   GAsyncReadyCallback       callback,
+                                                                   gpointer                  user_data);
 
 WING_AVAILABLE_IN_ALL
-WingNamedPipeConnection  *wing_named_pipe_client_connect_finish   (WingNamedPipeClient  *client,
-                                                                   GAsyncResult         *result,
-                                                                   GError              **error);
+WingNamedPipeConnection  *wing_named_pipe_client_connect_finish   (WingNamedPipeClient      *client,
+                                                                   GAsyncResult             *result,
+                                                                   GError                  **error);
 
 G_END_DECLS
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]