1 /* -*- Mode: C; tab-width: 4 -*-
3 * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 Change History (most recent first):
19 $Log: dnssd_NET.cpp,v $
20 Revision 1.10 2006/08/14 23:25:43 cheshire
21 Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
23 Revision 1.9 2004/09/16 18:17:13 shersche
24 Use background threads, cleanup to parameter names.
25 Submitted by: prepin@gmail.com
27 Revision 1.8 2004/09/13 19:35:58 shersche
28 <rdar://problem/3798941> Add Apple.DNSSD namespace to MC++ wrapper class
29 <rdar://problem/3798950> Change all instances of unsigned short to int
30 Bug #: 3798941, 3798950
32 Revision 1.7 2004/09/11 00:36:40 shersche
33 <rdar://problem/3786226> Modified .NET shim code to use host byte order for ports in APIs and callbacks
36 Revision 1.6 2004/09/02 21:20:56 cheshire
37 <rdar://problem/3774871> DLL.NET crashes on null record
39 Revision 1.5 2004/07/27 07:12:56 shersche
40 make TextRecord an instantiable class object
42 Revision 1.4 2004/07/26 06:19:05 shersche
43 Treat byte arrays of zero-length as null arrays
45 Revision 1.3 2004/07/19 16:08:56 shersche
46 fix problems in UTF8/Unicode string translations
48 Revision 1.2 2004/07/19 07:48:34 shersche
49 fix bug in DNSService.Register when passing in NULL text record, add TextRecord APIs
51 Revision 1.1 2004/06/26 04:01:22 shersche
57 // This is the main DLL file.
61 #include "dnssd_NET.h"
62 #include "DebugServices.h"
66 using namespace System::Net::Sockets
;
67 using namespace System::Diagnostics
;
68 using namespace Apple
;
69 using namespace Apple::DNSSD
;
72 //===========================================================================================================================
74 //===========================================================================================================================
76 #define DEBUG_NAME "[dnssd.NET] "
82 ConvertToString(const char * utf8String
)
84 return __gc
new String(utf8String
, 0, strlen(utf8String
), __gc
new UTF8Encoding(true, true));
91 // ServiceRef serves as the base class for all DNSService operations.
93 // It manages the DNSServiceRef, and implements processing the
96 ServiceRef::ServiceRef(Object
* callback
)
102 m_impl
= new ServiceRefImpl(this);
106 ServiceRef::~ServiceRef()
114 // Starts the main processing thread
117 ServiceRef::StartThread()
119 check( m_impl
!= NULL
);
121 m_impl
->SetupEvents();
123 m_thread
= new Thread(new ThreadStart(this, ProcessingThread
));
124 m_thread
->Name
= S
"DNSService Thread";
125 m_thread
->IsBackground
= true;
134 // The Thread class can only invoke methods in MC++ types. So we
135 // make a ProcessingThread method that forwards to the impl
138 ServiceRef::ProcessingThread()
140 m_impl
->ProcessingThread();
147 // Calls impl-Dispose(). This ultimately will call DNSServiceRefDeallocate()
150 ServiceRef::Dispose()
152 check(m_impl
!= NULL
);
153 check(m_bDisposed
== false);
160 // Call Dispose. This won't call DNSServiceRefDeallocate()
161 // necessarily. It depends on what thread this is being
169 GC::SuppressFinalize(this);
175 // EnumerateDomainsDispatch
177 // Dispatch a reply to the delegate.
180 ServiceRef::EnumerateDomainsDispatch
188 if ((m_callback
!= NULL
) && (m_impl
!= NULL
))
190 DNSService::EnumerateDomainsReply
* OnEnumerateDomainsReply
= static_cast<DNSService::EnumerateDomainsReply
*>(m_callback
);
191 OnEnumerateDomainsReply(this, flags
, interfaceIndex
, errorCode
, replyDomain
);
199 // Dispatch a reply to the delegate.
202 ServiceRef::RegisterDispatch
211 if ((m_callback
!= NULL
) && (m_impl
!= NULL
))
213 DNSService::RegisterReply
* OnRegisterReply
= static_cast<DNSService::RegisterReply
*>(m_callback
);
214 OnRegisterReply(this, flags
, errorCode
, name
, regtype
, domain
);
222 // Dispatch a reply to the delegate.
225 ServiceRef::BrowseDispatch
230 String
* serviceName
,
235 if ((m_callback
!= NULL
) && (m_impl
!= NULL
))
237 DNSService::BrowseReply
* OnBrowseReply
= static_cast<DNSService::BrowseReply
*>(m_callback
);
238 OnBrowseReply(this, flags
, interfaceIndex
, errorCode
, serviceName
, regtype
, replyDomain
);
246 // Dispatch a reply to the delegate.
249 ServiceRef::ResolveDispatch
260 if ((m_callback
!= NULL
) && (m_impl
!= NULL
))
262 DNSService::ResolveReply
* OnResolveReply
= static_cast<DNSService::ResolveReply
*>(m_callback
);
263 OnResolveReply(this, flags
, interfaceIndex
, errorCode
, fullname
, hosttarget
, port
, txtRecord
);
269 // RegisterRecordDispatch
271 // Dispatch a reply to the delegate.
274 ServiceRef::RegisterRecordDispatch
281 if ((m_callback
!= NULL
) && (m_impl
!= NULL
))
283 DNSService::RegisterRecordReply
* OnRegisterRecordReply
= static_cast<DNSService::RegisterRecordReply
*>(m_callback
);
284 OnRegisterRecordReply(this, flags
, errorCode
, record
);
290 // QueryRecordDispatch
292 // Dispatch a reply to the delegate.
295 ServiceRef::QueryRecordDispatch
307 if ((m_callback
!= NULL
) && (m_impl
!= NULL
))
309 DNSService::QueryRecordReply
* OnQueryRecordReply
= static_cast<DNSService::QueryRecordReply
*>(m_callback
);
310 OnQueryRecordReply(this, flags
, interfaceIndex
, errorCode
, fullname
, rrtype
, rrclass
, rdata
, ttl
);
316 // ServiceRefImpl::ServiceRefImpl()
318 // Constructs a new ServiceRefImpl. We save the pointer to our enclosing
319 // class in a gcroot handle. This satisfies the garbage collector as
320 // the outer class is a managed type
322 ServiceRef::ServiceRefImpl::ServiceRefImpl(ServiceRef
* outer
)
330 m_threadId
= GetCurrentThreadId();
335 // ServiceRefImpl::~ServiceRefImpl()
337 // Deallocate all resources associated with the ServiceRefImpl
339 ServiceRef::ServiceRefImpl::~ServiceRefImpl()
341 if (m_socketEvent
!= NULL
)
343 CloseHandle(m_socketEvent
);
344 m_socketEvent
= NULL
;
347 if (m_stopEvent
!= NULL
)
349 CloseHandle(m_stopEvent
);
355 DNSServiceRefDeallocate(m_ref
);
362 // ServiceRefImpl::SetupEvents()
364 // Setup the events necessary to manage multi-threaded dispatch
365 // of DNSService Events
368 ServiceRef::ServiceRefImpl::SetupEvents()
370 check(m_ref
!= NULL
);
372 m_socket
= (SOCKET
) DNSServiceRefSockFD(m_ref
);
373 check(m_socket
!= INVALID_SOCKET
);
375 m_socketEvent
= CreateEvent(NULL
, 0, 0, NULL
);
377 if (m_socketEvent
== NULL
)
379 throw new DNSServiceException(Unknown
);
382 int err
= WSAEventSelect(m_socket
, m_socketEvent
, FD_READ
|FD_CLOSE
);
386 throw new DNSServiceException(Unknown
);
389 m_stopEvent
= CreateEvent(NULL
, 0, 0, NULL
);
391 if (m_stopEvent
== NULL
)
393 throw new DNSServiceException(Unknown
);
399 // ServiceRefImpl::ProcessingThread()
401 // Wait for socket events on the DNSServiceRefSockFD(). Also wait
405 ServiceRef::ServiceRefImpl::ProcessingThread()
407 check( m_socketEvent
!= NULL
);
408 check( m_stopEvent
!= NULL
);
409 check( m_ref
!= NULL
);
413 handles
[0] = m_socketEvent
;
414 handles
[1] = m_stopEvent
;
416 while (m_disposed
== false)
418 int ret
= WaitForMultipleObjects(2, handles
, FALSE
, INFINITE
);
421 // it's a socket event
423 if (ret
== WAIT_OBJECT_0
)
425 DNSServiceProcessResult(m_ref
);
428 // else it's a stop event
430 else if (ret
== WAIT_OBJECT_0
+ 1)
437 // unexpected wait result
439 dlog( kDebugLevelWarning
, DEBUG_NAME
"%s: unexpected wait result (result=0x%08X)\n", __ROUTINE__
, ret
);
448 // ServiceRefImpl::Dispose()
450 // Calls DNSServiceRefDeallocate()
453 ServiceRef::ServiceRefImpl::Dispose()
458 check(m_disposed
== false);
462 ok
= SetEvent(m_stopEvent
);
463 err
= translate_errno( ok
, (OSStatus
) GetLastError(), kUnknownErr
);
464 require_noerr( err
, exit
);
473 // ServiceRefImpl::EnumerateDomainsCallback()
475 // This is the callback from dnssd.dll. We pass this up to our outer, managed type
478 ServiceRef::ServiceRefImpl::EnumerateDomainsCallback
481 DNSServiceFlags flags
,
482 uint32_t interfaceIndex
,
483 DNSServiceErrorType errorCode
,
484 const char * replyDomain
,
488 ServiceRef::ServiceRefImpl
* self
= static_cast<ServiceRef::ServiceRefImpl
*>(context
);
490 check( self
!= NULL
);
491 check( self
->m_outer
!= NULL
);
493 if (self
->m_disposed
== false)
495 self
->m_outer
->EnumerateDomainsDispatch((ServiceFlags
) flags
, interfaceIndex
, (ErrorCode
) errorCode
, ConvertToString(replyDomain
));
501 // ServiceRefImpl::RegisterCallback()
503 // This is the callback from dnssd.dll. We pass this up to our outer, managed type
506 ServiceRef::ServiceRefImpl::RegisterCallback
509 DNSServiceFlags flags
,
510 DNSServiceErrorType errorCode
,
512 const char * regtype
,
517 ServiceRef::ServiceRefImpl
* self
= static_cast<ServiceRef::ServiceRefImpl
*>(context
);
519 check( self
!= NULL
);
520 check( self
->m_outer
!= NULL
);
522 if (self
->m_disposed
== false)
524 self
->m_outer
->RegisterDispatch((ServiceFlags
) flags
, (ErrorCode
) errorCode
, ConvertToString(name
), ConvertToString(regtype
), ConvertToString(domain
));
530 // ServiceRefImpl::BrowseCallback()
532 // This is the callback from dnssd.dll. We pass this up to our outer, managed type
535 ServiceRef::ServiceRefImpl::BrowseCallback
538 DNSServiceFlags flags
,
539 uint32_t interfaceIndex
,
540 DNSServiceErrorType errorCode
,
541 const char * serviceName
,
542 const char * regtype
,
543 const char * replyDomain
,
547 ServiceRef::ServiceRefImpl
* self
= static_cast<ServiceRef::ServiceRefImpl
*>(context
);
549 check( self
!= NULL
);
550 check( self
->m_outer
!= NULL
);
552 if (self
->m_disposed
== false)
554 self
->m_outer
->BrowseDispatch((ServiceFlags
) flags
, interfaceIndex
, (ErrorCode
) errorCode
, ConvertToString(serviceName
), ConvertToString(regtype
), ConvertToString(replyDomain
));
560 // ServiceRefImpl::ResolveCallback()
562 // This is the callback from dnssd.dll. We pass this up to our outer, managed type
565 ServiceRef::ServiceRefImpl::ResolveCallback
568 DNSServiceFlags flags
,
569 uint32_t interfaceIndex
,
570 DNSServiceErrorType errorCode
,
571 const char * fullname
,
572 const char * hosttarget
,
573 uint16_t notAnIntPort
,
575 const char * txtRecord
,
579 ServiceRef::ServiceRefImpl
* self
= static_cast<ServiceRef::ServiceRefImpl
*>(context
);
581 check( self
!= NULL
);
582 check( self
->m_outer
!= NULL
);
584 if (self
->m_disposed
== false)
586 Byte txtRecordBytes
[];
588 txtRecordBytes
= NULL
;
593 // copy raw memory into managed byte array
595 txtRecordBytes
= new Byte
[txtLen
];
596 Byte __pin
* p
= &txtRecordBytes
[0];
597 memcpy(p
, txtRecord
, txtLen
);
600 self
->m_outer
->ResolveDispatch((ServiceFlags
) flags
, interfaceIndex
, (ErrorCode
) errorCode
, ConvertToString(fullname
), ConvertToString(hosttarget
), ntohs(notAnIntPort
), txtRecordBytes
);
606 // ServiceRefImpl::RegisterRecordCallback()
608 // This is the callback from dnssd.dll. We pass this up to our outer, managed type
611 ServiceRef::ServiceRefImpl::RegisterRecordCallback
615 DNSServiceFlags flags
,
616 DNSServiceErrorType errorCode
,
620 ServiceRef::ServiceRefImpl
* self
= static_cast<ServiceRef::ServiceRefImpl
*>(context
);
622 check( self
!= NULL
);
623 check( self
->m_outer
!= NULL
);
625 if (self
->m_disposed
== false)
627 RecordRef
* record
= NULL
;
631 record
= new RecordRef
;
633 record
->m_impl
->m_ref
= rrRef
;
636 self
->m_outer
->RegisterRecordDispatch((ServiceFlags
) flags
, (ErrorCode
) errorCode
, record
);
642 // ServiceRefImpl::QueryRecordCallback()
644 // This is the callback from dnssd.dll. We pass this up to our outer, managed type
647 ServiceRef::ServiceRefImpl::QueryRecordCallback
649 DNSServiceRef DNSServiceRef
,
650 DNSServiceFlags flags
,
651 uint32_t interfaceIndex
,
652 DNSServiceErrorType errorCode
,
653 const char * fullname
,
662 ServiceRef::ServiceRefImpl
* self
= static_cast<ServiceRef::ServiceRefImpl
*>(context
);
664 check( self
!= NULL
);
665 check( self
->m_outer
!= NULL
);
667 if (self
->m_disposed
== false)
673 rdataBytes
= new Byte
[rdlen
];
674 Byte __pin
* p
= &rdataBytes
[0];
675 memcpy(p
, rdata
, rdlen
);
678 self
->m_outer
->QueryRecordDispatch((ServiceFlags
) flags
, (int) interfaceIndex
, (ErrorCode
) errorCode
, ConvertToString(fullname
), rrtype
, rrclass
, rdataBytes
, ttl
);
686 * This maps to DNSServiceEnumerateDomains(). Returns an
687 * initialized ServiceRef on success, throws an exception
691 DNSService::EnumerateDomains
695 EnumerateDomainsReply
* callback
698 ServiceRef
* sdRef
= new ServiceRef(callback
);
701 err
= DNSServiceEnumerateDomains(&sdRef
->m_impl
->m_ref
, flags
, interfaceIndex
, ServiceRef::ServiceRefImpl::EnumerateDomainsCallback
, sdRef
->m_impl
);
705 throw new DNSServiceException(err
);
708 sdRef
->StartThread();
717 * This maps to DNSServiceRegister(). Returns an
718 * initialized ServiceRef on success, throws an exception
732 RegisterReply
* callback
735 ServiceRef
* sdRef
= new ServiceRef(callback
);
736 PString
* pName
= new PString(name
);
737 PString
* pType
= new PString(regtype
);
738 PString
* pDomain
= new PString(domain
);
739 PString
* pHost
= new PString(host
);
741 Byte __pin
* p
= NULL
;
744 if ((txtRecord
!= NULL
) && (txtRecord
->Length
> 0))
746 len
= txtRecord
->Length
;
751 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
);
755 throw new DNSServiceException(err
);
758 sdRef
->StartThread();
767 * This maps to DNSServiceAddRecord(). Returns an
768 * initialized ServiceRef on success, throws an exception
772 DNSService::AddRecord
782 Byte __pin
* p
= NULL
;
785 if ((rdata
!= NULL
) && (rdata
->Length
> 0))
792 RecordRef
* record
= new RecordRef
;
794 int err
= DNSServiceAddRecord(sdRef
->m_impl
->m_ref
, &record
->m_impl
->m_ref
, flags
, rrtype
, len
, v
, ttl
);
798 throw new DNSServiceException(err
);
808 * This maps to DNSServiceUpdateRecord(). Returns an
809 * initialized ServiceRef on success, throws an exception
813 DNSService::UpdateRecord
823 Byte __pin
* p
= NULL
;
826 if ((rdata
!= NULL
) && (rdata
->Length
> 0))
833 int err
= DNSServiceUpdateRecord(sdRef
->m_impl
->m_ref
, record
? record
->m_impl
->m_ref
: NULL
, flags
, len
, v
, ttl
);
837 throw new DNSServiceException(err
);
845 * This maps to DNSServiceRemoveRecord(). Returns an
846 * initialized ServiceRef on success, throws an exception
850 DNSService::RemoveRecord
857 int err
= DNSServiceRemoveRecord(sdRef
->m_impl
->m_ref
, record
->m_impl
->m_ref
, flags
);
861 throw new DNSServiceException(err
);
869 * This maps to DNSServiceBrowse(). Returns an
870 * initialized ServiceRef on success, throws an exception
880 BrowseReply
* callback
883 ServiceRef
* sdRef
= new ServiceRef(callback
);
884 PString
* pType
= new PString(regtype
);
885 PString
* pDomain
= new PString(domain
);
887 int err
= DNSServiceBrowse(&sdRef
->m_impl
->m_ref
, flags
, interfaceIndex
, pType
->c_str(), pDomain
->c_str(),(DNSServiceBrowseReply
) ServiceRef::ServiceRefImpl::BrowseCallback
, sdRef
->m_impl
);
891 throw new DNSServiceException(err
);
894 sdRef
->StartThread();
903 * This maps to DNSServiceResolve(). Returns an
904 * initialized ServiceRef on success, throws an exception
915 ResolveReply
* callback
918 ServiceRef
* sdRef
= new ServiceRef(callback
);
919 PString
* pName
= new PString(name
);
920 PString
* pType
= new PString(regtype
);
921 PString
* pDomain
= new PString(domain
);
923 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
);
927 throw new DNSServiceException(err
);
930 sdRef
->StartThread();
939 * This maps to DNSServiceCreateConnection(). Returns an
940 * initialized ServiceRef on success, throws an exception
944 DNSService::CreateConnection
946 RegisterRecordReply
* callback
949 ServiceRef
* sdRef
= new ServiceRef(callback
);
951 int err
= DNSServiceCreateConnection(&sdRef
->m_impl
->m_ref
);
955 throw new DNSServiceException(err
);
958 sdRef
->StartThread();
967 * This maps to DNSServiceRegisterRecord(). Returns an
968 * initialized ServiceRef on success, throws an exception
973 DNSService::RegisterRecord
985 RecordRef
* record
= new RecordRef
;
987 Byte __pin
* p
= NULL
;
990 PString
* pFullname
= new PString(fullname
);
992 if ((rdata
!= NULL
) && (rdata
->Length
> 0))
999 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
);
1003 throw new DNSServiceException(err
);
1012 * This maps to DNSServiceQueryRecord(). Returns an
1013 * initialized ServiceRef on success, throws an exception
1017 DNSService::QueryRecord
1024 QueryRecordReply
* callback
1027 ServiceRef
* sdRef
= new ServiceRef(callback
);
1028 PString
* pFullname
= new PString(fullname
);
1030 int err
= DNSServiceQueryRecord(&sdRef
->m_impl
->m_ref
, flags
, interfaceIndex
, pFullname
->c_str(), rrtype
, rrclass
, (DNSServiceQueryRecordReply
) ServiceRef::ServiceRefImpl::QueryRecordCallback
, sdRef
->m_impl
);
1034 throw new DNSServiceException(err
);
1037 sdRef
->StartThread();
1046 * This maps to DNSServiceReconfirmRecord(). Returns an
1047 * initialized ServiceRef on success, throws an exception
1051 DNSService::ReconfirmRecord
1062 Byte __pin
* p
= NULL
;
1065 PString
* pFullname
= new PString(fullname
);
1067 if ((rdata
!= NULL
) && (rdata
->Length
> 0))
1069 len
= rdata
->Length
;
1074 DNSServiceReconfirmRecord(flags
, interfaceIndex
, pFullname
->c_str(), rrtype
, rrclass
, len
, v
);
1079 TextRecord::SetValue
1082 Byte value
[] /* may be NULL */
1085 PString
* pKey
= new PString(key
);
1087 Byte __pin
* p
= NULL
;
1089 DNSServiceErrorType err
;
1091 if (value
&& (value
->Length
> 0))
1093 len
= value
->Length
;
1098 err
= TXTRecordSetValue(&m_impl
->m_ref
, pKey
->c_str(), len
, v
);
1102 throw new DNSServiceException(err
);
1108 TextRecord::RemoveValue
1113 PString
* pKey
= new PString(key
);
1114 DNSServiceErrorType err
;
1116 err
= TXTRecordRemoveValue(&m_impl
->m_ref
, pKey
->c_str());
1120 throw new DNSServiceException(err
);
1126 TextRecord::GetLength
1130 return TXTRecordGetLength(&m_impl
->m_ref
);
1135 TextRecord::GetBytes
1139 const void * noGCBytes
= NULL
;
1140 Byte gcBytes
[] = NULL
;
1142 noGCBytes
= TXTRecordGetBytesPtr(&m_impl
->m_ref
);
1143 int len
= GetLength();
1145 if (noGCBytes
&& len
)
1147 gcBytes
= new Byte
[len
];
1148 Byte __pin
* p
= &gcBytes
[0];
1149 memcpy(p
, noGCBytes
, len
);
1157 TextRecord::ContainsKey
1163 PString
* pKey
= new PString(key
);
1164 Byte __pin
* p
= &txtRecord
[0];
1166 return (TXTRecordContainsKey(txtRecord
->Length
, p
, pKey
->c_str()) > 0) ? true : false;
1171 TextRecord::GetValueBytes
1179 PString
* pKey
= new PString(key
);
1180 Byte __pin
* p1
= &txtRecord
[0];
1183 v
= TXTRecordGetValuePtr(txtRecord
->Length
, p1
, pKey
->c_str(), &valueLen
);
1187 ret
= new Byte
[valueLen
];
1188 Byte __pin
* p2
= &ret
[0];
1190 memcpy(p2
, v
, valueLen
);
1198 TextRecord::GetCount
1203 Byte __pin
* p
= &txtRecord
[0];
1205 return TXTRecordGetCount(txtRecord
->Length
, p
);
1210 TextRecord::GetItemAtIndex
1218 uint8_t keyBufLen
= 255;
1222 DNSServiceErrorType err
;
1223 Byte __pin
* p1
= &txtRecord
[0];
1226 err
= TXTRecordGetItemAtIndex(txtRecord
->Length
, p1
, index
, keyBufLen
, keyBuf
, &valueLen
, (const void**) &value
);
1230 throw new DNSServiceException(err
);
1233 *key
= ConvertToString(keyBuf
);
1237 ret
= new Byte
[valueLen
];
1238 Byte __pin
* p2
= &ret
[0];
1240 memcpy(p2
, value
, valueLen
);
1248 // DNSServiceException::DNSServiceException()
1250 // Constructs an exception with an error code
1252 DNSServiceException::DNSServiceException
1263 // This version of the constructor is useful for instances in which
1264 // an inner exception is thrown, caught, and then a new exception
1265 // is thrown in it's place
1267 DNSServiceException::DNSServiceException
1270 System::Exception
* innerException