diff options
Diffstat (limited to 'mDNSResponder/mDNSWindows/DLLX/DNSSD.cpp')
-rwxr-xr-x | mDNSResponder/mDNSWindows/DLLX/DNSSD.cpp | 892 |
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; +} + |