[PATCH 4/4] Add windows-specific context manager



---
 configure.ac                             |    1 +
 libgupnp/Makefile.am                     |    8 +-
 libgupnp/gupnp-context-manager.c         |    3 +
 libgupnp/gupnp-windows-context-manager.c |  207 ++++++++++++++++++++++++++++++
 libgupnp/gupnp-windows-context-manager.h |   73 +++++++++++
 5 files changed, 291 insertions(+), 1 deletions(-)
 create mode 100644 libgupnp/gupnp-windows-context-manager.c
 create mode 100644 libgupnp/gupnp-windows-context-manager.h

diff --git a/configure.ac b/configure.ac
index af4569d..860f532 100644
--- a/configure.ac
+++ b/configure.ac
@@ -52,6 +52,7 @@ if test "x$os_win32" = "xno"; then
             [with_context_manager="unix"])
 else
     LIBGUPNP_LIBS="$LIBGUPNP_LIBS -lrpcrt4"
+    with_context_manager="windows"
 fi
 
 AC_MSG_CHECKING([Context Manager backend to use])
diff --git a/libgupnp/Makefile.am b/libgupnp/Makefile.am
index f4c4e31..bcb2680 100644
--- a/libgupnp/Makefile.am
+++ b/libgupnp/Makefile.am
@@ -1,6 +1,10 @@
 LTVERSION = 4:0:0
 
 if OS_WIN32
+CONTEXT_MANAGER_IMPL = gupnp-windows-context-manager.c \
+		       gupnp-windows-context-manager.h
+CONTEXT_MANAGER_CFLAGS =
+CONTEXT_MANAGER_LIBS = -lws2_32 -liphlpapi
 WIN32_LDFLAGS = -no-undefined
 else
 CONTEXT_MANAGER_IMPL = gupnp-unix-context-manager.c \
@@ -100,7 +104,9 @@ EXTRA_DIST = gupnp-marshal.list 	   \
 	     gupnp-network-manager.c   	   \
 	     gupnp-network-manager.h       \
 	     gupnp-unix-context-manager.c  \
-	     gupnp-unix-context-manager.h
+	     gupnp-unix-context-manager.h  \
+	     gupnp-windows-context-manager.c \
+	     gupnp-windows-context-manager.h
 
 -include $(INTROSPECTION_MAKEFILE)
 INTROSPECTION_GIRS =
diff --git a/libgupnp/gupnp-context-manager.c b/libgupnp/gupnp-context-manager.c
index 00f06ee..299efb6 100644
--- a/libgupnp/gupnp-context-manager.c
+++ b/libgupnp/gupnp-context-manager.c
@@ -369,6 +369,9 @@ gupnp_context_manager_new (GMainContext *main_context,
         GUPnPContextManager *impl;
         GType impl_type = G_TYPE_INVALID;
 #ifdef G_OS_WIN32
+#include "gupnp-windows-context-manager.h"
+
+        impl_type = GUPNP_TYPE_WINDOWS_CONTEXT_MANAGER;
 #else
 #ifdef USE_NETWORK_MANAGER
 #include "gupnp-network-manager.h"
diff --git a/libgupnp/gupnp-windows-context-manager.c b/libgupnp/gupnp-windows-context-manager.c
new file mode 100644
index 0000000..e3866c7
--- /dev/null
+++ b/libgupnp/gupnp-windows-context-manager.c
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2009, 2010 Jens Georg
+ * Copyright (C) 2009 Nokia Corporation, all rights reserved.
+ * Copyright (C) 2006, 2007, 2008 OpenedHand Ltd.
+ *
+ * Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
+ *         Jorn Baayen <jorn openedhand com>
+ *         Jens Georg <mail jensge org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * SECTION:gupnp-windows-context-manager
+ * @short_description: Windows-specific implementation of #GUPnPContextManager.
+ *
+ * Based on GUPnPUnixContextManger implementation
+ */
+
+#include <config.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#define _WIN32_WINNT 0x0502
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <iphlpapi.h>
+#include <libsoup/soup-address.h>
+#include <glib/gstdio.h>
+
+#include "gupnp-windows-context-manager.h"
+#include "gupnp-context.h"
+
+G_DEFINE_TYPE (GUPnPWindowsContextManager,
+               gupnp_windows_context_manager,
+               GUPNP_TYPE_CONTEXT_MANAGER);
+
+void
+create_and_signal_context (GUPnPWindowsContextManager *manager,
+                           const char              *host_ip)
+{
+        GUPnPContext *context;
+        GMainContext *main_context;
+        guint port;
+
+        GError *error;
+
+        if (host_ip == NULL)
+                return;
+
+        g_object_get (manager,
+                      "main-context", &main_context,
+                      "port", &port,
+                      NULL);
+
+        error = NULL;
+        context = gupnp_context_new (main_context,
+                                     host_ip,
+                                     port,
+                                     &error);
+        if (error != NULL) {
+                g_warning ("Failed to create context for host/IP '%s': %s\n",
+                           host_ip,
+                           error->message);
+
+                g_error_free (error);
+
+                return;
+        }
+
+        g_signal_emit_by_name (manager,
+                               "context-available",
+                               context);
+
+        g_object_unref (context);
+}
+
+/*
+ * Create a context for all network interfaces that are up.
+ */
+static gboolean
+create_contexts (gpointer data)
+{
+        GUPnPWindowsContextManager *manager =
+                                        GUPNP_WINDOWS_CONTEXT_MANAGER (data);
+
+        ULONG flags = GAA_FLAG_INCLUDE_PREFIX |
+                      GAA_FLAG_SKIP_DNS_SERVER |
+                      GAA_FLAG_SKIP_MULTICAST;
+        /* use 15k buffer initially as documented in MSDN */
+        DWORD size = 0x3C00;
+        DWORD ret;
+        PIP_ADAPTER_ADDRESSES adapters_addresses;
+        PIP_ADAPTER_ADDRESSES adapter;
+
+        do {
+                adapters_addresses = (PIP_ADAPTER_ADDRESSES) g_malloc0 (size);
+                ret = GetAdaptersAddresses (AF_UNSPEC,
+                                            flags,
+                                            NULL,
+                                            adapters_addresses,
+                                            &size);
+                if (ret == ERROR_BUFFER_OVERFLOW) {
+                        g_free (adapters_addresses);
+                }
+        } while (ret == ERROR_BUFFER_OVERFLOW);
+
+        if (ret == ERROR_SUCCESS) {
+                for (adapter = adapters_addresses;
+                     adapter != NULL;
+                     adapter = adapter->Next) {
+                        if (adapter->FirstUnicastAddress == NULL)
+                                continue;
+                        if (adapter->OperStatus != IfOperStatusUp)
+                                continue;
+                        create_and_signal_context (manager,
+                                                   adapter->AdapterName);
+                }
+        }
+
+        return FALSE;
+}
+
+static void
+schedule_contexts_creation (GUPnPWindowsContextManager *manager)
+{
+        GMainContext *main_context;
+        GSource *source;
+
+        g_object_get (manager,
+                      "main-context", &main_context,
+                      NULL);
+
+        /* Create contexts in mainloop so that is happens after user has hooked
+         * to the "context-available" signal.
+         */
+        source = g_idle_source_new ();
+        g_source_attach (source, main_context);
+        g_source_set_callback (source,
+                               create_contexts,
+                               manager,
+                               NULL);
+}
+
+static void
+gupnp_windows_context_manager_init (GUPnPWindowsContextManager *manager)
+{
+}
+
+static void
+gupnp_windows_context_manager_constructed (GObject *object)
+{
+        GObjectClass *parent_class;
+        GUPnPWindowsContextManager *manager;
+
+        manager = GUPNP_WINDOWS_CONTEXT_MANAGER (object);
+
+        schedule_contexts_creation (manager);
+
+        /* Chain-up */
+        parent_class =
+                G_OBJECT_CLASS (gupnp_windows_context_manager_parent_class);
+        if (parent_class->constructed != NULL) {
+                parent_class->constructed (object);
+        }
+}
+
+static void
+gupnp_windows_context_manager_dispose (GObject *object)
+{
+        GUPnPWindowsContextManager *manager;
+        GObjectClass *object_class;
+
+        manager = GUPNP_WINDOWS_CONTEXT_MANAGER (object);
+
+        /* Call super */
+        object_class =
+                G_OBJECT_CLASS (gupnp_windows_context_manager_parent_class);
+        object_class->dispose (object);
+}
+
+static void
+gupnp_windows_context_manager_class_init (GUPnPWindowsContextManagerClass *klass)
+{
+        GObjectClass *object_class;
+
+        object_class = G_OBJECT_CLASS (klass);
+
+        object_class->constructed  = gupnp_windows_context_manager_constructed;
+        object_class->dispose      = gupnp_windows_context_manager_dispose;
+}
diff --git a/libgupnp/gupnp-windows-context-manager.h b/libgupnp/gupnp-windows-context-manager.h
new file mode 100644
index 0000000..65997cf
--- /dev/null
+++ b/libgupnp/gupnp-windows-context-manager.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2009, 2010 Jens Georg
+ * Copyright (C) 2009 Nokia Corporation, all rights reserved.
+ * Copyright (C) 2006, 2007, 2008 OpenedHand Ltd.
+ *
+ * Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
+ *         Jorn Baayen <jorn openedhand com>
+ *         Jens Georg <mail jensge org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GUPNP_WINDOWS_CONTEXT_MANAGER_H__
+#define __GUPNP_WINDOWS_CONTEXT_MANAGER_H__
+
+#include "gupnp-context-manager.h"
+
+G_BEGIN_DECLS
+
+GType
+gupnp_windows_context_manager_get_type (void) G_GNUC_CONST;
+
+#define GUPNP_TYPE_WINDOWS_CONTEXT_MANAGER \
+                (gupnp_windows_context_manager_get_type ())
+#define GUPNP_WINDOWS_CONTEXT_MANAGER(obj) \
+                (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+                 GUPNP_TYPE_WINDOWS_CONTEXT_MANAGER, \
+                 GUPnPWindowsContextManager))
+#define GUPNP_WINDOWS_CONTEXT_MANAGER_CLASS(obj) \
+                (G_TYPE_CHECK_CLASS_CAST ((obj), \
+                 GUPNP_TYPE_WINDOWS_CONTEXT_MANAGER, \
+                 GUPnPWindowsContextManagerClass))
+#define GUPNP_IS_WINDOWS_CONTEXT_MANAGER(obj) \
+                (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+                 GUPNP_TYPE_WINDOWS_CONTEXT_MANAGER))
+#define GUPNP_IS_WINDOWS_CONTEXT_MANAGER_CLASS(obj) \
+                (G_TYPE_CHECK_CLASS_TYPE ((obj), \
+                 GUPNP_TYPE_WINDOWS_CONTEXT_MANAGER))
+#define GUPNP_WINDOWS_CONTEXT_MANAGER_GET_CLASS(obj) \
+                (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+                 GUPNP_TYPE_WINDOWS_CONTEXT_MANAGER, \
+                 GUPnPWindowsContextManagerClass))
+
+typedef struct {
+        GUPnPContextManager parent;
+} GUPnPWindowsContextManager;
+
+typedef struct {
+        GUPnPContextManagerClass parent_class;
+
+        /* future padding */
+        void (* _gupnp_reserved1) (void);
+        void (* _gupnp_reserved2) (void);
+        void (* _gupnp_reserved3) (void);
+        void (* _gupnp_reserved4) (void);
+} GUPnPWindowsContextManagerClass;
+
+G_END_DECLS
+
+#endif /* __GUPNP_WINDOWS_CONTEXT_MANAGER_H__ */
-- 
1.7.5.4



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