• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Dynamic wrapper for Bonjour SDK for Windows.
3  *
4  * Copyright © 2020-2024 by OpenPrinting.
5  * Copyright 2018 by Apple Inc.
6  *
7  * Licensed under Apache License v2.0.  See the file "LICENSE" for more
8  * information.
9  */
10 
11 //#include <cups/http-private.h>
12 #include <cups/thread-private.h>
13 #include "dns_sd.h"
14 
15 
16 /*
17  * Pointers for functions...
18  */
19 
20 static int		dnssd_initialized = 0;
21 static _cups_mutex_t	dnssd_mutex = _CUPS_MUTEX_INITIALIZER;
22 static DNSServiceErrorType (*dnssd_add_record)(DNSServiceRef sdRef, DNSRecordRef *RecordRef, DNSServiceFlags flags, uint16_t rrtype, uint16_t rdlen, const void *rdata, uint32_t ttl);
23 static DNSServiceErrorType (*dnssd_browse)(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, const char *regtype, const char *domain, DNSServiceBrowseReply callBack, void *context);
24 static DNSServiceErrorType (*dnssd_construct_full_name)(char * const fullName, const char * const service, const char * const regtype, const char * const domain);
25 static DNSServiceErrorType (*dnssd_create_connection)(DNSServiceRef *sdRef);
26 static DNSServiceErrorType (*dnssd_process_result)(DNSServiceRef sdRef);
27 static DNSServiceErrorType (*dnssd_query_record)(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, const char *fullname, uint16_t rrtype, uint16_t rrclass, DNSServiceQueryRecordReply callBack, void *context);
28 static void (*dnssd_deallocate)(DNSServiceRef sdRef);
29 static int (*dnssd_sock_fd)(DNSServiceRef sdRef);
30 static DNSServiceErrorType (*dnssd_register)(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, const char *name, const char *regtype, const char *domain, const char *host, uint16_t port, uint16_t txtLen, const void *txtRecord, DNSServiceRegisterReply callBack, void *context);
31 static DNSServiceErrorType (*dnssd_remove_record)(DNSServiceRef sdRef, DNSRecordRef RecordRef, DNSServiceFlags flags);
32 static DNSServiceErrorType (*dnssd_resolve)(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, const char *name, const char *regtype, const char *domain, DNSServiceResolveReply callBack, void *context);
33 static DNSServiceErrorType (*dnssd_update_record)(DNSServiceRef sdRef, DNSRecordRef RecordRef, DNSServiceFlags flags, uint16_t rdlen, const void *rdata, uint32_t ttl);
34 
35 static void (*dnssd_txt_create)(TXTRecordRef *txtRecord, uint16_t bufferLen, void *buffer);
36 static void (*dnssd_txt_deallocate)(TXTRecordRef *txtRecord);
37 static const void *(*dnssd_txt_get_bytes_ptr)(const TXTRecordRef *txtRecord);
38 static uint16_t (*dnssd_txt_get_count)(uint16_t txtLen, const void *txtRecord);
39 static uint16_t (*dnssd_txt_get_length)(const TXTRecordRef *txtRecord);
40 static DNSServiceErrorType (*dnssd_txt_get_item_at_index)(uint16_t txtLen, const void *txtRecord, uint16_t itemIndex, uint16_t keyBufLen, char *key, uint8_t *valueLen, const void **value);
41 static const void *(*dnssd_txt_get_value_ptr)(uint16_t txtLen, const void *txtRecord, const char *key, uint8_t *valueLen);
42 static DNSServiceErrorType (*dnssd_txt_set_value)(TXTRecordRef *txtRecord, const char *key, uint8_t valueSize, const void *value);
43 
44 
45 /*
46  * Function to initialize pointers...
47  */
48 
49 static void
dnssd_init(void)50 dnssd_init(void)
51 {
52   _cupsMutexLock(&dnssd_mutex);
53   if (!dnssd_initialized)
54   {
55     HINSTANCE	dll_handle = LoadLibraryA("dnssd.dll");
56 
57     if (dll_handle)
58     {
59       dnssd_add_record          = (DNSServiceErrorType (*)(DNSServiceRef, DNSRecordRef *, DNSServiceFlags, uint16_t, uint16_t, const void *, uint32_t))GetProcAddress(dll_handle, "DNSServiceAddRecord");
60       dnssd_browse              = (DNSServiceErrorType(*)(DNSServiceRef *, DNSServiceFlags, uint32_t, const char *, const char *, DNSServiceBrowseReply, void *))GetProcAddress(dll_handle, "DNSServiceBrowse");
61       dnssd_construct_full_name = (DNSServiceErrorType(*)(char * const, const char * const, const char * const, const char * const))GetProcAddress(dll_handle, "DNSServiceConstructFullName");
62       dnssd_create_connection   = (DNSServiceErrorType(*)(DNSServiceRef *))GetProcAddress(dll_handle, "DNSServiceCreateConnection");
63       dnssd_deallocate          = (DNSServiceErrorType(*)(DNSServiceRef))GetProcAddress(dll_handle, "DNSServiceRefDeallocate");
64       dnssd_process_result      = (DNSServiceErrorType(*)(DNSServiceRef))GetProcAddress(dll_handle, "DNSServiceProcessResult");
65       dnssd_query_record        = (DNSServiceErrorType(*)(DNSServiceRef *, DNSServiceFlags, uint32_t, const char *, uint16_t, uint16_t, DNSServiceQueryRecordReply, void *))GetProcAddress(dll_handle, "DNSServiceQueryRecord");
66       dnssd_register            = (DNSServiceErrorType(*)(DNSServiceRef *, DNSServiceFlags, uint32_t, const char *, const char *, const char *, const char *, uint16_t, uint16_t, const void *, DNSServiceRegisterReply, void *))GetProcAddress(dll_handle, "DNSServiceRegister");
67       dnssd_remove_record       = (DNSServiceErrorType(*)(DNSServiceRef, DNSRecordRef, DNSServiceFlags))GetProcAddress(dll_handle, "DNSServiceRemoveRecord");
68       dnssd_resolve             = (DNSServiceErrorType(*)(DNSServiceRef *, DNSServiceFlags, uint32_t, const char *, const char *, const char *, DNSServiceResolveReply, void *))GetProcAddress(dll_handle, "DNSServiceResolve");
69       dnssd_sock_fd             = (int(*)(DNSServiceRef))GetProcAddress(dll_handle, "DNSServiceRefSockFD");
70       dnssd_update_record       = (DNSServiceErrorType(*)(DNSServiceRef, DNSRecordRef, DNSServiceFlags, uint16_t, const void *, uint32_t))GetProcAddress(dll_handle, "DNSServiceUpdateRecord");
71 
72       dnssd_txt_create          = (void (*)(TXTRecordRef *, uint16_t, void *))GetProcAddress(dll_handle, "TXTRecordCreate");
73       dnssd_txt_deallocate      = (void (*)(TXTRecordRef *))GetProcAddress(dll_handle, "TXTRecordDeallocate");
74       dnssd_txt_get_bytes_ptr   = (const void *(*)(const TXTRecordRef *))GetProcAddress(dll_handle, "TXTRecordGetBytesPtr");
75       dnssd_txt_get_count       = (uint16_t (*)(uint16_t, const void *))GetProcAddress(dll_handle, "TXTRecordGetCount");
76       dnssd_txt_get_item_at_index = (DNSServiceErrorType (*)(uint16_t, const void *, uint16_t, uint16_t, char *, uint8_t *, const void **))GetProcAddress(dll_handle, "TXTRecordGetItemAtIndex");
77       dnssd_txt_get_length      = (uint16_t (*)(const TXTRecordRef *))GetProcAddress(dll_handle, "TXTRecordGetLength");
78       dnssd_txt_get_value_ptr   = (const void *(*)(uint16_t, const void *, const char *, uint8_t *))GetProcAddress(dll_handle, "TXTRecordGetValuePtr");
79       dnssd_txt_set_value       = (DNSServiceErrorType (*)(TXTRecordRef *, const char *, uint8_t, const void *))GetProcAddress(dll_handle, "TXTRecordSetValue");
80     }
81 
82     dnssd_initialized = 1;
83   }
84   _cupsMutexUnlock(&dnssd_mutex);
85 }
86 
87 
88 // DNSServiceAddRecord
DNSServiceAddRecord(DNSServiceRef sdRef,DNSRecordRef * RecordRef,DNSServiceFlags flags,uint16_t rrtype,uint16_t rdlen,const void * rdata,uint32_t ttl)89 DNSServiceErrorType DNSSD_API DNSServiceAddRecord
90     (
91     DNSServiceRef                       sdRef,
92     DNSRecordRef                        *RecordRef,
93     DNSServiceFlags                     flags,
94     uint16_t                            rrtype,
95     uint16_t                            rdlen,
96     const void                          *rdata,
97     uint32_t                            ttl
98     )
99 {
100   if (!dnssd_initialized)
101     dnssd_init();
102 
103   if (dnssd_add_record)
104     return (*dnssd_add_record)(sdRef, RecordRef, flags, rrtype, rdlen, rdata, ttl);
105   else
106     return (kDNSServiceErr_ServiceNotRunning);
107 }
108 
109 
110 // DNSServiceBrowse
DNSServiceBrowse(DNSServiceRef * sdRef,DNSServiceFlags flags,uint32_t interfaceIndex,const char * regtype,const char * domain,DNSServiceBrowseReply callBack,void * context)111 DNSServiceErrorType DNSSD_API DNSServiceBrowse
112     (
113     DNSServiceRef                       *sdRef,
114     DNSServiceFlags                     flags,
115     uint32_t                            interfaceIndex,
116     const char                          *regtype,
117     const char                          *domain,    /* may be NULL */
118     DNSServiceBrowseReply               callBack,
119     void                                *context    /* may be NULL */
120     )
121 {
122   if (!dnssd_initialized)
123     dnssd_init();
124 
125   if (dnssd_browse)
126     return (*dnssd_browse)(sdRef, flags, interfaceIndex, regtype, domain, callBack, context);
127   else
128     return (kDNSServiceErr_ServiceNotRunning);
129 }
130 
131 
132 // DNSServiceConstructFullName
DNSServiceConstructFullName(char * const fullName,const char * const service,const char * const regtype,const char * const domain)133 DNSServiceErrorType DNSSD_API DNSServiceConstructFullName
134     (
135     char                            * const fullName,
136     const char                      * const service,      /* may be NULL */
137     const char                      * const regtype,
138     const char                      * const domain
139     )
140 {
141   if (!dnssd_initialized)
142     dnssd_init();
143 
144   if (dnssd_construct_full_name)
145     return (*dnssd_construct_full_name)(fullName, service, regtype, domain);
146   else
147     return (-1);
148 }
149 
150 
151 // DNSServiceCreateConnection
DNSServiceCreateConnection(DNSServiceRef * sdRef)152 DNSServiceErrorType DNSSD_API DNSServiceCreateConnection(DNSServiceRef *sdRef)
153 {
154   if (!dnssd_initialized)
155     dnssd_init();
156 
157   if (dnssd_create_connection)
158     return (*dnssd_create_connection)(sdRef);
159   else
160     return (kDNSServiceErr_ServiceNotRunning);
161 }
162 
163 
164 // DNSServiceProcessResult
DNSServiceProcessResult(DNSServiceRef sdRef)165 DNSServiceErrorType DNSSD_API DNSServiceProcessResult(DNSServiceRef sdRef)
166 {
167   if (!dnssd_initialized)
168     dnssd_init();
169 
170   if (dnssd_process_result)
171     return (*dnssd_process_result)(sdRef);
172   else
173     return (kDNSServiceErr_ServiceNotRunning);
174 }
175 
176 
177 // DNSServiceQueryRecord
DNSServiceQueryRecord(DNSServiceRef * sdRef,DNSServiceFlags flags,uint32_t interfaceIndex,const char * fullname,uint16_t rrtype,uint16_t rrclass,DNSServiceQueryRecordReply callBack,void * context)178 DNSServiceErrorType DNSSD_API DNSServiceQueryRecord
179     (
180     DNSServiceRef                       *sdRef,
181     DNSServiceFlags                     flags,
182     uint32_t                            interfaceIndex,
183     const char                          *fullname,
184     uint16_t                            rrtype,
185     uint16_t                            rrclass,
186     DNSServiceQueryRecordReply          callBack,
187     void                                *context  /* may be NULL */
188     )
189 {
190   if (!dnssd_initialized)
191     dnssd_init();
192 
193   if (dnssd_query_record)
194     return (*dnssd_query_record)(sdRef, flags, interfaceIndex, fullname, rrtype, rrclass, callBack, context);
195   else
196     return (kDNSServiceErr_ServiceNotRunning);
197 }
198 
199 
200 // DNSServiceRefDeallocate
DNSServiceRefDeallocate(DNSServiceRef sdRef)201 void DNSSD_API DNSServiceRefDeallocate(DNSServiceRef sdRef)
202 {
203   if (!dnssd_initialized)
204     dnssd_init();
205 
206   if (dnssd_deallocate)
207     (*dnssd_deallocate)(sdRef);
208 }
209 
210 
211 // DNSServiceRefSockFD
DNSServiceRefSockFD(DNSServiceRef sdRef)212 int DNSSD_API DNSServiceRefSockFD(DNSServiceRef sdRef)
213 {
214   if (!dnssd_initialized)
215     dnssd_init();
216 
217   if (dnssd_sock_fd)
218     return (*dnssd_sock_fd)(sdRef);
219   else
220     return (kDNSServiceErr_ServiceNotRunning);
221 }
222 
223 
224 // DNSServiceRegister
DNSServiceRegister(DNSServiceRef * sdRef,DNSServiceFlags flags,uint32_t interfaceIndex,const char * name,const char * regtype,const char * domain,const char * host,uint16_t port,uint16_t txtLen,const void * txtRecord,DNSServiceRegisterReply callBack,void * context)225 DNSServiceErrorType DNSSD_API DNSServiceRegister
226     (
227     DNSServiceRef                       *sdRef,
228     DNSServiceFlags                     flags,
229     uint32_t                            interfaceIndex,
230     const char                          *name,         /* may be NULL */
231     const char                          *regtype,
232     const char                          *domain,       /* may be NULL */
233     const char                          *host,         /* may be NULL */
234     uint16_t                            port,          /* In network byte order */
235     uint16_t                            txtLen,
236     const void                          *txtRecord,    /* may be NULL */
237     DNSServiceRegisterReply             callBack,      /* may be NULL */
238     void                                *context       /* may be NULL */
239     )
240 {
241   if (!dnssd_initialized)
242     dnssd_init();
243 
244   if (dnssd_register)
245     return (*dnssd_register)(sdRef, flags, interfaceIndex, name, regtype, domain, host, port, txtLen, txtRecord, callBack, context);
246   else
247     return (kDNSServiceErr_ServiceNotRunning);
248 }
249 
250 
251 // DNSServiceRemoveRecord
DNSServiceRemoveRecord(DNSServiceRef sdRef,DNSRecordRef RecordRef,DNSServiceFlags flags)252 DNSServiceErrorType DNSSD_API DNSServiceRemoveRecord
253     (
254     DNSServiceRef                 sdRef,
255     DNSRecordRef                  RecordRef,
256     DNSServiceFlags               flags
257     )
258 {
259   if (!dnssd_initialized)
260     dnssd_init();
261 
262   if (dnssd_remove_record)
263     return (*dnssd_remove_record)(sdRef, RecordRef, flags);
264   else
265     return (kDNSServiceErr_ServiceNotRunning);
266 }
267 
268 
269 // DNSServiceResolve
DNSServiceResolve(DNSServiceRef * sdRef,DNSServiceFlags flags,uint32_t interfaceIndex,const char * name,const char * regtype,const char * domain,DNSServiceResolveReply callBack,void * context)270 DNSServiceErrorType DNSSD_API DNSServiceResolve
271     (
272     DNSServiceRef                       *sdRef,
273     DNSServiceFlags                     flags,
274     uint32_t                            interfaceIndex,
275     const char                          *name,
276     const char                          *regtype,
277     const char                          *domain,
278     DNSServiceResolveReply              callBack,
279     void                                *context  /* may be NULL */
280     )
281 {
282   if (!dnssd_initialized)
283     dnssd_init();
284 
285   if (dnssd_resolve)
286     return (*dnssd_resolve)(sdRef, flags, interfaceIndex, name, regtype, domain, callBack, context);
287   else
288     return (kDNSServiceErr_ServiceNotRunning);
289 }
290 
291 
292 // DNSServiceUpdateRecord
DNSServiceUpdateRecord(DNSServiceRef sdRef,DNSRecordRef RecordRef,DNSServiceFlags flags,uint16_t rdlen,const void * rdata,uint32_t ttl)293 DNSServiceErrorType DNSSD_API DNSServiceUpdateRecord
294     (
295     DNSServiceRef                       sdRef,
296     DNSRecordRef                        RecordRef,     /* may be NULL */
297     DNSServiceFlags                     flags,
298     uint16_t                            rdlen,
299     const void                          *rdata,
300     uint32_t                            ttl
301     )
302 {
303   if (!dnssd_initialized)
304     dnssd_init();
305 
306   if (dnssd_update_record)
307     return (*dnssd_update_record)(sdRef, RecordRef, flags, rdlen, rdata, ttl);
308   else
309     return (kDNSServiceErr_ServiceNotRunning);
310 }
311 
312 
313 // TXTRecordCreate
314 void DNSSD_API
TXTRecordCreate(TXTRecordRef * txtRecord,uint16_t bufferLen,void * buffer)315 TXTRecordCreate(
316     TXTRecordRef     *txtRecord,
317     uint16_t         bufferLen,
318     void             *buffer)
319 {
320   if (!dnssd_initialized)
321     dnssd_init();
322 
323   if (dnssd_txt_create)
324     (*dnssd_txt_create)(txtRecord, bufferLen, buffer);
325 }
326 
327 
328 // TXTRecordDeallocate
TXTRecordDeallocate(TXTRecordRef * txtRecord)329 void DNSSD_API TXTRecordDeallocate
330     (
331     TXTRecordRef     *txtRecord
332     )
333 {
334   if (!dnssd_initialized)
335     dnssd_init();
336 
337   if (dnssd_txt_deallocate)
338     (*dnssd_txt_deallocate)(txtRecord);
339 }
340 
341 
342 // TXTRecordGetBytesPtr
TXTRecordGetBytesPtr(const TXTRecordRef * txtRecord)343 const void * DNSSD_API TXTRecordGetBytesPtr
344     (
345     const TXTRecordRef *txtRecord
346     )
347 {
348   if (!dnssd_initialized)
349     dnssd_init();
350 
351   if (dnssd_txt_get_bytes_ptr)
352     return (*dnssd_txt_get_bytes_ptr)(txtRecord);
353   else
354     return (NULL);
355 }
356 
357 
358 // TXTRecordGetLength
TXTRecordGetLength(const TXTRecordRef * txtRecord)359 uint16_t DNSSD_API TXTRecordGetLength
360     (
361     const TXTRecordRef *txtRecord
362     )
363 {
364   if (!dnssd_initialized)
365     dnssd_init();
366 
367   if (dnssd_txt_get_length)
368     return (*dnssd_txt_get_length)(txtRecord);
369   else
370     return (0);
371 }
372 
373 
374 // TXTRecordSetValue
TXTRecordSetValue(TXTRecordRef * txtRecord,const char * key,uint8_t valueSize,const void * value)375 DNSServiceErrorType DNSSD_API TXTRecordSetValue
376     (
377     TXTRecordRef     *txtRecord,
378     const char       *key,
379     uint8_t          valueSize,        /* may be zero */
380     const void       *value            /* may be NULL */
381     )
382 {
383   if (!dnssd_initialized)
384     dnssd_init();
385 
386   if (dnssd_txt_set_value)
387     return (*dnssd_txt_set_value)(txtRecord, key, valueSize, value);
388   else
389     return (-1);
390 }
391 
392 
393 // TXTRecordGetCount
394 uint16_t DNSSD_API
TXTRecordGetCount(uint16_t txtLen,const void * txtRecord)395 TXTRecordGetCount(
396     uint16_t         txtLen,
397     const void       *txtRecord)
398 {
399   if (!dnssd_initialized)
400     dnssd_init();
401 
402   if (dnssd_txt_get_count)
403     return (*dnssd_txt_get_count)(txtLen, txtRecord);
404   else
405     return (0);
406 }
407 
408 
409 // TXTRecordGetItemAtIndex
410 DNSServiceErrorType DNSSD_API
TXTRecordGetItemAtIndex(uint16_t txtLen,const void * txtRecord,uint16_t itemIndex,uint16_t keyBufLen,char * key,uint8_t * valueLen,const void ** value)411 TXTRecordGetItemAtIndex(
412     uint16_t         txtLen,
413     const void       *txtRecord,
414     uint16_t         itemIndex,
415     uint16_t         keyBufLen,
416     char             *key,
417     uint8_t          *valueLen,
418     const void       **value)
419 {
420   if (!dnssd_initialized)
421     dnssd_init();
422 
423   if (dnssd_txt_get_item_at_index)
424     return (*dnssd_txt_get_item_at_index)(txtLen, txtRecord, itemIndex, keyBufLen, key, valueLen, value);
425   else
426     return (-1);
427 }
428 
429 
430 // TXTRecordGetValuePtr
431 const void * DNSSD_API
TXTRecordGetValuePtr(uint16_t txtLen,const void * txtRecord,const char * key,uint8_t * valueLen)432 TXTRecordGetValuePtr(
433     uint16_t         txtLen,
434     const void       *txtRecord,
435     const char       *key,
436     uint8_t          *valueLen)
437 {
438   if (!dnssd_initialized)
439     dnssd_init();
440 
441   if (dnssd_txt_get_value_ptr)
442     return (*dnssd_txt_get_value_ptr)(txtLen, txtRecord, key, valueLen);
443   else
444     return (NULL);
445 }
446