[wing] wingnamedpipelistener: pass pipe settings in constructor instead of in set_named_pipe
- From: Ignacio Casal Quinteiro <icq src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [wing] wingnamedpipelistener: pass pipe settings in constructor instead of in set_named_pipe
- Date: Wed, 10 Aug 2022 14:50:31 +0000 (UTC)
commit fbdae67dace7fc153819f4fea5e3e3d09a8a5c36
Author: Silvio Lazzeretti <silviola amazon com>
Date: Tue Aug 9 11:27:34 2022 +0200
wingnamedpipelistener: pass pipe settings in constructor instead of in set_named_pipe
tests/named-pipe.c | 151 +++++++++----------
wing/wingnamedpipelistener.c | 344 +++++++++++++++++++++++--------------------
wing/wingnamedpipelistener.h | 7 +-
3 files changed, 255 insertions(+), 247 deletions(-)
---
diff --git a/tests/named-pipe.c b/tests/named-pipe.c
index 0c229d5..df4422e 100644
--- a/tests/named-pipe.c
+++ b/tests/named-pipe.c
@@ -36,27 +36,23 @@ test_add_named_pipe (gconstpointer user_data)
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_set_named_pipe (listener,
- "\\\\.\\pipe\\gtest-good-named-pipe-name",
+ listener = wing_named_pipe_listener_new ("\\\\.\\pipe\\gtest-good-named-pipe-name",
NULL,
FALSE,
+ NULL,
&error);
+ g_assert (listener != NULL);
g_assert_no_error (error);
+
g_object_unref (listener);
- listener = wing_named_pipe_listener_new ();
- wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
- wing_named_pipe_listener_set_named_pipe (listener,
- "\\\\.\\gtest-bad-named-pipe-name",
+ listener = wing_named_pipe_listener_new ("\\\\.\\gtest-bad-named-pipe-name",
NULL,
FALSE,
+ NULL,
&error);
+ g_assert (listener == NULL);
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
-
- g_object_unref (listener);
}
static void
@@ -67,24 +63,20 @@ test_add_named_pipe_multiple_instances_no_protect (gconstpointer user_data)
GError *error = NULL;
TestData *test_data = (TestData *) user_data;
- listener1 = wing_named_pipe_listener_new ();
- wing_named_pipe_listener_set_use_iocp (listener1, test_data->use_iocp);
-
- wing_named_pipe_listener_set_named_pipe (listener1,
- "\\\\.\\pipe\\unprotected-named-pipe",
+ listener1 = wing_named_pipe_listener_new ("\\\\.\\pipe\\unprotected-named-pipe",
NULL,
FALSE,
+ NULL,
&error);
+ g_assert (listener1 != NULL);
g_assert_no_error (error);
- listener2 = wing_named_pipe_listener_new ();
- wing_named_pipe_listener_set_use_iocp (listener2, test_data->use_iocp);
-
- wing_named_pipe_listener_set_named_pipe (listener2,
- "\\\\.\\pipe\\unprotected-named-pipe",
+ listener2 = wing_named_pipe_listener_new ("\\\\.\\pipe\\unprotected-named-pipe",
NULL,
FALSE,
+ NULL,
&error);
+ g_assert (listener2 != NULL);
g_assert_no_error (error);
g_object_unref (listener1);
@@ -99,28 +91,23 @@ test_add_named_pipe_multiple_instances_protected (gconstpointer user_data)
GError *error = NULL;
TestData *test_data = (TestData *) user_data;
- listener1 = wing_named_pipe_listener_new ();
- wing_named_pipe_listener_set_use_iocp (listener1, test_data->use_iocp);
-
- wing_named_pipe_listener_set_named_pipe (listener1,
- "\\\\.\\pipe\\protected-named-pipe",
+ listener1 = wing_named_pipe_listener_new ("\\\\.\\pipe\\protected-named-pipe",
NULL,
TRUE,
+ NULL,
&error);
+ g_assert (listener1 != NULL);
g_assert_no_error (error);
- listener2 = wing_named_pipe_listener_new ();
- wing_named_pipe_listener_set_use_iocp (listener2, test_data->use_iocp);
-
- wing_named_pipe_listener_set_named_pipe (listener2,
- "\\\\.\\pipe\\protected-named-pipe",
+ listener2 = wing_named_pipe_listener_new ("\\\\.\\pipe\\protected-named-pipe",
NULL,
TRUE,
+ NULL,
&error);
+ g_assert (listener2 == NULL);
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
g_object_unref (listener1);
- g_object_unref (listener2);
}
static void
@@ -167,16 +154,16 @@ test_connect_basic (gconstpointer user_data)
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_set_named_pipe (listener,
- "\\\\.\\pipe\\gtest-named-pipe-name",
+ listener = wing_named_pipe_listener_new ("\\\\.\\pipe\\gtest-named-pipe-name",
NULL,
FALSE,
+ NULL,
&error);
+ g_assert (listener != NULL);
g_assert_no_error (error);
+ wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
+
wing_named_pipe_listener_accept_async (listener,
NULL,
accepted_cb,
@@ -210,16 +197,16 @@ test_connect_before_accept (gconstpointer user_data)
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_set_named_pipe (listener,
- "\\\\.\\pipe\\gtest-named-pipe-name",
+ listener = wing_named_pipe_listener_new ("\\\\.\\pipe\\gtest-named-pipe-name",
NULL,
FALSE,
+ NULL,
&error);
+ g_assert (listener != NULL);
g_assert_no_error (error);
+ wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
+
client = wing_named_pipe_client_new ();
wing_named_pipe_client_set_use_iocp (client, test_data->use_iocp);
@@ -252,16 +239,16 @@ test_connect_sync (gconstpointer user_data)
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_set_named_pipe (listener,
- "\\\\.\\pipe\\gtest-connect-sync",
+ listener = wing_named_pipe_listener_new ("\\\\.\\pipe\\gtest-connect-sync",
NULL,
FALSE,
+ NULL,
&error);
+ g_assert (listener != NULL);
g_assert_no_error (error);
+ wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
+
client = wing_named_pipe_client_new ();
wing_named_pipe_client_set_use_iocp (client, test_data->use_iocp);
@@ -337,16 +324,16 @@ test_accept_cancel (gconstpointer user_data)
TestData *test_data = (TestData *) user_data;
cancellable = g_cancellable_new ();
- listener = wing_named_pipe_listener_new ();
- wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
-
- wing_named_pipe_listener_set_named_pipe (listener,
- "\\\\.\\pipe\\gtest-named-pipe-name-cancel",
+ listener = wing_named_pipe_listener_new ("\\\\.\\pipe\\gtest-named-pipe-name-cancel",
NULL,
FALSE,
+ NULL,
&error);
+ g_assert (listener != NULL);
g_assert_no_error (error);
+ wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
+
wing_named_pipe_listener_accept_async (listener,
cancellable,
accept_cancelled_cb,
@@ -374,16 +361,16 @@ test_connect_accept_cancel (gconstpointer user_data)
TestData *test_data = (TestData *) user_data;
cancellable = g_cancellable_new ();
- listener = wing_named_pipe_listener_new ();
- wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
-
- wing_named_pipe_listener_set_named_pipe (listener,
- "\\\\.\\pipe\\gtest-named-pipe-name-connect-then-cancel",
+ listener = wing_named_pipe_listener_new ("\\\\.\\pipe\\gtest-named-pipe-name-connect-then-cancel",
NULL,
FALSE,
+ NULL,
&error);
+ g_assert (listener != NULL);
g_assert_no_error (error);
+ wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
+
wing_named_pipe_listener_accept_async (listener,
cancellable,
accepted_cb,
@@ -433,16 +420,16 @@ test_multi_client_basic (gconstpointer user_data)
TestData *test_data = (TestData *) user_data;
cancellable = g_cancellable_new ();
- listener = wing_named_pipe_listener_new ();
- wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
-
- wing_named_pipe_listener_set_named_pipe (listener,
- "\\\\.\\pipe\\gtest-named-pipe-name-connect-multi-client",
+ listener = wing_named_pipe_listener_new ("\\\\.\\pipe\\gtest-named-pipe-name-connect-multi-client",
NULL,
FALSE,
+ NULL,
&error);
+ g_assert (listener != NULL);
g_assert_no_error (error);
+ wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
+
wing_named_pipe_listener_accept_async (listener,
cancellable,
accepted_cb,
@@ -718,16 +705,16 @@ test_read_write_basic (gconstpointer user_data)
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_set_named_pipe (listener,
- "\\\\.\\pipe\\gtest-named-pipe-name",
+ listener = wing_named_pipe_listener_new ("\\\\.\\pipe\\gtest-named-pipe-name",
NULL,
FALSE,
+ NULL,
&error);
+ g_assert (listener != NULL);
g_assert_no_error (error);
+ wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
+
wing_named_pipe_listener_accept_async (listener,
NULL,
accepted_read_write_cb,
@@ -764,15 +751,15 @@ test_read_write_several_connections (gconstpointer user_data)
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_set_named_pipe (listener,
- "\\\\.\\pipe\\gtest-named-pipe-name-read-write-several",
+ listener = wing_named_pipe_listener_new ("\\\\.\\pipe\\gtest-named-pipe-name-read-write-several",
NULL,
FALSE,
+ NULL,
&error);
+ g_assert (listener != NULL);
g_assert_no_error (error);
+
+ wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
for (i = 0; i < MAX_ITERATIONS; i++)
{
@@ -820,16 +807,16 @@ test_read_write_same_time_several_connections (gconstpointer user_data)
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_set_named_pipe (listener,
- "\\\\.\\pipe\\gtest-named-pipe-name-read-write-several",
+ listener = wing_named_pipe_listener_new ("\\\\.\\pipe\\gtest-named-pipe-name-read-write-several",
NULL,
FALSE,
+ NULL,
&error);
+ g_assert (listener != NULL);
g_assert_no_error (error);
+ wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
+
client_conns = g_ptr_array_new_with_free_func (g_object_unref);
server_conns = g_ptr_array_new_with_free_func (g_object_unref);
@@ -909,16 +896,16 @@ test_cancel_read (gconstpointer user_data)
gchar data[256];
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_set_named_pipe (listener,
- "\\\\.\\pipe\\gtest-named-pipe-name",
+ listener = wing_named_pipe_listener_new ("\\\\.\\pipe\\gtest-named-pipe-name",
NULL,
FALSE,
+ NULL,
&error);
+ g_assert (listener != NULL);
g_assert_no_error (error);
+ wing_named_pipe_listener_set_use_iocp (listener, test_data->use_iocp);
+
wing_named_pipe_listener_accept_async (listener,
NULL,
accepted_read_write_cb,
diff --git a/wing/wingnamedpipelistener.c b/wing/wingnamedpipelistener.c
index 5de48dd..2178b9d 100644
--- a/wing/wingnamedpipelistener.c
+++ b/wing/wingnamedpipelistener.c
@@ -29,65 +29,38 @@
typedef struct
{
gchar *pipe_name;
- gunichar2 *pipe_namew;
gchar *security_descriptor;
+ gboolean protect_first_instance;
+
+ gunichar2 *pipe_namew;
gunichar2 *security_descriptorw;
HANDLE handle;
OVERLAPPED overlapped;
gboolean already_connected;
-} PipeData;
-typedef struct
-{
- PipeData *named_pipe;
gboolean use_iocp;
} WingNamedPipeListenerPrivate;
enum
{
PROP_0,
+ PROP_PIPE_NAME,
+ PROP_SECURITY_DESCRIPTOR,
+ PROP_PROTECT_FIRST_INSTANCE,
PROP_USE_IOCP,
LAST_PROP
};
static GParamSpec *props[LAST_PROP];
-G_DEFINE_TYPE_WITH_PRIVATE (WingNamedPipeListener, wing_named_pipe_listener, G_TYPE_OBJECT)
-
-static GQuark source_quark = 0;
-
-static PipeData *
-pipe_data_new (const gchar *pipe_name,
- const gchar *security_descriptor)
-{
- PipeData *data;
-
- data = g_slice_new0 (PipeData);
- data->pipe_name = g_strdup (pipe_name);
- data->pipe_namew = g_utf8_to_utf16 (pipe_name, -1, NULL, NULL, NULL);
- data->security_descriptor = g_strdup (security_descriptor);
- data->security_descriptorw = security_descriptor != NULL ? g_utf8_to_utf16 (security_descriptor, -1, NULL,
NULL, NULL) : NULL;
- data->handle = INVALID_HANDLE_VALUE;
- data->overlapped.hEvent = CreateEvent (NULL, /* default security attribute */
- TRUE, /* manual-reset event */
- TRUE, /* initial state = signaled */
- NULL); /* unnamed event object */
+static void wing_named_pipe_listener_initable_iface_init (GInitableIface *iface);
- return data;
-}
+G_DEFINE_TYPE_EXTENDED (WingNamedPipeListener, wing_named_pipe_listener, G_TYPE_OBJECT, 0,
+ G_ADD_PRIVATE (WingNamedPipeListener)
+ G_IMPLEMENT_INTERFACE(G_TYPE_INITABLE,
+ wing_named_pipe_listener_initable_iface_init))
-static void
-pipe_data_free (PipeData *data)
-{
- g_free (data->pipe_name);
- g_free (data->pipe_namew);
- g_free (data->security_descriptor);
- g_free (data->security_descriptorw);
- if (data->handle != INVALID_HANDLE_VALUE)
- CloseHandle (data->handle);
- CloseHandle (data->overlapped.hEvent);
- g_slice_free (PipeData, data);
-}
+static GQuark source_quark = 0;
static void
wing_named_pipe_listener_set_property (GObject *object,
@@ -101,15 +74,27 @@ wing_named_pipe_listener_set_property (GObject *object,
priv = wing_named_pipe_listener_get_instance_private (listener);
switch (prop_id)
- {
- case PROP_USE_IOCP:
- priv->use_iocp = g_value_get_boolean (value);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
+ {
+ case PROP_PIPE_NAME:
+ priv->pipe_name = g_value_dup_string (value);
+ break;
+
+ case PROP_SECURITY_DESCRIPTOR:
+ priv->security_descriptor = g_value_dup_string (value);
+ break;
+
+ case PROP_PROTECT_FIRST_INSTANCE:
+ priv->protect_first_instance = g_value_get_boolean (value);
+ break;
+
+ case PROP_USE_IOCP:
+ priv->use_iocp = g_value_get_boolean (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
}
static void
@@ -124,15 +109,27 @@ wing_named_pipe_listener_get_property (GObject *object,
priv = wing_named_pipe_listener_get_instance_private (listener);
switch (prop_id)
- {
- case PROP_USE_IOCP:
+ {
+ case PROP_PIPE_NAME:
+ g_value_set_string (value, priv->pipe_name);
+ break;
+
+ case PROP_SECURITY_DESCRIPTOR:
+ g_value_set_string (value, priv->security_descriptor);
+ break;
+
+ case PROP_PROTECT_FIRST_INSTANCE:
+ g_value_set_boolean (value, priv->protect_first_instance);
+ break;
+
+ case PROP_USE_IOCP:
g_value_set_boolean (value, priv->use_iocp);
break;
- default:
+ default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
- }
+ }
}
static void
@@ -143,7 +140,12 @@ wing_named_pipe_listener_finalize (GObject *object)
priv = wing_named_pipe_listener_get_instance_private (listener);
- g_clear_pointer (&priv->named_pipe, pipe_data_free);
+ g_free (priv->pipe_name);
+ g_free (priv->pipe_namew);
+ g_free (priv->security_descriptor);
+ g_free (priv->security_descriptorw);
+ CloseHandle (priv->handle);
+ CloseHandle (priv->overlapped.hEvent);
G_OBJECT_CLASS (wing_named_pipe_listener_parent_class)->finalize (object);
}
@@ -159,6 +161,33 @@ wing_named_pipe_listener_class_init (WingNamedPipeListenerClass *klass)
source_quark = g_quark_from_static_string ("g-win32-named-pipe-listener-source");
+ props[PROP_PIPE_NAME] =
+ g_param_spec_string ("pipe-name",
+ "The name of the pipe",
+ "The name of the pipe",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS);
+
+ props[PROP_SECURITY_DESCRIPTOR] =
+ g_param_spec_string ("security-descriptor",
+ "The security descriptor to apply to the pipe",
+ "The security descriptor to apply to the pipe",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS);
+
+ props[PROP_PROTECT_FIRST_INSTANCE] =
+ g_param_spec_boolean ("protect-first-instance",
+ "Protect the first instance of the pipe",
+ "Whether the creation of the pipe should fail if an instance of the pipe already
exists",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS);
+
/**
* WingNamedPipeConnection:use-iocp:
*
@@ -183,29 +212,58 @@ wing_named_pipe_listener_init (WingNamedPipeListener *listener)
/**
* wing_named_pipe_listener_new:
+ * @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
+ * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
+ * @error: #GError for error reporting, or %NULL to ignore.
*
* Creates a new #WingNamedPipeListener.
*
+ * @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.
+ *
+ * @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.
+ *
+ * @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
+ *
* Returns: (transfer full): a new #WingNamedPipeListener.
*/
WingNamedPipeListener *
-wing_named_pipe_listener_new (void)
+wing_named_pipe_listener_new (const gchar *pipe_name,
+ const gchar *security_descriptor,
+ gboolean protect_first_instance,
+ GCancellable *cancellable,
+ GError **error)
{
- return g_object_new (WING_TYPE_NAMED_PIPE_LISTENER, NULL);
+ return g_initable_new (WING_TYPE_NAMED_PIPE_LISTENER,
+ cancellable,
+ error,
+ "pipe-name", pipe_name,
+ "security-descriptor", security_descriptor,
+ "protect-first-instance", protect_first_instance,
+ NULL);
}
static gboolean
-create_pipe_from_pipe_data (PipeData *pipe_data,
- gboolean protect_first_instance,
- GError **error)
+create_pipe_from_pipe_data (WingNamedPipeListenerPrivate *priv,
+ gboolean protect_first_instance,
+ GError **error)
{
SECURITY_ATTRIBUTES sa = { 0, };
- if (pipe_data->security_descriptorw != NULL)
+ if (priv->security_descriptorw != NULL)
{
sa.nLength = sizeof (sa);
- if (!ConvertStringSecurityDescriptorToSecurityDescriptorW (pipe_data->security_descriptorw,
+ if (!ConvertStringSecurityDescriptorToSecurityDescriptorW (priv->security_descriptorw,
SDDL_REVISION_1,
&sa.lpSecurityDescriptor,
NULL))
@@ -217,7 +275,7 @@ create_pipe_from_pipe_data (PipeData *pipe_data,
G_IO_ERROR,
g_io_error_from_win32_error (errsv),
"Could not convert the security descriptor '%s': %s",
- pipe_data->security_descriptor, emsg);
+ priv->security_descriptor, emsg);
g_free (emsg);
return FALSE;
@@ -225,29 +283,29 @@ create_pipe_from_pipe_data (PipeData *pipe_data,
}
/* Set event as signaled */
- SetEvent(pipe_data->overlapped.hEvent);
+ SetEvent(priv->overlapped.hEvent);
/* clear the flag if this was already connected */
- pipe_data->already_connected = FALSE;
-
- pipe_data->handle = CreateNamedPipeW (pipe_data->pipe_namew,
- PIPE_ACCESS_DUPLEX |
- FILE_FLAG_OVERLAPPED |
- (protect_first_instance ? FILE_FLAG_FIRST_PIPE_INSTANCE : 0),
- PIPE_TYPE_BYTE |
- PIPE_READMODE_BYTE |
- PIPE_WAIT |
- PIPE_REJECT_REMOTE_CLIENTS,
- PIPE_UNLIMITED_INSTANCES,
- DEFAULT_PIPE_BUF_SIZE,
- DEFAULT_PIPE_BUF_SIZE,
- 0,
- pipe_data->security_descriptorw != NULL ? &sa : NULL);
+ priv->already_connected = FALSE;
+
+ priv->handle = CreateNamedPipeW (priv->pipe_namew,
+ PIPE_ACCESS_DUPLEX |
+ FILE_FLAG_OVERLAPPED |
+ (protect_first_instance ? FILE_FLAG_FIRST_PIPE_INSTANCE : 0),
+ PIPE_TYPE_BYTE |
+ PIPE_READMODE_BYTE |
+ PIPE_WAIT |
+ PIPE_REJECT_REMOTE_CLIENTS,
+ PIPE_UNLIMITED_INSTANCES,
+ DEFAULT_PIPE_BUF_SIZE,
+ DEFAULT_PIPE_BUF_SIZE,
+ 0,
+ priv->security_descriptorw != NULL ? &sa : NULL);
if (sa.lpSecurityDescriptor != NULL)
LocalFree (sa.lpSecurityDescriptor);
- if (pipe_data->handle == INVALID_HANDLE_VALUE)
+ if (priv->handle == INVALID_HANDLE_VALUE)
{
int errsv = GetLastError ();
gchar *emsg = g_win32_error_message (errsv);
@@ -256,20 +314,20 @@ create_pipe_from_pipe_data (PipeData *pipe_data,
G_IO_ERROR,
g_io_error_from_win32_error (errsv),
"Error creating named pipe '%s': %s",
- pipe_data->pipe_name, emsg);
+ priv->pipe_name, emsg);
g_free (emsg);
return FALSE;
}
- if (!ConnectNamedPipe (pipe_data->handle, &pipe_data->overlapped))
+ if (!ConnectNamedPipe (priv->handle, &priv->overlapped))
{
switch (GetLastError ())
{
case ERROR_IO_PENDING:
break;
case ERROR_PIPE_CONNECTED:
- pipe_data->already_connected = TRUE;
+ priv->already_connected = TRUE;
break;
default:
{
@@ -279,7 +337,7 @@ create_pipe_from_pipe_data (PipeData *pipe_data,
g_set_error (error,
G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
"Failed to connect named pipe '%s': %s",
- pipe_data->pipe_name, emsg);
+ priv->pipe_name, emsg);
g_free (emsg);
return FALSE;
@@ -290,61 +348,6 @@ create_pipe_from_pipe_data (PipeData *pipe_data,
return TRUE;
}
-/**
- * wing_named_pipe_listener_set_named_pipe:
- * @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
- * @error: #GError for error reporting, or %NULL to ignore.
- *
- * Adds @named_pipe to the set of named pipes that we try to accept clients
- * from.
- *
- * @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.
- *
- * @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.
- *
- * Returns: %TRUE on success, %FALSE on error.
- */
-gboolean
-wing_named_pipe_listener_set_named_pipe (WingNamedPipeListener *listener,
- const gchar *pipe_name,
- const gchar *security_descriptor,
- gboolean protect_first_instance,
- GError **error)
-{
- WingNamedPipeListenerPrivate *priv;
- PipeData *pipe_data;
-
- g_return_val_if_fail (WING_IS_NAMED_PIPE_LISTENER (listener), FALSE);
- g_return_val_if_fail (pipe_name != NULL, FALSE);
-
- priv = wing_named_pipe_listener_get_instance_private (listener);
-
- pipe_data = pipe_data_new (pipe_name, security_descriptor);
- if (!create_pipe_from_pipe_data (pipe_data, protect_first_instance, error))
- {
- pipe_data_free (pipe_data);
- return FALSE;
- }
-
- g_clear_pointer (&priv->named_pipe, pipe_data_free);
- priv->named_pipe = pipe_data;
-
- return TRUE;
-}
-
static gboolean
connect_ready (HANDLE handle,
gpointer user_data)
@@ -352,16 +355,12 @@ connect_ready (HANDLE handle,
GTask *task = user_data;
WingNamedPipeListener *listener = g_task_get_source_object (task);
WingNamedPipeListenerPrivate *priv;
- PipeData *pipe_data = NULL;
gulong cbret;
guint i;
priv = wing_named_pipe_listener_get_instance_private (listener);
- pipe_data = priv->named_pipe;
- g_return_val_if_fail (pipe_data != NULL, FALSE);
-
- if (!GetOverlappedResult (pipe_data->handle, &pipe_data->overlapped, &cbret, FALSE))
+ if (!GetOverlappedResult (priv->handle, &priv->overlapped, &cbret, FALSE))
{
int errsv = GetLastError ();
gchar *emsg = g_win32_error_message (errsv);
@@ -379,14 +378,14 @@ connect_ready (HANDLE handle,
GError *error = NULL;
connection = g_object_new (WING_TYPE_NAMED_PIPE_CONNECTION,
- "pipe-name", pipe_data->pipe_name,
- "handle", pipe_data->handle,
+ "pipe-name", priv->pipe_name,
+ "handle", priv->handle,
"close-handle", TRUE,
"use-iocp", priv->use_iocp,
NULL);
/* Put another pipe to listen so more clients can already connect */
- if (!create_pipe_from_pipe_data (pipe_data, FALSE, &error))
+ if (!create_pipe_from_pipe_data (priv, FALSE, &error))
{
g_object_unref (connection);
g_task_return_error (task, error);
@@ -431,7 +430,6 @@ wing_named_pipe_listener_accept (WingNamedPipeListener *listener,
GError **error)
{
WingNamedPipeListenerPrivate *priv;
- PipeData *pipe_data = NULL;
WingNamedPipeConnection *connection = NULL;
gboolean success;
@@ -439,25 +437,22 @@ wing_named_pipe_listener_accept (WingNamedPipeListener *listener,
priv = wing_named_pipe_listener_get_instance_private (listener);
- pipe_data = priv->named_pipe;
- g_return_val_if_fail(pipe_data != NULL, NULL);
-
- success = pipe_data->already_connected;
+ success = priv->already_connected;
if (!success)
- success = WaitForSingleObject (pipe_data->overlapped.hEvent, INFINITE) == WAIT_OBJECT_0;
+ success = WaitForSingleObject (priv->overlapped.hEvent, INFINITE) == WAIT_OBJECT_0;
if (success)
{
connection = g_object_new (WING_TYPE_NAMED_PIPE_CONNECTION,
- "pipe-name", pipe_data->pipe_name,
- "handle", pipe_data->handle,
+ "pipe-name", priv->pipe_name,
+ "handle", priv->handle,
"close-handle", TRUE,
"use-iocp", priv->use_iocp,
NULL);
/* Put another pipe to listen so more clients can already connect */
- if (!create_pipe_from_pipe_data (pipe_data, FALSE, error))
+ if (!create_pipe_from_pipe_data (priv, FALSE, error))
g_clear_object (&connection);
}
@@ -490,21 +485,20 @@ wing_named_pipe_listener_accept_async (WingNamedPipeListener *listener,
task = g_task_new (listener, cancellable, callback, user_data);
priv = wing_named_pipe_listener_get_instance_private (listener);
- g_return_if_fail (priv->named_pipe != NULL);
- if (priv->named_pipe->already_connected)
+ if (priv->already_connected)
{
WingNamedPipeConnection *connection;
GError *error = NULL;
connection = g_object_new (WING_TYPE_NAMED_PIPE_CONNECTION,
- "pipe-name", priv->named_pipe->pipe_name,
- "handle", priv->named_pipe->handle,
+ "pipe-name", priv->pipe_name,
+ "handle", priv->handle,
"close-handle", TRUE,
"use-iocp", priv->use_iocp,
NULL);
- if (!create_pipe_from_pipe_data (priv->named_pipe, FALSE, &error))
+ if (!create_pipe_from_pipe_data (priv, FALSE, &error))
{
g_object_unref (connection);
g_task_return_error (task, error);
@@ -517,7 +511,7 @@ wing_named_pipe_listener_accept_async (WingNamedPipeListener *listener,
return;
}
- source = wing_create_source (priv->named_pipe->overlapped.hEvent,
+ source = wing_create_source (priv->overlapped.hEvent,
G_IO_IN,
cancellable);
g_source_set_callback (source,
@@ -564,4 +558,34 @@ wing_named_pipe_listener_set_use_iocp (WingNamedPipeListener *listener,
priv->use_iocp = use_iocp;
g_object_notify_by_pspec (G_OBJECT (listener), props[PROP_USE_IOCP]);
}
+}
+
+static gboolean
+wing_named_pipe_listener_initable_init (GInitable *initable,
+ GCancellable *cancellable,
+ GError **error)
+{
+ WingNamedPipeListener *listener;
+ WingNamedPipeListenerPrivate *priv;
+
+ g_return_val_if_fail (WING_IS_NAMED_PIPE_LISTENER (initable), FALSE);
+
+ listener = WING_NAMED_PIPE_LISTENER (initable);
+ priv = wing_named_pipe_listener_get_instance_private (listener);
+
+ priv->pipe_namew = g_utf8_to_utf16 (priv->pipe_name, -1, NULL, NULL, NULL);
+ priv->security_descriptorw = priv->security_descriptor != NULL ? g_utf8_to_utf16
(priv->security_descriptor, -1, NULL, NULL, NULL) : NULL;
+ priv->handle = INVALID_HANDLE_VALUE;
+ priv->overlapped.hEvent = CreateEvent (NULL, /* default security attribute */
+ TRUE, /* manual-reset event */
+ TRUE, /* initial state = signaled */
+ NULL); /* unnamed event object */
+
+ return create_pipe_from_pipe_data (priv, priv->protect_first_instance, error);
+}
+
+static void
+wing_named_pipe_listener_initable_iface_init (GInitableIface *iface)
+{
+ iface->init = wing_named_pipe_listener_initable_init;
}
\ No newline at end of file
diff --git a/wing/wingnamedpipelistener.h b/wing/wingnamedpipelistener.h
index fc41678..51e5680 100644
--- a/wing/wingnamedpipelistener.h
+++ b/wing/wingnamedpipelistener.h
@@ -52,13 +52,10 @@ WING_AVAILABLE_IN_ALL
GType wing_named_pipe_listener_get_type (void) G_GNUC_CONST;
WING_AVAILABLE_IN_ALL
-WingNamedPipeListener *wing_named_pipe_listener_new (void);
-
-WING_AVAILABLE_IN_ALL
-gboolean wing_named_pipe_listener_set_named_pipe (WingNamedPipeListener *listener,
- const gchar *pipe_name,
+WingNamedPipeListener *wing_named_pipe_listener_new (const gchar *pipe_name,
const gchar
*security_descriptor,
gboolean
protect_first_instance,
+ GCancellable *cancellable,
GError **error);
WING_AVAILABLE_IN_ALL
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]