diff options
Diffstat (limited to 'mDNSResponder/mDNSWindows/DLL.NET/dnssd_NET.cpp')
-rwxr-xr-x | mDNSResponder/mDNSWindows/DLL.NET/dnssd_NET.cpp | 1234 |
1 files changed, 1234 insertions, 0 deletions
diff --git a/mDNSResponder/mDNSWindows/DLL.NET/dnssd_NET.cpp b/mDNSResponder/mDNSWindows/DLL.NET/dnssd_NET.cpp new file mode 100755 index 00000000..3e22146e --- /dev/null +++ b/mDNSResponder/mDNSWindows/DLL.NET/dnssd_NET.cpp @@ -0,0 +1,1234 @@ +/* -*- Mode: C; tab-width: 4 -*- + * + * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// This is the main DLL file. + +#include "stdafx.h" + +#include "dnssd_NET.h" +#include "DebugServices.h" +#include "PString.h" + + +using namespace System::Net::Sockets; +using namespace System::Diagnostics; +using namespace Apple; +using namespace Apple::DNSSD; + + +//=========================================================================================================================== +// Constants +//=========================================================================================================================== + +#define DEBUG_NAME "[dnssd.NET] " + +// +// ConvertToString +// +static String* +ConvertToString(const char * utf8String) +{ + return __gc new String(utf8String, 0, strlen(utf8String), __gc new UTF8Encoding(true, true)); +} + + +// +// class ServiceRef +// +// ServiceRef serves as the base class for all DNSService operations. +// +// It manages the DNSServiceRef, and implements processing the +// result +// +ServiceRef::ServiceRef(Object * callback) +: + m_bDisposed(false), + m_callback(callback), + m_thread(NULL) +{ + m_impl = new ServiceRefImpl(this); +} + + +ServiceRef::~ServiceRef() +{ +} + + +// +// StartThread +// +// Starts the main processing thread +// +void +ServiceRef::StartThread() +{ + check( m_impl != NULL ); + + m_impl->SetupEvents(); + + m_thread = new Thread(new ThreadStart(this, &Apple::DNSSD::ServiceRef::ProcessingThread)); + m_thread->Name = S"DNSService Thread"; + m_thread->IsBackground = true; + + m_thread->Start(); +} + + +// +// ProcessingThread +// +// The Thread class can only invoke methods in MC++ types. So we +// make a ProcessingThread method that forwards to the impl +// +void +ServiceRef::ProcessingThread() +{ + m_impl->ProcessingThread(); +} + + +// +// Dispose +// +// Calls impl-Dispose(). This ultimately will call DNSServiceRefDeallocate() +// +void +ServiceRef::Dispose() +{ + check(m_impl != NULL); + check(m_bDisposed == false); + + if (!m_bDisposed) + { + m_bDisposed = true; + + // + // Call Dispose. This won't call DNSServiceRefDeallocate() + // necessarily. It depends on what thread this is being + // called in. + // + m_impl->Dispose(); + m_impl = NULL; + + m_thread = NULL; + + GC::SuppressFinalize(this); + } +} + + +// +// EnumerateDomainsDispatch +// +// Dispatch a reply to the delegate. +// +void +ServiceRef::EnumerateDomainsDispatch + ( + ServiceFlags flags, + int interfaceIndex, + ErrorCode errorCode, + String * replyDomain + ) +{ + if ((m_callback != NULL) && (m_impl != NULL)) + { + DNSService::EnumerateDomainsReply * OnEnumerateDomainsReply = static_cast<DNSService::EnumerateDomainsReply*>(m_callback); + OnEnumerateDomainsReply(this, flags, interfaceIndex, errorCode, replyDomain); + } +} + + +// +// RegisterDispatch +// +// Dispatch a reply to the delegate. +// +void +ServiceRef::RegisterDispatch + ( + ServiceFlags flags, + ErrorCode errorCode, + String * name, + String * regtype, + String * domain + ) +{ + if ((m_callback != NULL) && (m_impl != NULL)) + { + DNSService::RegisterReply * OnRegisterReply = static_cast<DNSService::RegisterReply*>(m_callback); + OnRegisterReply(this, flags, errorCode, name, regtype, domain); + } +} + + +// +// BrowseDispatch +// +// Dispatch a reply to the delegate. +// +void +ServiceRef::BrowseDispatch + ( + ServiceFlags flags, + int interfaceIndex, + ErrorCode errorCode, + String * serviceName, + String * regtype, + String * replyDomain + ) +{ + if ((m_callback != NULL) && (m_impl != NULL)) + { + DNSService::BrowseReply * OnBrowseReply = static_cast<DNSService::BrowseReply*>(m_callback); + OnBrowseReply(this, flags, interfaceIndex, errorCode, serviceName, regtype, replyDomain); + } +} + + +// +// ResolveDispatch +// +// Dispatch a reply to the delegate. +// +void +ServiceRef::ResolveDispatch + ( + ServiceFlags flags, + int interfaceIndex, + ErrorCode errorCode, + String * fullname, + String * hosttarget, + int port, + Byte txtRecord[] + ) +{ + if ((m_callback != NULL) && (m_impl != NULL)) + { + DNSService::ResolveReply * OnResolveReply = static_cast<DNSService::ResolveReply*>(m_callback); + OnResolveReply(this, flags, interfaceIndex, errorCode, fullname, hosttarget, port, txtRecord); + } +} + + +// +// RegisterRecordDispatch +// +// Dispatch a reply to the delegate. +// +void +ServiceRef::RegisterRecordDispatch + ( + ServiceFlags flags, + ErrorCode errorCode, + RecordRef * record + ) +{ + if ((m_callback != NULL) && (m_impl != NULL)) + { + DNSService::RegisterRecordReply * OnRegisterRecordReply = static_cast<DNSService::RegisterRecordReply*>(m_callback); + OnRegisterRecordReply(this, flags, errorCode, record); + } +} + + +// +// QueryRecordDispatch +// +// Dispatch a reply to the delegate. +// +void +ServiceRef::QueryRecordDispatch + ( + ServiceFlags flags, + int interfaceIndex, + ErrorCode errorCode, + String * fullname, + int rrtype, + int rrclass, + Byte rdata[], + int ttl + ) +{ + if ((m_callback != NULL) && (m_impl != NULL)) + { + DNSService::QueryRecordReply * OnQueryRecordReply = static_cast<DNSService::QueryRecordReply*>(m_callback); + OnQueryRecordReply(this, flags, interfaceIndex, errorCode, fullname, rrtype, rrclass, rdata, ttl); + } +} + + +// +// ServiceRefImpl::ServiceRefImpl() +// +// Constructs a new ServiceRefImpl. We save the pointer to our enclosing +// class in a gcroot handle. This satisfies the garbage collector as +// the outer class is a managed type +// +ServiceRef::ServiceRefImpl::ServiceRefImpl(ServiceRef * outer) +: + m_socketEvent(NULL), + m_stopEvent(NULL), + m_disposed(false), + m_outer(outer), + m_ref(NULL) +{ + m_threadId = GetCurrentThreadId(); +} + + +// +// ServiceRefImpl::~ServiceRefImpl() +// +// Deallocate all resources associated with the ServiceRefImpl +// +ServiceRef::ServiceRefImpl::~ServiceRefImpl() +{ + if (m_socketEvent != NULL) + { + CloseHandle(m_socketEvent); + m_socketEvent = NULL; + } + + if (m_stopEvent != NULL) + { + CloseHandle(m_stopEvent); + m_stopEvent = NULL; + } + + if (m_ref != NULL) + { + DNSServiceRefDeallocate(m_ref); + m_ref = NULL; + } +} + + +// +// ServiceRefImpl::SetupEvents() +// +// Setup the events necessary to manage multi-threaded dispatch +// of DNSService Events +// +void +ServiceRef::ServiceRefImpl::SetupEvents() +{ + check(m_ref != NULL); + + m_socket = (SOCKET) DNSServiceRefSockFD(m_ref); + check(m_socket != INVALID_SOCKET); + + m_socketEvent = CreateEvent(NULL, 0, 0, NULL); + + if (m_socketEvent == NULL) + { + throw new DNSServiceException(Unknown); + } + + int err = WSAEventSelect(m_socket, m_socketEvent, FD_READ|FD_CLOSE); + + if (err != 0) + { + throw new DNSServiceException(Unknown); + } + + m_stopEvent = CreateEvent(NULL, 0, 0, NULL); + + if (m_stopEvent == NULL) + { + throw new DNSServiceException(Unknown); + } +} + + +// +// ServiceRefImpl::ProcessingThread() +// +// Wait for socket events on the DNSServiceRefSockFD(). Also wait +// for stop events +// +void +ServiceRef::ServiceRefImpl::ProcessingThread() +{ + check( m_socketEvent != NULL ); + check( m_stopEvent != NULL ); + check( m_ref != NULL ); + + HANDLE handles[2]; + + handles[0] = m_socketEvent; + handles[1] = m_stopEvent; + + while (m_disposed == false) + { + int ret = WaitForMultipleObjects(2, handles, FALSE, INFINITE); + + // + // it's a socket event + // + if (ret == WAIT_OBJECT_0) + { + DNSServiceProcessResult(m_ref); + } + // + // else it's a stop event + // + else if (ret == WAIT_OBJECT_0 + 1) + { + break; + } + else + { + // + // unexpected wait result + // + dlog( kDebugLevelWarning, DEBUG_NAME "%s: unexpected wait result (result=0x%08X)\n", __ROUTINE__, ret ); + } + } + + delete this; +} + + +// +// ServiceRefImpl::Dispose() +// +// Calls DNSServiceRefDeallocate() +// +void +ServiceRef::ServiceRefImpl::Dispose() +{ + OSStatus err; + BOOL ok; + + check(m_disposed == false); + + m_disposed = true; + + ok = SetEvent(m_stopEvent); + err = translate_errno( ok, (OSStatus) GetLastError(), kUnknownErr ); + require_noerr( err, exit ); + +exit: + + return; +} + + +// +// ServiceRefImpl::EnumerateDomainsCallback() +// +// This is the callback from dnssd.dll. We pass this up to our outer, managed type +// +void DNSSD_API +ServiceRef::ServiceRefImpl::EnumerateDomainsCallback + ( + DNSServiceRef sdRef, + DNSServiceFlags flags, + uint32_t interfaceIndex, + DNSServiceErrorType errorCode, + const char * replyDomain, + void * context + ) +{ + ServiceRef::ServiceRefImpl * self = static_cast<ServiceRef::ServiceRefImpl*>(context); + + check( self != NULL ); + check( self->m_outer != NULL ); + + if (self->m_disposed == false) + { + self->m_outer->EnumerateDomainsDispatch((ServiceFlags) flags, interfaceIndex, (ErrorCode) errorCode, ConvertToString(replyDomain)); + } +} + + +// +// ServiceRefImpl::RegisterCallback() +// +// This is the callback from dnssd.dll. We pass this up to our outer, managed type +// +void DNSSD_API +ServiceRef::ServiceRefImpl::RegisterCallback + ( + DNSServiceRef sdRef, + DNSServiceFlags flags, + DNSServiceErrorType errorCode, + const char * name, + const char * regtype, + const char * domain, + void * context + ) +{ + ServiceRef::ServiceRefImpl * self = static_cast<ServiceRef::ServiceRefImpl*>(context); + + check( self != NULL ); + check( self->m_outer != NULL ); + + if (self->m_disposed == false) + { + self->m_outer->RegisterDispatch((ServiceFlags) flags, (ErrorCode) errorCode, ConvertToString(name), ConvertToString(regtype), ConvertToString(domain)); + } +} + + +// +// ServiceRefImpl::BrowseCallback() +// +// This is the callback from dnssd.dll. We pass this up to our outer, managed type +// +void DNSSD_API +ServiceRef::ServiceRefImpl::BrowseCallback + ( + DNSServiceRef sdRef, + DNSServiceFlags flags, + uint32_t interfaceIndex, + DNSServiceErrorType errorCode, + const char * serviceName, + const char * regtype, + const char * replyDomain, + void * context + ) +{ + ServiceRef::ServiceRefImpl * self = static_cast<ServiceRef::ServiceRefImpl*>(context); + + check( self != NULL ); + check( self->m_outer != NULL ); + + if (self->m_disposed == false) + { + self->m_outer->BrowseDispatch((ServiceFlags) flags, interfaceIndex, (ErrorCode) errorCode, ConvertToString(serviceName), ConvertToString(regtype), ConvertToString(replyDomain)); + } +} + + +// +// ServiceRefImpl::ResolveCallback() +// +// This is the callback from dnssd.dll. We pass this up to our outer, managed type +// +void DNSSD_API +ServiceRef::ServiceRefImpl::ResolveCallback + ( + DNSServiceRef sdRef, + DNSServiceFlags flags, + uint32_t interfaceIndex, + DNSServiceErrorType errorCode, + const char * fullname, + const char * hosttarget, + uint16_t notAnIntPort, + uint16_t txtLen, + const char * txtRecord, + void * context + ) +{ + ServiceRef::ServiceRefImpl * self = static_cast<ServiceRef::ServiceRefImpl*>(context); + + check( self != NULL ); + check( self->m_outer != NULL ); + + if (self->m_disposed == false) + { + Byte txtRecordBytes[]; + + txtRecordBytes = NULL; + + if (txtLen > 0) + { + // + // copy raw memory into managed byte array + // + txtRecordBytes = new Byte[txtLen]; + Byte __pin * p = &txtRecordBytes[0]; + memcpy(p, txtRecord, txtLen); + } + + self->m_outer->ResolveDispatch((ServiceFlags) flags, interfaceIndex, (ErrorCode) errorCode, ConvertToString(fullname), ConvertToString(hosttarget), ntohs(notAnIntPort), txtRecordBytes); + } +} + + +// +// ServiceRefImpl::RegisterRecordCallback() +// +// This is the callback from dnssd.dll. We pass this up to our outer, managed type +// +void DNSSD_API +ServiceRef::ServiceRefImpl::RegisterRecordCallback + ( + DNSServiceRef sdRef, + DNSRecordRef rrRef, + DNSServiceFlags flags, + DNSServiceErrorType errorCode, + void * context + ) +{ + ServiceRef::ServiceRefImpl * self = static_cast<ServiceRef::ServiceRefImpl*>(context); + + check( self != NULL ); + check( self->m_outer != NULL ); + + if (self->m_disposed == false) + { + RecordRef * record = NULL; + + if (errorCode == 0) + { + record = new RecordRef; + + record->m_impl->m_ref = rrRef; + } + + self->m_outer->RegisterRecordDispatch((ServiceFlags) flags, (ErrorCode) errorCode, record); + } +} + + +// +// ServiceRefImpl::QueryRecordCallback() +// +// This is the callback from dnssd.dll. We pass this up to our outer, managed type +// +void DNSSD_API +ServiceRef::ServiceRefImpl::QueryRecordCallback + ( + DNSServiceRef DNSServiceRef, + DNSServiceFlags flags, + uint32_t interfaceIndex, + DNSServiceErrorType errorCode, + const char * fullname, + uint16_t rrtype, + uint16_t rrclass, + uint16_t rdlen, + const void * rdata, + uint32_t ttl, + void * context + ) +{ + ServiceRef::ServiceRefImpl * self = static_cast<ServiceRef::ServiceRefImpl*>(context); + + check( self != NULL ); + check( self->m_outer != NULL ); + + if (self->m_disposed == false) + { + Byte rdataBytes[]; + + if (rdlen) + { + rdataBytes = new Byte[rdlen]; + Byte __pin * p = &rdataBytes[0]; + memcpy(p, rdata, rdlen); + } + + self->m_outer->QueryRecordDispatch((ServiceFlags) flags, (int) interfaceIndex, (ErrorCode) errorCode, ConvertToString(fullname), rrtype, rrclass, rdataBytes, ttl); + } +} + + +/* + * EnumerateDomains() + * + * This maps to DNSServiceEnumerateDomains(). Returns an + * initialized ServiceRef on success, throws an exception + * on failure. + */ +ServiceRef* +DNSService::EnumerateDomains + ( + int flags, + int interfaceIndex, + EnumerateDomainsReply * callback + ) +{ + ServiceRef * sdRef = new ServiceRef(callback); + int err; + + err = DNSServiceEnumerateDomains(&sdRef->m_impl->m_ref, flags, interfaceIndex, ServiceRef::ServiceRefImpl::EnumerateDomainsCallback, sdRef->m_impl); + + if (err != 0) + { + throw new DNSServiceException(err); + } + + sdRef->StartThread(); + + return sdRef; +} + + +/* + * Register() + * + * This maps to DNSServiceRegister(). Returns an + * initialized ServiceRef on success, throws an exception + * on failure. + */ +ServiceRef* +DNSService::Register + ( + int flags, + int interfaceIndex, + String * name, + String * regtype, + String * domain, + String * host, + int port, + Byte txtRecord[], + RegisterReply * callback + ) +{ + ServiceRef * sdRef = new ServiceRef(callback); + PString * pName = new PString(name); + PString * pType = new PString(regtype); + PString * pDomain = new PString(domain); + PString * pHost = new PString(host); + int len = 0; + Byte __pin * p = NULL; + void * v = NULL; + + if ((txtRecord != NULL) && (txtRecord->Length > 0)) + { + len = txtRecord->Length; + p = &txtRecord[0]; + v = (void*) p; + } + + int err = DNSServiceRegister(&sdRef->m_impl->m_ref, flags, interfaceIndex, pName->c_str(), pType->c_str(), pDomain->c_str(), pHost->c_str(), htons(port), len, v, ServiceRef::ServiceRefImpl::RegisterCallback, sdRef->m_impl ); + + if (err != 0) + { + throw new DNSServiceException(err); + } + + sdRef->StartThread(); + + return sdRef; +} + + +/* + * AddRecord() + * + * This maps to DNSServiceAddRecord(). Returns an + * initialized ServiceRef on success, throws an exception + * on failure. + */ +RecordRef* +DNSService::AddRecord + ( + ServiceRef * sdRef, + int flags, + int rrtype, + Byte rdata[], + int ttl + ) +{ + int len = 0; + Byte __pin * p = NULL; + void * v = NULL; + + if ((rdata != NULL) && (rdata->Length > 0)) + { + len = rdata->Length; + p = &rdata[0]; + v = (void*) p; + } + + RecordRef * record = new RecordRef; + + int err = DNSServiceAddRecord(sdRef->m_impl->m_ref, &record->m_impl->m_ref, flags, rrtype, len, v, ttl); + + if (err != 0) + { + throw new DNSServiceException(err); + } + + return record; +} + + +/* + * UpdateRecord() + * + * This maps to DNSServiceUpdateRecord(). Returns an + * initialized ServiceRef on success, throws an exception + * on failure. + */ +void +DNSService::UpdateRecord + ( + ServiceRef * sdRef, + RecordRef * record, + int flags, + Byte rdata[], + int ttl + ) +{ + int len = 0; + Byte __pin * p = NULL; + void * v = NULL; + + if ((rdata != NULL) && (rdata->Length > 0)) + { + len = rdata->Length; + p = &rdata[0]; + v = (void*) p; + } + + int err = DNSServiceUpdateRecord(sdRef->m_impl->m_ref, record ? record->m_impl->m_ref : NULL, flags, len, v, ttl); + + if (err != 0) + { + throw new DNSServiceException(err); + } +} + + +/* + * RemoveRecord() + * + * This maps to DNSServiceRemoveRecord(). Returns an + * initialized ServiceRef on success, throws an exception + * on failure. + */ +void +DNSService::RemoveRecord + ( + ServiceRef * sdRef, + RecordRef * record, + int flags + ) +{ + int err = DNSServiceRemoveRecord(sdRef->m_impl->m_ref, record->m_impl->m_ref, flags); + + if (err != 0) + { + throw new DNSServiceException(err); + } +} + + +/* + * Browse() + * + * This maps to DNSServiceBrowse(). Returns an + * initialized ServiceRef on success, throws an exception + * on failure. + */ +ServiceRef* +DNSService::Browse + ( + int flags, + int interfaceIndex, + String * regtype, + String * domain, + BrowseReply * callback + ) +{ + ServiceRef * sdRef = new ServiceRef(callback); + PString * pType = new PString(regtype); + PString * pDomain = new PString(domain); + + int err = DNSServiceBrowse(&sdRef->m_impl->m_ref, flags, interfaceIndex, pType->c_str(), pDomain->c_str(),(DNSServiceBrowseReply) ServiceRef::ServiceRefImpl::BrowseCallback, sdRef->m_impl); + + if (err != 0) + { + throw new DNSServiceException(err); + } + + sdRef->StartThread(); + + return sdRef; +} + + +/* + * Resolve() + * + * This maps to DNSServiceResolve(). Returns an + * initialized ServiceRef on success, throws an exception + * on failure. + */ +ServiceRef* +DNSService::Resolve + ( + int flags, + int interfaceIndex, + String * name, + String * regtype, + String * domain, + ResolveReply * callback + ) +{ + ServiceRef * sdRef = new ServiceRef(callback); + PString * pName = new PString(name); + PString * pType = new PString(regtype); + PString * pDomain = new PString(domain); + + int err = DNSServiceResolve(&sdRef->m_impl->m_ref, flags, interfaceIndex, pName->c_str(), pType->c_str(), pDomain->c_str(),(DNSServiceResolveReply) ServiceRef::ServiceRefImpl::ResolveCallback, sdRef->m_impl); + + if (err != 0) + { + throw new DNSServiceException(err); + } + + sdRef->StartThread(); + + return sdRef; +} + + +/* + * CreateConnection() + * + * This maps to DNSServiceCreateConnection(). Returns an + * initialized ServiceRef on success, throws an exception + * on failure. + */ +ServiceRef* +DNSService::CreateConnection + ( + RegisterRecordReply * callback + ) +{ + ServiceRef * sdRef = new ServiceRef(callback); + + int err = DNSServiceCreateConnection(&sdRef->m_impl->m_ref); + + if (err != 0) + { + throw new DNSServiceException(err); + } + + sdRef->StartThread(); + + return sdRef; +} + + +/* + * RegisterRecord() + * + * This maps to DNSServiceRegisterRecord(). Returns an + * initialized ServiceRef on success, throws an exception + * on failure. + */ + +RecordRef* +DNSService::RegisterRecord + ( + ServiceRef * sdRef, + ServiceFlags flags, + int interfaceIndex, + String * fullname, + int rrtype, + int rrclass, + Byte rdata[], + int ttl + ) +{ + RecordRef * record = new RecordRef; + int len = 0; + Byte __pin * p = NULL; + void * v = NULL; + + PString * pFullname = new PString(fullname); + + if ((rdata != NULL) && (rdata->Length > 0)) + { + len = rdata->Length; + p = &rdata[0]; + v = (void*) p; + } + + int err = DNSServiceRegisterRecord(sdRef->m_impl->m_ref, &record->m_impl->m_ref, flags, interfaceIndex, pFullname->c_str(), rrtype, rrclass, len, v, ttl, (DNSServiceRegisterRecordReply) ServiceRef::ServiceRefImpl::RegisterRecordCallback, sdRef->m_impl); + + if (err != 0) + { + throw new DNSServiceException(err); + } + + return record; +} + +/* + * QueryRecord() + * + * This maps to DNSServiceQueryRecord(). Returns an + * initialized ServiceRef on success, throws an exception + * on failure. + */ +ServiceRef* +DNSService::QueryRecord + ( + ServiceFlags flags, + int interfaceIndex, + String * fullname, + int rrtype, + int rrclass, + QueryRecordReply * callback + ) +{ + ServiceRef * sdRef = new ServiceRef(callback); + PString * pFullname = new PString(fullname); + + int err = DNSServiceQueryRecord(&sdRef->m_impl->m_ref, flags, interfaceIndex, pFullname->c_str(), rrtype, rrclass, (DNSServiceQueryRecordReply) ServiceRef::ServiceRefImpl::QueryRecordCallback, sdRef->m_impl); + + if (err != 0) + { + throw new DNSServiceException(err); + } + + sdRef->StartThread(); + + return sdRef; +} + + +/* + * ReconfirmRecord() + * + * This maps to DNSServiceReconfirmRecord(). Returns an + * initialized ServiceRef on success, throws an exception + * on failure. + */ +void +DNSService::ReconfirmRecord + ( + ServiceFlags flags, + int interfaceIndex, + String * fullname, + int rrtype, + int rrclass, + Byte rdata[] + ) +{ + int len = 0; + Byte __pin * p = NULL; + void * v = NULL; + + PString * pFullname = new PString(fullname); + + if ((rdata != NULL) && (rdata->Length > 0)) + { + len = rdata->Length; + p = &rdata[0]; + v = (void*) p; + } + + DNSServiceReconfirmRecord(flags, interfaceIndex, pFullname->c_str(), rrtype, rrclass, len, v); +} + + +void +TextRecord::SetValue + ( + String * key, + Byte value[] /* may be NULL */ + ) +{ + PString * pKey = new PString(key); + int len = 0; + Byte __pin * p = NULL; + void * v = NULL; + DNSServiceErrorType err; + + if (value && (value->Length > 0)) + { + len = value->Length; + p = &value[0]; + v = (void*) p; + } + + err = TXTRecordSetValue(&m_impl->m_ref, pKey->c_str(), len, v); + + if (err != 0) + { + throw new DNSServiceException(err); + } +} + + +void +TextRecord::RemoveValue + ( + String * key + ) +{ + PString * pKey = new PString(key); + DNSServiceErrorType err; + + err = TXTRecordRemoveValue(&m_impl->m_ref, pKey->c_str()); + + if (err != 0) + { + throw new DNSServiceException(err); + } +} + + +int +TextRecord::GetLength + ( + ) +{ + return TXTRecordGetLength(&m_impl->m_ref); +} + + +Byte +TextRecord::GetBytes + ( + ) __gc[] +{ + const void * noGCBytes = NULL; + Byte gcBytes[] = NULL; + + noGCBytes = TXTRecordGetBytesPtr(&m_impl->m_ref); + int len = GetLength(); + + if (noGCBytes && len) + { + gcBytes = new Byte[len]; + Byte __pin * p = &gcBytes[0]; + memcpy(p, noGCBytes, len); + } + + return gcBytes; +} + + +bool +TextRecord::ContainsKey + ( + Byte txtRecord[], + String * key + ) +{ + PString * pKey = new PString(key); + Byte __pin * p = &txtRecord[0]; + + return (TXTRecordContainsKey(txtRecord->Length, p, pKey->c_str()) > 0) ? true : false; +} + + +Byte +TextRecord::GetValueBytes + ( + Byte txtRecord[], + String * key + ) __gc[] +{ + uint8_t valueLen; + Byte ret[] = NULL; + PString * pKey = new PString(key); + Byte __pin * p1 = &txtRecord[0]; + const void * v; + + v = TXTRecordGetValuePtr(txtRecord->Length, p1, pKey->c_str(), &valueLen); + + if (v != NULL) + { + ret = new Byte[valueLen]; + Byte __pin * p2 = &ret[0]; + + memcpy(p2, v, valueLen); + } + + return ret; +} + + +int +TextRecord::GetCount + ( + Byte txtRecord[] + ) +{ + Byte __pin * p = &txtRecord[0]; + + return TXTRecordGetCount(txtRecord->Length, p); +} + + +Byte +TextRecord::GetItemAtIndex + ( + Byte txtRecord[], + int index, + [Out] String ** key + ) __gc[] +{ + char keyBuf[255]; + uint8_t keyBufLen = 255; + uint8_t valueLen; + void * value; + Byte ret[] = NULL; + DNSServiceErrorType err; + Byte __pin * p1 = &txtRecord[0]; + + + err = TXTRecordGetItemAtIndex(txtRecord->Length, p1, index, keyBufLen, keyBuf, &valueLen, (const void**) &value); + + if (err != 0) + { + throw new DNSServiceException(err); + } + + *key = ConvertToString(keyBuf); + + if (valueLen) + { + ret = new Byte[valueLen]; + Byte __pin * p2 = &ret[0]; + + memcpy(p2, value, valueLen); + } + + return ret; +} + + +// +// DNSServiceException::DNSServiceException() +// +// Constructs an exception with an error code +// +DNSServiceException::DNSServiceException + ( + int _err + ) +: + err(_err) +{ +} + + +// +// This version of the constructor is useful for instances in which +// an inner exception is thrown, caught, and then a new exception +// is thrown in it's place +// +DNSServiceException::DNSServiceException + ( + String * message, + System::Exception * innerException + ) +{ +} |