1/* -*- Mode: C; tab-width: 4 -*-
2 *
3 * Copyright (c) 2009, Apple Computer, Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1.  Redistributions of source code must retain the above copyright notice,
9 *     this list of conditions and the following disclaimer.
10 * 2.  Redistributions in binary form must reproduce the above copyright notice,
11 *     this list of conditions and the following disclaimer in the documentation
12 *     and/or other materials provided with the distribution.
13 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
14 *     contributors may be used to endorse or promote products derived from this
15 *     software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include "DLLStub.h"
30
31static int		g_defaultErrorCode = kDNSServiceErr_ServiceNotRunning;
32static DLLStub	g_glueLayer;
33
34
35// ------------------------------------------
36// DLLStub implementation
37// ------------------------------------------
38DLLStub * DLLStub::m_instance;
39
40DLLStub::DLLStub()
41:
42	m_library( LoadLibrary( TEXT( "dnssd.dll" ) ) )
43{
44	m_instance = this;
45}
46
47
48DLLStub::~DLLStub()
49{
50	if ( m_library != NULL )
51	{
52		FreeLibrary( m_library );
53		m_library = NULL;
54	}
55
56	m_instance = NULL;
57}
58
59
60bool
61DLLStub::GetProcAddress( FARPROC * func, LPCSTR lpProcName )
62{
63	if ( m_instance && m_instance->m_library )
64	{
65		// Only call ::GetProcAddress if *func is NULL. This allows
66		// the calling code to cache the funcptr value, and we get
67		// some performance benefit.
68
69		if ( *func == NULL )
70		{
71			*func = ::GetProcAddress( m_instance->m_library, lpProcName );
72		}
73	}
74	else
75	{
76		*func = NULL;
77	}
78
79	return ( *func != NULL );
80}
81
82
83int DNSSD_API
84DNSServiceRefSockFD(DNSServiceRef sdRef)
85{
86	typedef int (DNSSD_API * Func)(DNSServiceRef sdRef);
87	static Func func = NULL;
88	int ret = -1;
89
90	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
91	{
92		ret = func( sdRef );
93	}
94
95	return ret;
96}
97
98
99DNSServiceErrorType DNSSD_API
100DNSServiceProcessResult(DNSServiceRef sdRef)
101{
102	typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef sdRef);
103	static Func func = NULL;
104	DNSServiceErrorType ret = g_defaultErrorCode;
105
106	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
107	{
108		ret = func( sdRef );
109	}
110
111	return ret;
112}
113
114
115void DNSSD_API
116DNSServiceRefDeallocate(DNSServiceRef sdRef)
117{
118	typedef void (DNSSD_API * Func)(DNSServiceRef sdRef);
119	static Func func = NULL;
120
121	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
122	{
123		func( sdRef );
124	}
125}
126
127
128DNSServiceErrorType DNSSD_API
129DNSServiceEnumerateDomains
130		(
131		DNSServiceRef                       *sdRef,
132		DNSServiceFlags                     flags,
133		uint32_t                            interfaceIndex,
134		DNSServiceDomainEnumReply           callBack,
135		void                                *context
136		)
137{
138	typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef*, DNSServiceFlags, uint32_t, DNSServiceDomainEnumReply, void* );
139	static Func func = NULL;
140	DNSServiceErrorType ret = g_defaultErrorCode;
141
142	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
143	{
144		ret = func( sdRef, flags, interfaceIndex, callBack, context );
145	}
146
147	return ret;
148}
149
150
151DNSServiceErrorType DNSSD_API
152DNSServiceRegister
153		(
154		DNSServiceRef                       *sdRef,
155		DNSServiceFlags                     flags,
156		uint32_t                            interfaceIndex,
157		const char                          *name,
158		const char                          *regtype,
159		const char                          *domain,
160		const char                          *host,
161		uint16_t                            port,
162		uint16_t                            txtLen,
163		const void                          *txtRecord,
164		DNSServiceRegisterReply             callBack,
165		void                                *context
166		)
167{
168	typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef*, DNSServiceFlags, uint32_t, const char*, const char*, const char*, const char*, uint16_t, uint16_t, const void*, DNSServiceRegisterReply, void* );
169	static Func func = NULL;
170	DNSServiceErrorType ret = g_defaultErrorCode;
171
172	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
173	{
174		ret = func( sdRef, flags, interfaceIndex, name, regtype, domain, host, port, txtLen, txtRecord, callBack, context );
175	}
176
177	return ret;
178}
179
180
181DNSServiceErrorType DNSSD_API
182DNSServiceAddRecord
183		(
184		DNSServiceRef                       sdRef,
185		DNSRecordRef                        *RecordRef,
186		DNSServiceFlags                     flags,
187		uint16_t                            rrtype,
188		uint16_t                            rdlen,
189		const void                          *rdata,
190		uint32_t                            ttl
191		)
192{
193	typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef, DNSRecordRef*, DNSServiceFlags, uint16_t, uint16_t, const void*, uint32_t );
194	static Func func = NULL;
195	DNSServiceErrorType ret = g_defaultErrorCode;
196
197	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
198	{
199		ret = func( sdRef, RecordRef, flags, rrtype, rdlen, rdata, ttl );
200	}
201
202	return ret;
203}
204
205
206DNSServiceErrorType DNSSD_API
207DNSServiceUpdateRecord
208		(
209		DNSServiceRef                       sdRef,
210		DNSRecordRef                        RecordRef,     /* may be NULL */
211		DNSServiceFlags                     flags,
212		uint16_t                            rdlen,
213		const void                          *rdata,
214		uint32_t                            ttl
215		)
216{
217	typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef, DNSRecordRef, DNSServiceFlags, uint16_t, const void*, uint32_t );
218	static Func func = NULL;
219	DNSServiceErrorType ret = g_defaultErrorCode;
220
221	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
222	{
223		ret = func( sdRef, RecordRef, flags, rdlen, rdata, ttl );
224	}
225
226	return ret;
227}
228
229
230DNSServiceErrorType DNSSD_API
231DNSServiceRemoveRecord
232		(
233		DNSServiceRef                 sdRef,
234		DNSRecordRef                  RecordRef,
235		DNSServiceFlags               flags
236		)
237{
238	typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef, DNSRecordRef, DNSServiceFlags );
239	static Func func = NULL;
240	DNSServiceErrorType ret = g_defaultErrorCode;
241
242	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
243	{
244		ret = func( sdRef, RecordRef, flags );
245	}
246
247	return ret;
248}
249
250
251DNSServiceErrorType DNSSD_API
252DNSServiceBrowse
253		(
254		DNSServiceRef                       *sdRef,
255		DNSServiceFlags                     flags,
256		uint32_t                            interfaceIndex,
257		const char                          *regtype,
258		const char                          *domain,    /* may be NULL */
259		DNSServiceBrowseReply               callBack,
260		void                                *context    /* may be NULL */
261		)
262{
263	typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef*, DNSServiceFlags, uint32_t, const char*, const char*, DNSServiceBrowseReply, void* );
264	static Func func = NULL;
265	DNSServiceErrorType ret = g_defaultErrorCode;
266
267	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
268	{
269		ret = func( sdRef, flags, interfaceIndex, regtype, domain, callBack, context );
270	}
271
272	return ret;
273}
274
275
276DNSServiceErrorType DNSSD_API
277DNSServiceResolve
278		(
279		DNSServiceRef                       *sdRef,
280		DNSServiceFlags                     flags,
281		uint32_t                            interfaceIndex,
282		const char                          *name,
283		const char                          *regtype,
284		const char                          *domain,
285		DNSServiceResolveReply              callBack,
286		void                                *context  /* may be NULL */
287		)
288{
289	typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef*, DNSServiceFlags, uint32_t, const char*, const char*, const char*, DNSServiceResolveReply, void* );
290	static Func func = NULL;
291	DNSServiceErrorType ret = g_defaultErrorCode;
292
293	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
294	{
295		ret = func( sdRef, flags, interfaceIndex, name, regtype, domain, callBack, context );
296	}
297
298	return ret;
299}
300
301
302DNSServiceErrorType DNSSD_API
303DNSServiceConstructFullName
304		(
305		char                            *fullName,
306		const char                      *service,      /* may be NULL */
307		const char                      *regtype,
308		const char                      *domain
309		)
310{
311	typedef DNSServiceErrorType (DNSSD_API * Func)( char*, const char*, const char*, const char* );
312	static Func func = NULL;
313	DNSServiceErrorType ret = g_defaultErrorCode;
314
315	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
316	{
317		ret = func( fullName, service, regtype, domain );
318	}
319
320	return ret;
321}
322
323
324DNSServiceErrorType DNSSD_API
325DNSServiceCreateConnection(DNSServiceRef *sdRef)
326{
327	typedef DNSServiceErrorType (DNSSD_API * Func)( DNSServiceRef* );
328	static Func func = NULL;
329	DNSServiceErrorType ret = g_defaultErrorCode;
330
331	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
332	{
333		ret = func( sdRef );
334	}
335
336	return ret;
337}
338
339
340DNSServiceErrorType DNSSD_API
341DNSServiceRegisterRecord
342		(
343		DNSServiceRef                       sdRef,
344		DNSRecordRef                        *RecordRef,
345		DNSServiceFlags                     flags,
346		uint32_t                            interfaceIndex,
347		const char                          *fullname,
348		uint16_t                            rrtype,
349		uint16_t                            rrclass,
350		uint16_t                            rdlen,
351		const void                          *rdata,
352		uint32_t                            ttl,
353		DNSServiceRegisterRecordReply       callBack,
354		void                                *context    /* may be NULL */
355		)
356{
357	typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef, DNSRecordRef*, DNSServiceFlags, uint32_t, const char*, uint16_t, uint16_t, uint16_t, const void*, uint16_t, DNSServiceRegisterRecordReply, void* );
358	static Func func = NULL;
359	DNSServiceErrorType ret = g_defaultErrorCode;
360
361	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
362	{
363		ret = func( sdRef, RecordRef, flags, interfaceIndex, fullname, rrtype, rrclass, rdlen, rdata, ttl, callBack, context );
364	}
365
366	return ret;
367}
368
369
370DNSServiceErrorType DNSSD_API
371DNSServiceQueryRecord
372		(
373		DNSServiceRef                       *sdRef,
374		DNSServiceFlags                     flags,
375		uint32_t                            interfaceIndex,
376		const char                          *fullname,
377		uint16_t                            rrtype,
378		uint16_t                            rrclass,
379		DNSServiceQueryRecordReply          callBack,
380		void                                *context  /* may be NULL */
381		)
382{
383	typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef*, DNSServiceFlags, uint32_t, const char*, uint16_t, uint16_t, DNSServiceQueryRecordReply, void* );
384	static Func func = NULL;
385	DNSServiceErrorType ret = g_defaultErrorCode;
386
387	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
388	{
389		ret = func( sdRef, flags, interfaceIndex, fullname, rrtype, rrclass, callBack, context );
390	}
391
392	return ret;
393}
394
395
396DNSServiceErrorType DNSSD_API
397DNSServiceReconfirmRecord
398		(
399		DNSServiceFlags                    flags,
400		uint32_t                           interfaceIndex,
401		const char                         *fullname,
402		uint16_t                           rrtype,
403		uint16_t                           rrclass,
404		uint16_t                           rdlen,
405		const void                         *rdata
406		)
407{
408	typedef DNSServiceErrorType (DNSSD_API * Func)( DNSServiceFlags, uint32_t, const char*, uint16_t, uint16_t, uint16_t, const void* );
409	static Func func = NULL;
410	DNSServiceErrorType ret = g_defaultErrorCode;
411
412	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
413	{
414		ret = func( flags, interfaceIndex, fullname, rrtype, rrclass, rdlen, rdata );
415	}
416
417	return ret;
418}
419
420
421DNSServiceErrorType DNSSD_API
422DNSServiceNATPortMappingCreate
423		(
424		DNSServiceRef                    *sdRef,
425		DNSServiceFlags                  flags,
426		uint32_t                         interfaceIndex,
427		DNSServiceProtocol               protocol,          /* TCP and/or UDP          */
428		uint16_t                         internalPort,      /* network byte order      */
429		uint16_t                         externalPort,      /* network byte order      */
430		uint32_t                         ttl,               /* time to live in seconds */
431		DNSServiceNATPortMappingReply    callBack,
432		void                             *context           /* may be NULL             */
433		)
434{
435	typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef*, DNSServiceFlags, uint32_t, DNSServiceProtocol, uint16_t, uint16_t, uint16_t, DNSServiceNATPortMappingReply, void* );
436	static Func func = NULL;
437	DNSServiceErrorType ret = g_defaultErrorCode;
438
439	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
440	{
441		ret = func( sdRef, flags, interfaceIndex, protocol, internalPort, externalPort, ttl, callBack, context );
442	}
443
444	return ret;
445}
446
447
448DNSServiceErrorType DNSSD_API
449DNSServiceGetAddrInfo
450		(
451		DNSServiceRef                    *sdRef,
452		DNSServiceFlags                  flags,
453		uint32_t                         interfaceIndex,
454		DNSServiceProtocol               protocol,
455		const char                       *hostname,
456		DNSServiceGetAddrInfoReply       callBack,
457		void                             *context          /* may be NULL */
458		)
459{
460	typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef*, DNSServiceFlags, uint32_t, DNSServiceProtocol, const char*, DNSServiceGetAddrInfoReply, void* );
461	static Func func = NULL;
462	DNSServiceErrorType ret = g_defaultErrorCode;
463
464	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
465	{
466		ret = func( sdRef, flags, interfaceIndex, protocol, hostname, callBack, context );
467	}
468
469	return ret;
470}
471
472
473DNSServiceErrorType DNSSD_API
474DNSServiceGetProperty
475		(
476		const char *property,  /* Requested property (i.e. kDNSServiceProperty_DaemonVersion) */
477		void       *result,    /* Pointer to place to store result */
478		uint32_t   *size       /* size of result location */
479		)
480{
481	typedef DNSServiceErrorType (DNSSD_API * Func)( const char*, void*, uint32_t* );
482	static Func func = NULL;
483	DNSServiceErrorType ret = g_defaultErrorCode;
484
485	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
486	{
487		ret = func( property, result, size );
488	}
489
490	return ret;
491}
492
493
494void DNSSD_API
495TXTRecordCreate
496		(
497		TXTRecordRef     *txtRecord,
498		uint16_t         bufferLen,
499		void             *buffer
500		)
501{
502	typedef void (DNSSD_API * Func)( TXTRecordRef*, uint16_t, void* );
503	static Func func = NULL;
504
505	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
506	{
507		func( txtRecord, bufferLen, buffer );
508	}
509}
510
511
512void DNSSD_API
513TXTRecordDeallocate
514		(
515		TXTRecordRef     *txtRecord
516		)
517{
518	typedef void (DNSSD_API * Func)( TXTRecordRef* );
519	static Func func = NULL;
520
521	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
522	{
523		func( txtRecord );
524	}
525}
526
527
528DNSServiceErrorType DNSSD_API
529TXTRecordSetValue
530		(
531		TXTRecordRef     *txtRecord,
532		const char       *key,
533		uint8_t          valueSize,        /* may be zero */
534		const void       *value            /* may be NULL */
535		)
536{
537	typedef DNSServiceErrorType (DNSSD_API * Func)( TXTRecordRef*, const char*, uint8_t, const void* );
538	static Func func = NULL;
539	DNSServiceErrorType ret = g_defaultErrorCode;
540
541	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
542	{
543		ret = func( txtRecord, key, valueSize, value );
544	}
545
546	return ret;
547}
548
549
550DNSServiceErrorType DNSSD_API
551TXTRecordRemoveValue
552		(
553		TXTRecordRef     *txtRecord,
554		const char       *key
555		)
556{
557	typedef DNSServiceErrorType (DNSSD_API * Func)( TXTRecordRef*, const char* );
558	static Func func = NULL;
559	DNSServiceErrorType ret = g_defaultErrorCode;
560
561	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
562	{
563		ret = func( txtRecord, key );
564	}
565
566	return ret;
567}
568
569
570int DNSSD_API
571TXTRecordContainsKey
572		(
573		uint16_t         txtLen,
574		const void       *txtRecord,
575		const char       *key
576		)
577{
578	typedef int (DNSSD_API * Func)( uint16_t, const void*, const char* );
579	static Func func = NULL;
580	int ret = 0;
581
582	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
583	{
584		ret = func( txtLen, txtRecord, key );
585	}
586
587	return ret;
588}
589
590
591uint16_t DNSSD_API
592TXTRecordGetCount
593		(
594		uint16_t         txtLen,
595		const void       *txtRecord
596		)
597{
598	typedef uint16_t (DNSSD_API * Func)( uint16_t, const void* );
599	static Func func = NULL;
600	uint16_t ret = 0;
601
602	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
603	{
604		ret = func( txtLen, txtRecord );
605	}
606
607	return ret;
608}
609
610
611uint16_t DNSSD_API
612TXTRecordGetLength
613		(
614		const TXTRecordRef *txtRecord
615		)
616{
617	typedef uint16_t (DNSSD_API * Func)( const TXTRecordRef* );
618	static Func func = NULL;
619	uint16_t ret = 0;
620
621	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
622	{
623		ret = func( txtRecord );
624	}
625
626	return ret;
627}
628
629
630const void * DNSSD_API
631TXTRecordGetBytesPtr
632		(
633		const TXTRecordRef *txtRecord
634		)
635{
636	typedef const void* (DNSSD_API * Func)( const TXTRecordRef* );
637	static Func func = NULL;
638	const void* ret = NULL;
639
640	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
641	{
642		ret = func( txtRecord );
643	}
644
645	return ret;
646}
647
648
649const void * DNSSD_API
650TXTRecordGetValuePtr
651		(
652		uint16_t         txtLen,
653		const void       *txtRecord,
654		const char       *key,
655		uint8_t          *valueLen
656		)
657{
658	typedef const void* (DNSSD_API * Func)( uint16_t, const void*, const char*, uint8_t* );
659	static Func func = NULL;
660	const void* ret = NULL;
661
662	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
663	{
664		ret = func( txtLen, txtRecord, key, valueLen );
665	}
666
667	return ret;
668}
669
670
671DNSServiceErrorType DNSSD_API
672TXTRecordGetItemAtIndex
673		(
674		uint16_t         txtLen,
675		const void       *txtRecord,
676		uint16_t         itemIndex,
677		uint16_t         keyBufLen,
678		char             *key,
679		uint8_t          *valueLen,
680		const void       **value
681		)
682{
683	typedef DNSServiceErrorType (DNSSD_API * Func)( uint16_t, const void*, uint16_t, uint16_t, char*, uint8_t*, const void** );
684	static Func func = NULL;
685	DNSServiceErrorType ret = g_defaultErrorCode;
686
687	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
688	{
689		ret = func( txtLen, txtRecord, itemIndex, keyBufLen, key, valueLen, value );
690	}
691
692	return ret;
693}
694