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