| // 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; |
| } |
| |