2 * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
23 Change History (most recent first):
25 $Log: dnssd_NET.cpp,v $
26 Revision 1.9 2004/09/16 18:17:13 shersche
27 Use background threads, cleanup to parameter names.
28 Submitted by: prepin@gmail.com
30 Revision 1.8 2004/09/13 19:35:58 shersche
31 <rdar://problem/3798941> Add Apple.DNSSD namespace to MC++ wrapper class
32 <rdar://problem/3798950> Change all instances of unsigned short to int
33 Bug #: 3798941, 3798950
35 Revision 1.7 2004/09/11 00:36:40 shersche
36 <rdar://problem/3786226> Modified .NET shim code to use host byte order for ports in APIs and callbacks
39 Revision 1.6 2004/09/02 21:20:56 cheshire
40 <rdar://problem/3774871> Rendezvous DLL.NET crashes on null record
42 Revision 1.5 2004/07/27 07:12:56 shersche
43 make TextRecord an instantiable class object
45 Revision 1.4 2004/07/26 06:19:05 shersche
46 Treat byte arrays of zero-length as null arrays
48 Revision 1.3 2004/07/19 16:08:56 shersche
49 fix problems in UTF8/Unicode string translations
51 Revision 1.2 2004/07/19 07:48:34 shersche
52 fix bug in DNSService.Register when passing in NULL text record, add TextRecord APIs
54 Revision 1.1 2004/06/26 04:01:22 shersche
60 // This is the main DLL file.
64 #include "dnssd_NET.h"
65 #include "DebugServices.h"
69 using namespace System::Net::Sockets
;
70 using namespace System::Diagnostics
;
71 using namespace Apple
;
72 using namespace Apple::DNSSD
;
75 //===========================================================================================================================
77 //===========================================================================================================================
79 #define DEBUG_NAME "[dnssd.NET] "
85 ConvertToString(const char * utf8String
)
87 return __gc
new String(utf8String
, 0, strlen(utf8String
), __gc
new UTF8Encoding(true, true));
94 // ServiceRef serves as the base class for all DNSService operations.
96 // It manages the DNSServiceRef, and implements processing the
99 ServiceRef::ServiceRef(Object
* callback
)
102 m_callback(callback
),
105 m_impl
= new ServiceRefImpl(this);
109 ServiceRef::~ServiceRef()
117 // Starts the main processing thread
120 ServiceRef::StartThread()
122 check( m_impl
!= NULL
);
124 m_impl
->SetupEvents();
126 m_thread
= new Thread(new ThreadStart(this, ProcessingThread
));
127 m_thread
->Name
= S
"DNSService Thread";
128 m_thread
->IsBackground
= true;
137 // The Thread class can only invoke methods in MC++ types. So we
138 // make a ProcessingThread method that forwards to the impl
141 ServiceRef::ProcessingThread()
143 m_impl
->ProcessingThread();
150 // Calls impl-Dispose(). This ultimately will call DNSServiceRefDeallocate()
153 ServiceRef::Dispose()
155 check(m_impl
!= NULL
);
156 check(m_bDisposed
== false);
163 // Call Dispose. This won't call DNSServiceRefDeallocate()
164 // necessarily. It depends on what thread this is being
172 GC::SuppressFinalize(this);
178 // EnumerateDomainsDispatch
180 // Dispatch a reply to the delegate.
183 ServiceRef::EnumerateDomainsDispatch
191 if ((m_callback
!= NULL
) && (m_impl
!= NULL
))
193 DNSService::EnumerateDomainsReply
* OnEnumerateDomainsReply
= static_cast<DNSService::EnumerateDomainsReply
*>(m_callback
);
194 OnEnumerateDomainsReply(this, flags
, interfaceIndex
, errorCode
, replyDomain
);
202 // Dispatch a reply to the delegate.
205 ServiceRef::RegisterDispatch
214 if ((m_callback
!= NULL
) && (m_impl
!= NULL
))
216 DNSService::RegisterReply
* OnRegisterReply
= static_cast<DNSService::RegisterReply
*>(m_callback
);
217 OnRegisterReply(this, flags
, errorCode
, name
, regtype
, domain
);
225 // Dispatch a reply to the delegate.
228 ServiceRef::BrowseDispatch
233 String
* serviceName
,
238 if ((m_callback
!= NULL
) && (m_impl
!= NULL
))
240 DNSService::BrowseReply
* OnBrowseReply
= static_cast<DNSService::BrowseReply
*>(m_callback
);
241 OnBrowseReply(this, flags
, interfaceIndex
, errorCode
, serviceName
, regtype
, replyDomain
);
249 // Dispatch a reply to the delegate.
252 ServiceRef::ResolveDispatch
263 if ((m_callback
!= NULL
) && (m_impl
!= NULL
))
265 DNSService::ResolveReply
* OnResolveReply
= static_cast<DNSService::ResolveReply
*>(m_callback
);
266 OnResolveReply(this, flags
, interfaceIndex
, errorCode
, fullname
, hosttarget
, port
, txtRecord
);
272 // RegisterRecordDispatch
274 // Dispatch a reply to the delegate.
277 ServiceRef::RegisterRecordDispatch
284 if ((m_callback
!= NULL
) && (m_impl
!= NULL
))
286 DNSService::RegisterRecordReply
* OnRegisterRecordReply
= static_cast<DNSService::RegisterRecordReply
*>(m_callback
);
287 OnRegisterRecordReply(this, flags
, errorCode
, record
);
293 // QueryRecordDispatch
295 // Dispatch a reply to the delegate.
298 ServiceRef::QueryRecordDispatch
310 if ((m_callback
!= NULL
) && (m_impl
!= NULL
))
312 DNSService::QueryRecordReply
* OnQueryRecordReply
= static_cast<DNSService::QueryRecordReply
*>(m_callback
);
313 OnQueryRecordReply(this, flags
, interfaceIndex
, errorCode
, fullname
, rrtype
, rrclass
, rdata
, ttl
);
319 // ServiceRefImpl::ServiceRefImpl()
321 // Constructs a new ServiceRefImpl. We save the pointer to our enclosing
322 // class in a gcroot handle. This satisfies the garbage collector as
323 // the outer class is a managed type
325 ServiceRef::ServiceRefImpl::ServiceRefImpl(ServiceRef
* outer
)
333 m_threadId
= GetCurrentThreadId();
338 // ServiceRefImpl::~ServiceRefImpl()
340 // Deallocate all resources associated with the ServiceRefImpl
342 ServiceRef::ServiceRefImpl::~ServiceRefImpl()
344 if (m_socketEvent
!= NULL
)
346 CloseHandle(m_socketEvent
);
347 m_socketEvent
= NULL
;
350 if (m_stopEvent
!= NULL
)
352 CloseHandle(m_stopEvent
);
358 DNSServiceRefDeallocate(m_ref
);
365 // ServiceRefImpl::SetupEvents()
367 // Setup the events necessary to manage multi-threaded dispatch
368 // of DNSService Events
371 ServiceRef::ServiceRefImpl::SetupEvents()
373 check(m_ref
!= NULL
);
375 m_socket
= (SOCKET
) DNSServiceRefSockFD(m_ref
);
376 check(m_socket
!= INVALID_SOCKET
);
378 m_socketEvent
= CreateEvent(NULL
, 0, 0, NULL
);
380 if (m_socketEvent
== NULL
)
382 throw new DNSServiceException(Unknown
);
385 int err
= WSAEventSelect(m_socket
, m_socketEvent
, FD_READ
|FD_CLOSE
);
389 throw new DNSServiceException(Unknown
);
392 m_stopEvent
= CreateEvent(NULL
, 0, 0, NULL
);
394 if (m_stopEvent
== NULL
)
396 throw new DNSServiceException(Unknown
);
402 // ServiceRefImpl::ProcessingThread()
404 // Wait for socket events on the DNSServiceRefSockFD(). Also wait
408 ServiceRef::ServiceRefImpl::ProcessingThread()
410 check( m_socketEvent
!= NULL
);
411 check( m_stopEvent
!= NULL
);
412 check( m_ref
!= NULL
);
416 handles
[0] = m_socketEvent
;
417 handles
[1] = m_stopEvent
;
419 while (m_disposed
== false)
421 int ret
= WaitForMultipleObjects(2, handles
, FALSE
, INFINITE
);
424 // it's a socket event
426 if (ret
== WAIT_OBJECT_0
)
428 DNSServiceProcessResult(m_ref
);
431 // else it's a stop event
433 else if (ret
== WAIT_OBJECT_0
+ 1)
440 // unexpected wait result
442 dlog( kDebugLevelWarning
, DEBUG_NAME
"%s: unexpected wait result (result=0x%08X)\n", __ROUTINE__
, ret
);
451 // ServiceRefImpl::Dispose()
453 // Calls DNSServiceRefDeallocate()
456 ServiceRef::ServiceRefImpl::Dispose()
461 check(m_disposed
== false);
465 ok
= SetEvent(m_stopEvent
);
466 err
= translate_errno( ok
, (OSStatus
) GetLastError(), kUnknownErr
);
467 require_noerr( err
, exit
);
476 // ServiceRefImpl::EnumerateDomainsCallback()
478 // This is the callback from dnssd.dll. We pass this up to our outer, managed type
481 ServiceRef::ServiceRefImpl::EnumerateDomainsCallback
484 DNSServiceFlags flags
,
485 uint32_t interfaceIndex
,
486 DNSServiceErrorType errorCode
,
487 const char * replyDomain
,
491 ServiceRef::ServiceRefImpl
* self
= static_cast<ServiceRef::ServiceRefImpl
*>(context
);
493 check( self
!= NULL
);
494 check( self
->m_outer
!= NULL
);
496 if (self
->m_disposed
== false)
498 self
->m_outer
->EnumerateDomainsDispatch((ServiceFlags
) flags
, interfaceIndex
, (ErrorCode
) errorCode
, ConvertToString(replyDomain
));
504 // ServiceRefImpl::RegisterCallback()
506 // This is the callback from dnssd.dll. We pass this up to our outer, managed type
509 ServiceRef::ServiceRefImpl::RegisterCallback
512 DNSServiceFlags flags
,
513 DNSServiceErrorType errorCode
,
515 const char * regtype
,
520 ServiceRef::ServiceRefImpl
* self
= static_cast<ServiceRef::ServiceRefImpl
*>(context
);
522 check( self
!= NULL
);
523 check( self
->m_outer
!= NULL
);
525 if (self
->m_disposed
== false)
527 self
->m_outer
->RegisterDispatch((ServiceFlags
) flags
, (ErrorCode
) errorCode
, ConvertToString(name
), ConvertToString(regtype
), ConvertToString(domain
));
533 // ServiceRefImpl::BrowseCallback()
535 // This is the callback from dnssd.dll. We pass this up to our outer, managed type
538 ServiceRef::ServiceRefImpl::BrowseCallback
541 DNSServiceFlags flags
,
542 uint32_t interfaceIndex
,
543 DNSServiceErrorType errorCode
,
544 const char * serviceName
,
545 const char * regtype
,
546 const char * replyDomain
,
550 ServiceRef::ServiceRefImpl
* self
= static_cast<ServiceRef::ServiceRefImpl
*>(context
);
552 check( self
!= NULL
);
553 check( self
->m_outer
!= NULL
);
555 if (self
->m_disposed
== false)
557 self
->m_outer
->BrowseDispatch((ServiceFlags
) flags
, interfaceIndex
, (ErrorCode
) errorCode
, ConvertToString(serviceName
), ConvertToString(regtype
), ConvertToString(replyDomain
));
563 // ServiceRefImpl::ResolveCallback()
565 // This is the callback from dnssd.dll. We pass this up to our outer, managed type
568 ServiceRef::ServiceRefImpl::ResolveCallback
571 DNSServiceFlags flags
,
572 uint32_t interfaceIndex
,
573 DNSServiceErrorType errorCode
,
574 const char * fullname
,
575 const char * hosttarget
,
576 uint16_t notAnIntPort
,
578 const char * txtRecord
,
582 ServiceRef::ServiceRefImpl
* self
= static_cast<ServiceRef::ServiceRefImpl
*>(context
);
584 check( self
!= NULL
);
585 check( self
->m_outer
!= NULL
);
587 if (self
->m_disposed
== false)
589 Byte txtRecordBytes
[];
591 txtRecordBytes
= NULL
;
596 // copy raw memory into managed byte array
598 txtRecordBytes
= new Byte
[txtLen
];
599 Byte __pin
* p
= &txtRecordBytes
[0];
600 memcpy(p
, txtRecord
, txtLen
);
603 self
->m_outer
->ResolveDispatch((ServiceFlags
) flags
, interfaceIndex
, (ErrorCode
) errorCode
, ConvertToString(fullname
), ConvertToString(hosttarget
), ntohs(notAnIntPort
), txtRecordBytes
);
609 // ServiceRefImpl::RegisterRecordCallback()
611 // This is the callback from dnssd.dll. We pass this up to our outer, managed type
614 ServiceRef::ServiceRefImpl::RegisterRecordCallback
618 DNSServiceFlags flags
,
619 DNSServiceErrorType errorCode
,
623 ServiceRef::ServiceRefImpl
* self
= static_cast<ServiceRef::ServiceRefImpl
*>(context
);
625 check( self
!= NULL
);
626 check( self
->m_outer
!= NULL
);
628 if (self
->m_disposed
== false)
630 RecordRef
* record
= NULL
;
634 record
= new RecordRef
;
636 record
->m_impl
->m_ref
= rrRef
;
639 self
->m_outer
->RegisterRecordDispatch((ServiceFlags
) flags
, (ErrorCode
) errorCode
, record
);
645 // ServiceRefImpl::QueryRecordCallback()
647 // This is the callback from dnssd.dll. We pass this up to our outer, managed type
650 ServiceRef::ServiceRefImpl::QueryRecordCallback
652 DNSServiceRef DNSServiceRef
,
653 DNSServiceFlags flags
,
654 uint32_t interfaceIndex
,
655 DNSServiceErrorType errorCode
,
656 const char * fullname
,
665 ServiceRef::ServiceRefImpl
* self
= static_cast<ServiceRef::ServiceRefImpl
*>(context
);
667 check( self
!= NULL
);
668 check( self
->m_outer
!= NULL
);
670 if (self
->m_disposed
== false)
676 rdataBytes
= new Byte
[rdlen
];
677 Byte __pin
* p
= &rdataBytes
[0];
678 memcpy(p
, rdata
, rdlen
);
681 self
->m_outer
->QueryRecordDispatch((ServiceFlags
) flags
, (int) interfaceIndex
, (ErrorCode
) errorCode
, ConvertToString(fullname
), rrtype
, rrclass
, rdataBytes
, ttl
);
689 * This maps to DNSServiceEnumerateDomains(). Returns an
690 * initialized ServiceRef on success, throws an exception
694 DNSService::EnumerateDomains
698 EnumerateDomainsReply
* callback
701 ServiceRef
* sdRef
= new ServiceRef(callback
);
704 err
= DNSServiceEnumerateDomains(&sdRef
->m_impl
->m_ref
, flags
, interfaceIndex
, ServiceRef::ServiceRefImpl::EnumerateDomainsCallback
, sdRef
->m_impl
);
708 throw new DNSServiceException(err
);
711 sdRef
->StartThread();
720 * This maps to DNSServiceRegister(). Returns an
721 * initialized ServiceRef on success, throws an exception
735 RegisterReply
* callback
738 ServiceRef
* sdRef
= new ServiceRef(callback
);
739 PString
* pName
= new PString(name
);
740 PString
* pType
= new PString(regtype
);
741 PString
* pDomain
= new PString(domain
);
742 PString
* pHost
= new PString(host
);
744 Byte __pin
* p
= NULL
;
747 if ((txtRecord
!= NULL
) && (txtRecord
->Length
> 0))
749 len
= txtRecord
->Length
;
754 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
);
758 throw new DNSServiceException(err
);
761 sdRef
->StartThread();
770 * This maps to DNSServiceAddRecord(). Returns an
771 * initialized ServiceRef on success, throws an exception
775 DNSService::AddRecord
785 Byte __pin
* p
= NULL
;
788 if ((rdata
!= NULL
) && (rdata
->Length
> 0))
795 RecordRef
* record
= new RecordRef
;
797 int err
= DNSServiceAddRecord(sdRef
->m_impl
->m_ref
, &record
->m_impl
->m_ref
, flags
, rrtype
, len
, v
, ttl
);
801 throw new DNSServiceException(err
);
811 * This maps to DNSServiceUpdateRecord(). Returns an
812 * initialized ServiceRef on success, throws an exception
816 DNSService::UpdateRecord
826 Byte __pin
* p
= NULL
;
829 if ((rdata
!= NULL
) && (rdata
->Length
> 0))
836 int err
= DNSServiceUpdateRecord(sdRef
->m_impl
->m_ref
, record
? record
->m_impl
->m_ref
: NULL
, flags
, len
, v
, ttl
);
840 throw new DNSServiceException(err
);
848 * This maps to DNSServiceRemoveRecord(). Returns an
849 * initialized ServiceRef on success, throws an exception
853 DNSService::RemoveRecord
860 int err
= DNSServiceRemoveRecord(sdRef
->m_impl
->m_ref
, record
->m_impl
->m_ref
, flags
);
864 throw new DNSServiceException(err
);
872 * This maps to DNSServiceBrowse(). Returns an
873 * initialized ServiceRef on success, throws an exception
883 BrowseReply
* callback
886 ServiceRef
* sdRef
= new ServiceRef(callback
);
887 PString
* pType
= new PString(regtype
);
888 PString
* pDomain
= new PString(domain
);
890 int err
= DNSServiceBrowse(&sdRef
->m_impl
->m_ref
, flags
, interfaceIndex
, pType
->c_str(), pDomain
->c_str(),(DNSServiceBrowseReply
) ServiceRef::ServiceRefImpl::BrowseCallback
, sdRef
->m_impl
);
894 throw new DNSServiceException(err
);
897 sdRef
->StartThread();
906 * This maps to DNSServiceResolve(). Returns an
907 * initialized ServiceRef on success, throws an exception
918 ResolveReply
* callback
921 ServiceRef
* sdRef
= new ServiceRef(callback
);
922 PString
* pName
= new PString(name
);
923 PString
* pType
= new PString(regtype
);
924 PString
* pDomain
= new PString(domain
);
926 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
);
930 throw new DNSServiceException(err
);
933 sdRef
->StartThread();
942 * This maps to DNSServiceCreateConnection(). Returns an
943 * initialized ServiceRef on success, throws an exception
947 DNSService::CreateConnection
949 RegisterRecordReply
* callback
952 ServiceRef
* sdRef
= new ServiceRef(callback
);
954 int err
= DNSServiceCreateConnection(&sdRef
->m_impl
->m_ref
);
958 throw new DNSServiceException(err
);
961 sdRef
->StartThread();
970 * This maps to DNSServiceRegisterRecord(). Returns an
971 * initialized ServiceRef on success, throws an exception
976 DNSService::RegisterRecord
988 RecordRef
* record
= new RecordRef
;
990 Byte __pin
* p
= NULL
;
993 PString
* pFullname
= new PString(fullname
);
995 if ((rdata
!= NULL
) && (rdata
->Length
> 0))
1002 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
);
1006 throw new DNSServiceException(err
);
1015 * This maps to DNSServiceQueryRecord(). Returns an
1016 * initialized ServiceRef on success, throws an exception
1020 DNSService::QueryRecord
1027 QueryRecordReply
* callback
1030 ServiceRef
* sdRef
= new ServiceRef(callback
);
1031 PString
* pFullname
= new PString(fullname
);
1033 int err
= DNSServiceQueryRecord(&sdRef
->m_impl
->m_ref
, flags
, interfaceIndex
, pFullname
->c_str(), rrtype
, rrclass
, (DNSServiceQueryRecordReply
) ServiceRef::ServiceRefImpl::QueryRecordCallback
, sdRef
->m_impl
);
1037 throw new DNSServiceException(err
);
1040 sdRef
->StartThread();
1049 * This maps to DNSServiceReconfirmRecord(). Returns an
1050 * initialized ServiceRef on success, throws an exception
1054 DNSService::ReconfirmRecord
1065 Byte __pin
* p
= NULL
;
1068 PString
* pFullname
= new PString(fullname
);
1070 if ((rdata
!= NULL
) && (rdata
->Length
> 0))
1072 len
= rdata
->Length
;
1077 DNSServiceReconfirmRecord(flags
, interfaceIndex
, pFullname
->c_str(), rrtype
, rrclass
, len
, v
);
1082 TextRecord::SetValue
1085 Byte value
[] /* may be NULL */
1088 PString
* pKey
= new PString(key
);
1090 Byte __pin
* p
= NULL
;
1092 DNSServiceErrorType err
;
1094 if (value
&& (value
->Length
> 0))
1096 len
= value
->Length
;
1101 err
= TXTRecordSetValue(&m_impl
->m_ref
, pKey
->c_str(), len
, v
);
1105 throw new DNSServiceException(err
);
1111 TextRecord::RemoveValue
1116 PString
* pKey
= new PString(key
);
1117 DNSServiceErrorType err
;
1119 err
= TXTRecordRemoveValue(&m_impl
->m_ref
, pKey
->c_str());
1123 throw new DNSServiceException(err
);
1129 TextRecord::GetLength
1133 return TXTRecordGetLength(&m_impl
->m_ref
);
1138 TextRecord::GetBytes
1142 const void * noGCBytes
= NULL
;
1143 Byte gcBytes
[] = NULL
;
1145 noGCBytes
= TXTRecordGetBytesPtr(&m_impl
->m_ref
);
1146 int len
= GetLength();
1148 if (noGCBytes
&& len
)
1150 gcBytes
= new Byte
[len
];
1151 Byte __pin
* p
= &gcBytes
[0];
1152 memcpy(p
, noGCBytes
, len
);
1160 TextRecord::ContainsKey
1166 PString
* pKey
= new PString(key
);
1167 Byte __pin
* p
= &txtRecord
[0];
1169 return (TXTRecordContainsKey(txtRecord
->Length
, p
, pKey
->c_str()) > 0) ? true : false;
1174 TextRecord::GetValueBytes
1182 PString
* pKey
= new PString(key
);
1183 Byte __pin
* p1
= &txtRecord
[0];
1186 v
= TXTRecordGetValuePtr(txtRecord
->Length
, p1
, pKey
->c_str(), &valueLen
);
1190 ret
= new Byte
[valueLen
];
1191 Byte __pin
* p2
= &ret
[0];
1193 memcpy(p2
, v
, valueLen
);
1201 TextRecord::GetCount
1206 Byte __pin
* p
= &txtRecord
[0];
1208 return TXTRecordGetCount(txtRecord
->Length
, p
);
1213 TextRecord::GetItemAtIndex
1221 uint8_t keyBufLen
= 255;
1225 DNSServiceErrorType err
;
1226 Byte __pin
* p1
= &txtRecord
[0];
1229 err
= TXTRecordGetItemAtIndex(txtRecord
->Length
, p1
, index
, keyBufLen
, keyBuf
, &valueLen
, (const void**) &value
);
1233 throw new DNSServiceException(err
);
1236 *key
= ConvertToString(keyBuf
);
1240 ret
= new Byte
[valueLen
];
1241 Byte __pin
* p2
= &ret
[0];
1243 memcpy(p2
, value
, valueLen
);
1251 // DNSServiceException::DNSServiceException()
1253 // Constructs an exception with an error code
1255 DNSServiceException::DNSServiceException
1266 // This version of the constructor is useful for instances in which
1267 // an inner exception is thrown, caught, and then a new exception
1268 // is thrown in it's place
1270 DNSServiceException::DNSServiceException
1273 System::Exception
* innerException