]> git.saurik.com Git - apple/mdnsresponder.git/blob - mDNSWindows/DLLX/DNSSD.cpp
mDNSResponder-878.270.2.tar.gz
[apple/mdnsresponder.git] / mDNSWindows / DLLX / DNSSD.cpp
1 // DNSSD.cpp : Implementation of CDNSSD
2
3 #include "stdafx.h"
4 #include "DNSSD.h"
5 #include "DNSSDService.h"
6 #include "TXTRecord.h"
7 #include <dns_sd.h>
8 #include <CommonServices.h>
9 #include <DebugServices.h>
10 #include "StringServices.h"
11
12
13 // CDNSSD
14
15 STDMETHODIMP CDNSSD::Browse(DNSSDFlags flags, ULONG ifIndex, BSTR regtype, BSTR domain, IBrowseListener* listener, IDNSSDService** browser )
16 {
17 CComObject<CDNSSDService> * object = NULL;
18 std::string regtypeUTF8;
19 std::string domainUTF8;
20 DNSServiceRef sref = NULL;
21 DNSServiceErrorType err = 0;
22 HRESULT hr = 0;
23 BOOL ok;
24
25 // Initialize
26 *browser = NULL;
27
28 // Convert BSTR params to utf8
29 ok = BSTRToUTF8( regtype, regtypeUTF8 );
30 require_action( ok, exit, err = kDNSServiceErr_BadParam );
31 ok = BSTRToUTF8( domain, domainUTF8 );
32 require_action( ok, exit, err = kDNSServiceErr_BadParam );
33
34 try
35 {
36 object = new CComObject<CDNSSDService>();
37 }
38 catch ( ... )
39 {
40 object = NULL;
41 }
42
43 require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );
44 hr = object->FinalConstruct();
45 require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown );
46 object->AddRef();
47
48 err = DNSServiceBrowse( &sref, flags, ifIndex, regtypeUTF8.c_str(), domainUTF8.c_str(), ( DNSServiceBrowseReply ) &BrowseReply, object );
49 require_noerr( err, exit );
50
51 object->SetServiceRef( sref );
52 object->SetListener( listener );
53
54 err = object->Run();
55 require_noerr( err, exit );
56
57 *browser = object;
58
59 exit:
60
61 if ( err && object )
62 {
63 object->Release();
64 }
65
66 return err;
67 }
68
69
70 STDMETHODIMP CDNSSD::Resolve(DNSSDFlags flags, ULONG ifIndex, BSTR serviceName, BSTR regType, BSTR domain, IResolveListener* listener, IDNSSDService** service)
71 {
72 CComObject<CDNSSDService> * object = NULL;
73 std::string serviceNameUTF8;
74 std::string regTypeUTF8;
75 std::string domainUTF8;
76 DNSServiceRef sref = NULL;
77 DNSServiceErrorType err = 0;
78 HRESULT hr = 0;
79 BOOL ok;
80
81 // Initialize
82 *service = NULL;
83
84 // Convert BSTR params to utf8
85 ok = BSTRToUTF8( serviceName, serviceNameUTF8 );
86 require_action( ok, exit, err = kDNSServiceErr_BadParam );
87 ok = BSTRToUTF8( regType, regTypeUTF8 );
88 require_action( ok, exit, err = kDNSServiceErr_BadParam );
89 ok = BSTRToUTF8( domain, domainUTF8 );
90 require_action( ok, exit, err = kDNSServiceErr_BadParam );
91
92 try
93 {
94 object = new CComObject<CDNSSDService>();
95 }
96 catch ( ... )
97 {
98 object = NULL;
99 }
100
101 require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );
102 hr = object->FinalConstruct();
103 require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown );
104 object->AddRef();
105
106 err = DNSServiceResolve( &sref, flags, ifIndex, serviceNameUTF8.c_str(), regTypeUTF8.c_str(), domainUTF8.c_str(), ( DNSServiceResolveReply ) &ResolveReply, object );
107 require_noerr( err, exit );
108
109 object->SetServiceRef( sref );
110 object->SetListener( listener );
111
112 err = object->Run();
113 require_noerr( err, exit );
114
115 *service = object;
116
117 exit:
118
119 if ( err && object )
120 {
121 object->Release();
122 }
123
124 return err;
125 }
126
127
128 STDMETHODIMP CDNSSD::EnumerateDomains(DNSSDFlags flags, ULONG ifIndex, IDomainListener *listener, IDNSSDService **service)
129 {
130 CComObject<CDNSSDService> * object = NULL;
131 DNSServiceRef sref = NULL;
132 DNSServiceErrorType err = 0;
133 HRESULT hr = 0;
134
135 // Initialize
136 *service = NULL;
137
138 try
139 {
140 object = new CComObject<CDNSSDService>();
141 }
142 catch ( ... )
143 {
144 object = NULL;
145 }
146
147 require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );
148 hr = object->FinalConstruct();
149 require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown );
150 object->AddRef();
151
152 err = DNSServiceEnumerateDomains( &sref, flags, ifIndex, ( DNSServiceDomainEnumReply ) &DomainEnumReply, object );
153 require_noerr( err, exit );
154
155 object->SetServiceRef( sref );
156 object->SetListener( listener );
157
158 err = object->Run();
159 require_noerr( err, exit );
160
161 *service = object;
162
163 exit:
164
165 if ( err && object )
166 {
167 object->Release();
168 }
169
170 return err;
171 }
172
173
174 STDMETHODIMP CDNSSD::Register(DNSSDFlags flags, ULONG ifIndex, BSTR serviceName, BSTR regType, BSTR domain, BSTR host, USHORT port, ITXTRecord *record, IRegisterListener *listener, IDNSSDService **service)
175 {
176 CComObject<CDNSSDService> * object = NULL;
177 std::string serviceNameUTF8;
178 std::string regTypeUTF8;
179 std::string domainUTF8;
180 std::string hostUTF8;
181 const void * txtRecord = NULL;
182 uint16_t txtLen = 0;
183 DNSServiceRef sref = NULL;
184 DNSServiceErrorType err = 0;
185 HRESULT hr = 0;
186 BOOL ok;
187
188 // Initialize
189 *service = NULL;
190
191 // Convert BSTR params to utf8
192 ok = BSTRToUTF8( serviceName, serviceNameUTF8 );
193 require_action( ok, exit, err = kDNSServiceErr_BadParam );
194 ok = BSTRToUTF8( regType, regTypeUTF8 );
195 require_action( ok, exit, err = kDNSServiceErr_BadParam );
196 ok = BSTRToUTF8( domain, domainUTF8 );
197 require_action( ok, exit, err = kDNSServiceErr_BadParam );
198 ok = BSTRToUTF8( host, hostUTF8 );
199 require_action( ok, exit, err = kDNSServiceErr_BadParam );
200
201 try
202 {
203 object = new CComObject<CDNSSDService>();
204 }
205 catch ( ... )
206 {
207 object = NULL;
208 }
209
210 require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );
211 hr = object->FinalConstruct();
212 require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown );
213 object->AddRef();
214
215 if ( record )
216 {
217 CComObject< CTXTRecord > * realTXTRecord;
218
219 realTXTRecord = ( CComObject< CTXTRecord >* ) record;
220
221 txtRecord = realTXTRecord->GetBytes();
222 txtLen = realTXTRecord->GetLen();
223 }
224
225 err = DNSServiceRegister( &sref, flags, ifIndex, serviceNameUTF8.c_str(), regTypeUTF8.c_str(), domainUTF8.c_str(), hostUTF8.c_str(), port, txtLen, txtRecord, ( DNSServiceRegisterReply ) &RegisterReply, object );
226 require_noerr( err, exit );
227
228 object->SetServiceRef( sref );
229 object->SetListener( listener );
230
231 err = object->Run();
232 require_noerr( err, exit );
233
234 *service = object;
235
236 exit:
237
238 if ( err && object )
239 {
240 object->Release();
241 }
242
243 return err;
244 }
245
246
247 STDMETHODIMP CDNSSD::QueryRecord(DNSSDFlags flags, ULONG ifIndex, BSTR fullname, DNSSDRRType rrtype, DNSSDRRClass rrclass, IQueryRecordListener *listener, IDNSSDService **service)
248 {
249 CComObject<CDNSSDService> * object = NULL;
250 DNSServiceRef sref = NULL;
251 std::string fullNameUTF8;
252 DNSServiceErrorType err = 0;
253 HRESULT hr = 0;
254 BOOL ok;
255
256 // Initialize
257 *service = NULL;
258
259 // Convert BSTR params to utf8
260 ok = BSTRToUTF8( fullname, fullNameUTF8 );
261 require_action( ok, exit, err = kDNSServiceErr_BadParam );
262
263 try
264 {
265 object = new CComObject<CDNSSDService>();
266 }
267 catch ( ... )
268 {
269 object = NULL;
270 }
271
272 require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );
273 hr = object->FinalConstruct();
274 require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown );
275 object->AddRef();
276
277 err = DNSServiceQueryRecord( &sref, flags, ifIndex, fullNameUTF8.c_str(), ( uint16_t ) rrtype, ( uint16_t ) rrclass, ( DNSServiceQueryRecordReply ) &QueryRecordReply, object );
278 require_noerr( err, exit );
279
280 object->SetServiceRef( sref );
281 object->SetListener( listener );
282
283 err = object->Run();
284 require_noerr( err, exit );
285
286 *service = object;
287
288 exit:
289
290 if ( err && object )
291 {
292 object->Release();
293 }
294
295 return err;
296 }
297
298
299 STDMETHODIMP CDNSSD::GetAddrInfo(DNSSDFlags flags, ULONG ifIndex, DNSSDAddressFamily addressFamily, BSTR hostName, IGetAddrInfoListener *listener, IDNSSDService **service)
300 {
301 CComObject<CDNSSDService> * object = NULL;
302 DNSServiceRef sref = NULL;
303 std::string hostNameUTF8;
304 DNSServiceErrorType err = 0;
305 HRESULT hr = 0;
306 BOOL ok;
307
308 // Initialize
309 *service = NULL;
310
311 // Convert BSTR params to utf8
312 ok = BSTRToUTF8( hostName, hostNameUTF8 );
313 require_action( ok, exit, err = kDNSServiceErr_BadParam );
314
315 try
316 {
317 object = new CComObject<CDNSSDService>();
318 }
319 catch ( ... )
320 {
321 object = NULL;
322 }
323
324 require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );
325 hr = object->FinalConstruct();
326 require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown );
327 object->AddRef();
328
329 err = DNSServiceGetAddrInfo( &sref, flags, ifIndex, addressFamily, hostNameUTF8.c_str(), ( DNSServiceGetAddrInfoReply ) &GetAddrInfoReply, object );
330 require_noerr( err, exit );
331
332 object->SetServiceRef( sref );
333 object->SetListener( listener );
334
335 err = object->Run();
336 require_noerr( err, exit );
337
338 *service = object;
339
340 exit:
341
342 if ( err && object )
343 {
344 object->Release();
345 }
346
347 return err;
348 }
349
350
351 STDMETHODIMP CDNSSD::CreateConnection(IDNSSDService **service)
352 {
353 CComObject<CDNSSDService> * object = NULL;
354 DNSServiceRef sref = NULL;
355 DNSServiceErrorType err = 0;
356 HRESULT hr = 0;
357
358 // Initialize
359 *service = NULL;
360
361 try
362 {
363 object = new CComObject<CDNSSDService>();
364 }
365 catch ( ... )
366 {
367 object = NULL;
368 }
369
370 require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );
371 hr = object->FinalConstruct();
372 require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown );
373 object->AddRef();
374
375 err = DNSServiceCreateConnection( &sref );
376 require_noerr( err, exit );
377
378 object->SetServiceRef( sref );
379
380 *service = object;
381
382 exit:
383
384 if ( err && object )
385 {
386 object->Release();
387 }
388
389 return err;
390 }
391
392
393 STDMETHODIMP CDNSSD::NATPortMappingCreate(DNSSDFlags flags, ULONG ifIndex, DNSSDAddressFamily addressFamily, DNSSDProtocol protocol, USHORT internalPort, USHORT externalPort, ULONG ttl, INATPortMappingListener *listener, IDNSSDService **service)
394 {
395 CComObject<CDNSSDService> * object = NULL;
396 DNSServiceRef sref = NULL;
397 DNSServiceProtocol prot = 0;
398 DNSServiceErrorType err = 0;
399 HRESULT hr = 0;
400
401 // Initialize
402 *service = NULL;
403
404 try
405 {
406 object = new CComObject<CDNSSDService>();
407 }
408 catch ( ... )
409 {
410 object = NULL;
411 }
412
413 require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );
414 hr = object->FinalConstruct();
415 require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown );
416 object->AddRef();
417
418 prot = ( addressFamily | protocol );
419
420 err = DNSServiceNATPortMappingCreate( &sref, flags, ifIndex, prot, internalPort, externalPort, ttl, ( DNSServiceNATPortMappingReply ) &NATPortMappingReply, object );
421 require_noerr( err, exit );
422
423 object->SetServiceRef( sref );
424 object->SetListener( listener );
425
426 err = object->Run();
427 require_noerr( err, exit );
428
429 *service = object;
430
431 exit:
432
433 if ( err && object )
434 {
435 object->Release();
436 }
437
438 return err;
439 }
440
441
442 STDMETHODIMP CDNSSD::GetProperty(BSTR prop, VARIANT * value )
443 {
444 std::string propUTF8;
445 std::vector< BYTE > byteArray;
446 SAFEARRAY * psa = NULL;
447 BYTE * pData = NULL;
448 uint32_t elems = 0;
449 DNSServiceErrorType err = 0;
450 BOOL ok = TRUE;
451
452 // Convert BSTR params to utf8
453 ok = BSTRToUTF8( prop, propUTF8 );
454 require_action( ok, exit, err = kDNSServiceErr_BadParam );
455
456 // Setup the byte array
457 require_action( V_VT( value ) == ( VT_ARRAY|VT_UI1 ), exit, err = kDNSServiceErr_Unknown );
458 psa = V_ARRAY( value );
459 require_action( psa, exit, err = kDNSServiceErr_Unknown );
460 require_action( SafeArrayGetDim( psa ) == 1, exit, err = kDNSServiceErr_Unknown );
461 byteArray.reserve( psa->rgsabound[0].cElements );
462 byteArray.assign( byteArray.capacity(), 0 );
463 elems = ( uint32_t ) byteArray.capacity();
464
465 // Call the function and package the return value in the Variant
466 err = DNSServiceGetProperty( propUTF8.c_str(), &byteArray[ 0 ], &elems );
467 require_noerr( err, exit );
468 ok = ByteArrayToVariant( &byteArray[ 0 ], elems, value );
469 require_action( ok, exit, err = kDNSSDError_Unknown );
470
471 exit:
472
473 if ( psa )
474 {
475 SafeArrayUnaccessData( psa );
476 psa = NULL;
477 }
478
479 return err;
480 }
481
482
483 void DNSSD_API
484 CDNSSD::DomainEnumReply
485 (
486 DNSServiceRef sdRef,
487 DNSServiceFlags flags,
488 uint32_t ifIndex,
489 DNSServiceErrorType errorCode,
490 const char *replyDomainUTF8,
491 void *context
492 )
493 {
494 CComObject<CDNSSDService> * service;
495 int err;
496
497 service = ( CComObject< CDNSSDService>* ) context;
498 require_action( service, exit, err = kDNSServiceErr_Unknown );
499
500 if ( !service->Stopped() )
501 {
502 IDomainListener * listener;
503
504 listener = ( IDomainListener* ) service->GetListener();
505 require_action( listener, exit, err = kDNSServiceErr_Unknown );
506
507 if ( !errorCode )
508 {
509 CComBSTR replyDomain;
510
511 UTF8ToBSTR( replyDomainUTF8, replyDomain );
512
513 if ( flags & kDNSServiceFlagsAdd )
514 {
515 listener->DomainFound( service, ( DNSSDFlags ) flags, ifIndex, replyDomain );
516 }
517 else
518 {
519 listener->DomainLost( service, ( DNSSDFlags ) flags, ifIndex, replyDomain );
520 }
521 }
522 else
523 {
524 listener->EnumDomainsFailed( service, ( DNSSDError ) errorCode );
525 }
526 }
527
528 exit:
529
530 return;
531 }
532
533
534 void DNSSD_API
535 CDNSSD::BrowseReply
536 (
537 DNSServiceRef sdRef,
538 DNSServiceFlags flags,
539 uint32_t ifIndex,
540 DNSServiceErrorType errorCode,
541 const char *serviceNameUTF8,
542 const char *regTypeUTF8,
543 const char *replyDomainUTF8,
544 void *context
545 )
546 {
547 CComObject<CDNSSDService> * service;
548 int err;
549
550 service = ( CComObject< CDNSSDService>* ) context;
551 require_action( service, exit, err = kDNSServiceErr_Unknown );
552
553 if ( !service->Stopped() )
554 {
555 IBrowseListener * listener;
556
557 listener = ( IBrowseListener* ) service->GetListener();
558 require_action( listener, exit, err = kDNSServiceErr_Unknown );
559
560 if ( !errorCode )
561 {
562 CComBSTR serviceName;
563 CComBSTR regType;
564 CComBSTR replyDomain;
565
566 UTF8ToBSTR( serviceNameUTF8, serviceName );
567 UTF8ToBSTR( regTypeUTF8, regType );
568 UTF8ToBSTR( replyDomainUTF8, replyDomain );
569
570 if ( flags & kDNSServiceFlagsAdd )
571 {
572 listener->ServiceFound( service, ( DNSSDFlags ) flags, ifIndex, serviceName, regType, replyDomain );
573 }
574 else
575 {
576 listener->ServiceLost( service, ( DNSSDFlags ) flags, ifIndex, serviceName, regType, replyDomain );
577 }
578 }
579 else
580 {
581 listener->BrowseFailed( service, ( DNSSDError ) errorCode );
582 }
583 }
584
585 exit:
586
587 return;
588 }
589
590
591 void DNSSD_API
592 CDNSSD::ResolveReply
593 (
594 DNSServiceRef sdRef,
595 DNSServiceFlags flags,
596 uint32_t ifIndex,
597 DNSServiceErrorType errorCode,
598 const char *fullNameUTF8,
599 const char *hostNameUTF8,
600 uint16_t port,
601 uint16_t txtLen,
602 const unsigned char *txtRecord,
603 void *context
604 )
605 {
606 CComObject<CDNSSDService> * service;
607 int err;
608
609 service = ( CComObject< CDNSSDService>* ) context;
610 require_action( service, exit, err = kDNSServiceErr_Unknown );
611
612 if ( !service->Stopped() )
613 {
614 IResolveListener * listener;
615
616 listener = ( IResolveListener* ) service->GetListener();
617 require_action( listener, exit, err = kDNSServiceErr_Unknown );
618
619 if ( !errorCode )
620 {
621 CComBSTR fullName;
622 CComBSTR hostName;
623 CComBSTR regType;
624 CComBSTR replyDomain;
625 CComObject< CTXTRecord >* record;
626 BOOL ok;
627
628 ok = UTF8ToBSTR( fullNameUTF8, fullName );
629 require_action( ok, exit, err = kDNSServiceErr_Unknown );
630 ok = UTF8ToBSTR( hostNameUTF8, hostName );
631 require_action( ok, exit, err = kDNSServiceErr_Unknown );
632
633 try
634 {
635 record = new CComObject<CTXTRecord>();
636 }
637 catch ( ... )
638 {
639 record = NULL;
640 }
641
642 require_action( record, exit, err = kDNSServiceErr_NoMemory );
643 record->AddRef();
644
645 char buf[ 64 ];
646 snprintf( buf, sizeof( buf ), "txtLen = %d", txtLen );
647 OutputDebugStringA( buf );
648
649 if ( txtLen > 0 )
650 {
651 record->SetBytes( txtRecord, txtLen );
652 }
653
654 listener->ServiceResolved( service, ( DNSSDFlags ) flags, ifIndex, fullName, hostName, port, record );
655 }
656 else
657 {
658 listener->ResolveFailed( service, ( DNSSDError ) errorCode );
659 }
660 }
661
662 exit:
663
664 return;
665 }
666
667
668 void DNSSD_API
669 CDNSSD::RegisterReply
670 (
671 DNSServiceRef sdRef,
672 DNSServiceFlags flags,
673 DNSServiceErrorType errorCode,
674 const char *serviceNameUTF8,
675 const char *regTypeUTF8,
676 const char *domainUTF8,
677 void *context
678 )
679 {
680 CComObject<CDNSSDService> * service;
681 int err;
682
683 service = ( CComObject< CDNSSDService>* ) context;
684 require_action( service, exit, err = kDNSServiceErr_Unknown );
685
686 if ( !service->Stopped() )
687 {
688 IRegisterListener * listener;
689
690 listener = ( IRegisterListener* ) service->GetListener();
691 require_action( listener, exit, err = kDNSServiceErr_Unknown );
692
693 if ( !errorCode )
694 {
695 CComBSTR serviceName;
696 CComBSTR regType;
697 CComBSTR domain;
698 BOOL ok;
699
700 ok = UTF8ToBSTR( serviceNameUTF8, serviceName );
701 require_action( ok, exit, err = kDNSServiceErr_Unknown );
702 ok = UTF8ToBSTR( regTypeUTF8, regType );
703 require_action( ok, exit, err = kDNSServiceErr_Unknown );
704 ok = UTF8ToBSTR( domainUTF8, domain );
705 require_action( ok, exit, err = kDNSServiceErr_Unknown );
706
707 listener->ServiceRegistered( service, ( DNSSDFlags ) flags, serviceName, regType, domain );
708 }
709 else
710 {
711 listener->ServiceRegisterFailed( service, ( DNSSDError ) errorCode );
712 }
713 }
714
715 exit:
716
717 return;
718 }
719
720
721 void DNSSD_API
722 CDNSSD::QueryRecordReply
723 (
724 DNSServiceRef sdRef,
725 DNSServiceFlags flags,
726 uint32_t ifIndex,
727 DNSServiceErrorType errorCode,
728 const char *fullNameUTF8,
729 uint16_t rrtype,
730 uint16_t rrclass,
731 uint16_t rdlen,
732 const void *rdata,
733 uint32_t ttl,
734 void *context
735 )
736 {
737 CComObject<CDNSSDService> * service;
738 int err;
739
740 service = ( CComObject< CDNSSDService>* ) context;
741 require_action( service, exit, err = kDNSServiceErr_Unknown );
742
743 if ( !service->Stopped() )
744 {
745 IQueryRecordListener * listener;
746
747 listener = ( IQueryRecordListener* ) service->GetListener();
748 require_action( listener, exit, err = kDNSServiceErr_Unknown );
749
750 if ( !errorCode )
751 {
752 CComBSTR fullName;
753 VARIANT var;
754 BOOL ok;
755
756 ok = UTF8ToBSTR( fullNameUTF8, fullName );
757 require_action( ok, exit, err = kDNSServiceErr_Unknown );
758 ok = ByteArrayToVariant( rdata, rdlen, &var );
759 require_action( ok, exit, err = kDNSServiceErr_Unknown );
760
761 listener->QueryRecordAnswered( service, ( DNSSDFlags ) flags, ifIndex, fullName, ( DNSSDRRType ) rrtype, ( DNSSDRRClass ) rrclass, var, ttl );
762 }
763 else
764 {
765 listener->QueryRecordFailed( service, ( DNSSDError ) errorCode );
766 }
767 }
768
769 exit:
770
771 return;
772 }
773
774
775 void DNSSD_API
776 CDNSSD::GetAddrInfoReply
777 (
778 DNSServiceRef sdRef,
779 DNSServiceFlags flags,
780 uint32_t ifIndex,
781 DNSServiceErrorType errorCode,
782 const char *hostNameUTF8,
783 const struct sockaddr *rawAddress,
784 uint32_t ttl,
785 void *context
786 )
787 {
788 CComObject<CDNSSDService> * service;
789 int err;
790
791 service = ( CComObject< CDNSSDService>* ) context;
792 require_action( service, exit, err = kDNSServiceErr_Unknown );
793
794 if ( !service->Stopped() )
795 {
796 IGetAddrInfoListener * listener;
797
798 listener = ( IGetAddrInfoListener* ) service->GetListener();
799 require_action( listener, exit, err = kDNSServiceErr_Unknown );
800
801 if ( !errorCode )
802 {
803 CComBSTR hostName;
804 DWORD sockaddrLen;
805 DNSSDAddressFamily addressFamily;
806 char addressUTF8[INET6_ADDRSTRLEN];
807 DWORD addressLen = sizeof( addressUTF8 );
808 CComBSTR address;
809 BOOL ok;
810
811 ok = UTF8ToBSTR( hostNameUTF8, hostName );
812 require_action( ok, exit, err = kDNSServiceErr_Unknown );
813
814 switch ( rawAddress->sa_family )
815 {
816 case AF_INET:
817 {
818 addressFamily = kDNSSDAddressFamily_IPv4;
819 sockaddrLen = sizeof( sockaddr_in );
820 }
821 break;
822
823 case AF_INET6:
824 {
825 addressFamily = kDNSSDAddressFamily_IPv6;
826 sockaddrLen = sizeof( sockaddr_in6 );
827 }
828 break;
829 }
830
831 err = WSAAddressToStringA( ( LPSOCKADDR ) rawAddress, sockaddrLen, NULL, addressUTF8, &addressLen );
832 require_noerr( err, exit );
833 ok = UTF8ToBSTR( addressUTF8, address );
834 require_action( ok, exit, err = kDNSServiceErr_Unknown );
835
836 listener->GetAddrInfoReply( service, ( DNSSDFlags ) flags, ifIndex, hostName, addressFamily, address, ttl );
837 }
838 else
839 {
840 listener->GetAddrInfoFailed( service, ( DNSSDError ) errorCode );
841 }
842 }
843
844 exit:
845
846 return;
847 }
848
849
850 void DNSSD_API
851 CDNSSD::NATPortMappingReply
852 (
853 DNSServiceRef sdRef,
854 DNSServiceFlags flags,
855 uint32_t ifIndex,
856 DNSServiceErrorType errorCode,
857 uint32_t externalAddress, /* four byte IPv4 address in network byte order */
858 DNSServiceProtocol protocol,
859 uint16_t internalPort,
860 uint16_t externalPort, /* may be different than the requested port */
861 uint32_t ttl, /* may be different than the requested ttl */
862 void *context
863 )
864 {
865 CComObject<CDNSSDService> * service;
866 int err;
867
868 service = ( CComObject< CDNSSDService>* ) context;
869 require_action( service, exit, err = kDNSServiceErr_Unknown );
870
871 if ( !service->Stopped() )
872 {
873 INATPortMappingListener * listener;
874
875 listener = ( INATPortMappingListener* ) service->GetListener();
876 require_action( listener, exit, err = kDNSServiceErr_Unknown );
877
878 if ( !errorCode )
879 {
880 listener->MappingCreated( service, ( DNSSDFlags ) flags, ifIndex, externalAddress, ( DNSSDAddressFamily ) ( protocol & 0x8 ), ( DNSSDProtocol ) ( protocol & 0x80 ), internalPort, externalPort, ttl );
881 }
882 else
883 {
884 listener->MappingFailed( service, ( DNSSDError ) errorCode );
885 }
886 }
887
888 exit:
889
890 return;
891 }
892