Skip to content

Commit 689d0b0

Browse files
committed
Save work on WIN32 DNS-SD API support (Issue #29)
1 parent 7df2a4d commit 689d0b0

1 file changed

Lines changed: 174 additions & 24 deletions

File tree

cups/dnssd.c

Lines changed: 174 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
struct _cups_dnssd_s // DNS-SD context
5555
{
5656
cups_rwlock_t rwlock; // R/W lock for context
57-
size_t config_changes; // Number of hostname/network changes
57+
size_t config_changes; // Number of hostname/network changes
5858
cups_dnssd_error_cb_t cb; // Error callback function
5959
void *cb_data; // Error callback data
6060
cups_array_t *browses, // Browse requests
@@ -66,19 +66,19 @@ struct _cups_dnssd_s // DNS-SD context
6666
DNSServiceRef ref; // Master service reference
6767
char hostname[256]; // Current mDNS hostname
6868
DNSServiceRef hostname_ref; // Hostname monitoring reference
69-
cups_thread_t monitor; // Monitoring thread
69+
cups_thread_t monitor; // Monitoring thread
7070

7171
#elif _WIN32
7272
char hostname[256]; // Current mDNS hostname
7373

7474
#else // HAVE_AVAHI
7575
cups_mutex_t mutex; // Avahi poll mutex
7676
bool in_callback; // Doing a callback?
77-
AvahiClient *client; // Avahi client connection
77+
AvahiClient *client; // Avahi client connection
7878
AvahiSimplePoll *poll; // Avahi poll class
79-
cups_thread_t monitor; // Monitoring thread
79+
cups_thread_t monitor; // Monitoring thread
8080
AvahiDomainBrowser *dbrowser; // Domain browser
81-
size_t num_domains; // Number of domains
81+
size_t num_domains; // Number of domains
8282
char domains[_CUPS_DNSSD_MAX][256];
8383
// Domains
8484
#endif // HAVE_MDNSRESPONDER
@@ -94,7 +94,7 @@ struct _cups_dnssd_browse_s // DNS-SD browse request
9494
DNSServiceRef ref; // Browse reference
9595

9696
#elif _WIN32
97-
size_t num_browsers; // Number of browsers
97+
size_t num_browsers; // Number of browsers
9898
struct
9999
{ // Browsers
100100
WCHAR name[256]; // Browse name as a UTF-16 string
@@ -103,7 +103,7 @@ struct _cups_dnssd_browse_s // DNS-SD browse request
103103
} browsers[_CUPS_DNSSD_MAX];
104104

105105
#else // HAVE_AVAHI
106-
size_t num_browsers; // Number of browsers
106+
size_t num_browsers; // Number of browsers
107107
AvahiServiceBrowser *browsers[_CUPS_DNSSD_MAX];
108108
// Browsers
109109
#endif // HAVE_MDNSRESPONDER
@@ -177,7 +177,7 @@ struct _cups_dnssd_service_s // DNS-SD service registration
177177
// Service location records
178178

179179
#elif _WIN32
180-
size_t num_srvs; // Number of services
180+
size_t num_srvs; // Number of services
181181
struct _win32_srv_s srvs[_CUPS_DNSSD_MAX];
182182
// Services
183183

@@ -212,6 +212,7 @@ static void win32_browse_cb(DWORD status, PVOID context, PDNS_RECORD record);
212212
static void win32_query_cb(PVOID context, PDNS_QUERY_RESULT result);
213213
static void win32_resolve_cb(DWORD status, PVOID context, PDNS_SERVICE_INSTANCE instance);
214214
static void win32_service_cb(DWORD status, PVOID context, PDNS_SERVICE_INSTANCE instance);
215+
static void win32_utf8cpy(char *dst, const WCHAR *src, size_t dstsize);
215216
static void win32_wstrcpy(WCHAR *dst, const char *src, size_t dstsize);
216217

217218
#else // HAVE_AVAHI
@@ -239,7 +240,7 @@ static void avahi_service_cb(AvahiEntryGroup *srv, AvahiEntryGroupState state,
239240
bool // O - `true` on success, `false` on failure
240241
cupsDNSSDAssembleFullName(
241242
char *fullname, // I - Buffer for full name
242-
size_t fullsize, // I - Size of buffer
243+
size_t fullsize, // I - Size of buffer
243244
const char *name, // I - Service instance name
244245
const char *type, // I - Registration type
245246
const char *domain) // I - Domain
@@ -254,7 +255,28 @@ cupsDNSSDAssembleFullName(
254255
return (DNSServiceConstructFullName(fullname, name, type, domain) == kDNSServiceErr_NoError);
255256

256257
#elif _WIN32
257-
return (snprintf(fullname, fullsize, "%s.%s.%s", name, type, domain ? domain : "local") > 0);
258+
char *fullptr, // Pointer into full name
259+
*fullend; // End of full name
260+
261+
for (fullptr = fullname, fullend = fullname + fullsize - 1; *name; name ++)
262+
{
263+
if (*name == ' ' || *name == '\\' || (*name & 0x80))
264+
{
265+
if ((fullend - fullptr) < 4)
266+
return (false);
267+
268+
snprintf(fullptr, fullend - fullptr + 1, "\\%03d", *name & 255);
269+
fullptr += strlen(fullptr);
270+
}
271+
else
272+
{
273+
*fullptr++ = *name;
274+
}
275+
}
276+
277+
snprintf(fullptr, fullend - fullptr + 1, ".%s.%s", type, domain ? domain : "local");
278+
279+
return (true);
258280

259281
#else // HAVE_AVAHI
260282
return (!avahi_service_name_join(fullname, fullsize, name, type, domain));
@@ -1038,13 +1060,16 @@ cupsDNSSDQueryNew(
10381060

10391061
query->res.Version = DNS_QUERY_REQUEST_VERSION1;
10401062

1063+
// TODO: FIgure out why mDNS queries can't work...
1064+
# if 0
10411065
if ((status = DnsQueryEx(&query->req, &query->res, &query->cancel)) != DNS_REQUEST_PENDING)
10421066
{
10431067
report_error(dnssd, "Unable to create DNS-SD query request: %d", status);
10441068
free(query);
10451069
query = NULL;
10461070
goto done;
10471071
}
1072+
# endif // 0
10481073

10491074
#else // HAVE_AVAHI
10501075
if (!dnssd->in_callback)
@@ -1280,9 +1305,9 @@ bool // O - `true` on success, `false` on error
12801305
cupsDNSSDSeparateFullName(
12811306
const char *fullname, // I - Full service name
12821307
char *name, // I - Instance name buffer
1283-
size_t namesize, // I - Size of instance name buffer
1308+
size_t namesize, // I - Size of instance name buffer
12841309
char *type, // I - Registration type buffer
1285-
size_t typesize, // I - Size of registration type buffer
1310+
size_t typesize, // I - Size of registration type buffer
12861311
char *domain, // I - Domain name buffer
12871312
size_t domainsize) // I - Size of domain name buffer
12881313
{
@@ -1477,8 +1502,7 @@ cupsDNSSDServiceAdd(
14771502
*end, // End of TXT buffer
14781503
*keys[256], // TXT key strings
14791504
*values[256]; // TXT value strings
1480-
const char *base, // Base query name
1481-
*subtype; // Subtype
1505+
const char *base; // Base service type
14821506
char fullname[256]; // Full service instance name
14831507
cups_array_t *tarray; // Types array
14841508

@@ -1492,16 +1516,12 @@ cupsDNSSDServiceAdd(
14921516
base = (const char *)cupsArrayGetElement(tarray, 0);
14931517
count = cupsArrayGetCount(tarray);
14941518

1495-
if (count == 1)
1496-
count ++;
1497-
1498-
for (i = 1; i < count; i ++)
1519+
// TODO: Figure out how WinDNS wants sub-types registered, yields invalid argument error for sub-type
1520+
for (i = 0; i < count && i < 1; i ++)
14991521
{
15001522
// Get the fullname...
1501-
subtype = (const char *)cupsArrayGetElement(tarray, i);
1502-
1503-
if (subtype)
1504-
snprintf(fullname, sizeof(fullname), "%s.%s._sub.%s.%s", service->name, subtype, base, domain ? domain : "local");
1523+
if (i)
1524+
snprintf(fullname, sizeof(fullname), "%s.%s._sub.%s.%s", service->name, (const char*)cupsArrayGetElement(tarray, i), base, domain ? domain : "local");
15051525
else
15061526
snprintf(fullname, sizeof(fullname), "%s.%s.%s", service->name, base, domain ? domain : "local");
15071527

@@ -2445,9 +2465,30 @@ mdns_to_cups(
24452465
static void
24462466
win32_browse_cb(
24472467
DWORD status, // I - Status
2448-
PVOID context, // I - Browser
2449-
PDNS_RECORD record) // I - New record
2468+
PVOID context, // I - Browser
2469+
PDNS_RECORD records) // I - Record list
24502470
{
2471+
cups_dnssd_browse_t *browse = (cups_dnssd_browse_t *)context;
2472+
PDNS_RECORD record; // Current DNS record
2473+
char fullname[256], // Full service instance name
2474+
name[256] = "", // Service name
2475+
type[256] = "", // Service type
2476+
domain[256] = ""; // Domain name
2477+
2478+
2479+
for (record = records; record; record = record->pNext)
2480+
{
2481+
if (record->wType == DNS_TYPE_PTR)
2482+
{
2483+
win32_utf8cpy(fullname, record->Data.PTR.pNameHost, sizeof(fullname));
2484+
cupsDNSSDSeparateFullName(fullname, name, sizeof(name), type, sizeof(type), domain, sizeof(domain));
2485+
break;
2486+
}
2487+
}
2488+
2489+
(browse->cb)(browse, browse->cb_data, status == ERROR_SUCCESS ? CUPS_DNSSD_FLAGS_NONE : CUPS_DNSSD_FLAGS_ERROR, /*if_index*/0, name, type, domain);
2490+
2491+
DnsRecordListFree(records, DnsFreeRecordList);
24512492
}
24522493

24532494

@@ -2460,6 +2501,22 @@ win32_query_cb(
24602501
PVOID context, // I - Pointer to query
24612502
PDNS_QUERY_RESULT result) // I - Query result
24622503
{
2504+
cups_dnssd_query_t *query = (cups_dnssd_query_t *)context;
2505+
// Query
2506+
char fullname[256]; // Full instance name of query
2507+
2508+
2509+
win32_utf8cpy(fullname, query->fullname, sizeof(fullname));
2510+
2511+
if (result && result->pQueryRecords)
2512+
{
2513+
PDNS_RECORD record; // Current DNS record
2514+
2515+
for (record = result->pQueryRecords; record; record = record->pNext)
2516+
(query->cb)(query, query->cb_data, CUPS_DNSSD_FLAGS_NONE, /*if_index*/0, fullname, record->wType, &record->Data, record->wDataLength);
2517+
2518+
DnsRecordListFree(result->pQueryRecords, DnsFreeRecordList);
2519+
}
24632520
}
24642521

24652522

@@ -2473,6 +2530,39 @@ win32_resolve_cb(
24732530
PVOID context, // I - Resolver
24742531
PDNS_SERVICE_INSTANCE instance) // I - Service instance
24752532
{
2533+
cups_dnssd_resolve_t *resolve = (cups_dnssd_resolve_t *)context;
2534+
// Resolver
2535+
2536+
2537+
if (status == ERROR_SUCCESS)
2538+
{
2539+
char fullname[256], // Full instance name
2540+
hostname[256], // Hostname
2541+
txtname[256], // TXT name
2542+
txtvalue[256]; // TXT value
2543+
DWORD i; // Looping var
2544+
size_t num_txt = 0; // Number of TXT values
2545+
cups_option_t *txt = NULL; // TXT values
2546+
2547+
win32_utf8cpy(fullname, instance->pszInstanceName, sizeof(fullname));
2548+
win32_utf8cpy(hostname, instance->pszHostName, sizeof(hostname));
2549+
2550+
for (i = 0; i < instance->dwPropertyCount; i ++)
2551+
{
2552+
win32_utf8cpy(txtname, instance->keys[i], sizeof(txtname));
2553+
win32_utf8cpy(txtvalue, instance->values[i], sizeof(txtvalue));
2554+
2555+
num_txt = cupsAddOption(txtname, txtvalue, num_txt, &txt);
2556+
}
2557+
2558+
(resolve->cb)(resolve, resolve->cb_data, CUPS_DNSSD_FLAGS_NONE, instance->dwInterfaceIndex, fullname, hostname, instance->wPort, num_txt, txt);
2559+
2560+
cupsFreeOptions(num_txt, txt);
2561+
}
2562+
else
2563+
{
2564+
(resolve->cb)(resolve, resolve->cb_data, CUPS_DNSSD_FLAGS_ERROR, /*if_index*/0, /*fullname*/NULL, /*host*/NULL, /*port*/0, /*num_txt*/0, /*txt*/NULL);
2565+
}
24762566
}
24772567

24782568

@@ -2486,6 +2576,66 @@ win32_service_cb(
24862576
PVOID context, // I - Service
24872577
PDNS_SERVICE_INSTANCE instance) // I - New instance
24882578
{
2579+
cups_dnssd_service_t *service = (cups_dnssd_service_t *)context;
2580+
// Service
2581+
2582+
(service->cb)(service, service->cb_data, status == ERROR_SUCCESS ? CUPS_DNSSD_FLAGS_NONE : CUPS_DNSSD_FLAGS_ERROR);
2583+
2584+
if (instance)
2585+
DnsServiceFreeInstance(instance);
2586+
}
2587+
2588+
2589+
//
2590+
// 'win32_utf8cpy()' - Copy a UTF-16 string to a UTF-8 string.
2591+
//
2592+
2593+
static void
2594+
win32_utf8cpy(char *dst, // I - Destination string
2595+
const WCHAR *src, // I - Source string
2596+
size_t dstsize) // I - Size of destination string
2597+
{
2598+
int ch; // Current character
2599+
2600+
2601+
// Loop until we run out of characters or buffer space...
2602+
while (*src && dstsize > 4)
2603+
{
2604+
// Get the current character...
2605+
ch = *src++;
2606+
2607+
if (ch >= 0xd800 && ch <= 0xdbff && *src >= 0xdc00 && *src <= 0xdfff)
2608+
{
2609+
// Convert UTF-16 to unicode...
2610+
ch = ((ch - 0xd800) << 10) | (*src++ - 0xdc00);
2611+
}
2612+
2613+
if (ch < 0x80)
2614+
{
2615+
*dst++ = ch;
2616+
}
2617+
else if (ch < 0x800)
2618+
{
2619+
*dst++ = 0xc0 | (ch >> 6);
2620+
*dst++ = 0x80 | (ch & 0x3f);
2621+
}
2622+
else if (ch < 0x10000)
2623+
{
2624+
*dst++ = 0xe0 | (ch >> 12);
2625+
*dst++ = 0x80 | ((ch >> 6) & 0x3f);
2626+
*dst++ = 0x80 | (ch & 0x3f);
2627+
}
2628+
else
2629+
{
2630+
*dst++ = 0xf0 | (ch >> 18);
2631+
*dst++ = 0x80 | ((ch >> 12) & 0x3f);
2632+
*dst++ = 0x80 | ((ch >> 6) & 0x3f);
2633+
*dst++ = 0x80 | (ch & 0x3f);
2634+
}
2635+
}
2636+
2637+
// Nul-terminate the destination...
2638+
*dst = '\0';
24892639
}
24902640

24912641

0 commit comments

Comments
 (0)