summaryrefslogtreecommitdiffstats
path: root/mDNSResponder/mDNSWindows/DLL.NET/dnssd_NET.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mDNSResponder/mDNSWindows/DLL.NET/dnssd_NET.cpp')
-rwxr-xr-xmDNSResponder/mDNSWindows/DLL.NET/dnssd_NET.cpp1234
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
+ )
+{
+}