[wing] Adds argument to create pipes with FILE_FLAG_FIRST_PIPE_INSTANCE



commit 4f210b1820727f48ebcf9b2281b0b2625286466d
Author: Marco Mastropaolo <marcomp amazon com>
Date:   Fri Jan 10 11:14:21 2020 +0100

    Adds argument to create pipes with FILE_FLAG_FIRST_PIPE_INSTANCE

 tests/named-pipe.c           | 72 ++++++++++++++++++++++++++++++++++++++++++++
 wing/wingnamedpipelistener.c | 24 ++++++++++++---
 wing/wingnamedpipelistener.h |  1 +
 3 files changed, 92 insertions(+), 5 deletions(-)
---
diff --git a/tests/named-pipe.c b/tests/named-pipe.c
index b3f55ec..e745e78 100644
--- a/tests/named-pipe.c
+++ b/tests/named-pipe.c
@@ -42,6 +42,7 @@ test_add_named_pipe (gconstpointer user_data)
   wing_named_pipe_listener_add_named_pipe (listener,
                                            "\\\\.\\pipe\\gtest-good-named-pipe-name",
                                            NULL,
+                                           FALSE,
                                            NULL,
                                            &error);
   g_assert_no_error (error);
@@ -49,6 +50,65 @@ test_add_named_pipe (gconstpointer user_data)
   wing_named_pipe_listener_add_named_pipe (listener,
                                            "\\\\.\\gtest-bad-named-pipe-name",
                                            NULL,
+                                           FALSE,
+                                           NULL,
+                                           &error);
+  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
+
+  g_object_unref (listener);
+}
+
+static void
+test_add_named_pipe_multiple_instances_no_protect (gconstpointer user_data)
+{
+  WingNamedPipeListener *listener;
+  GError *error = NULL;
+  TestData *test_data = (TestData *) user_data;
+
+  listener = wing_named_pipe_listener_new ();
+  wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
+
+  wing_named_pipe_listener_add_named_pipe (listener,
+                                           "\\\\.\\pipe\\unprotected-named-pipe",
+                                           NULL,
+                                           FALSE,
+                                           NULL,
+                                           &error);
+  g_assert_no_error (error);
+
+  wing_named_pipe_listener_add_named_pipe (listener,
+                                           "\\\\.\\pipe\\unprotected-named-pipe",
+                                           NULL,
+                                           FALSE,
+                                           NULL,
+                                           &error);
+  g_assert_no_error (error);
+
+  g_object_unref (listener);
+}
+
+static void
+test_add_named_pipe_multiple_instances_protected (gconstpointer user_data)
+{
+  WingNamedPipeListener *listener;
+  GError *error = NULL;
+  TestData *test_data = (TestData *) user_data;
+
+  listener = wing_named_pipe_listener_new ();
+  wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
+
+  wing_named_pipe_listener_add_named_pipe (listener,
+                                           "\\\\.\\pipe\\protected-named-pipe",
+                                           NULL,
+                                           TRUE,
+                                           NULL,
+                                           &error);
+  g_assert_no_error (error);
+
+  wing_named_pipe_listener_add_named_pipe (listener,
+                                           "\\\\.\\pipe\\protected-named-pipe",
+                                           NULL,
+                                           TRUE,
                                            NULL,
                                            &error);
   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
@@ -106,6 +166,7 @@ test_connect_basic (gconstpointer user_data)
   wing_named_pipe_listener_add_named_pipe (listener,
                                            "\\\\.\\pipe\\gtest-named-pipe-name",
                                            NULL,
+                                           FALSE,
                                            NULL,
                                            &error);
   g_assert_no_error (error);
@@ -149,6 +210,7 @@ test_connect_before_accept (gconstpointer user_data)
   wing_named_pipe_listener_add_named_pipe (listener,
                                            "\\\\.\\pipe\\gtest-named-pipe-name",
                                            NULL,
+                                           FALSE,
                                            NULL,
                                            &error);
   g_assert_no_error (error);
@@ -191,6 +253,7 @@ test_connect_sync (gconstpointer user_data)
   wing_named_pipe_listener_add_named_pipe (listener,
                                            "\\\\.\\pipe\\gtest-connect-sync",
                                            NULL,
+                                           FALSE,
                                            NULL,
                                            &error);
   g_assert_no_error (error);
@@ -276,6 +339,7 @@ test_accept_cancel (gconstpointer user_data)
   wing_named_pipe_listener_add_named_pipe (listener,
                                            "\\\\.\\pipe\\gtest-named-pipe-name-cancel",
                                            NULL,
+                                           FALSE,
                                            NULL,
                                            &error);
   g_assert_no_error (error);
@@ -313,6 +377,7 @@ test_connect_accept_cancel (gconstpointer user_data)
   wing_named_pipe_listener_add_named_pipe (listener,
                                            "\\\\.\\pipe\\gtest-named-pipe-name-connect-then-cancel",
                                            NULL,
+                                           FALSE,
                                            NULL,
                                            &error);
   g_assert_no_error (error);
@@ -372,6 +437,7 @@ test_multi_client_basic (gconstpointer user_data)
   wing_named_pipe_listener_add_named_pipe (listener,
                                            "\\\\.\\pipe\\gtest-named-pipe-name-connect-multi-client",
                                            NULL,
+                                           FALSE,
                                            NULL,
                                            &error);
   g_assert_no_error (error);
@@ -657,6 +723,7 @@ test_read_write_basic (gconstpointer user_data)
   wing_named_pipe_listener_add_named_pipe (listener,
                                            "\\\\.\\pipe\\gtest-named-pipe-name",
                                            NULL,
+                                           FALSE,
                                            NULL,
                                            &error);
   g_assert_no_error (error);
@@ -703,6 +770,7 @@ test_read_write_several_connections (gconstpointer user_data)
   wing_named_pipe_listener_add_named_pipe (listener,
                                            "\\\\.\\pipe\\gtest-named-pipe-name-read-write-several",
                                            NULL,
+                                           FALSE,
                                            NULL,
                                            &error);
   g_assert_no_error (error);
@@ -759,6 +827,7 @@ test_read_write_same_time_several_connections (gconstpointer user_data)
   wing_named_pipe_listener_add_named_pipe (listener,
                                            "\\\\.\\pipe\\gtest-named-pipe-name-read-write-several",
                                            NULL,
+                                           FALSE,
                                            NULL,
                                            &error);
   g_assert_no_error (error);
@@ -848,6 +917,7 @@ test_cancel_read (gconstpointer user_data)
   wing_named_pipe_listener_add_named_pipe (listener,
                                            "\\\\.\\pipe\\gtest-named-pipe-name",
                                            NULL,
+                                           FALSE,
                                            NULL,
                                            &error);
   g_assert_no_error (error);
@@ -920,6 +990,8 @@ main (int   argc,
   test_data_iocp_sync_async.read_write_fn = write_and_read_mix_sync_async;
 
   g_test_add_data_func ("/named-pipes/add-named-pipe", &test_data, test_add_named_pipe);
+  g_test_add_data_func ("/named-pipes/add-named-pipe-multiple-instances-no-protect", &test_data, 
test_add_named_pipe_multiple_instances_no_protect);
+  g_test_add_data_func ("/named-pipes/add-named-pipe-multiple-instances-protected", &test_data, 
test_add_named_pipe_multiple_instances_protected);
   g_test_add_data_func ("/named-pipes/connect-basic", &test_data, test_connect_basic);
   g_test_add_data_func ("/named-pipes/connect-before-accept", &test_data, test_connect_before_accept);
   g_test_add_data_func ("/named-pipes/connect-sync", &test_data, test_connect_sync);
diff --git a/wing/wingnamedpipelistener.c b/wing/wingnamedpipelistener.c
index 40c7925..bf27cf0 100644
--- a/wing/wingnamedpipelistener.c
+++ b/wing/wingnamedpipelistener.c
@@ -210,6 +210,7 @@ wing_named_pipe_listener_new (void)
 
 static gboolean
 create_pipe_from_pipe_data (PipeData  *pipe_data,
+                            gboolean   protect_first_instance,
                             GError   **error)
 {
   SECURITY_ATTRIBUTES sa = { 0, };
@@ -245,7 +246,8 @@ create_pipe_from_pipe_data (PipeData  *pipe_data,
 
   pipe_data->handle = CreateNamedPipeW (pipe_data->pipe_namew,
                                         PIPE_ACCESS_DUPLEX |
-                                        FILE_FLAG_OVERLAPPED,
+                                        FILE_FLAG_OVERLAPPED |
+                                        (protect_first_instance ? FILE_FLAG_FIRST_PIPE_INSTANCE : 0),
                                         PIPE_TYPE_BYTE |
                                         PIPE_READMODE_BYTE |
                                         PIPE_WAIT |
@@ -307,6 +309,7 @@ create_pipe_from_pipe_data (PipeData  *pipe_data,
  * @listener: a #WingNamedPipeListener.
  * @pipe_name: a name for the pipe.
  * @security_descriptor: (allow-none): a security descriptor or %NULL.
+ * @protect_first_instance: if %TRUE, the pipe creation will fail if the pipe already exists
  * @source_object: (allow-none): Optional #GObject identifying this source
  * @error: #GError for error reporting, or %NULL to ignore.
  *
@@ -317,6 +320,16 @@ create_pipe_from_pipe_data (PipeData  *pipe_data,
  * https://msdn.microsoft.com/en-us/library/windows/desktop/aa379570(v=vs.85).aspx
  * or set to %NULL to not set any security descriptor to the pipe.
  *
+ * @protect_first_instance will cause the first instance of the named pipe to be
+ * created with the FILE_FLAG_FIRST_PIPE_INSTANCE flag specified. This, in turn,
+ * will cause the creation of the pipe to fail if an instance of the pipe already
+ * exists.For more details see FILE_FLAG_FIRST_PIPE_INSTANCE details at:
+ * https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createnamedpipew
+ *
+ * @security_descriptor must be of the format specified by Microsoft:
+ * https://msdn.microsoft.com/en-us/library/windows/desktop/aa379570(v=vs.85).aspx
+ * or set to %NULL to not set any security descriptor to the pipe.
+ *
  * @source_object will be passed out in the various calls
  * to accept to identify this particular source, which is
  * useful if you're listening on multiple pipes and do
@@ -328,6 +341,7 @@ gboolean
 wing_named_pipe_listener_add_named_pipe (WingNamedPipeListener  *listener,
                                          const gchar            *pipe_name,
                                          const gchar            *security_descriptor,
+                                         gboolean                protect_first_instance,
                                          GObject                *source_object,
                                          GError                **error)
 {
@@ -340,7 +354,7 @@ wing_named_pipe_listener_add_named_pipe (WingNamedPipeListener  *listener,
   priv = wing_named_pipe_listener_get_instance_private (listener);
 
   pipe_data = pipe_data_new (pipe_name, security_descriptor, source_object);
-  if (!create_pipe_from_pipe_data (pipe_data, error))
+  if (!create_pipe_from_pipe_data (pipe_data, protect_first_instance, error))
     {
       pipe_data_free (pipe_data);
       return FALSE;
@@ -409,7 +423,7 @@ connect_ready (HANDLE   handle,
                                  NULL);
 
       /* Put another pipe to listen so more clients can already connect */
-      if (!create_pipe_from_pipe_data (pipe_data, &error))
+      if (!create_pipe_from_pipe_data (pipe_data, FALSE, &error))
         {
           g_object_unref (connection);
           g_task_return_error (task, error);
@@ -618,7 +632,7 @@ wing_named_pipe_listener_accept (WingNamedPipeListener  *listener,
         *source_object = pipe_data->source_object;
 
       /* Put another pipe to listen so more clients can already connect */
-      if (!create_pipe_from_pipe_data (pipe_data, error))
+      if (!create_pipe_from_pipe_data (pipe_data, FALSE, error))
         {
           g_object_unref (connection);
           connection = NULL;
@@ -676,7 +690,7 @@ wing_named_pipe_listener_accept_async (WingNamedPipeListener *listener,
                                  "use-iocp", priv->use_iocp,
                                  NULL);
 
-      if (!create_pipe_from_pipe_data (pipe_data, &error))
+      if (!create_pipe_from_pipe_data (pipe_data, FALSE, &error))
         {
           g_object_unref (connection);
           g_task_return_error (task, error);
diff --git a/wing/wingnamedpipelistener.h b/wing/wingnamedpipelistener.h
index b7f4afd..4623a83 100644
--- a/wing/wingnamedpipelistener.h
+++ b/wing/wingnamedpipelistener.h
@@ -58,6 +58,7 @@ WING_AVAILABLE_IN_ALL
 gboolean                  wing_named_pipe_listener_add_named_pipe (WingNamedPipeListener  *listener,
                                                                    const gchar            *pipe_name,
                                                                    const gchar            
*security_descriptor,
+                                                                   gboolean                
protect_first_instance,
                                                                    GObject                *source_object,
                                                                    GError                **error);
 


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