Home | History | Annotate | Download | only in DLLX
      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 
     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 
    168 void CDNSSDService::FinalRelease()
    169 
    170 {
    171 
    172 	dlog( kDebugLevelTrace, "FinalRelease()\n" );
    173 
    174 	Stop();
    175 
    176 }
    177 
    178 
    179 
    180 
    181 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
   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 
   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 
   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 
   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
   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
   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 
   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
   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
   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
   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
   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
   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 
   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 
   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