--- a/libpurple/protocols/bonjour/mdns_dnsapi.c Tue Jan 05 06:13:59 2021 -0500
+++ b/libpurple/protocols/bonjour/mdns_dnsapi.c Thu Jan 07 05:38:13 2021 -0500
@@ -44,7 +44,7 @@
+ PMDNS_QUERY_HANDLE null_query; @@ -280,6 +280,63 @@
+_mdns_null_query_error(gpointer _data) + DWORD status = GPOINTER_TO_UINT(_data); + purple_debug_error("bonjour", "record query - callback error (%ld)", + return G_SOURCE_REMOVE; +_mdns_null_query_parse(gpointer _data) + DnsAPIRecordData *data = _data; + PDNS_RECORD pDnsRecord = data->dns_record; + BonjourBuddy *bb = (BonjourBuddy *)data->context; + Win32BuddyImplData *idata = bb->mdns_impl_data; + g_return_val_if_fail(idata != NULL, G_SOURCE_REMOVE); + /* } else if (flags & kDNSServiceFlagsAdd && rrtype == kDNSServiceType_NULL) { */ + /* Buddy Icon response */ + /* bonjour_buddy_got_buddy_icon(bb, rdata, rdlen); */ + /* We've got what we need; stop listening */ + DnsStopMulticastQuery(idata->null_query); + g_clear_pointer(&idata->null_query, g_free); + return G_SOURCE_REMOVE; +/* This callback occurs in a different thread; so all it does is pass this to + * the main context thread, or Purple will break. */ +_mdns_null_query_callback(PVOID pQueryContext, PMDNS_QUERY_HANDLE pQueryHandle, + PDNS_QUERY_RESULT pQueryResults) + if (pQueryResults->QueryStatus == ERROR_SUCCESS) { + DnsAPIRecordData *data = g_new(DnsAPIRecordData, 1); + data->dns_record = pQueryResults->pQueryRecords; + data->context = pQueryContext; + g_timeout_add_seconds_full(G_PRIORITY_DEFAULT, 0, + G_SOURCE_FUNC(_mdns_null_query_parse), data, + (GDestroyNotify)_mdns_record_data_free); + g_timeout_add_seconds(0, G_SOURCE_FUNC(_mdns_null_query_error), + GUINT_TO_POINTER(pQueryResults->QueryStatus)); + if (pQueryResults->pQueryRecords) { + DnsRecordListFree(pQueryResults->pQueryRecords, DnsFreeRecordList); /****************************
* mdns_interface functions *
****************************/
@@ -493,6 +550,11 @@
g_return_if_fail(idata != NULL);
+ if (idata->null_query != NULL) { + DnsStopMulticastQuery(idata->null_query); + g_free(idata->null_query); g_clear_pointer(&buddy->mdns_impl_data, g_free);
@@ -500,8 +562,46 @@
dnsapi_mdns_retrieve_buddy_icon(BonjourBuddy *buddy)
Win32BuddyImplData *idata = buddy->mdns_impl_data;
+ gchar *service_name = NULL; + MDNS_QUERY_REQUEST query; g_return_if_fail(idata != NULL);
+ /* Cancel any existing query */ + if (idata->null_query != NULL) { + DnsStopMulticastQuery(idata->null_query); + g_clear_pointer(&idata->null_query, g_free); + service_name = g_strjoin(".", buddy->name, LINK_LOCAL_DOMAIN_NAME, NULL); + query.Version = DNS_QUERY_REQUEST_VERSION1; + query.Query = g_utf8_to_utf16(service_name, -1, NULL, NULL, &error); + purple_debug_error("bonjour", + "Unable to convert service name '%s' to UTF-16: %s", + service_name, error->message); + query.QueryType = DNS_TYPE_NULL; + query.QueryOptions = DNS_QUERY_STANDARD; + query.InterfaceIndex = 0; + query.pQueryCallback = _mdns_null_query_callback; + query.pQueryContext = buddy; + idata->null_query = g_new0(MDNS_QUERY_HANDLE, 1); + status = DnsStartMulticastQuery(&query, idata->null_query); + if (status != ERROR_SUCCESS) { + purple_debug_error("bonjour", + "Unable to query buddy icon record for %s (%ld)", + g_free((gpointer)query.Query);