• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -*- Mode: C; tab-width: 4 -*-
2  *
3  * Copyright (c) 2009 Apple Computer, Inc. All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 
19 
20 #pragma warning(disable:4995)
21 
22 
23 
24 #include "stdafx.h"
25 
26 #include <strsafe.h>
27 
28 #include "DNSSDService.h"
29 
30 #include "DNSSDEventManager.h"
31 
32 #include "DNSSDRecord.h"
33 
34 #include "TXTRecord.h"
35 
36 #include "StringServices.h"
37 
38 #include <DebugServices.h>
39 
40 
41 
42 
43 
44 #define WM_SOCKET (WM_APP + 100)
45 
46 
47 
48 
49 
50 // CDNSSDService
51 
52 
53 
54 BOOL						CDNSSDService::m_registeredWindowClass	= FALSE;
55 
56 HWND						CDNSSDService::m_hiddenWindow			= NULL;
57 
58 CDNSSDService::SocketMap	CDNSSDService::m_socketMap;
59 
60 
61 
62 
63 
FinalConstruct()64 HRESULT CDNSSDService::FinalConstruct()
65 
66 {
67 
68 	DNSServiceErrorType	err	= 0;
69 
70 	HRESULT				hr	= S_OK;
71 
72 
73 
74 	m_isPrimary = TRUE;
75 
76 	err = DNSServiceCreateConnection( &m_primary );
77 
78 	require_action( !err, exit, hr = E_FAIL );
79 
80 
81 
82 	if ( !m_hiddenWindow )
83 
84 	{
85 
86 		TCHAR windowClassName[ 256 ];
87 
88 
89 
90 		StringCchPrintf( windowClassName, sizeof( windowClassName ) / sizeof( TCHAR ), TEXT( "Bonjour Hidden Window %d" ), GetProcessId( NULL ) );
91 
92 
93 
94 		if ( !m_registeredWindowClass )
95 
96 		{
97 
98 			WNDCLASS	wc;
99 
100 			ATOM		atom;
101 
102 
103 
104 			wc.style			= 0;
105 
106 			wc.lpfnWndProc		= WndProc;
107 
108 			wc.cbClsExtra		= 0;
109 
110 			wc.cbWndExtra		= 0;
111 
112 			wc.hInstance		= NULL;
113 
114 			wc.hIcon			= NULL;
115 
116 			wc.hCursor			= NULL;
117 
118 			wc.hbrBackground	= NULL;
119 
120 			wc.lpszMenuName		= NULL;
121 
122 			wc.lpszClassName	= windowClassName;
123 
124 
125 
126 			atom = RegisterClass(&wc);
127 
128 			require_action( atom != NULL, exit, hr = E_FAIL );
129 
130 
131 
132 			m_registeredWindowClass = TRUE;
133 
134 		}
135 
136 
137 
138 		m_hiddenWindow = CreateWindow( windowClassName, windowClassName, WS_OVERLAPPED, 0, 0, 0, 0, NULL, NULL, GetModuleHandle( NULL ), NULL );
139 
140 		require_action( m_hiddenWindow != NULL, exit, hr = E_FAIL );
141 
142 	}
143 
144 
145 
146 	err = WSAAsyncSelect( DNSServiceRefSockFD( m_primary ), m_hiddenWindow, WM_SOCKET, FD_READ );
147 
148 	require_action( !err, exit, hr = E_FAIL );
149 
150 
151 
152 	m_socketMap[ DNSServiceRefSockFD( m_primary ) ] = this;
153 
154 
155 
156 exit:
157 
158 
159 
160 	return hr;
161 
162 }
163 
164 
165 
166 
167 
FinalRelease()168 void CDNSSDService::FinalRelease()
169 
170 {
171 
172 	dlog( kDebugLevelTrace, "FinalRelease()\n" );
173 
174 	Stop();
175 
176 }
177 
178 
179 
180 
181 
EnumerateDomains(DNSSDFlags flags,ULONG ifIndex,IDNSSDEventManager * eventManager,IDNSSDService ** service)182 STDMETHODIMP CDNSSDService::EnumerateDomains(DNSSDFlags flags, ULONG ifIndex, IDNSSDEventManager *eventManager, IDNSSDService **service)
183 
184 {
185 
186 	CComObject<CDNSSDService>	*	object	= NULL;
187 
188 	DNSServiceRef					subord	= NULL;
189 
190 	DNSServiceErrorType				err		= 0;
191 
192 	HRESULT							hr		= 0;
193 
194 
195 
196 	check( m_primary );
197 
198 
199 
200 	// Initialize
201 
202 	*service = NULL;
203 
204 
205 
206 	try
207 
208 	{
209 
210 		object = new CComObject<CDNSSDService>();
211 
212 	}
213 
214 	catch ( ... )
215 
216 	{
217 
218 		object = NULL;
219 
220 	}
221 
222 
223 
224 	require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );
225 
226 	object->AddRef();
227 
228 
229 
230 	subord = m_primary;
231 
232 	err = DNSServiceEnumerateDomains( &subord, flags | kDNSServiceFlagsShareConnection, ifIndex, ( DNSServiceDomainEnumReply ) &DomainEnumReply, object );
233 
234 	require_noerr( err, exit );
235 
236 
237 
238 	object->SetPrimaryRef( m_primary );
239 
240 	object->SetSubordRef( subord );
241 
242 	object->SetEventManager( eventManager );
243 
244 
245 
246 	*service = object;
247 
248 
249 
250 exit:
251 
252 
253 
254 	if ( err && object )
255 
256 	{
257 
258 		object->Release();
259 
260 	}
261 
262 
263 
264 	return err;
265 
266 }
267 
268 
269 
270 
271 
Browse(DNSSDFlags flags,ULONG ifIndex,BSTR regtype,BSTR domain,IDNSSDEventManager * eventManager,IDNSSDService ** service)272 STDMETHODIMP CDNSSDService::Browse(DNSSDFlags flags, ULONG ifIndex, BSTR regtype, BSTR domain, IDNSSDEventManager* eventManager, IDNSSDService** service )
273 
274 {
275 
276 	CComObject<CDNSSDService>	*	object		= NULL;
277 
278 	std::string						regtypeUTF8;
279 
280 	std::string						domainUTF8;
281 
282 	DNSServiceRef					subord		= NULL;
283 
284 	DNSServiceErrorType				err			= 0;
285 
286 	HRESULT							hr			= 0;
287 
288 	BOOL							ok;
289 
290 
291 
292 	check( m_primary );
293 
294 
295 
296 	// Initialize
297 
298 	*service = NULL;
299 
300 
301 
302 	// Convert BSTR params to utf8
303 
304 	ok = BSTRToUTF8( regtype, regtypeUTF8 );
305 
306 	require_action( ok, exit, err = kDNSServiceErr_BadParam );
307 
308 	ok = BSTRToUTF8( domain, domainUTF8 );
309 
310 	require_action( ok, exit, err = kDNSServiceErr_BadParam );
311 
312 
313 
314 	try
315 
316 	{
317 
318 		object = new CComObject<CDNSSDService>();
319 
320 	}
321 
322 	catch ( ... )
323 
324 	{
325 
326 		object = NULL;
327 
328 	}
329 
330 
331 
332 	require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );
333 
334 	object->AddRef();
335 
336 
337 
338 	subord = m_primary;
339 
340 	err = DNSServiceBrowse( &subord, flags | kDNSServiceFlagsShareConnection, ifIndex, regtypeUTF8.c_str(), ( domainUTF8.size() > 0 ) ? domainUTF8.c_str() : NULL, ( DNSServiceBrowseReply ) &BrowseReply, object );
341 
342 	require_noerr( err, exit );
343 
344 
345 
346 	object->SetPrimaryRef( m_primary );
347 
348 	object->SetSubordRef( subord );
349 
350 	object->SetEventManager( eventManager );
351 
352 
353 
354 	*service = object;
355 
356 
357 
358 exit:
359 
360 
361 
362 	if ( err && object )
363 
364 	{
365 
366 		object->Release();
367 
368 	}
369 
370 
371 
372 	return err;
373 
374 }
375 
376 
377 
378 
379 
Resolve(DNSSDFlags flags,ULONG ifIndex,BSTR serviceName,BSTR regType,BSTR domain,IDNSSDEventManager * eventManager,IDNSSDService ** service)380 STDMETHODIMP CDNSSDService::Resolve(DNSSDFlags flags, ULONG ifIndex, BSTR serviceName, BSTR regType, BSTR domain, IDNSSDEventManager* eventManager, IDNSSDService** service)
381 
382 {
383 
384 	CComObject<CDNSSDService>	*	object			= NULL;
385 
386 	std::string						serviceNameUTF8;
387 
388 	std::string						regTypeUTF8;
389 
390 	std::string						domainUTF8;
391 
392 	DNSServiceRef					subord			= NULL;
393 
394 	DNSServiceErrorType				err				= 0;
395 
396 	HRESULT							hr				= 0;
397 
398 	BOOL							ok;
399 
400 
401 
402 	check( m_primary );
403 
404 
405 
406 	// Initialize
407 
408 	*service = NULL;
409 
410 
411 
412 	// Convert BSTR params to utf8
413 
414 	ok = BSTRToUTF8( serviceName, serviceNameUTF8 );
415 
416 	require_action( ok, exit, err = kDNSServiceErr_BadParam );
417 
418 	ok = BSTRToUTF8( regType, regTypeUTF8 );
419 
420 	require_action( ok, exit, err = kDNSServiceErr_BadParam );
421 
422 	ok = BSTRToUTF8( domain, domainUTF8 );
423 
424 	require_action( ok, exit, err = kDNSServiceErr_BadParam );
425 
426 
427 
428 	try
429 
430 	{
431 
432 		object = new CComObject<CDNSSDService>();
433 
434 	}
435 
436 	catch ( ... )
437 
438 	{
439 
440 		object = NULL;
441 
442 	}
443 
444 
445 
446 	require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );
447 
448 	object->AddRef();
449 
450 
451 
452 	subord = m_primary;
453 
454 	err = DNSServiceResolve( &subord, flags | kDNSServiceFlagsShareConnection, ifIndex, serviceNameUTF8.c_str(), regTypeUTF8.c_str(), domainUTF8.c_str(), ( DNSServiceResolveReply ) &ResolveReply, object );
455 
456 	require_noerr( err, exit );
457 
458 
459 
460 	object->SetPrimaryRef( m_primary );
461 
462 	object->SetSubordRef( subord );
463 
464 	object->SetEventManager( eventManager );
465 
466 
467 
468 	*service = object;
469 
470 
471 
472 exit:
473 
474 
475 
476 	if ( err && object )
477 
478 	{
479 
480 		object->Release();
481 
482 	}
483 
484 
485 
486 	return err;
487 
488 }
489 
490 
491 
492 
493 
Register(DNSSDFlags flags,ULONG ifIndex,BSTR serviceName,BSTR regType,BSTR domain,BSTR host,USHORT port,ITXTRecord * record,IDNSSDEventManager * eventManager,IDNSSDService ** service)494 STDMETHODIMP CDNSSDService::Register(DNSSDFlags flags, ULONG ifIndex, BSTR serviceName, BSTR regType, BSTR domain, BSTR host, USHORT port, ITXTRecord *record, IDNSSDEventManager *eventManager, IDNSSDService **service)
495 
496 {
497 
498 	CComObject<CDNSSDService>	*	object			= NULL;
499 
500 	std::string						serviceNameUTF8;
501 
502 	std::string						regTypeUTF8;
503 
504 	std::string						domainUTF8;
505 
506 	std::string						hostUTF8;
507 
508 	const void					*	txtRecord		= NULL;
509 
510 	uint16_t						txtLen			= 0;
511 
512 	DNSServiceRef					subord			= NULL;
513 
514 	DNSServiceErrorType				err				= 0;
515 
516 	HRESULT							hr				= 0;
517 
518 	BOOL							ok;
519 
520 
521 
522 	check( m_primary );
523 
524 
525 
526 	// Initialize
527 
528 	*service = NULL;
529 
530 
531 
532 	// Convert BSTR params to utf8
533 
534 	ok = BSTRToUTF8( serviceName, serviceNameUTF8 );
535 
536 	require_action( ok, exit, err = kDNSServiceErr_BadParam );
537 
538 	ok = BSTRToUTF8( regType, regTypeUTF8 );
539 
540 	require_action( ok, exit, err = kDNSServiceErr_BadParam );
541 
542 	ok = BSTRToUTF8( domain, domainUTF8 );
543 
544 	require_action( ok, exit, err = kDNSServiceErr_BadParam );
545 
546 	ok = BSTRToUTF8( host, hostUTF8 );
547 
548 	require_action( ok, exit, err = kDNSServiceErr_BadParam );
549 
550 
551 
552 	try
553 
554 	{
555 
556 		object = new CComObject<CDNSSDService>();
557 
558 	}
559 
560 	catch ( ... )
561 
562 	{
563 
564 		object = NULL;
565 
566 	}
567 
568 
569 
570 	require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );
571 
572 	object->AddRef();
573 
574 
575 
576 	if ( record )
577 
578 	{
579 
580 		CComObject< CTXTRecord > * realTXTRecord;
581 
582 
583 
584 		realTXTRecord = ( CComObject< CTXTRecord >* ) record;
585 
586 
587 
588 		txtRecord	= realTXTRecord->GetBytes();
589 
590 		txtLen		= realTXTRecord->GetLen();
591 
592 	}
593 
594 
595 
596 	subord = m_primary;
597 
598 	err = DNSServiceRegister( &subord, flags | kDNSServiceFlagsShareConnection, ifIndex, serviceNameUTF8.c_str(), regTypeUTF8.c_str(), ( domainUTF8.size() > 0 ) ? domainUTF8.c_str() : NULL, hostUTF8.c_str(), htons( port ), txtLen, txtRecord, ( DNSServiceRegisterReply ) &RegisterReply, object );
599 
600 	require_noerr( err, exit );
601 
602 
603 
604 	object->SetPrimaryRef( m_primary );
605 
606 	object->SetSubordRef( subord );
607 
608 	object->SetEventManager( eventManager );
609 
610 
611 
612 	*service = object;
613 
614 
615 
616 exit:
617 
618 
619 
620 	if ( err && object )
621 
622 	{
623 
624 		object->Release();
625 
626 	}
627 
628 
629 
630 	return err;
631 
632 }
633 
634 
635 
636 
637 
QueryRecord(DNSSDFlags flags,ULONG ifIndex,BSTR fullname,DNSSDRRType rrtype,DNSSDRRClass rrclass,IDNSSDEventManager * eventManager,IDNSSDService ** service)638 STDMETHODIMP CDNSSDService::QueryRecord(DNSSDFlags flags, ULONG ifIndex, BSTR fullname, DNSSDRRType rrtype, DNSSDRRClass rrclass, IDNSSDEventManager *eventManager, IDNSSDService **service)
639 
640 {
641 
642 	CComObject<CDNSSDService>	*	object			= NULL;
643 
644 	DNSServiceRef					subord			= NULL;
645 
646 	std::string						fullNameUTF8;
647 
648 	DNSServiceErrorType				err				= 0;
649 
650 	HRESULT							hr				= 0;
651 
652 	BOOL							ok;
653 
654 
655 
656 	check( m_primary );
657 
658 
659 
660 	// Initialize
661 
662 	*service = NULL;
663 
664 
665 
666 	// Convert BSTR params to utf8
667 
668 	ok = BSTRToUTF8( fullname, fullNameUTF8 );
669 
670 	require_action( ok, exit, err = kDNSServiceErr_BadParam );
671 
672 
673 
674 	try
675 
676 	{
677 
678 		object = new CComObject<CDNSSDService>();
679 
680 	}
681 
682 	catch ( ... )
683 
684 	{
685 
686 		object = NULL;
687 
688 	}
689 
690 
691 
692 	require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );
693 
694 	object->AddRef();
695 
696 
697 
698 	subord = m_primary;
699 
700 	err = DNSServiceQueryRecord( &subord, flags | kDNSServiceFlagsShareConnection, ifIndex, fullNameUTF8.c_str(), ( uint16_t ) rrtype, ( uint16_t ) rrclass, ( DNSServiceQueryRecordReply ) &QueryRecordReply, object );
701 
702 	require_noerr( err, exit );
703 
704 
705 
706 	object->SetPrimaryRef( m_primary );
707 
708 	object->SetSubordRef( subord );
709 
710 	object->SetEventManager( eventManager );
711 
712 
713 
714 	*service = object;
715 
716 
717 
718 exit:
719 
720 
721 
722 	if ( err && object )
723 
724 	{
725 
726 		object->Release();
727 
728 	}
729 
730 
731 
732 	return err;
733 
734 }
735 
736 
737 
738 
739 
RegisterRecord(DNSSDFlags flags,ULONG ifIndex,BSTR fullName,DNSSDRRType rrtype,DNSSDRRClass rrclass,VARIANT rdata,ULONG ttl,IDNSSDEventManager * eventManager,IDNSSDRecord ** record)740 STDMETHODIMP CDNSSDService::RegisterRecord(DNSSDFlags flags, ULONG ifIndex, BSTR fullName, DNSSDRRType rrtype, DNSSDRRClass rrclass, VARIANT rdata, ULONG ttl, IDNSSDEventManager* eventManager, IDNSSDRecord** record)
741 
742 {
743 
744 	CComObject<CDNSSDRecord>	*	object			= NULL;
745 
746 	DNSRecordRef					rref			= NULL;
747 
748 	std::string						fullNameUTF8;
749 
750 	std::vector< BYTE >				byteArray;
751 
752 	const void					*	byteArrayPtr	= NULL;
753 
754 	DNSServiceErrorType				err				= 0;
755 
756 	HRESULT							hr				= 0;
757 
758 	BOOL							ok;
759 
760 
761 
762 	check( m_primary );
763 
764 
765 
766 	// Initialize
767 
768 	*object = NULL;
769 
770 
771 
772 	// Convert BSTR params to utf8
773 
774 	ok = BSTRToUTF8( fullName, fullNameUTF8 );
775 
776 	require_action( ok, exit, err = kDNSServiceErr_BadParam );
777 
778 
779 
780 	// Convert the VARIANT
781 
782 	ok = VariantToByteArray( &rdata, byteArray );
783 
784 	require_action( ok, exit, err = kDNSServiceErr_Unknown );
785 
786 
787 
788 	try
789 
790 	{
791 
792 		object = new CComObject<CDNSSDRecord>();
793 
794 	}
795 
796 	catch ( ... )
797 
798 	{
799 
800 		object = NULL;
801 
802 	}
803 
804 
805 
806 	require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );
807 
808 	object->AddRef();
809 
810 
811 
812 	err = DNSServiceRegisterRecord( m_primary, &rref, flags, ifIndex, fullNameUTF8.c_str(), rrtype, rrclass, ( uint16_t ) byteArray.size(), byteArray.size() > 0 ? &byteArray[ 0 ] : NULL, ttl, &RegisterRecordReply, object );
813 
814 	require_noerr( err, exit );
815 
816 
817 
818 	object->SetServiceObject( this );
819 
820 	object->SetRecordRef( rref );
821 
822 	this->SetEventManager( eventManager );
823 
824 
825 
826 	*record = object;
827 
828 
829 
830 exit:
831 
832 
833 
834 	if ( err && object )
835 
836 	{
837 
838 		object->Release();
839 
840 	}
841 
842 
843 
844 	return err;
845 
846 }
847 
848 
849 
850 
851 
AddRecord(DNSSDFlags flags,DNSSDRRType rrtype,VARIANT rdata,ULONG ttl,IDNSSDRecord ** record)852 STDMETHODIMP CDNSSDService::AddRecord(DNSSDFlags flags, DNSSDRRType rrtype, VARIANT rdata, ULONG ttl, IDNSSDRecord ** record)
853 
854 {
855 
856 	CComObject<CDNSSDRecord>	*	object			= NULL;
857 
858 	DNSRecordRef					rref			= NULL;
859 
860 	std::vector< BYTE >				byteArray;
861 
862 	const void					*	byteArrayPtr	= NULL;
863 
864 	DNSServiceErrorType				err				= 0;
865 
866 	HRESULT							hr				= 0;
867 
868 	BOOL							ok;
869 
870 
871 
872 	check( m_primary );
873 
874 
875 
876 	// Initialize
877 
878 	*object = NULL;
879 
880 
881 
882 	// Convert the VARIANT
883 
884 	ok = VariantToByteArray( &rdata, byteArray );
885 
886 	require_action( ok, exit, err = kDNSServiceErr_Unknown );
887 
888 
889 
890 	try
891 
892 	{
893 
894 		object = new CComObject<CDNSSDRecord>();
895 
896 	}
897 
898 	catch ( ... )
899 
900 	{
901 
902 		object = NULL;
903 
904 	}
905 
906 
907 
908 	require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );
909 
910 	object->AddRef();
911 
912 
913 
914 	err = DNSServiceAddRecord( m_primary, &rref, flags, rrtype, ( uint16_t ) byteArray.size(), byteArray.size() > 0 ? &byteArray[ 0 ] : NULL, ttl );
915 
916 	require_noerr( err, exit );
917 
918 
919 
920 	object->SetServiceObject( this );
921 
922 	object->SetRecordRef( rref );
923 
924 
925 
926 	*record = object;
927 
928 
929 
930 exit:
931 
932 
933 
934 	if ( err && object )
935 
936 	{
937 
938 		object->Release();
939 
940 	}
941 
942 
943 
944 	return err;
945 
946 }
947 
948 
949 
ReconfirmRecord(DNSSDFlags flags,ULONG ifIndex,BSTR fullName,DNSSDRRType rrtype,DNSSDRRClass rrclass,VARIANT rdata)950 STDMETHODIMP CDNSSDService::ReconfirmRecord(DNSSDFlags flags, ULONG ifIndex, BSTR fullName, DNSSDRRType rrtype, DNSSDRRClass rrclass, VARIANT rdata)
951 
952 {
953 
954 	std::string						fullNameUTF8;
955 
956 	std::vector< BYTE >				byteArray;
957 
958 	const void					*	byteArrayPtr	= NULL;
959 
960 	DNSServiceErrorType				err				= 0;
961 
962 	HRESULT							hr				= 0;
963 
964 	BOOL							ok;
965 
966 
967 
968 	// Convert BSTR params to utf8
969 
970 	ok = BSTRToUTF8( fullName, fullNameUTF8 );
971 
972 	require_action( ok, exit, err = kDNSServiceErr_BadParam );
973 
974 
975 
976 	// Convert the VARIANT
977 
978 	ok = VariantToByteArray( &rdata, byteArray );
979 
980 	require_action( ok, exit, err = kDNSServiceErr_Unknown );
981 
982 
983 
984 	err = DNSServiceReconfirmRecord( flags, ifIndex, fullNameUTF8.c_str(), rrtype, rrclass, ( uint16_t ) byteArray.size(), byteArray.size() > 0 ? &byteArray[ 0 ] : NULL );
985 
986 	require_noerr( err, exit );
987 
988 
989 
990 exit:
991 
992 
993 
994 	return err;
995 
996 }
997 
998 
999 
1000 
1001 
GetProperty(BSTR prop,VARIANT * value)1002 STDMETHODIMP CDNSSDService::GetProperty(BSTR prop, VARIANT * value )
1003 
1004 {
1005 
1006 	std::string			propUTF8;
1007 
1008 	std::vector< BYTE >	byteArray;
1009 
1010 	SAFEARRAY		*	psa			= NULL;
1011 
1012 	BYTE			*	pData		= NULL;
1013 
1014 	uint32_t			elems		= 0;
1015 
1016 	DNSServiceErrorType	err			= 0;
1017 
1018 	BOOL				ok = TRUE;
1019 
1020 
1021 
1022 	// Convert BSTR params to utf8
1023 
1024 	ok = BSTRToUTF8( prop, propUTF8 );
1025 
1026 	require_action( ok, exit, err = kDNSServiceErr_BadParam );
1027 
1028 
1029 
1030 	// Setup the byte array
1031 
1032 	require_action( V_VT( value ) == ( VT_ARRAY|VT_UI1 ), exit, err = kDNSServiceErr_Unknown );
1033 
1034 	psa = V_ARRAY( value );
1035 
1036 	require_action( psa, exit, err = kDNSServiceErr_Unknown );
1037 
1038 	require_action( SafeArrayGetDim( psa ) == 1, exit, err = kDNSServiceErr_Unknown );
1039 
1040 	byteArray.reserve( psa->rgsabound[0].cElements );
1041 
1042 	byteArray.assign( byteArray.capacity(), 0 );
1043 
1044 	elems = ( uint32_t ) byteArray.capacity();
1045 
1046 
1047 
1048 	// Call the function and package the return value in the Variant
1049 
1050 	err = DNSServiceGetProperty( propUTF8.c_str(), &byteArray[ 0 ], &elems );
1051 
1052 	require_noerr( err, exit );
1053 
1054 	ok = ByteArrayToVariant( &byteArray[ 0 ], elems, value );
1055 
1056 	require_action( ok, exit, err = kDNSSDError_Unknown );
1057 
1058 
1059 
1060 exit:
1061 
1062 
1063 
1064 	if ( psa )
1065 
1066 	{
1067 
1068 		SafeArrayUnaccessData( psa );
1069 
1070 		psa = NULL;
1071 
1072 	}
1073 
1074 
1075 
1076 	return err;
1077 
1078 }
1079 
1080 
1081 
GetAddrInfo(DNSSDFlags flags,ULONG ifIndex,DNSSDAddressFamily addressFamily,BSTR hostName,IDNSSDEventManager * eventManager,IDNSSDService ** service)1082 STDMETHODIMP CDNSSDService::GetAddrInfo(DNSSDFlags flags, ULONG ifIndex, DNSSDAddressFamily addressFamily, BSTR hostName, IDNSSDEventManager *eventManager, IDNSSDService **service)
1083 
1084 {
1085 
1086 	CComObject<CDNSSDService>	*	object			= NULL;
1087 
1088 	DNSServiceRef					subord			= NULL;
1089 
1090 	std::string						hostNameUTF8;
1091 
1092 	DNSServiceErrorType				err				= 0;
1093 
1094 	HRESULT							hr				= 0;
1095 
1096 	BOOL							ok;
1097 
1098 
1099 
1100 	check( m_primary );
1101 
1102 
1103 
1104 	// Initialize
1105 
1106 	*service = NULL;
1107 
1108 
1109 
1110 	// Convert BSTR params to utf8
1111 
1112 	ok = BSTRToUTF8( hostName, hostNameUTF8 );
1113 
1114 	require_action( ok, exit, err = kDNSServiceErr_BadParam );
1115 
1116 
1117 
1118 	try
1119 
1120 	{
1121 
1122 		object = new CComObject<CDNSSDService>();
1123 
1124 	}
1125 
1126 	catch ( ... )
1127 
1128 	{
1129 
1130 		object = NULL;
1131 
1132 	}
1133 
1134 
1135 
1136 	require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );
1137 
1138 	object->AddRef();
1139 
1140 
1141 
1142 	subord = m_primary;
1143 
1144 	err = DNSServiceGetAddrInfo( &subord, flags | kDNSServiceFlagsShareConnection, ifIndex, addressFamily, hostNameUTF8.c_str(), ( DNSServiceGetAddrInfoReply ) &GetAddrInfoReply, object );
1145 
1146 	require_noerr( err, exit );
1147 
1148 
1149 
1150 	object->SetPrimaryRef( m_primary );
1151 
1152 	object->SetSubordRef( subord );
1153 
1154 	object->SetEventManager( eventManager );
1155 
1156 
1157 
1158 	*service = object;
1159 
1160 
1161 
1162 exit:
1163 
1164 
1165 
1166 	if ( err && object )
1167 
1168 	{
1169 
1170 		object->Release();
1171 
1172 	}
1173 
1174 
1175 
1176 	return err;
1177 
1178 }
1179 
1180 
1181 
1182 
1183 
NATPortMappingCreate(DNSSDFlags flags,ULONG ifIndex,DNSSDAddressFamily addressFamily,DNSSDProtocol protocol,USHORT internalPort,USHORT externalPort,ULONG ttl,IDNSSDEventManager * eventManager,IDNSSDService ** service)1184 STDMETHODIMP CDNSSDService::NATPortMappingCreate(DNSSDFlags flags, ULONG ifIndex, DNSSDAddressFamily addressFamily, DNSSDProtocol protocol, USHORT internalPort, USHORT externalPort, ULONG ttl, IDNSSDEventManager *eventManager, IDNSSDService **service)
1185 
1186 {
1187 
1188 	CComObject<CDNSSDService>	*	object			= NULL;
1189 
1190 	DNSServiceRef					subord			= NULL;
1191 
1192 	DNSServiceProtocol				prot			= 0;
1193 
1194 	DNSServiceErrorType				err				= 0;
1195 
1196 	HRESULT							hr				= 0;
1197 
1198 
1199 
1200 	check( m_primary );
1201 
1202 
1203 
1204 	// Initialize
1205 
1206 	*service = NULL;
1207 
1208 
1209 
1210 	try
1211 
1212 	{
1213 
1214 		object = new CComObject<CDNSSDService>();
1215 
1216 	}
1217 
1218 	catch ( ... )
1219 
1220 	{
1221 
1222 		object = NULL;
1223 
1224 	}
1225 
1226 
1227 
1228 	require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );
1229 
1230 	object->AddRef();
1231 
1232 
1233 
1234 	prot = ( addressFamily | protocol );
1235 
1236 
1237 
1238 	subord = m_primary;
1239 
1240 	err = DNSServiceNATPortMappingCreate( &subord, flags | kDNSServiceFlagsShareConnection, ifIndex, prot, htons( internalPort ), htons( externalPort ), ttl, ( DNSServiceNATPortMappingReply ) &NATPortMappingReply, object );
1241 
1242 	require_noerr( err, exit );
1243 
1244 
1245 
1246 	object->SetPrimaryRef( m_primary );
1247 
1248 	object->SetSubordRef( subord );
1249 
1250 	object->SetEventManager( eventManager );
1251 
1252 
1253 
1254 	*service = object;
1255 
1256 
1257 
1258 exit:
1259 
1260 
1261 
1262 	if ( err && object )
1263 
1264 	{
1265 
1266 		object->Release();
1267 
1268 	}
1269 
1270 
1271 
1272 	return err;
1273 
1274 }
1275 
1276 
1277 
1278 
1279 
Stop(void)1280 STDMETHODIMP CDNSSDService::Stop(void)
1281 
1282 {
1283 
1284 	if ( !m_stopped )
1285 
1286 	{
1287 
1288 		m_stopped = TRUE;
1289 
1290 
1291 
1292 		dlog( kDebugLevelTrace, "Stop()\n" );
1293 
1294 
1295 
1296 		if ( m_isPrimary && m_primary )
1297 
1298 		{
1299 
1300 			SocketMap::iterator it;
1301 
1302 
1303 
1304 			if ( m_hiddenWindow )
1305 
1306 			{
1307 
1308 				WSAAsyncSelect( DNSServiceRefSockFD( m_primary ), m_hiddenWindow, 0, 0 );
1309 
1310 			}
1311 
1312 
1313 
1314 			it = m_socketMap.find( DNSServiceRefSockFD( m_primary ) );
1315 
1316 
1317 
1318 			if ( it != m_socketMap.end() )
1319 
1320 			{
1321 
1322 				m_socketMap.erase( it );
1323 
1324 			}
1325 
1326 
1327 
1328 			DNSServiceRefDeallocate( m_primary );
1329 
1330 			m_primary = NULL;
1331 
1332 		}
1333 
1334 		else if ( m_subord )
1335 
1336 		{
1337 
1338 			DNSServiceRefDeallocate( m_subord );
1339 
1340 			m_subord = NULL;
1341 
1342 		}
1343 
1344 
1345 
1346 		if ( m_eventManager != NULL )
1347 
1348 		{
1349 
1350 			m_eventManager->Release();
1351 
1352 			m_eventManager = NULL;
1353 
1354 		}
1355 
1356 	}
1357 
1358 
1359 
1360 	return S_OK;
1361 
1362 }
1363 
1364 
1365 
1366 
1367 
1368 void DNSSD_API
DomainEnumReply(DNSServiceRef sdRef,DNSServiceFlags flags,uint32_t ifIndex,DNSServiceErrorType errorCode,const char * replyDomainUTF8,void * context)1369 CDNSSDService::DomainEnumReply
1370     (
1371     DNSServiceRef                       sdRef,
1372     DNSServiceFlags                     flags,
1373     uint32_t                            ifIndex,
1374     DNSServiceErrorType                 errorCode,
1375     const char                          *replyDomainUTF8,
1376     void                                *context
1377     )
1378 
1379 {
1380 
1381 	CComObject<CDNSSDService>	* service		= NULL;
1382 
1383 	CDNSSDEventManager			* eventManager	= NULL;
1384 
1385 	int err = 0;
1386 
1387 
1388 
1389 	service = ( CComObject< CDNSSDService>* ) context;
1390 
1391 	require_action( service, exit, err = kDNSServiceErr_Unknown );
1392 
1393 
1394 
1395 	if ( service->ShouldHandleReply( errorCode, eventManager ) )
1396 
1397 	{
1398 
1399 		CComBSTR replyDomain;
1400 
1401 		BOOL ok;
1402 
1403 
1404 
1405 		ok = UTF8ToBSTR( replyDomainUTF8, replyDomain );
1406 
1407 		require_action( ok, exit, err = kDNSServiceErr_Unknown );
1408 
1409 
1410 
1411 		if ( flags & kDNSServiceFlagsAdd )
1412 
1413 		{
1414 
1415 			eventManager->Fire_DomainFound( service, ( DNSSDFlags ) flags, ifIndex, replyDomain );
1416 
1417 		}
1418 
1419 		else
1420 
1421 		{
1422 
1423 			eventManager->Fire_DomainLost( service, ( DNSSDFlags ) flags, ifIndex, replyDomain );
1424 
1425 		}
1426 
1427 	}
1428 
1429 
1430 
1431 exit:
1432 
1433 
1434 
1435 	return;
1436 
1437 }
1438 
1439 
1440 
1441 
1442 
1443 void DNSSD_API
BrowseReply(DNSServiceRef sdRef,DNSServiceFlags flags,uint32_t ifIndex,DNSServiceErrorType errorCode,const char * serviceNameUTF8,const char * regTypeUTF8,const char * replyDomainUTF8,void * context)1444 CDNSSDService::BrowseReply
1445 		(
1446 		DNSServiceRef                       sdRef,
1447 		DNSServiceFlags                     flags,
1448 		uint32_t                            ifIndex,
1449 		DNSServiceErrorType                 errorCode,
1450 		const char                          *serviceNameUTF8,
1451 		const char                          *regTypeUTF8,
1452 		const char                          *replyDomainUTF8,
1453 		void                                *context
1454 		)
1455 
1456 {
1457 
1458 	CComObject<CDNSSDService>	* service		= NULL;
1459 
1460 	CDNSSDEventManager			* eventManager	= NULL;
1461 
1462 	int err = 0;
1463 
1464 
1465 
1466 	service = ( CComObject< CDNSSDService>* ) context;
1467 
1468 	require_action( service, exit, err = kDNSServiceErr_Unknown );
1469 
1470 
1471 
1472 	if ( service->ShouldHandleReply( errorCode, eventManager ) )
1473 
1474 	{
1475 
1476 		CComBSTR	serviceName;
1477 
1478 		CComBSTR	regType;
1479 
1480 		CComBSTR	replyDomain;
1481 
1482 
1483 
1484 		UTF8ToBSTR( serviceNameUTF8, serviceName );
1485 
1486 		UTF8ToBSTR( regTypeUTF8, regType );
1487 
1488 		UTF8ToBSTR( replyDomainUTF8, replyDomain );
1489 
1490 
1491 
1492 		if ( flags & kDNSServiceFlagsAdd )
1493 
1494 		{
1495 
1496 			eventManager->Fire_ServiceFound( service, ( DNSSDFlags ) flags, ifIndex, serviceName, regType, replyDomain );
1497 
1498 		}
1499 
1500 		else
1501 
1502 		{
1503 
1504 			eventManager->Fire_ServiceLost( service, ( DNSSDFlags ) flags, ifIndex, serviceName, regType, replyDomain );
1505 
1506 		}
1507 
1508 	}
1509 
1510 
1511 
1512 exit:
1513 
1514 
1515 
1516 	return;
1517 
1518 }
1519 
1520 
1521 
1522 
1523 
1524 void DNSSD_API
1525 
ResolveReply(DNSServiceRef sdRef,DNSServiceFlags flags,uint32_t ifIndex,DNSServiceErrorType errorCode,const char * fullNameUTF8,const char * hostNameUTF8,uint16_t port,uint16_t txtLen,const unsigned char * txtRecord,void * context)1526 CDNSSDService::ResolveReply
1527 
1528 		(
1529 		DNSServiceRef                       sdRef,
1530 		DNSServiceFlags                     flags,
1531 		uint32_t                            ifIndex,
1532 		DNSServiceErrorType                 errorCode,
1533 		const char                          *fullNameUTF8,
1534 		const char                          *hostNameUTF8,
1535 		uint16_t                            port,
1536 		uint16_t                            txtLen,
1537 		const unsigned char                 *txtRecord,
1538 		void                                *context
1539 
1540 		)
1541 
1542 {
1543 
1544 	CComObject<CDNSSDService>	* service		= NULL;
1545 
1546 	CDNSSDEventManager			* eventManager	= NULL;
1547 
1548 	int err = 0;
1549 
1550 
1551 
1552 	service = ( CComObject< CDNSSDService>* ) context;
1553 
1554 	require_action( service, exit, err = kDNSServiceErr_Unknown );
1555 
1556 
1557 
1558 	if ( service->ShouldHandleReply( errorCode, eventManager ) )
1559 
1560 	{
1561 
1562 		CComBSTR					fullName;
1563 
1564 		CComBSTR					hostName;
1565 
1566 		CComBSTR					regType;
1567 
1568 		CComBSTR					replyDomain;
1569 
1570 		CComObject< CTXTRecord >*	record;
1571 
1572 		BOOL						ok;
1573 
1574 
1575 
1576 		ok = UTF8ToBSTR( fullNameUTF8, fullName );
1577 
1578 		require_action( ok, exit, err = kDNSServiceErr_Unknown );
1579 
1580 		ok = UTF8ToBSTR( hostNameUTF8, hostName );
1581 
1582 		require_action( ok, exit, err = kDNSServiceErr_Unknown );
1583 
1584 
1585 
1586 		try
1587 
1588 		{
1589 
1590 			record = new CComObject<CTXTRecord>();
1591 
1592 		}
1593 
1594 		catch ( ... )
1595 
1596 		{
1597 
1598 			record = NULL;
1599 
1600 		}
1601 
1602 
1603 
1604 		require_action( record, exit, err = kDNSServiceErr_NoMemory );
1605 
1606 		record->AddRef();
1607 
1608 
1609 
1610 		if ( txtLen > 0 )
1611 
1612 		{
1613 
1614 			record->SetBytes( txtRecord, txtLen );
1615 
1616 		}
1617 
1618 
1619 
1620 		eventManager->Fire_ServiceResolved( service, ( DNSSDFlags ) flags, ifIndex, fullName, hostName, ntohs( port ), record );
1621 
1622 	}
1623 
1624 
1625 
1626 exit:
1627 
1628 
1629 
1630 	return;
1631 
1632 }
1633 
1634 
1635 
1636 
1637 
1638 void DNSSD_API
RegisterReply(DNSServiceRef sdRef,DNSServiceFlags flags,DNSServiceErrorType errorCode,const char * serviceNameUTF8,const char * regTypeUTF8,const char * domainUTF8,void * context)1639 CDNSSDService::RegisterReply
1640 		(
1641 		DNSServiceRef                       sdRef,
1642 		DNSServiceFlags                     flags,
1643 		DNSServiceErrorType                 errorCode,
1644 		const char                          *serviceNameUTF8,
1645 		const char                          *regTypeUTF8,
1646 		const char                          *domainUTF8,
1647 		void                                *context
1648 		)
1649 
1650 {
1651 
1652 	CComObject<CDNSSDService>	* service		= NULL;
1653 
1654 	CDNSSDEventManager			* eventManager	= NULL;
1655 
1656 	int err = 0;
1657 
1658 
1659 
1660 	service = ( CComObject< CDNSSDService>* ) context;
1661 
1662 	require_action( service, exit, err = kDNSServiceErr_Unknown );
1663 
1664 
1665 
1666 	if ( service->ShouldHandleReply( errorCode, eventManager ) )
1667 
1668 	{
1669 
1670 		CComBSTR					serviceName;
1671 
1672 		CComBSTR					regType;
1673 
1674 		CComBSTR					domain;
1675 
1676 		BOOL						ok;
1677 
1678 
1679 
1680 		ok = UTF8ToBSTR( serviceNameUTF8, serviceName );
1681 
1682 		require_action( ok, exit, err = kDNSServiceErr_Unknown );
1683 
1684 		ok = UTF8ToBSTR( regTypeUTF8, regType );
1685 
1686 		require_action( ok, exit, err = kDNSServiceErr_Unknown );
1687 
1688 		ok = UTF8ToBSTR( domainUTF8, domain );
1689 
1690 		require_action( ok, exit, err = kDNSServiceErr_Unknown );
1691 
1692 
1693 
1694 		eventManager->Fire_ServiceRegistered( service, ( DNSSDFlags ) flags, serviceName, regType, domain );
1695 
1696 	}
1697 
1698 
1699 
1700 exit:
1701 
1702 
1703 
1704 	return;
1705 
1706 }
1707 
1708 
1709 
1710 
1711 
1712 void DNSSD_API
QueryRecordReply(DNSServiceRef sdRef,DNSServiceFlags flags,uint32_t ifIndex,DNSServiceErrorType errorCode,const char * fullNameUTF8,uint16_t rrtype,uint16_t rrclass,uint16_t rdlen,const void * rdata,uint32_t ttl,void * context)1713 CDNSSDService::QueryRecordReply
1714 		(
1715 		DNSServiceRef                       sdRef,
1716 		DNSServiceFlags                     flags,
1717 		uint32_t                            ifIndex,
1718 		DNSServiceErrorType                 errorCode,
1719 		const char                          *fullNameUTF8,
1720 		uint16_t                            rrtype,
1721 		uint16_t                            rrclass,
1722 		uint16_t                            rdlen,
1723 		const void                          *rdata,
1724 		uint32_t                            ttl,
1725 		void                                *context
1726 		)
1727 
1728 {
1729 
1730 	CComObject<CDNSSDService>	* service		= NULL;
1731 
1732 	CDNSSDEventManager			* eventManager	= NULL;
1733 
1734 	int err = 0;
1735 
1736 
1737 
1738 	service = ( CComObject< CDNSSDService>* ) context;
1739 
1740 	require_action( service, exit, err = kDNSServiceErr_Unknown );
1741 
1742 
1743 
1744 	if ( service->ShouldHandleReply( errorCode, eventManager ) )
1745 
1746 	{
1747 
1748 		CComBSTR	fullName;
1749 
1750 		VARIANT		var;
1751 
1752 		BOOL		ok;
1753 
1754 
1755 
1756 		ok = UTF8ToBSTR( fullNameUTF8, fullName );
1757 
1758 		require_action( ok, exit, err = kDNSServiceErr_Unknown );
1759 
1760 		ok = ByteArrayToVariant( rdata, rdlen, &var );
1761 
1762 		require_action( ok, exit, err = kDNSServiceErr_Unknown );
1763 
1764 
1765 
1766 		eventManager->Fire_QueryRecordAnswered( service, ( DNSSDFlags ) flags, ifIndex, fullName, ( DNSSDRRType ) rrtype, ( DNSSDRRClass ) rrclass, var, ttl );
1767 
1768 	}
1769 
1770 
1771 
1772 exit:
1773 
1774 
1775 
1776 	return;
1777 
1778 }
1779 
1780 
1781 
1782 
1783 
1784 void DNSSD_API
GetAddrInfoReply(DNSServiceRef sdRef,DNSServiceFlags flags,uint32_t ifIndex,DNSServiceErrorType errorCode,const char * hostNameUTF8,const struct sockaddr * rawAddress,uint32_t ttl,void * context)1785 CDNSSDService::GetAddrInfoReply
1786 		(
1787 		DNSServiceRef                    sdRef,
1788 		DNSServiceFlags                  flags,
1789 		uint32_t                         ifIndex,
1790 		DNSServiceErrorType              errorCode,
1791 		const char                       *hostNameUTF8,
1792 		const struct sockaddr            *rawAddress,
1793 		uint32_t                         ttl,
1794 		void                             *context
1795 		)
1796 
1797 {
1798 
1799 	CComObject<CDNSSDService>	* service		= NULL;
1800 
1801 	CDNSSDEventManager			* eventManager	= NULL;
1802 
1803 	int err = 0;
1804 
1805 
1806 
1807 	service = ( CComObject< CDNSSDService>* ) context;
1808 
1809 	require_action( service, exit, err = kDNSServiceErr_Unknown );
1810 
1811 
1812 
1813 	if ( service->ShouldHandleReply( errorCode, eventManager ) )
1814 
1815 	{
1816 
1817 		CComBSTR			hostName;
1818 
1819 		DWORD				sockaddrLen;
1820 
1821 		DNSSDAddressFamily	addressFamily;
1822 
1823 		char				addressUTF8[INET6_ADDRSTRLEN];
1824 
1825 		DWORD				addressLen = sizeof( addressUTF8 );
1826 
1827 		CComBSTR			address;
1828 
1829 		BOOL				ok;
1830 
1831 
1832 
1833 		ok = UTF8ToBSTR( hostNameUTF8, hostName );
1834 
1835 		require_action( ok, exit, err = kDNSServiceErr_Unknown );
1836 
1837 
1838 
1839 		switch ( rawAddress->sa_family )
1840 
1841 		{
1842 
1843 			case AF_INET:
1844 
1845 			{
1846 
1847 				addressFamily	= kDNSSDAddressFamily_IPv4;
1848 
1849 				sockaddrLen		= sizeof( sockaddr_in );
1850 
1851 			}
1852 
1853 			break;
1854 
1855 
1856 
1857 			case AF_INET6:
1858 
1859 			{
1860 
1861 				addressFamily	= kDNSSDAddressFamily_IPv6;
1862 
1863 				sockaddrLen		= sizeof( sockaddr_in6 );
1864 
1865 			}
1866 
1867 			break;
1868 
1869 		}
1870 
1871 
1872 
1873 		err = WSAAddressToStringA( ( LPSOCKADDR ) rawAddress, sockaddrLen, NULL, addressUTF8, &addressLen );
1874 
1875 		require_noerr( err, exit );
1876 
1877 		ok = UTF8ToBSTR( addressUTF8, address );
1878 
1879 		require_action( ok, exit, err = kDNSServiceErr_Unknown );
1880 
1881 
1882 
1883 		eventManager->Fire_AddressFound( service, ( DNSSDFlags ) flags, ifIndex, hostName, addressFamily, address, ttl );
1884 
1885 	}
1886 
1887 
1888 
1889 exit:
1890 
1891 
1892 
1893 	return;
1894 
1895 }
1896 
1897 
1898 
1899 
1900 
1901 void DNSSD_API
NATPortMappingReply(DNSServiceRef sdRef,DNSServiceFlags flags,uint32_t ifIndex,DNSServiceErrorType errorCode,uint32_t externalAddress,DNSServiceProtocol protocol,uint16_t internalPort,uint16_t externalPort,uint32_t ttl,void * context)1902 CDNSSDService::NATPortMappingReply
1903     (
1904     DNSServiceRef                    sdRef,
1905     DNSServiceFlags                  flags,
1906     uint32_t                         ifIndex,
1907     DNSServiceErrorType              errorCode,
1908     uint32_t                         externalAddress,   /* four byte IPv4 address in network byte order */
1909     DNSServiceProtocol               protocol,
1910     uint16_t                         internalPort,
1911     uint16_t                         externalPort,      /* may be different than the requested port     */
1912     uint32_t                         ttl,               /* may be different than the requested ttl      */
1913     void                             *context
1914     )
1915 
1916 {
1917 
1918 	CComObject<CDNSSDService>	* service		= NULL;
1919 
1920 	CDNSSDEventManager			* eventManager	= NULL;
1921 
1922 	int err = 0;
1923 
1924 
1925 
1926 	service = ( CComObject< CDNSSDService>* ) context;
1927 
1928 	require_action( service, exit, err = kDNSServiceErr_Unknown );
1929 
1930 
1931 
1932 	if ( service->ShouldHandleReply( errorCode, eventManager ) )
1933 
1934 	{
1935 
1936 		eventManager->Fire_MappingCreated( service, ( DNSSDFlags ) flags, ifIndex, externalAddress, ( DNSSDAddressFamily ) ( protocol & 0x8 ), ( DNSSDProtocol ) ( protocol & 0x80 ), ntohs( internalPort ), ntohs( externalPort ), ttl  );
1937 
1938 	}
1939 
1940 
1941 
1942 exit:
1943 
1944 
1945 
1946 	return;
1947 
1948 }
1949 
1950 
1951 
1952 
1953 
1954 void DNSSD_API
RegisterRecordReply(DNSServiceRef sdRef,DNSRecordRef RecordRef,DNSServiceFlags flags,DNSServiceErrorType errorCode,void * context)1955 CDNSSDService::RegisterRecordReply
1956 		(
1957 		DNSServiceRef		sdRef,
1958 		DNSRecordRef		RecordRef,
1959 		DNSServiceFlags		flags,
1960 		DNSServiceErrorType	errorCode,
1961 		void				*context
1962 		)
1963 
1964 {
1965 
1966 	CComObject<CDNSSDRecord>	* record		= NULL;
1967 
1968 	CDNSSDService				* service		= NULL;
1969 
1970 	CDNSSDEventManager			* eventManager	= NULL;
1971 
1972 	int err = 0;
1973 
1974 
1975 
1976 	record = ( CComObject< CDNSSDRecord >* ) context;
1977 
1978 	require_action( record, exit, err = kDNSServiceErr_Unknown );
1979 
1980 	service = record->GetServiceObject();
1981 
1982 	require_action( service, exit, err = kDNSServiceErr_Unknown );
1983 
1984 
1985 
1986 	if ( service->ShouldHandleReply( errorCode, eventManager ) )
1987 
1988 	{
1989 
1990 		eventManager->Fire_RecordRegistered( record, ( DNSSDFlags ) flags );
1991 
1992 	}
1993 
1994 
1995 
1996 exit:
1997 
1998 
1999 
2000 	return;
2001 
2002 }
2003 
2004 
2005 
2006 
2007 
2008 BOOL
2009 
ShouldHandleReply(DNSServiceErrorType errorCode,CDNSSDEventManager * & eventManager)2010 CDNSSDService::ShouldHandleReply( DNSServiceErrorType errorCode, CDNSSDEventManager *& eventManager )
2011 
2012 {
2013 
2014 	BOOL ok = FALSE;
2015 
2016 
2017 
2018 	if ( !this->Stopped() )
2019 
2020 	{
2021 
2022 		eventManager = this->GetEventManager();
2023 
2024 		require_action( eventManager, exit, ok = FALSE );
2025 
2026 
2027 
2028 		if ( !errorCode )
2029 
2030 		{
2031 
2032 			ok = TRUE;
2033 
2034 		}
2035 
2036 		else
2037 
2038 		{
2039 
2040 			eventManager->Fire_OperationFailed( this, ( DNSSDError ) errorCode );
2041 
2042 		}
2043 
2044 	}
2045 
2046 
2047 
2048 exit:
2049 
2050 
2051 
2052 	return ok;
2053 
2054 }
2055 
2056 
2057 
2058 
2059 
2060 LRESULT CALLBACK
2061 
WndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)2062 CDNSSDService::WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
2063 
2064 {
2065 
2066 	if ( msg == WM_SOCKET )
2067 
2068 	{
2069 
2070 		SocketMap::iterator it;
2071 
2072 
2073 
2074 		it = m_socketMap.find( ( SOCKET ) wParam );
2075 
2076 		check( it != m_socketMap.end() );
2077 
2078 
2079 
2080 		if ( it != m_socketMap.end() )
2081 
2082 		{
2083 
2084 			DNSServiceProcessResult( it->second->m_primary );
2085 
2086 		}
2087 
2088 	}
2089 
2090 
2091 
2092 	return DefWindowProc(hWnd, msg, wParam, lParam);;
2093 
2094 }
2095 
2096