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 CTXTRecord::SetValue(BSTR key, VARIANT value) { std::string keyUTF8; ByteArray valueArray; BOOL ok; DNSServiceErrorType err; HRESULT hr = S_OK; if ( !m_allocated ) { TXTRecordCreate( &m_tref, 0, NULL ); m_allocated = TRUE; } ok = BSTRToUTF8( key, keyUTF8 ); require_action( ok, exit, hr = S_FALSE ); ok = VariantToByteArray( &value, valueArray ); require_action( ok, exit, hr = S_FALSE ); err = TXTRecordSetValue( &m_tref, keyUTF8.c_str(), ( uint8_t ) valueArray.size(), &valueArray[ 0 ] ); require_action( !err, exit, hr = S_FALSE ); exit: return hr; }
STDMETHODIMP CTXTRecord::GetValueForKey(BSTR key, VARIANT* value) { std::string keyUTF8; const void * rawValue; uint8_t rawValueLen; BOOL ok = TRUE; HRESULT hr = S_OK; VariantClear( value ); if ( m_byteArray.size() > 0 ) { ok = BSTRToUTF8( key, keyUTF8 ); require_action( ok, exit, hr = S_FALSE ); rawValue = TXTRecordGetValuePtr( ( uint16_t ) m_byteArray.size(), &m_byteArray[ 0 ], keyUTF8.c_str(), &rawValueLen ); if ( rawValue ) { ok = ByteArrayToVariant( rawValue, rawValueLen, value ); require_action( ok, exit, hr = S_FALSE ); } } exit: return hr; }
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::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; }
// CJavaObject STDMETHODIMP CJavaObject::GetDispID(BSTR name, DWORD options, DISPID* dispId){ std::string nameString = BSTRToUTF8(name); // toString is the only non-numeric dispid we recognize if (nameString == "toString") { *dispId = DISPID_TOSTRING; return S_OK; } char* lastChar; int d = strtol(nameString.c_str(), &lastChar, 10); if (*lastChar != '\0' || d < 0) { Debug::log(Debug::Error) << "Unable to get dispatch id for " << nameString << Debug::flush; // Set to unknown name in the case of an error *dispId = DISPID_UNKNOWN; return DISP_E_UNKNOWNNAME; } *dispId = d; return S_OK; }
STDMETHODIMP CTXTRecord::RemoveValue(BSTR key) { HRESULT hr = S_OK; if ( m_allocated ) { std::string keyUTF8; BOOL ok; DNSServiceErrorType err; ok = BSTRToUTF8( key, keyUTF8 ); require_action( ok, exit, hr = S_FALSE ); err = TXTRecordRemoveValue( &m_tref, keyUTF8.c_str() ); require_action( !err, exit, hr = S_FALSE ); } exit: return hr; }
STDMETHODIMP CTXTRecord::ContainsKey(BSTR key, VARIANT_BOOL* retval) { std::string keyUTF8; int ret = 0; HRESULT err = S_OK; if ( m_byteArray.size() > 0 ) { BOOL ok; ok = BSTRToUTF8( key, keyUTF8 ); require_action( ok, exit, err = S_FALSE ); ret = TXTRecordContainsKey( ( uint16_t ) m_byteArray.size(), &m_byteArray[ 0 ], keyUTF8.c_str() ); } *retval = ( ret ) ? VARIANT_TRUE : VARIANT_FALSE; exit: 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; }
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; }