--- /dev/null
+// DNSSD.cpp : Implementation of CDNSSD\r
+\r
+#include "stdafx.h"\r
+#include "DNSSD.h"\r
+#include "DNSSDService.h"\r
+#include "TXTRecord.h"\r
+#include <dns_sd.h>\r
+#include <CommonServices.h>\r
+#include <DebugServices.h>\r
+#include "StringServices.h"\r
+\r
+\r
+// CDNSSD\r
+\r
+STDMETHODIMP CDNSSD::Browse(DNSSDFlags flags, ULONG ifIndex, BSTR regtype, BSTR domain, IBrowseListener* listener, IDNSSDService** browser )\r
+{\r
+ CComObject<CDNSSDService> * object = NULL;\r
+ std::string regtypeUTF8;\r
+ std::string domainUTF8;\r
+ DNSServiceRef sref = NULL;\r
+ DNSServiceErrorType err = 0;\r
+ HRESULT hr = 0;\r
+ BOOL ok;\r
+\r
+ // Initialize\r
+ *browser = NULL;\r
+\r
+ // Convert BSTR params to utf8\r
+ ok = BSTRToUTF8( regtype, regtypeUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+ ok = BSTRToUTF8( domain, domainUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+\r
+ try\r
+ {\r
+ object = new CComObject<CDNSSDService>();\r
+ }\r
+ catch ( ... )\r
+ {\r
+ object = NULL;\r
+ }\r
+\r
+ require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );\r
+ hr = object->FinalConstruct();\r
+ require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown );\r
+ object->AddRef();\r
+\r
+ err = DNSServiceBrowse( &sref, flags, ifIndex, regtypeUTF8.c_str(), domainUTF8.c_str(), ( DNSServiceBrowseReply ) &BrowseReply, object );\r
+ require_noerr( err, exit );\r
+\r
+ object->SetServiceRef( sref );\r
+ object->SetListener( listener );\r
+\r
+ err = object->Run();\r
+ require_noerr( err, exit );\r
+\r
+ *browser = object;\r
+\r
+exit:\r
+\r
+ if ( err && object )\r
+ {\r
+ object->Release();\r
+ }\r
+\r
+ return err;\r
+}\r
+\r
+\r
+STDMETHODIMP CDNSSD::Resolve(DNSSDFlags flags, ULONG ifIndex, BSTR serviceName, BSTR regType, BSTR domain, IResolveListener* listener, IDNSSDService** service)\r
+{\r
+ CComObject<CDNSSDService> * object = NULL;\r
+ std::string serviceNameUTF8;\r
+ std::string regTypeUTF8;\r
+ std::string domainUTF8;\r
+ DNSServiceRef sref = NULL;\r
+ DNSServiceErrorType err = 0;\r
+ HRESULT hr = 0;\r
+ BOOL ok;\r
+\r
+ // Initialize\r
+ *service = NULL;\r
+\r
+ // Convert BSTR params to utf8\r
+ ok = BSTRToUTF8( serviceName, serviceNameUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+ ok = BSTRToUTF8( regType, regTypeUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+ ok = BSTRToUTF8( domain, domainUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+\r
+ try\r
+ {\r
+ object = new CComObject<CDNSSDService>();\r
+ }\r
+ catch ( ... )\r
+ {\r
+ object = NULL;\r
+ }\r
+\r
+ require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );\r
+ hr = object->FinalConstruct();\r
+ require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown );\r
+ object->AddRef();\r
+\r
+ err = DNSServiceResolve( &sref, flags, ifIndex, serviceNameUTF8.c_str(), regTypeUTF8.c_str(), domainUTF8.c_str(), ( DNSServiceResolveReply ) &ResolveReply, object );\r
+ require_noerr( err, exit );\r
+\r
+ object->SetServiceRef( sref );\r
+ object->SetListener( listener );\r
+\r
+ err = object->Run();\r
+ require_noerr( err, exit );\r
+\r
+ *service = object;\r
+\r
+exit:\r
+\r
+ if ( err && object )\r
+ {\r
+ object->Release();\r
+ }\r
+\r
+ return err;\r
+}\r
+\r
+\r
+STDMETHODIMP CDNSSD::EnumerateDomains(DNSSDFlags flags, ULONG ifIndex, IDomainListener *listener, IDNSSDService **service)\r
+{\r
+ CComObject<CDNSSDService> * object = NULL;\r
+ DNSServiceRef sref = NULL;\r
+ DNSServiceErrorType err = 0;\r
+ HRESULT hr = 0;\r
+\r
+ // Initialize\r
+ *service = NULL;\r
+\r
+ try\r
+ {\r
+ object = new CComObject<CDNSSDService>();\r
+ }\r
+ catch ( ... )\r
+ {\r
+ object = NULL;\r
+ }\r
+\r
+ require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );\r
+ hr = object->FinalConstruct();\r
+ require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown );\r
+ object->AddRef();\r
+\r
+ err = DNSServiceEnumerateDomains( &sref, flags, ifIndex, ( DNSServiceDomainEnumReply ) &DomainEnumReply, object );\r
+ require_noerr( err, exit );\r
+\r
+ object->SetServiceRef( sref );\r
+ object->SetListener( listener );\r
+\r
+ err = object->Run();\r
+ require_noerr( err, exit );\r
+\r
+ *service = object;\r
+\r
+exit:\r
+\r
+ if ( err && object )\r
+ {\r
+ object->Release();\r
+ }\r
+\r
+ return err;\r
+}\r
+\r
+\r
+STDMETHODIMP CDNSSD::Register(DNSSDFlags flags, ULONG ifIndex, BSTR serviceName, BSTR regType, BSTR domain, BSTR host, USHORT port, ITXTRecord *record, IRegisterListener *listener, IDNSSDService **service)\r
+{\r
+ CComObject<CDNSSDService> * object = NULL;\r
+ std::string serviceNameUTF8;\r
+ std::string regTypeUTF8;\r
+ std::string domainUTF8;\r
+ std::string hostUTF8;\r
+ const void * txtRecord = NULL;\r
+ uint16_t txtLen = 0;\r
+ DNSServiceRef sref = NULL;\r
+ DNSServiceErrorType err = 0;\r
+ HRESULT hr = 0;\r
+ BOOL ok;\r
+\r
+ // Initialize\r
+ *service = NULL;\r
+\r
+ // Convert BSTR params to utf8\r
+ ok = BSTRToUTF8( serviceName, serviceNameUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+ ok = BSTRToUTF8( regType, regTypeUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+ ok = BSTRToUTF8( domain, domainUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+ ok = BSTRToUTF8( host, hostUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+\r
+ try\r
+ {\r
+ object = new CComObject<CDNSSDService>();\r
+ }\r
+ catch ( ... )\r
+ {\r
+ object = NULL;\r
+ }\r
+\r
+ require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );\r
+ hr = object->FinalConstruct();\r
+ require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown );\r
+ object->AddRef();\r
+\r
+ if ( record )\r
+ {\r
+ CComObject< CTXTRecord > * realTXTRecord;\r
+\r
+ realTXTRecord = ( CComObject< CTXTRecord >* ) record;\r
+\r
+ txtRecord = realTXTRecord->GetBytes();\r
+ txtLen = realTXTRecord->GetLen();\r
+ }\r
+\r
+ err = DNSServiceRegister( &sref, flags, ifIndex, serviceNameUTF8.c_str(), regTypeUTF8.c_str(), domainUTF8.c_str(), hostUTF8.c_str(), port, txtLen, txtRecord, ( DNSServiceRegisterReply ) &RegisterReply, object );\r
+ require_noerr( err, exit );\r
+\r
+ object->SetServiceRef( sref );\r
+ object->SetListener( listener );\r
+\r
+ err = object->Run();\r
+ require_noerr( err, exit );\r
+\r
+ *service = object;\r
+\r
+exit:\r
+\r
+ if ( err && object )\r
+ {\r
+ object->Release();\r
+ }\r
+\r
+ return err;\r
+}\r
+\r
+\r
+STDMETHODIMP CDNSSD::QueryRecord(DNSSDFlags flags, ULONG ifIndex, BSTR fullname, DNSSDRRType rrtype, DNSSDRRClass rrclass, IQueryRecordListener *listener, IDNSSDService **service)\r
+{\r
+ CComObject<CDNSSDService> * object = NULL;\r
+ DNSServiceRef sref = NULL;\r
+ std::string fullNameUTF8;\r
+ DNSServiceErrorType err = 0;\r
+ HRESULT hr = 0;\r
+ BOOL ok;\r
+\r
+ // Initialize\r
+ *service = NULL;\r
+\r
+ // Convert BSTR params to utf8\r
+ ok = BSTRToUTF8( fullname, fullNameUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+\r
+ try\r
+ {\r
+ object = new CComObject<CDNSSDService>();\r
+ }\r
+ catch ( ... )\r
+ {\r
+ object = NULL;\r
+ }\r
+\r
+ require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );\r
+ hr = object->FinalConstruct();\r
+ require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown );\r
+ object->AddRef();\r
+\r
+ err = DNSServiceQueryRecord( &sref, flags, ifIndex, fullNameUTF8.c_str(), ( uint16_t ) rrtype, ( uint16_t ) rrclass, ( DNSServiceQueryRecordReply ) &QueryRecordReply, object );\r
+ require_noerr( err, exit );\r
+\r
+ object->SetServiceRef( sref );\r
+ object->SetListener( listener );\r
+\r
+ err = object->Run();\r
+ require_noerr( err, exit );\r
+\r
+ *service = object;\r
+\r
+exit:\r
+\r
+ if ( err && object )\r
+ {\r
+ object->Release();\r
+ }\r
+\r
+ return err;\r
+}\r
+\r
+\r
+STDMETHODIMP CDNSSD::GetAddrInfo(DNSSDFlags flags, ULONG ifIndex, DNSSDAddressFamily addressFamily, BSTR hostName, IGetAddrInfoListener *listener, IDNSSDService **service)\r
+{\r
+ CComObject<CDNSSDService> * object = NULL;\r
+ DNSServiceRef sref = NULL;\r
+ std::string hostNameUTF8;\r
+ DNSServiceErrorType err = 0;\r
+ HRESULT hr = 0;\r
+ BOOL ok;\r
+\r
+ // Initialize\r
+ *service = NULL;\r
+\r
+ // Convert BSTR params to utf8\r
+ ok = BSTRToUTF8( hostName, hostNameUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+\r
+ try\r
+ {\r
+ object = new CComObject<CDNSSDService>();\r
+ }\r
+ catch ( ... )\r
+ {\r
+ object = NULL;\r
+ }\r
+\r
+ require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );\r
+ hr = object->FinalConstruct();\r
+ require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown );\r
+ object->AddRef();\r
+\r
+ err = DNSServiceGetAddrInfo( &sref, flags, ifIndex, addressFamily, hostNameUTF8.c_str(), ( DNSServiceGetAddrInfoReply ) &GetAddrInfoReply, object );\r
+ require_noerr( err, exit );\r
+\r
+ object->SetServiceRef( sref );\r
+ object->SetListener( listener );\r
+\r
+ err = object->Run();\r
+ require_noerr( err, exit );\r
+\r
+ *service = object;\r
+\r
+exit:\r
+\r
+ if ( err && object )\r
+ {\r
+ object->Release();\r
+ }\r
+\r
+ return err;\r
+}\r
+\r
+\r
+STDMETHODIMP CDNSSD::CreateConnection(IDNSSDService **service)\r
+{\r
+ CComObject<CDNSSDService> * object = NULL;\r
+ DNSServiceRef sref = NULL;\r
+ DNSServiceErrorType err = 0;\r
+ HRESULT hr = 0;\r
+\r
+ // Initialize\r
+ *service = NULL;\r
+\r
+ try\r
+ {\r
+ object = new CComObject<CDNSSDService>();\r
+ }\r
+ catch ( ... )\r
+ {\r
+ object = NULL;\r
+ }\r
+\r
+ require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );\r
+ hr = object->FinalConstruct();\r
+ require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown );\r
+ object->AddRef();\r
+\r
+ err = DNSServiceCreateConnection( &sref );\r
+ require_noerr( err, exit );\r
+\r
+ object->SetServiceRef( sref );\r
+\r
+ *service = object;\r
+\r
+exit:\r
+\r
+ if ( err && object )\r
+ {\r
+ object->Release();\r
+ }\r
+\r
+ return err;\r
+}\r
+\r
+\r
+STDMETHODIMP CDNSSD::NATPortMappingCreate(DNSSDFlags flags, ULONG ifIndex, DNSSDAddressFamily addressFamily, DNSSDProtocol protocol, USHORT internalPort, USHORT externalPort, ULONG ttl, INATPortMappingListener *listener, IDNSSDService **service)\r
+{\r
+ CComObject<CDNSSDService> * object = NULL;\r
+ DNSServiceRef sref = NULL;\r
+ DNSServiceProtocol prot = 0;\r
+ DNSServiceErrorType err = 0;\r
+ HRESULT hr = 0;\r
+\r
+ // Initialize\r
+ *service = NULL;\r
+\r
+ try\r
+ {\r
+ object = new CComObject<CDNSSDService>();\r
+ }\r
+ catch ( ... )\r
+ {\r
+ object = NULL;\r
+ }\r
+\r
+ require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );\r
+ hr = object->FinalConstruct();\r
+ require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown );\r
+ object->AddRef();\r
+\r
+ prot = ( addressFamily | protocol );\r
+\r
+ err = DNSServiceNATPortMappingCreate( &sref, flags, ifIndex, prot, internalPort, externalPort, ttl, ( DNSServiceNATPortMappingReply ) &NATPortMappingReply, object );\r
+ require_noerr( err, exit );\r
+\r
+ object->SetServiceRef( sref );\r
+ object->SetListener( listener );\r
+\r
+ err = object->Run();\r
+ require_noerr( err, exit );\r
+\r
+ *service = object;\r
+\r
+exit:\r
+\r
+ if ( err && object )\r
+ {\r
+ object->Release();\r
+ }\r
+\r
+ return err;\r
+}\r
+\r
+\r
+STDMETHODIMP CDNSSD::GetProperty(BSTR prop, VARIANT * value )\r
+{\r
+ std::string propUTF8;\r
+ std::vector< BYTE > byteArray;\r
+ SAFEARRAY * psa = NULL;\r
+ BYTE * pData = NULL;\r
+ uint32_t elems = 0;\r
+ DNSServiceErrorType err = 0;\r
+ BOOL ok = TRUE;\r
+\r
+ // Convert BSTR params to utf8\r
+ ok = BSTRToUTF8( prop, propUTF8 );\r
+ require_action( ok, exit, err = kDNSServiceErr_BadParam );\r
+\r
+ // Setup the byte array\r
+ require_action( V_VT( value ) == ( VT_ARRAY|VT_UI1 ), exit, err = kDNSServiceErr_Unknown );\r
+ psa = V_ARRAY( value );\r
+ require_action( psa, exit, err = kDNSServiceErr_Unknown );\r
+ require_action( SafeArrayGetDim( psa ) == 1, exit, err = kDNSServiceErr_Unknown );\r
+ byteArray.reserve( psa->rgsabound[0].cElements );\r
+ byteArray.assign( byteArray.capacity(), 0 );\r
+ elems = ( uint32_t ) byteArray.capacity();\r
+\r
+ // Call the function and package the return value in the Variant\r
+ err = DNSServiceGetProperty( propUTF8.c_str(), &byteArray[ 0 ], &elems );\r
+ require_noerr( err, exit );\r
+ ok = ByteArrayToVariant( &byteArray[ 0 ], elems, value );\r
+ require_action( ok, exit, err = kDNSSDError_Unknown );\r
+\r
+exit:\r
+\r
+ if ( psa )\r
+ {\r
+ SafeArrayUnaccessData( psa );\r
+ psa = NULL;\r
+ }\r
+\r
+ return err;\r
+}\r
+\r
+\r
+void DNSSD_API
+CDNSSD::DomainEnumReply
+ (
+ DNSServiceRef sdRef,
+ DNSServiceFlags flags,
+ uint32_t ifIndex,
+ DNSServiceErrorType errorCode,
+ const char *replyDomainUTF8,
+ void *context
+ )\r
+{\r
+ CComObject<CDNSSDService> * service;\r
+ int err;\r
+ \r
+ service = ( CComObject< CDNSSDService>* ) context;\r
+ require_action( service, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( !service->Stopped() )\r
+ {\r
+ IDomainListener * listener;\r
+\r
+ listener = ( IDomainListener* ) service->GetListener();\r
+ require_action( listener, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( !errorCode )\r
+ {\r
+ CComBSTR replyDomain;\r
+ \r
+ UTF8ToBSTR( replyDomainUTF8, replyDomain );\r
+\r
+ if ( flags & kDNSServiceFlagsAdd )\r
+ {\r
+ listener->DomainFound( service, ( DNSSDFlags ) flags, ifIndex, replyDomain );\r
+ }\r
+ else\r
+ {\r
+ listener->DomainLost( service, ( DNSSDFlags ) flags, ifIndex, replyDomain );\r
+ }\r
+ }\r
+ else\r
+ {\r
+ listener->EnumDomainsFailed( service, ( DNSSDError ) errorCode );\r
+ }\r
+ }\r
+\r
+exit:\r
+\r
+ return;\r
+}\r
+\r
+\r
+void DNSSD_API
+CDNSSD::BrowseReply
+ (
+ DNSServiceRef sdRef,
+ DNSServiceFlags flags,
+ uint32_t ifIndex,
+ DNSServiceErrorType errorCode,
+ const char *serviceNameUTF8,
+ const char *regTypeUTF8,
+ const char *replyDomainUTF8,
+ void *context
+ )\r
+{\r
+ CComObject<CDNSSDService> * service;\r
+ int err;\r
+ \r
+ service = ( CComObject< CDNSSDService>* ) context;\r
+ require_action( service, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( !service->Stopped() )\r
+ {\r
+ IBrowseListener * listener;\r
+\r
+ listener = ( IBrowseListener* ) service->GetListener();\r
+ require_action( listener, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( !errorCode )\r
+ {\r
+ CComBSTR serviceName;\r
+ CComBSTR regType;\r
+ CComBSTR replyDomain;\r
+ \r
+ UTF8ToBSTR( serviceNameUTF8, serviceName );\r
+ UTF8ToBSTR( regTypeUTF8, regType );\r
+ UTF8ToBSTR( replyDomainUTF8, replyDomain );\r
+\r
+ if ( flags & kDNSServiceFlagsAdd )\r
+ {\r
+ listener->ServiceFound( service, ( DNSSDFlags ) flags, ifIndex, serviceName, regType, replyDomain );\r
+ }\r
+ else\r
+ {\r
+ listener->ServiceLost( service, ( DNSSDFlags ) flags, ifIndex, serviceName, regType, replyDomain );\r
+ }\r
+ }\r
+ else\r
+ {\r
+ listener->BrowseFailed( service, ( DNSSDError ) errorCode );\r
+ }\r
+ }\r
+\r
+exit:\r
+\r
+ return;\r
+}\r
+\r
+\r
+void DNSSD_API\r
+CDNSSD::ResolveReply\r
+ (
+ 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\r
+ )\r
+{\r
+ CComObject<CDNSSDService> * service;\r
+ int err;\r
+ \r
+ service = ( CComObject< CDNSSDService>* ) context;\r
+ require_action( service, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( !service->Stopped() )\r
+ {\r
+ IResolveListener * listener;\r
+\r
+ listener = ( IResolveListener* ) service->GetListener();\r
+ require_action( listener, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( !errorCode )\r
+ {\r
+ CComBSTR fullName;\r
+ CComBSTR hostName;\r
+ CComBSTR regType;\r
+ CComBSTR replyDomain;\r
+ CComObject< CTXTRecord >* record;\r
+ BOOL ok;\r
+\r
+ ok = UTF8ToBSTR( fullNameUTF8, fullName );\r
+ require_action( ok, exit, err = kDNSServiceErr_Unknown );\r
+ ok = UTF8ToBSTR( hostNameUTF8, hostName );\r
+ require_action( ok, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ try\r
+ {\r
+ record = new CComObject<CTXTRecord>();\r
+ }\r
+ catch ( ... )\r
+ {\r
+ record = NULL;\r
+ }\r
+\r
+ require_action( record, exit, err = kDNSServiceErr_NoMemory );\r
+ record->AddRef();\r
+\r
+ char buf[ 64 ];\r
+ sprintf( buf, "txtLen = %d", txtLen );\r
+ OutputDebugStringA( buf );\r
+\r
+ if ( txtLen > 0 )\r
+ {\r
+ record->SetBytes( txtRecord, txtLen );\r
+ }\r
+\r
+ listener->ServiceResolved( service, ( DNSSDFlags ) flags, ifIndex, fullName, hostName, port, record );\r
+ }\r
+ else\r
+ {\r
+ listener->ResolveFailed( service, ( DNSSDError ) errorCode );\r
+ }\r
+ }\r
+\r
+exit:\r
+\r
+ return;\r
+}\r
+\r
+\r
+void DNSSD_API
+CDNSSD::RegisterReply
+ (
+ DNSServiceRef sdRef,
+ DNSServiceFlags flags,
+ DNSServiceErrorType errorCode,
+ const char *serviceNameUTF8,
+ const char *regTypeUTF8,
+ const char *domainUTF8,
+ void *context
+ )\r
+{\r
+ CComObject<CDNSSDService> * service;\r
+ int err;\r
+ \r
+ service = ( CComObject< CDNSSDService>* ) context;\r
+ require_action( service, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( !service->Stopped() )\r
+ {\r
+ IRegisterListener * listener;\r
+\r
+ listener = ( IRegisterListener* ) service->GetListener();\r
+ require_action( listener, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( !errorCode )\r
+ {\r
+ CComBSTR serviceName;\r
+ CComBSTR regType;\r
+ CComBSTR domain;\r
+ BOOL ok;\r
+\r
+ ok = UTF8ToBSTR( serviceNameUTF8, serviceName );\r
+ require_action( ok, exit, err = kDNSServiceErr_Unknown );\r
+ ok = UTF8ToBSTR( regTypeUTF8, regType );\r
+ require_action( ok, exit, err = kDNSServiceErr_Unknown );\r
+ ok = UTF8ToBSTR( domainUTF8, domain );\r
+ require_action( ok, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ listener->ServiceRegistered( service, ( DNSSDFlags ) flags, serviceName, regType, domain );\r
+ }\r
+ else\r
+ {\r
+ listener->ServiceRegisterFailed( service, ( DNSSDError ) errorCode );\r
+ }\r
+ }\r
+\r
+exit:\r
+\r
+ return;\r
+}\r
+\r
+\r
+void DNSSD_API
+CDNSSD::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
+ )\r
+{\r
+ CComObject<CDNSSDService> * service;\r
+ int err;\r
+ \r
+ service = ( CComObject< CDNSSDService>* ) context;\r
+ require_action( service, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( !service->Stopped() )\r
+ {\r
+ IQueryRecordListener * listener;\r
+\r
+ listener = ( IQueryRecordListener* ) service->GetListener();\r
+ require_action( listener, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( !errorCode )\r
+ {\r
+ CComBSTR fullName;\r
+ VARIANT var;\r
+ BOOL ok;\r
+\r
+ ok = UTF8ToBSTR( fullNameUTF8, fullName );\r
+ require_action( ok, exit, err = kDNSServiceErr_Unknown );\r
+ ok = ByteArrayToVariant( rdata, rdlen, &var );\r
+ require_action( ok, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ listener->QueryRecordAnswered( service, ( DNSSDFlags ) flags, ifIndex, fullName, ( DNSSDRRType ) rrtype, ( DNSSDRRClass ) rrclass, var, ttl );\r
+ }\r
+ else\r
+ {\r
+ listener->QueryRecordFailed( service, ( DNSSDError ) errorCode );\r
+ }\r
+ }\r
+\r
+exit:\r
+\r
+ return;\r
+}\r
+\r
+\r
+void DNSSD_API
+CDNSSD::GetAddrInfoReply
+ (
+ DNSServiceRef sdRef,
+ DNSServiceFlags flags,
+ uint32_t ifIndex,
+ DNSServiceErrorType errorCode,
+ const char *hostNameUTF8,
+ const struct sockaddr *rawAddress,
+ uint32_t ttl,
+ void *context
+ )\r
+{\r
+ CComObject<CDNSSDService> * service;\r
+ int err;\r
+ \r
+ service = ( CComObject< CDNSSDService>* ) context;\r
+ require_action( service, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( !service->Stopped() )\r
+ {\r
+ IGetAddrInfoListener * listener;\r
+\r
+ listener = ( IGetAddrInfoListener* ) service->GetListener();\r
+ require_action( listener, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( !errorCode )\r
+ {\r
+ CComBSTR hostName;\r
+ DWORD sockaddrLen;\r
+ DNSSDAddressFamily addressFamily;\r
+ char addressUTF8[INET6_ADDRSTRLEN];\r
+ DWORD addressLen = sizeof( addressUTF8 );\r
+ CComBSTR address;\r
+ BOOL ok;\r
+\r
+ ok = UTF8ToBSTR( hostNameUTF8, hostName );\r
+ require_action( ok, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ switch ( rawAddress->sa_family )\r
+ {\r
+ case AF_INET:\r
+ {\r
+ addressFamily = kDNSSDAddressFamily_IPv4;\r
+ sockaddrLen = sizeof( sockaddr_in );\r
+ }\r
+ break;\r
+\r
+ case AF_INET6:\r
+ {\r
+ addressFamily = kDNSSDAddressFamily_IPv6;\r
+ sockaddrLen = sizeof( sockaddr_in6 );\r
+ }\r
+ break;\r
+ }\r
+\r
+ err = WSAAddressToStringA( ( LPSOCKADDR ) rawAddress, sockaddrLen, NULL, addressUTF8, &addressLen );\r
+ require_noerr( err, exit );\r
+ ok = UTF8ToBSTR( addressUTF8, address );\r
+ require_action( ok, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ listener->GetAddrInfoReply( service, ( DNSSDFlags ) flags, ifIndex, hostName, addressFamily, address, ttl );\r
+ }\r
+ else\r
+ {\r
+ listener->GetAddrInfoFailed( service, ( DNSSDError ) errorCode );\r
+ }\r
+ }\r
+\r
+exit:\r
+\r
+ return;\r
+}\r
+\r
+\r
+void DNSSD_API
+CDNSSD::NATPortMappingReply
+ (
+ DNSServiceRef sdRef,
+ DNSServiceFlags flags,
+ uint32_t ifIndex,
+ DNSServiceErrorType errorCode,
+ uint32_t externalAddress, /* four byte IPv4 address in network byte order */
+ DNSServiceProtocol protocol,
+ uint16_t internalPort,
+ uint16_t externalPort, /* may be different than the requested port */
+ uint32_t ttl, /* may be different than the requested ttl */
+ void *context
+ )\r
+{\r
+ CComObject<CDNSSDService> * service;\r
+ int err;\r
+ \r
+ service = ( CComObject< CDNSSDService>* ) context;\r
+ require_action( service, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( !service->Stopped() )\r
+ {\r
+ INATPortMappingListener * listener;\r
+\r
+ listener = ( INATPortMappingListener* ) service->GetListener();\r
+ require_action( listener, exit, err = kDNSServiceErr_Unknown );\r
+\r
+ if ( !errorCode )\r
+ {\r
+ listener->MappingCreated( service, ( DNSSDFlags ) flags, ifIndex, externalAddress, ( DNSSDAddressFamily ) ( protocol & 0x8 ), ( DNSSDProtocol ) ( protocol & 0x80 ), internalPort, externalPort, ttl );\r
+ }\r
+ else\r
+ {\r
+ listener->MappingFailed( service, ( DNSSDError ) errorCode );\r
+ }\r
+ }\r
+\r
+exit:\r
+\r
+ return;\r
+}\r
+\r