qulogic/pidgin

Add a runtime-loading wrapper around the Windows 10 DNS Service API.
draft win-mdns
2020-12-30, Elliott Sales de Andrade
320f1e6a616d
Parents 95d36c221e21
Children 2b333e953bd1
Add a runtime-loading wrapper around the Windows 10 DNS Service API.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/protocols/bonjour/dnsapi_proxy.c Wed Dec 30 03:37:58 2020 -0500
@@ -0,0 +1,167 @@
+/*
+ * Purple - Internet Messaging Library
+ * Copyright (C) Pidgin Developers <devel@pidgin.im>
+ *
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <purple.h>
+
+#include "dnsapi_proxy.h"
+
+static void (WINAPI *_DnsFree)(PVOID pData, DNS_FREE_TYPE FreeType);
+static DNS_STATUS (*_DnsServiceBrowse)(PDNS_SERVICE_BROWSE_REQUEST pRequest, PDNS_SERVICE_CANCEL pCancel);
+static DNS_STATUS (*_DnsServiceBrowseCancel)(PDNS_SERVICE_CANCEL pCancelHandle);
+static PDNS_SERVICE_INSTANCE (*_DnsServiceConstructInstance)(PCWSTR pServiceName, PCWSTR pHostName, PIP4_ADDRESS pIp4, PIP6_ADDRESS pIp6, WORD wPort, WORD wPriority, WORD wWeight, DWORD dwPropertiesCount, PCWSTR *keys, PCWSTR *values);
+static PDNS_SERVICE_INSTANCE (*_DnsServiceCopyInstance)(PDNS_SERVICE_INSTANCE pOrig);
+static DWORD (*_DnsServiceDeRegister)(PDNS_SERVICE_REGISTER_REQUEST pRequest, PDNS_SERVICE_CANCEL pCancel);
+static void (*_DnsServiceFreeInstance)(PDNS_SERVICE_INSTANCE pInstance);
+static DWORD (*_DnsServiceRegister)(PDNS_SERVICE_REGISTER_REQUEST pRequest, PDNS_SERVICE_CANCEL pCancel);
+static DWORD (*_DnsServiceRegisterCancel)(PDNS_SERVICE_CANCEL pCancelHandle);
+static DNS_STATUS (*_DnsServiceResolve)(PDNS_SERVICE_RESOLVE_REQUEST pRequest, PDNS_SERVICE_CANCEL pCancel);
+static DNS_STATUS (*_DnsServiceResolveCancel)(PDNS_SERVICE_CANCEL pCancelHandle);
+static DNS_STATUS (*_DnsStartMulticastQuery)(PMDNS_QUERY_REQUEST pQueryRequest, PMDNS_QUERY_HANDLE pHandle);
+static DNS_STATUS (*_DnsStopMulticastQuery)(PMDNS_QUERY_HANDLE pHandle);
+
+gboolean
+dnsapi_available(void)
+{
+ static gboolean initialized = FALSE;
+ static gboolean loaded = FALSE;
+
+ if (!initialized) {
+ GModule *dnsapi = NULL;
+ initialized = TRUE;
+ if((dnsapi = g_module_open("dnsapi.dll", 0)) != NULL &&
+ g_module_symbol(dnsapi, "DnsFree", (gpointer *)&_DnsFree) &&
+ g_module_symbol(dnsapi, "DnsServiceBrowse", (gpointer *)&_DnsServiceBrowse) &&
+ g_module_symbol(dnsapi, "DnsServiceBrowseCancel", (gpointer *)&_DnsServiceBrowseCancel) &&
+ g_module_symbol(dnsapi, "DnsServiceConstructInstance", (gpointer *)&_DnsServiceConstructInstance) &&
+ g_module_symbol(dnsapi, "DnsServiceCopyInstance", (gpointer *)&_DnsServiceCopyInstance) &&
+ g_module_symbol(dnsapi, "DnsServiceDeRegister", (gpointer *)&_DnsServiceDeRegister) &&
+ g_module_symbol(dnsapi, "DnsServiceFreeInstance", (gpointer *)&_DnsServiceFreeInstance) &&
+ g_module_symbol(dnsapi, "DnsServiceRegister", (gpointer *)&_DnsServiceRegister) &&
+ g_module_symbol(dnsapi, "DnsServiceRegisterCancel", (gpointer *)&_DnsServiceRegisterCancel) &&
+ g_module_symbol(dnsapi, "DnsServiceResolve", (gpointer *)&_DnsServiceResolve) &&
+ g_module_symbol(dnsapi, "DnsServiceResolveCancel", (gpointer *)&_DnsServiceResolveCancel) &&
+ g_module_symbol(dnsapi, "DnsStartMulticastQuery", (gpointer *)&_DnsStartMulticastQuery) &&
+ g_module_symbol(dnsapi, "DnsStopMulticastQuery", (gpointer *)&_DnsStopMulticastQuery))
+ {
+ /* TODO: The dnsapi module leaks, but there's not a good
+ * place to put the cleanup yet, as there's quite a bit
+ * of abstraction between mDNS API here to the actual
+ * plugin unload. */
+ loaded = TRUE;
+ } else {
+ g_clear_pointer(&dnsapi, g_module_close);
+ }
+ }
+ return loaded;
+}
+
+
+void
+_wpurple_DnsFree(PVOID pData, DNS_FREE_TYPE FreeType)
+{
+ g_return_if_fail(_DnsFree != NULL);
+ _DnsFree(pData, FreeType);
+}
+
+DNS_STATUS
+_wpurple_DnsServiceBrowse(PDNS_SERVICE_BROWSE_REQUEST pRequest, PDNS_SERVICE_CANCEL pCancel)
+{
+ g_return_val_if_fail(_DnsServiceBrowse != NULL, WSAEINVALIDPROCTABLE);
+ return _DnsServiceBrowse(pRequest, pCancel);
+}
+
+DNS_STATUS
+_wpurple_DnsServiceBrowseCancel(PDNS_SERVICE_CANCEL pCancelHandle)
+{
+ g_return_val_if_fail(_DnsServiceBrowseCancel != NULL, WSAEINVALIDPROCTABLE);
+ return _DnsServiceBrowseCancel(pCancelHandle);
+}
+
+PDNS_SERVICE_INSTANCE
+_wpurple_DnsServiceConstructInstance(PCWSTR pServiceName, PCWSTR pHostName, PIP4_ADDRESS pIp4, PIP6_ADDRESS pIp6, WORD wPort, WORD wPriority, WORD wWeight, DWORD dwPropertiesCount, PCWSTR *keys, PCWSTR *values)
+{
+ g_return_val_if_fail(_DnsServiceConstructInstance != NULL, NULL);
+ return _DnsServiceConstructInstance(pServiceName, pHostName, pIp4, pIp6, wPort, wPriority, wWeight, dwPropertiesCount, keys, values);
+}
+
+PDNS_SERVICE_INSTANCE
+_wpurple_DnsServiceCopyInstance(PDNS_SERVICE_INSTANCE pOrig)
+{
+ g_return_val_if_fail(_DnsServiceCopyInstance != NULL, NULL);
+ return _DnsServiceCopyInstance(pOrig);
+}
+
+DWORD
+_wpurple_DnsServiceDeRegister(PDNS_SERVICE_REGISTER_REQUEST pRequest, PDNS_SERVICE_CANCEL pCancel)
+{
+ g_return_val_if_fail(_DnsServiceDeRegister != NULL, WSAEINVALIDPROCTABLE);
+ return _DnsServiceDeRegister(pRequest, pCancel);
+}
+
+void
+_wpurple_DnsServiceFreeInstance(PDNS_SERVICE_INSTANCE pInstance)
+{
+ g_return_if_fail(_DnsServiceFreeInstance != NULL);
+ _DnsServiceFreeInstance(pInstance);
+}
+
+DWORD
+_wpurple_DnsServiceRegister(PDNS_SERVICE_REGISTER_REQUEST pRequest, PDNS_SERVICE_CANCEL pCancel)
+{
+ g_return_val_if_fail(_DnsServiceRegister != NULL, WSAEINVALIDPROCTABLE);
+ return _DnsServiceRegister(pRequest, pCancel);
+}
+
+DWORD
+_wpurple_DnsServiceRegisterCancel(PDNS_SERVICE_CANCEL pCancelHandle)
+{
+ g_return_val_if_fail(_DnsServiceRegisterCancel != NULL, WSAEINVALIDPROCTABLE);
+ return _DnsServiceRegisterCancel(pCancelHandle);
+}
+
+DNS_STATUS
+_wpurple_DnsServiceResolve(PDNS_SERVICE_RESOLVE_REQUEST pRequest, PDNS_SERVICE_CANCEL pCancel)
+{
+ g_return_val_if_fail(_DnsServiceResolve != NULL, WSAEINVALIDPROCTABLE);
+ return _DnsServiceResolve(pRequest, pCancel);
+}
+
+DNS_STATUS
+_wpurple_DnsServiceResolveCancel(PDNS_SERVICE_CANCEL pCancelHandle)
+{
+ g_return_val_if_fail(_DnsServiceResolveCancel != NULL, WSAEINVALIDPROCTABLE);
+ return _DnsServiceResolveCancel(pCancelHandle);
+}
+
+DNS_STATUS
+_wpurple_DnsStartMulticastQuery(PMDNS_QUERY_REQUEST pQueryRequest, PMDNS_QUERY_HANDLE pHandle)
+{
+ g_return_val_if_fail(_DnsStartMulticastQuery != NULL, WSAEINVALIDPROCTABLE);
+ return _DnsStartMulticastQuery(pQueryRequest, pHandle);
+}
+
+DNS_STATUS
+_wpurple_DnsStopMulticastQuery(PMDNS_QUERY_HANDLE pHandle)
+{
+ g_return_val_if_fail(_DnsStopMulticastQuery != NULL, WSAEINVALIDPROCTABLE);
+ return _DnsStopMulticastQuery(pHandle);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/protocols/bonjour/dnsapi_proxy.h Wed Dec 30 03:37:58 2020 -0500
@@ -0,0 +1,88 @@
+/*
+ * Purple - Internet Messaging Library
+ * Copyright (C) Pidgin Developers <devel@pidgin.im>
+ *
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef PURPLE_BONJOUR_DNSAPI_PROXY_H
+#define PURPLE_BONJOUR_DNSAPI_PROXY_H
+
+#include <stdint.h>
+#include <windns.h>
+
+gboolean dnsapi_available(void);
+
+typedef void (DNS_QUERY_COMPLETION_ROUTINE)(PVOID pQueryContext, PDNS_QUERY_RESULT pQueryResults);
+typedef void (DNS_SERVICE_BROWSE_CALLBACK)(DWORD Status, PVOID pQueryContext, PDNS_RECORD pDnsRecord);
+typedef void (DNS_SERVICE_REGISTER_COMPLETE)(DWORD Status, PVOID pQueryContext, PDNS_SERVICE_INSTANCE pInstance);
+typedef void (DNS_SERVICE_RESOLVE_COMPLETE)(DWORD Status, PVOID pQueryContext, PDNS_SERVICE_INSTANCE pInstance);
+typedef void (MDNS_QUERY_CALLBACK)(PVOID pQueryContext, PMDNS_QUERY_HANDLE pQueryHandle, PDNS_QUERY_RESULT pQueryResults);
+void _wpurple_DnsFree(PVOID pData, DNS_FREE_TYPE FreeType);
+#define DnsFree(pData, FreeType) \
+ _wpurple_DnsFree(pData, FreeType)
+
+DNS_STATUS _wpurple_DnsServiceBrowse(PDNS_SERVICE_BROWSE_REQUEST pRequest, PDNS_SERVICE_CANCEL pCancel);
+#define DnsServiceBrowse(pRequest, pCancel) \
+ _wpurple_DnsServiceBrowse(pRequest, pCancel)
+
+DNS_STATUS _wpurple_DnsServiceBrowseCancel(PDNS_SERVICE_CANCEL pCancelHandle);
+#define DnsServiceBrowseCancel(pCancelHandle) \
+ _wpurple_DnsServiceBrowseCancel(pCancelHandle)
+
+PDNS_SERVICE_INSTANCE _wpurple_DnsServiceConstructInstance(PCWSTR pServiceName, PCWSTR pHostName, PIP4_ADDRESS pIp4, PIP6_ADDRESS pIp6, WORD wPort, WORD wPriority, WORD wWeight, DWORD dwPropertiesCount, PCWSTR *keys, PCWSTR *values);
+#define DnsServiceConstructInstance(pServiceName, pHostName, pIp4, pIp6, wPort, wPriority, wWeight, dwPropertiesCount, keys, values) \
+ _wpurple_DnsServiceConstructInstance(pServiceName, pHostName, pIp4, pIp6, wPort, wPriority, wWeight, dwPropertiesCount, keys, values)
+
+PDNS_SERVICE_INSTANCE _wpurple_DnsServiceCopyInstance(PDNS_SERVICE_INSTANCE pOrig);
+#define DnsServiceCopyInstance(pOrig) \
+ _wpurple_DnsServiceCopyInstance(pOrig)
+
+DWORD _wpurple_DnsServiceDeRegister(PDNS_SERVICE_REGISTER_REQUEST pRequest, PDNS_SERVICE_CANCEL pCancel);
+#define DnsServiceDeRegister(pRequest, pCancel) \
+ _wpurple_DnsServiceDeRegister(pRequest, pCancel)
+
+void _wpurple_DnsServiceFreeInstance(PDNS_SERVICE_INSTANCE pInstance);
+#define DnsServiceFreeInstance(pInstance) \
+ _wpurple_DnsServiceFreeInstance(pInstance)
+
+DWORD _wpurple_DnsServiceRegister(PDNS_SERVICE_REGISTER_REQUEST pRequest, PDNS_SERVICE_CANCEL pCancel);
+#define DnsServiceRegister(pRequest, pCancel) \
+ _wpurple_DnsServiceRegister(pRequest, pCancel)
+
+DWORD _wpurple_DnsServiceRegisterCancel(PDNS_SERVICE_CANCEL pCancelHandle);
+#define DnsServiceRegisterCancel(pCancelHandle) \
+ _wpurple_DnsServiceRegisterCancel(pCancelHandle)
+
+DNS_STATUS _wpurple_DnsServiceResolve(PDNS_SERVICE_RESOLVE_REQUEST pRequest, PDNS_SERVICE_CANCEL pCancel);
+#define DnsServiceResolve(pRequest, pCancel) \
+ _wpurple_DnsServiceResolve(pRequest, pCancel)
+
+DNS_STATUS _wpurple_DnsServiceResolveCancel(PDNS_SERVICE_CANCEL pCancelHandle);
+#define DnsServiceResolveCancel(pCancelHandle) \
+ _wpurple_DnsServiceResolveCancel(pCancelHandle)
+
+DNS_STATUS _wpurple_DnsStartMulticastQuery(PMDNS_QUERY_REQUEST pQueryRequest, PMDNS_QUERY_HANDLE pHandle);
+#define DnsStartMulticastQuery(pQueryRequest, pHandle) \
+ _wpurple_DnsStartMulticastQuery(pQueryRequest, pHandle)
+
+DNS_STATUS _wpurple_DnsStopMulticastQuery(PMDNS_QUERY_HANDLE pHandle);
+#define DnsStopMulticastQuery(pHandle) \
+ _wpurple_DnsStopMulticastQuery(pHandle)
+
+#endif /* PURPLE_BONJOUR_DNSAPI_PROXY_H */
--- a/libpurple/protocols/bonjour/meson.build Mon Dec 04 02:21:08 2023 -0600
+++ b/libpurple/protocols/bonjour/meson.build Wed Dec 30 03:37:58 2020 -0500
@@ -16,6 +16,7 @@
if IS_WIN32
BONJOUR_SOURCES += [
+ 'dnsapi_proxy.c',
'dns_sd_proxy.c', 'dns_sd_proxy.h', 'mdns_dns_sd.c', 'mdns_dns_sd.h',
'mdns_win32.c'
]