5454struct _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);
212212static void win32_query_cb (PVOID context , PDNS_QUERY_RESULT result );
213213static void win32_resolve_cb (DWORD status , PVOID context , PDNS_SERVICE_INSTANCE instance );
214214static 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 );
215216static 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,
239240bool // O - `true` on success, `false` on failure
240241cupsDNSSDAssembleFullName (
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
12801305cupsDNSSDSeparateFullName (
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(
24452465static void
24462466win32_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