1*4904Srs200217 /* -*- Mode: C; tab-width: 4 -*-
2*4904Srs200217 *
3*4904Srs200217 * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
4*4904Srs200217 *
5*4904Srs200217 * Licensed under the Apache License, Version 2.0 (the "License");
6*4904Srs200217 * you may not use this file except in compliance with the License.
7*4904Srs200217 * You may obtain a copy of the License at
8*4904Srs200217 *
9*4904Srs200217 * http://www.apache.org/licenses/LICENSE-2.0
10*4904Srs200217 *
11*4904Srs200217 * Unless required by applicable law or agreed to in writing, software
12*4904Srs200217 * distributed under the License is distributed on an "AS IS" BASIS,
13*4904Srs200217 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*4904Srs200217 * See the License for the specific language governing permissions and
15*4904Srs200217 * limitations under the License.
16*4904Srs200217
17*4904Srs200217 Change History (most recent first):
18*4904Srs200217
19*4904Srs200217 $Log: JNISupport.c,v $
20*4904Srs200217 Revision 1.17 2006/08/14 23:25:08 cheshire
21*4904Srs200217 Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
22*4904Srs200217
23*4904Srs200217 Revision 1.16 2006/07/14 02:35:47 cheshire
24*4904Srs200217 Added (commented out) syslog debugging messages
25*4904Srs200217
26*4904Srs200217 Revision 1.15 2006/06/27 19:34:43 cheshire
27*4904Srs200217 <rdar://problem/4430023> txtRecord parameter of DNSServiceResolveReply() should be unsigned char *
28*4904Srs200217
29*4904Srs200217 Revision 1.14 2006/06/20 23:03:35 rpantos
30*4904Srs200217 <rdar://problem/3839132> Java needs to implement DNSServiceRegisterRecord equivalent
31*4904Srs200217
32*4904Srs200217 Revision 1.13 2005/10/26 01:52:24 cheshire
33*4904Srs200217 <rdar://problem/4316286> Race condition in Java code (doesn't work at all on Linux)
34*4904Srs200217
35*4904Srs200217 Revision 1.12 2005/07/13 19:20:32 cheshire
36*4904Srs200217 <rdar://problem/4175511> Race condition in Java API
37*4904Srs200217 Additional cleanup suggested by Roger -- NewContext() doesn't need ownerClass parameter any more
38*4904Srs200217
39*4904Srs200217 Revision 1.11 2005/07/11 01:55:21 cheshire
40*4904Srs200217 <rdar://problem/4175511> Race condition in Java API
41*4904Srs200217
42*4904Srs200217 Revision 1.10 2005/07/05 13:01:52 cheshire
43*4904Srs200217 <rdar://problem/4169791> If mDNSResponder daemon is stopped, Java API spins, burning CPU time
44*4904Srs200217
45*4904Srs200217 Revision 1.9 2004/12/11 03:01:00 rpantos
46*4904Srs200217 <rdar://problem/3907498> Java DNSRecord API should be cleaned up
47*4904Srs200217
48*4904Srs200217 Revision 1.8 2004/11/30 23:51:05 cheshire
49*4904Srs200217 Remove double semicolons
50*4904Srs200217
51*4904Srs200217 Revision 1.7 2004/11/23 08:12:04 shersche
52*4904Srs200217 Implement if_nametoindex and if_indextoname for Win32 platforms
53*4904Srs200217
54*4904Srs200217 Revision 1.6 2004/11/23 03:41:14 cheshire
55*4904Srs200217 Change JNISupport.c to call if_indextoname & if_nametoindex directly.
56*4904Srs200217 (May require some additional glue code to work on Windows.)
57*4904Srs200217
58*4904Srs200217 Revision 1.5 2004/11/17 17:07:44 cheshire
59*4904Srs200217 Updated comment about AUTO_CALLBACKS
60*4904Srs200217
61*4904Srs200217 Revision 1.4 2004/11/12 03:23:09 rpantos
62*4904Srs200217 rdar://problem/3809541 implement getIfIndexForName, getNameForIfIndex.
63*4904Srs200217
64*4904Srs200217 Revision 1.3 2004/06/18 04:44:17 rpantos
65*4904Srs200217 Adapt to API unification on Windows
66*4904Srs200217
67*4904Srs200217 Revision 1.2 2004/05/28 23:34:42 ksekar
68*4904Srs200217 <rdar://problem/3672903>: Java project build errors
69*4904Srs200217
70*4904Srs200217 Revision 1.1 2004/04/30 16:29:35 rpantos
71*4904Srs200217 First checked in.
72*4904Srs200217
73*4904Srs200217
74*4904Srs200217 This file contains the platform support for DNSSD and related Java classes.
75*4904Srs200217 It is used to shim through to the underlying <dns_sd.h> API.
76*4904Srs200217 */
77*4904Srs200217
78*4904Srs200217 #pragma ident "%Z%%M% %I% %E% SMI"
79*4904Srs200217
80*4904Srs200217 // AUTO_CALLBACKS should be set to 1 if the underlying mDNS implementation fires response
81*4904Srs200217 // callbacks automatically (as in the early Windows prototypes).
82*4904Srs200217 // AUTO_CALLBACKS should be set to 0 if the client must call DNSServiceProcessResult() to
83*4904Srs200217 // invoke response callbacks (as is true on Mac OS X, Posix, Windows, etc.).
84*4904Srs200217 // (Invoking callbacks automatically on a different thread sounds attractive, but while
85*4904Srs200217 // the client gains by not needing to add an event source to its main event loop, it loses
86*4904Srs200217 // by being forced to deal with concurrency and locking, which can be a bigger burden.)
87*4904Srs200217 #ifndef AUTO_CALLBACKS
88*4904Srs200217 #define AUTO_CALLBACKS 0
89*4904Srs200217 #endif
90*4904Srs200217
91*4904Srs200217 #if !AUTO_CALLBACKS
92*4904Srs200217 #ifdef _WIN32
93*4904Srs200217 #include <winsock2.h>
94*4904Srs200217 #else //_WIN32
95*4904Srs200217 #include <sys/types.h>
96*4904Srs200217 #include <sys/select.h>
97*4904Srs200217 #endif // _WIN32
98*4904Srs200217 #endif // AUTO_CALLBACKS
99*4904Srs200217
100*4904Srs200217 #include <dns_sd.h>
101*4904Srs200217
102*4904Srs200217 #include <stdio.h>
103*4904Srs200217 #include <stdlib.h>
104*4904Srs200217 #include <string.h>
105*4904Srs200217 #ifdef _WIN32
106*4904Srs200217 #include <winsock2.h>
107*4904Srs200217 #include <iphlpapi.h>
108*4904Srs200217 static char * if_indextoname( DWORD ifIndex, char * nameBuff);
109*4904Srs200217 static DWORD if_nametoindex( const char * nameStr );
110*4904Srs200217 #define IF_NAMESIZE MAX_ADAPTER_NAME_LENGTH
111*4904Srs200217 #else // _WIN32
112*4904Srs200217 #include <sys/socket.h>
113*4904Srs200217 #include <net/if.h>
114*4904Srs200217 #endif // _WIN32
115*4904Srs200217 #include <jni.h>
116*4904Srs200217
117*4904Srs200217 #include "DNSSD.java.h"
118*4904Srs200217
119*4904Srs200217 //#include <syslog.h>
120*4904Srs200217
121*4904Srs200217 // convenience definition
122*4904Srs200217 #ifdef __GNUC__
123*4904Srs200217 #define _UNUSED __attribute__ ((unused))
124*4904Srs200217 #else
125*4904Srs200217 #define _UNUSED
126*4904Srs200217 #endif
127*4904Srs200217
128*4904Srs200217 enum {
129*4904Srs200217 kInterfaceVersion = 1 // Must match version in .jar file
130*4904Srs200217 };
131*4904Srs200217
132*4904Srs200217 typedef struct OpContext OpContext;
133*4904Srs200217
134*4904Srs200217 struct OpContext
135*4904Srs200217 {
136*4904Srs200217 DNSServiceRef ServiceRef;
137*4904Srs200217 JNIEnv *Env;
138*4904Srs200217 jobject JavaObj;
139*4904Srs200217 jobject ClientObj;
140*4904Srs200217 jmethodID Callback;
141*4904Srs200217 jmethodID Callback2;
142*4904Srs200217 };
143*4904Srs200217
144*4904Srs200217 // For AUTO_CALLBACKS, we must attach the callback thread to the Java VM prior to upcall.
145*4904Srs200217 #if AUTO_CALLBACKS
146*4904Srs200217 JavaVM *gJavaVM = NULL;
147*4904Srs200217 #endif
148*4904Srs200217
149*4904Srs200217
Java_com_apple_dnssd_AppleDNSSD_InitLibrary(JNIEnv * pEnv,jclass cls,jint callerVersion)150*4904Srs200217 JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDNSSD_InitLibrary( JNIEnv *pEnv, jclass cls,
151*4904Srs200217 jint callerVersion)
152*4904Srs200217 {
153*4904Srs200217 /* Ensure that caller & interface versions match. */
154*4904Srs200217 if ( callerVersion != kInterfaceVersion)
155*4904Srs200217 return kDNSServiceErr_Incompatible;
156*4904Srs200217
157*4904Srs200217 #if AUTO_CALLBACKS
158*4904Srs200217 {
159*4904Srs200217 jsize numVMs;
160*4904Srs200217
161*4904Srs200217 if ( 0 != JNI_GetCreatedJavaVMs( &gJavaVM, 1, &numVMs))
162*4904Srs200217 return kDNSServiceErr_BadState;
163*4904Srs200217 }
164*4904Srs200217 #endif
165*4904Srs200217
166*4904Srs200217 // Set AppleDNSSD.hasAutoCallbacks
167*4904Srs200217 {
168*4904Srs200217 #if AUTO_CALLBACKS
169*4904Srs200217 jboolean hasAutoC = JNI_TRUE;
170*4904Srs200217 #else
171*4904Srs200217 jboolean hasAutoC = JNI_FALSE;
172*4904Srs200217 #endif
173*4904Srs200217 jfieldID hasAutoCField = (*pEnv)->GetStaticFieldID( pEnv, cls, "hasAutoCallbacks", "Z");
174*4904Srs200217 (*pEnv)->SetStaticBooleanField( pEnv, cls, hasAutoCField, hasAutoC);
175*4904Srs200217 }
176*4904Srs200217
177*4904Srs200217 return kDNSServiceErr_NoError;
178*4904Srs200217 }
179*4904Srs200217
180*4904Srs200217
SafeGetUTFChars(JNIEnv * pEnv,jstring str)181*4904Srs200217 static const char* SafeGetUTFChars( JNIEnv *pEnv, jstring str)
182*4904Srs200217 // Wrapper for JNI GetStringUTFChars() that returns NULL for null str.
183*4904Srs200217 {
184*4904Srs200217 return str != NULL ? (*pEnv)->GetStringUTFChars( pEnv, str, 0) : NULL;
185*4904Srs200217 }
186*4904Srs200217
SafeReleaseUTFChars(JNIEnv * pEnv,jstring str,const char * buff)187*4904Srs200217 static void SafeReleaseUTFChars( JNIEnv *pEnv, jstring str, const char *buff)
188*4904Srs200217 // Wrapper for JNI GetStringUTFChars() that handles null str.
189*4904Srs200217 {
190*4904Srs200217 if ( str != NULL)
191*4904Srs200217 (*pEnv)->ReleaseStringUTFChars( pEnv, str, buff);
192*4904Srs200217 }
193*4904Srs200217
194*4904Srs200217
195*4904Srs200217 #if AUTO_CALLBACKS
SetupCallbackState(JNIEnv ** ppEnv)196*4904Srs200217 static void SetupCallbackState( JNIEnv **ppEnv)
197*4904Srs200217 {
198*4904Srs200217 (*gJavaVM)->AttachCurrentThread( gJavaVM, (void**) ppEnv, NULL);
199*4904Srs200217 }
200*4904Srs200217
TeardownCallbackState(void)201*4904Srs200217 static void TeardownCallbackState( void )
202*4904Srs200217 {
203*4904Srs200217 (*gJavaVM)->DetachCurrentThread( gJavaVM);
204*4904Srs200217 }
205*4904Srs200217
206*4904Srs200217 #else // AUTO_CALLBACKS
207*4904Srs200217
SetupCallbackState(JNIEnv ** ppEnv _UNUSED)208*4904Srs200217 static void SetupCallbackState( JNIEnv **ppEnv _UNUSED)
209*4904Srs200217 {
210*4904Srs200217 // No setup necessary if ProcessResults() has been called
211*4904Srs200217 }
212*4904Srs200217
TeardownCallbackState(void)213*4904Srs200217 static void TeardownCallbackState( void )
214*4904Srs200217 {
215*4904Srs200217 // No teardown necessary if ProcessResults() has been called
216*4904Srs200217 }
217*4904Srs200217 #endif // AUTO_CALLBACKS
218*4904Srs200217
219*4904Srs200217
NewContext(JNIEnv * pEnv,jobject owner,const char * callbackName,const char * callbackSig)220*4904Srs200217 static OpContext *NewContext( JNIEnv *pEnv, jobject owner,
221*4904Srs200217 const char *callbackName, const char *callbackSig)
222*4904Srs200217 // Create and initialize a new OpContext.
223*4904Srs200217 {
224*4904Srs200217 OpContext *pContext = (OpContext*) malloc( sizeof *pContext);
225*4904Srs200217
226*4904Srs200217 if ( pContext != NULL)
227*4904Srs200217 {
228*4904Srs200217 jfieldID clientField = (*pEnv)->GetFieldID( pEnv, (*pEnv)->GetObjectClass( pEnv, owner),
229*4904Srs200217 "fListener", "Lcom/apple/dnssd/BaseListener;");
230*4904Srs200217
231*4904Srs200217 pContext->JavaObj = (*pEnv)->NewWeakGlobalRef( pEnv, owner); // must convert local ref to global to cache;
232*4904Srs200217 pContext->ClientObj = (*pEnv)->GetObjectField( pEnv, owner, clientField);
233*4904Srs200217 pContext->ClientObj = (*pEnv)->NewWeakGlobalRef( pEnv, pContext->ClientObj); // must convert local ref to global to cache
234*4904Srs200217 pContext->Callback = (*pEnv)->GetMethodID( pEnv,
235*4904Srs200217 (*pEnv)->GetObjectClass( pEnv, pContext->ClientObj),
236*4904Srs200217 callbackName, callbackSig);
237*4904Srs200217 pContext->Callback2 = NULL; // not always used
238*4904Srs200217 }
239*4904Srs200217
240*4904Srs200217 return pContext;
241*4904Srs200217 }
242*4904Srs200217
243*4904Srs200217
ReportError(JNIEnv * pEnv,jobject target,jobject service,DNSServiceErrorType err)244*4904Srs200217 static void ReportError( JNIEnv *pEnv, jobject target, jobject service, DNSServiceErrorType err)
245*4904Srs200217 // Invoke operationFailed() method on target with err.
246*4904Srs200217 {
247*4904Srs200217 jclass cls = (*pEnv)->GetObjectClass( pEnv, target);
248*4904Srs200217 jmethodID opFailed = (*pEnv)->GetMethodID( pEnv, cls, "operationFailed",
249*4904Srs200217 "(Lcom/apple/dnssd/DNSSDService;I)V");
250*4904Srs200217
251*4904Srs200217 (*pEnv)->CallVoidMethod( pEnv, target, opFailed, service, err);
252*4904Srs200217 }
253*4904Srs200217
Java_com_apple_dnssd_AppleService_HaltOperation(JNIEnv * pEnv,jobject pThis)254*4904Srs200217 JNIEXPORT void JNICALL Java_com_apple_dnssd_AppleService_HaltOperation( JNIEnv *pEnv, jobject pThis)
255*4904Srs200217 /* Deallocate the dns_sd service browser and set the Java object's fNativeContext field to 0. */
256*4904Srs200217 {
257*4904Srs200217 jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
258*4904Srs200217 jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
259*4904Srs200217
260*4904Srs200217 if ( contextField != 0)
261*4904Srs200217 {
262*4904Srs200217 OpContext *pContext = (OpContext*) (*pEnv)->GetLongField( pEnv, pThis, contextField);
263*4904Srs200217 if ( pContext != NULL)
264*4904Srs200217 {
265*4904Srs200217 // MUST clear fNativeContext first, BEFORE calling DNSServiceRefDeallocate()
266*4904Srs200217 (*pEnv)->SetLongField( pEnv, pThis, contextField, 0);
267*4904Srs200217 if ( pContext->ServiceRef != NULL)
268*4904Srs200217 DNSServiceRefDeallocate( pContext->ServiceRef);
269*4904Srs200217
270*4904Srs200217 (*pEnv)->DeleteWeakGlobalRef( pEnv, pContext->JavaObj);
271*4904Srs200217 (*pEnv)->DeleteWeakGlobalRef( pEnv, pContext->ClientObj);
272*4904Srs200217 free( pContext);
273*4904Srs200217 }
274*4904Srs200217 }
275*4904Srs200217 }
276*4904Srs200217
277*4904Srs200217
Java_com_apple_dnssd_AppleService_BlockForData(JNIEnv * pEnv,jobject pThis)278*4904Srs200217 JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleService_BlockForData( JNIEnv *pEnv, jobject pThis)
279*4904Srs200217 /* Block until data arrives, or one second passes. Returns 1 if data present, 0 otherwise. */
280*4904Srs200217 {
281*4904Srs200217 // BlockForData() not supported with AUTO_CALLBACKS
282*4904Srs200217 #if !AUTO_CALLBACKS
283*4904Srs200217 jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
284*4904Srs200217 jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
285*4904Srs200217
286*4904Srs200217 if ( contextField != 0)
287*4904Srs200217 {
288*4904Srs200217 OpContext *pContext = (OpContext*) (*pEnv)->GetLongField( pEnv, pThis, contextField);
289*4904Srs200217 if ( pContext != NULL)
290*4904Srs200217 {
291*4904Srs200217 fd_set readFDs;
292*4904Srs200217 int sd = DNSServiceRefSockFD( pContext->ServiceRef);
293*4904Srs200217 struct timeval timeout = { 1, 0 };
294*4904Srs200217 FD_ZERO( &readFDs);
295*4904Srs200217 FD_SET( sd, &readFDs);
296*4904Srs200217
297*4904Srs200217 // Q: Why do we poll here?
298*4904Srs200217 // A: Because there's no other thread-safe way to do it.
299*4904Srs200217 // Mac OS X terminates a select() call if you close one of the sockets it's listening on, but Linux does not,
300*4904Srs200217 // and arguably Linux is correct (See <http://www.ussg.iu.edu/hypermail/linux/kernel/0405.1/0418.html>)
301*4904Srs200217 // The problem is that the Mac OS X behaviour assumes that it's okay for one thread to close a socket while
302*4904Srs200217 // some other thread is monitoring that socket in select(), but the difficulty is that there's no general way
303*4904Srs200217 // to make that thread-safe, because there's no atomic way to enter select() and release a lock simultaneously.
304*4904Srs200217 // If we try to do this without holding any lock, then right as we jump to the select() routine,
305*4904Srs200217 // some other thread could stop our operation (thereby closing the socket),
306*4904Srs200217 // and then that thread (or even some third, unrelated thread)
307*4904Srs200217 // could do some other DNS-SD operation (or some other operation that opens a new file descriptor)
308*4904Srs200217 // and then we'd blindly resume our fall into the select() call, now blocking on a file descriptor
309*4904Srs200217 // that may coincidentally have the same numerical value, but is semantically unrelated
310*4904Srs200217 // to the true file descriptor we thought we were blocking on.
311*4904Srs200217 // We can't stop this race condition from happening, but at least if we wake up once a second we can detect
312*4904Srs200217 // when fNativeContext has gone to zero, and thereby discover that we were blocking on the wrong fd.
313*4904Srs200217
314*4904Srs200217 if (select( sd + 1, &readFDs, (fd_set*) NULL, (fd_set*) NULL, &timeout) == 1) return(1);
315*4904Srs200217 }
316*4904Srs200217 }
317*4904Srs200217 #endif // !AUTO_CALLBACKS
318*4904Srs200217 return(0);
319*4904Srs200217 }
320*4904Srs200217
321*4904Srs200217
Java_com_apple_dnssd_AppleService_ProcessResults(JNIEnv * pEnv,jobject pThis)322*4904Srs200217 JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleService_ProcessResults( JNIEnv *pEnv, jobject pThis)
323*4904Srs200217 /* Call through to DNSServiceProcessResult() while data remains on socket. */
324*4904Srs200217 {
325*4904Srs200217 #if !AUTO_CALLBACKS // ProcessResults() not supported with AUTO_CALLBACKS
326*4904Srs200217
327*4904Srs200217 jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
328*4904Srs200217 jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
329*4904Srs200217 OpContext *pContext = (OpContext*) (*pEnv)->GetLongField( pEnv, pThis, contextField);
330*4904Srs200217 DNSServiceErrorType err = kDNSServiceErr_BadState;
331*4904Srs200217
332*4904Srs200217 if ( pContext != NULL)
333*4904Srs200217 {
334*4904Srs200217 int sd = DNSServiceRefSockFD( pContext->ServiceRef);
335*4904Srs200217 fd_set readFDs;
336*4904Srs200217 struct timeval zeroTimeout = { 0, 0 };
337*4904Srs200217
338*4904Srs200217 pContext->Env = pEnv;
339*4904Srs200217
340*4904Srs200217 FD_ZERO( &readFDs);
341*4904Srs200217 FD_SET( sd, &readFDs);
342*4904Srs200217
343*4904Srs200217 err = kDNSServiceErr_NoError;
344*4904Srs200217 if (0 < select(sd + 1, &readFDs, (fd_set*) NULL, (fd_set*) NULL, &zeroTimeout))
345*4904Srs200217 {
346*4904Srs200217 err = DNSServiceProcessResult(pContext->ServiceRef);
347*4904Srs200217 // Use caution here!
348*4904Srs200217 // We cannot touch any data structures associated with this operation!
349*4904Srs200217 // The DNSServiceProcessResult() routine should have invoked our callback,
350*4904Srs200217 // and our callback could have terminated the operation with op.stop();
351*4904Srs200217 // and that means HaltOperation() will have been called, which frees pContext.
352*4904Srs200217 // Basically, from here we just have to get out without touching any stale
353*4904Srs200217 // data structures that could blow up on us! Particularly, any attempt
354*4904Srs200217 // to loop here reading more results from the file descriptor is unsafe.
355*4904Srs200217 }
356*4904Srs200217 }
357*4904Srs200217 return err;
358*4904Srs200217 #endif // AUTO_CALLBACKS
359*4904Srs200217 }
360*4904Srs200217
361*4904Srs200217
ServiceBrowseReply(DNSServiceRef sdRef _UNUSED,DNSServiceFlags flags,uint32_t interfaceIndex,DNSServiceErrorType errorCode,const char * serviceName,const char * regtype,const char * replyDomain,void * context)362*4904Srs200217 static void DNSSD_API ServiceBrowseReply( DNSServiceRef sdRef _UNUSED, DNSServiceFlags flags, uint32_t interfaceIndex,
363*4904Srs200217 DNSServiceErrorType errorCode, const char *serviceName, const char *regtype,
364*4904Srs200217 const char *replyDomain, void *context)
365*4904Srs200217 {
366*4904Srs200217 OpContext *pContext = (OpContext*) context;
367*4904Srs200217
368*4904Srs200217 SetupCallbackState( &pContext->Env);
369*4904Srs200217
370*4904Srs200217 if ( pContext->ClientObj != NULL && pContext->Callback != NULL)
371*4904Srs200217 {
372*4904Srs200217 if ( errorCode == kDNSServiceErr_NoError)
373*4904Srs200217 {
374*4904Srs200217 (*pContext->Env)->CallVoidMethod( pContext->Env, pContext->ClientObj,
375*4904Srs200217 ( flags & kDNSServiceFlagsAdd) != 0 ? pContext->Callback : pContext->Callback2,
376*4904Srs200217 pContext->JavaObj, flags, interfaceIndex,
377*4904Srs200217 (*pContext->Env)->NewStringUTF( pContext->Env, serviceName),
378*4904Srs200217 (*pContext->Env)->NewStringUTF( pContext->Env, regtype),
379*4904Srs200217 (*pContext->Env)->NewStringUTF( pContext->Env, replyDomain));
380*4904Srs200217 }
381*4904Srs200217 else
382*4904Srs200217 ReportError( pContext->Env, pContext->ClientObj, pContext->JavaObj, errorCode);
383*4904Srs200217 }
384*4904Srs200217
385*4904Srs200217 TeardownCallbackState();
386*4904Srs200217 }
387*4904Srs200217
Java_com_apple_dnssd_AppleBrowser_CreateBrowser(JNIEnv * pEnv,jobject pThis,jint flags,jint ifIndex,jstring regType,jstring domain)388*4904Srs200217 JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleBrowser_CreateBrowser( JNIEnv *pEnv, jobject pThis,
389*4904Srs200217 jint flags, jint ifIndex, jstring regType, jstring domain)
390*4904Srs200217 {
391*4904Srs200217 jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
392*4904Srs200217 jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
393*4904Srs200217 OpContext *pContext = NULL;
394*4904Srs200217 DNSServiceErrorType err = kDNSServiceErr_NoError;
395*4904Srs200217
396*4904Srs200217 if ( contextField != 0)
397*4904Srs200217 pContext = NewContext( pEnv, pThis, "serviceFound",
398*4904Srs200217 "(Lcom/apple/dnssd/DNSSDService;IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
399*4904Srs200217 else
400*4904Srs200217 err = kDNSServiceErr_BadParam;
401*4904Srs200217
402*4904Srs200217 if ( pContext != NULL)
403*4904Srs200217 {
404*4904Srs200217 const char *regStr = SafeGetUTFChars( pEnv, regType);
405*4904Srs200217 const char *domainStr = SafeGetUTFChars( pEnv, domain);
406*4904Srs200217
407*4904Srs200217 pContext->Callback2 = (*pEnv)->GetMethodID( pEnv,
408*4904Srs200217 (*pEnv)->GetObjectClass( pEnv, pContext->ClientObj),
409*4904Srs200217 "serviceLost", "(Lcom/apple/dnssd/DNSSDService;IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
410*4904Srs200217
411*4904Srs200217 err = DNSServiceBrowse( &pContext->ServiceRef, flags, ifIndex, regStr, domainStr, ServiceBrowseReply, pContext);
412*4904Srs200217 if ( err == kDNSServiceErr_NoError)
413*4904Srs200217 {
414*4904Srs200217 (*pEnv)->SetLongField( pEnv, pThis, contextField, (jlong) pContext);
415*4904Srs200217 }
416*4904Srs200217
417*4904Srs200217 SafeReleaseUTFChars( pEnv, regType, regStr);
418*4904Srs200217 SafeReleaseUTFChars( pEnv, domain, domainStr);
419*4904Srs200217 }
420*4904Srs200217 else
421*4904Srs200217 err = kDNSServiceErr_NoMemory;
422*4904Srs200217
423*4904Srs200217 return err;
424*4904Srs200217 }
425*4904Srs200217
426*4904Srs200217
ServiceResolveReply(DNSServiceRef sdRef _UNUSED,DNSServiceFlags flags,uint32_t interfaceIndex,DNSServiceErrorType errorCode,const char * fullname,const char * hosttarget,uint16_t port,uint16_t txtLen,const unsigned char * txtRecord,void * context)427*4904Srs200217 static void DNSSD_API ServiceResolveReply( DNSServiceRef sdRef _UNUSED, DNSServiceFlags flags, uint32_t interfaceIndex,
428*4904Srs200217 DNSServiceErrorType errorCode, const char *fullname, const char *hosttarget,
429*4904Srs200217 uint16_t port, uint16_t txtLen, const unsigned char *txtRecord, void *context)
430*4904Srs200217 {
431*4904Srs200217 OpContext *pContext = (OpContext*) context;
432*4904Srs200217 jclass txtCls;
433*4904Srs200217 jmethodID txtCtor;
434*4904Srs200217 jbyteArray txtBytes;
435*4904Srs200217 jobject txtObj;
436*4904Srs200217 jbyte *pBytes;
437*4904Srs200217
438*4904Srs200217 SetupCallbackState( &pContext->Env);
439*4904Srs200217
440*4904Srs200217 txtCls = (*pContext->Env)->FindClass( pContext->Env, "com/apple/dnssd/TXTRecord");
441*4904Srs200217 txtCtor = (*pContext->Env)->GetMethodID( pContext->Env, txtCls, "<init>", "([B)V");
442*4904Srs200217
443*4904Srs200217 if ( pContext->ClientObj != NULL && pContext->Callback != NULL && txtCtor != NULL &&
444*4904Srs200217 NULL != ( txtBytes = (*pContext->Env)->NewByteArray( pContext->Env, txtLen)))
445*4904Srs200217 {
446*4904Srs200217 if ( errorCode == kDNSServiceErr_NoError)
447*4904Srs200217 {
448*4904Srs200217 // Since Java ints are defined to be big-endian, we canonicalize 'port' from a 16-bit
449*4904Srs200217 // pattern into a number here.
450*4904Srs200217 port = ( ((unsigned char*) &port)[0] << 8) | ((unsigned char*) &port)[1];
451*4904Srs200217
452*4904Srs200217 // Initialize txtBytes with contents of txtRecord
453*4904Srs200217 pBytes = (*pContext->Env)->GetByteArrayElements( pContext->Env, txtBytes, NULL);
454*4904Srs200217 memcpy( pBytes, txtRecord, txtLen);
455*4904Srs200217 (*pContext->Env)->ReleaseByteArrayElements( pContext->Env, txtBytes, pBytes, JNI_COMMIT);
456*4904Srs200217
457*4904Srs200217 // Construct txtObj with txtBytes
458*4904Srs200217 txtObj = (*pContext->Env)->NewObject( pContext->Env, txtCls, txtCtor, txtBytes);
459*4904Srs200217 (*pContext->Env)->DeleteLocalRef( pContext->Env, txtBytes);
460*4904Srs200217
461*4904Srs200217 (*pContext->Env)->CallVoidMethod( pContext->Env, pContext->ClientObj, pContext->Callback,
462*4904Srs200217 pContext->JavaObj, flags, interfaceIndex,
463*4904Srs200217 (*pContext->Env)->NewStringUTF( pContext->Env, fullname),
464*4904Srs200217 (*pContext->Env)->NewStringUTF( pContext->Env, hosttarget),
465*4904Srs200217 port, txtObj);
466*4904Srs200217 }
467*4904Srs200217 else
468*4904Srs200217 ReportError( pContext->Env, pContext->ClientObj, pContext->JavaObj, errorCode);
469*4904Srs200217 }
470*4904Srs200217
471*4904Srs200217 TeardownCallbackState();
472*4904Srs200217 }
473*4904Srs200217
Java_com_apple_dnssd_AppleResolver_CreateResolver(JNIEnv * pEnv,jobject pThis,jint flags,jint ifIndex,jstring serviceName,jstring regType,jstring domain)474*4904Srs200217 JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleResolver_CreateResolver( JNIEnv *pEnv, jobject pThis,
475*4904Srs200217 jint flags, jint ifIndex, jstring serviceName, jstring regType, jstring domain)
476*4904Srs200217 {
477*4904Srs200217 jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
478*4904Srs200217 jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
479*4904Srs200217 OpContext *pContext = NULL;
480*4904Srs200217 DNSServiceErrorType err = kDNSServiceErr_NoError;
481*4904Srs200217
482*4904Srs200217 if ( contextField != 0)
483*4904Srs200217 pContext = NewContext( pEnv, pThis, "serviceResolved",
484*4904Srs200217 "(Lcom/apple/dnssd/DNSSDService;IILjava/lang/String;Ljava/lang/String;ILcom/apple/dnssd/TXTRecord;)V");
485*4904Srs200217 else
486*4904Srs200217 err = kDNSServiceErr_BadParam;
487*4904Srs200217
488*4904Srs200217 if ( pContext != NULL)
489*4904Srs200217 {
490*4904Srs200217 const char *servStr = SafeGetUTFChars( pEnv, serviceName);
491*4904Srs200217 const char *regStr = SafeGetUTFChars( pEnv, regType);
492*4904Srs200217 const char *domainStr = SafeGetUTFChars( pEnv, domain);
493*4904Srs200217
494*4904Srs200217 err = DNSServiceResolve( &pContext->ServiceRef, flags, ifIndex,
495*4904Srs200217 servStr, regStr, domainStr, ServiceResolveReply, pContext);
496*4904Srs200217 if ( err == kDNSServiceErr_NoError)
497*4904Srs200217 {
498*4904Srs200217 (*pEnv)->SetLongField( pEnv, pThis, contextField, (jlong) pContext);
499*4904Srs200217 }
500*4904Srs200217
501*4904Srs200217 SafeReleaseUTFChars( pEnv, serviceName, servStr);
502*4904Srs200217 SafeReleaseUTFChars( pEnv, regType, regStr);
503*4904Srs200217 SafeReleaseUTFChars( pEnv, domain, domainStr);
504*4904Srs200217 }
505*4904Srs200217 else
506*4904Srs200217 err = kDNSServiceErr_NoMemory;
507*4904Srs200217
508*4904Srs200217 return err;
509*4904Srs200217 }
510*4904Srs200217
511*4904Srs200217
ServiceRegisterReply(DNSServiceRef sdRef _UNUSED,DNSServiceFlags flags,DNSServiceErrorType errorCode,const char * serviceName,const char * regType,const char * domain,void * context)512*4904Srs200217 static void DNSSD_API ServiceRegisterReply( DNSServiceRef sdRef _UNUSED, DNSServiceFlags flags,
513*4904Srs200217 DNSServiceErrorType errorCode, const char *serviceName,
514*4904Srs200217 const char *regType, const char *domain, void *context)
515*4904Srs200217 {
516*4904Srs200217 OpContext *pContext = (OpContext*) context;
517*4904Srs200217
518*4904Srs200217 SetupCallbackState( &pContext->Env);
519*4904Srs200217
520*4904Srs200217 if ( pContext->ClientObj != NULL && pContext->Callback != NULL)
521*4904Srs200217 {
522*4904Srs200217 if ( errorCode == kDNSServiceErr_NoError)
523*4904Srs200217 {
524*4904Srs200217 (*pContext->Env)->CallVoidMethod( pContext->Env, pContext->ClientObj, pContext->Callback,
525*4904Srs200217 pContext->JavaObj, flags,
526*4904Srs200217 (*pContext->Env)->NewStringUTF( pContext->Env, serviceName),
527*4904Srs200217 (*pContext->Env)->NewStringUTF( pContext->Env, regType),
528*4904Srs200217 (*pContext->Env)->NewStringUTF( pContext->Env, domain));
529*4904Srs200217 }
530*4904Srs200217 else
531*4904Srs200217 ReportError( pContext->Env, pContext->ClientObj, pContext->JavaObj, errorCode);
532*4904Srs200217 }
533*4904Srs200217 TeardownCallbackState();
534*4904Srs200217 }
535*4904Srs200217
Java_com_apple_dnssd_AppleRegistration_BeginRegister(JNIEnv * pEnv,jobject pThis,jint ifIndex,jint flags,jstring serviceName,jstring regType,jstring domain,jstring host,jint port,jbyteArray txtRecord)536*4904Srs200217 JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleRegistration_BeginRegister( JNIEnv *pEnv, jobject pThis,
537*4904Srs200217 jint ifIndex, jint flags, jstring serviceName, jstring regType,
538*4904Srs200217 jstring domain, jstring host, jint port, jbyteArray txtRecord)
539*4904Srs200217 {
540*4904Srs200217 //syslog(LOG_ERR, "BR");
541*4904Srs200217 jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
542*4904Srs200217 jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
543*4904Srs200217 OpContext *pContext = NULL;
544*4904Srs200217 DNSServiceErrorType err = kDNSServiceErr_NoError;
545*4904Srs200217 jbyte *pBytes;
546*4904Srs200217 jsize numBytes;
547*4904Srs200217
548*4904Srs200217 //syslog(LOG_ERR, "BR: contextField %d", contextField);
549*4904Srs200217
550*4904Srs200217 if ( contextField != 0)
551*4904Srs200217 pContext = NewContext( pEnv, pThis, "serviceRegistered",
552*4904Srs200217 "(Lcom/apple/dnssd/DNSSDRegistration;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
553*4904Srs200217 else
554*4904Srs200217 err = kDNSServiceErr_BadParam;
555*4904Srs200217
556*4904Srs200217 if ( pContext != NULL)
557*4904Srs200217 {
558*4904Srs200217 const char *servStr = SafeGetUTFChars( pEnv, serviceName);
559*4904Srs200217 const char *regStr = SafeGetUTFChars( pEnv, regType);
560*4904Srs200217 const char *domainStr = SafeGetUTFChars( pEnv, domain);
561*4904Srs200217 const char *hostStr = SafeGetUTFChars( pEnv, host);
562*4904Srs200217
563*4904Srs200217 //syslog(LOG_ERR, "BR: regStr %s", regStr);
564*4904Srs200217
565*4904Srs200217 // Since Java ints are defined to be big-endian, we de-canonicalize 'port' from a
566*4904Srs200217 // big-endian number into a 16-bit pattern here.
567*4904Srs200217 uint16_t portBits = port;
568*4904Srs200217 portBits = ( ((unsigned char*) &portBits)[0] << 8) | ((unsigned char*) &portBits)[1];
569*4904Srs200217
570*4904Srs200217 pBytes = txtRecord ? (*pEnv)->GetByteArrayElements( pEnv, txtRecord, NULL) : NULL;
571*4904Srs200217 numBytes = txtRecord ? (*pEnv)->GetArrayLength( pEnv, txtRecord) : 0;
572*4904Srs200217
573*4904Srs200217 err = DNSServiceRegister( &pContext->ServiceRef, flags, ifIndex, servStr, regStr,
574*4904Srs200217 domainStr, hostStr, portBits,
575*4904Srs200217 numBytes, pBytes, ServiceRegisterReply, pContext);
576*4904Srs200217 if ( err == kDNSServiceErr_NoError)
577*4904Srs200217 {
578*4904Srs200217 (*pEnv)->SetLongField( pEnv, pThis, contextField, (jlong) pContext);
579*4904Srs200217 }
580*4904Srs200217
581*4904Srs200217 if ( pBytes != NULL)
582*4904Srs200217 (*pEnv)->ReleaseByteArrayElements( pEnv, txtRecord, pBytes, 0);
583*4904Srs200217
584*4904Srs200217 SafeReleaseUTFChars( pEnv, serviceName, servStr);
585*4904Srs200217 SafeReleaseUTFChars( pEnv, regType, regStr);
586*4904Srs200217 SafeReleaseUTFChars( pEnv, domain, domainStr);
587*4904Srs200217 SafeReleaseUTFChars( pEnv, host, hostStr);
588*4904Srs200217 }
589*4904Srs200217 else
590*4904Srs200217 err = kDNSServiceErr_NoMemory;
591*4904Srs200217
592*4904Srs200217 return err;
593*4904Srs200217 }
594*4904Srs200217
Java_com_apple_dnssd_AppleRegistration_AddRecord(JNIEnv * pEnv,jobject pThis,jint flags,jint rrType,jbyteArray rData,jint ttl,jobject destObj)595*4904Srs200217 JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleRegistration_AddRecord( JNIEnv *pEnv, jobject pThis,
596*4904Srs200217 jint flags, jint rrType, jbyteArray rData, jint ttl, jobject destObj)
597*4904Srs200217 {
598*4904Srs200217 jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
599*4904Srs200217 jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
600*4904Srs200217 jclass destCls = (*pEnv)->GetObjectClass( pEnv, destObj);
601*4904Srs200217 jfieldID recField = (*pEnv)->GetFieldID( pEnv, destCls, "fRecord", "J");
602*4904Srs200217 OpContext *pContext = NULL;
603*4904Srs200217 DNSServiceErrorType err = kDNSServiceErr_NoError;
604*4904Srs200217 jbyte *pBytes;
605*4904Srs200217 jsize numBytes;
606*4904Srs200217 DNSRecordRef recRef;
607*4904Srs200217
608*4904Srs200217 if ( contextField != 0)
609*4904Srs200217 pContext = (OpContext*) (*pEnv)->GetLongField( pEnv, pThis, contextField);
610*4904Srs200217 if ( pContext == NULL || pContext->ServiceRef == NULL)
611*4904Srs200217 return kDNSServiceErr_BadParam;
612*4904Srs200217
613*4904Srs200217 pBytes = (*pEnv)->GetByteArrayElements( pEnv, rData, NULL);
614*4904Srs200217 numBytes = (*pEnv)->GetArrayLength( pEnv, rData);
615*4904Srs200217
616*4904Srs200217 err = DNSServiceAddRecord( pContext->ServiceRef, &recRef, flags, rrType, numBytes, pBytes, ttl);
617*4904Srs200217 if ( err == kDNSServiceErr_NoError)
618*4904Srs200217 {
619*4904Srs200217 (*pEnv)->SetLongField( pEnv, destObj, recField, (jlong) recRef);
620*4904Srs200217 }
621*4904Srs200217
622*4904Srs200217 if ( pBytes != NULL)
623*4904Srs200217 (*pEnv)->ReleaseByteArrayElements( pEnv, rData, pBytes, 0);
624*4904Srs200217
625*4904Srs200217 return err;
626*4904Srs200217 }
627*4904Srs200217
Java_com_apple_dnssd_AppleDNSRecord_Update(JNIEnv * pEnv,jobject pThis,jint flags,jbyteArray rData,jint ttl)628*4904Srs200217 JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDNSRecord_Update( JNIEnv *pEnv, jobject pThis,
629*4904Srs200217 jint flags, jbyteArray rData, jint ttl)
630*4904Srs200217 {
631*4904Srs200217 jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
632*4904Srs200217 jfieldID ownerField = (*pEnv)->GetFieldID( pEnv, cls, "fOwner", "Lcom/apple/dnssd/AppleService;");
633*4904Srs200217 jfieldID recField = (*pEnv)->GetFieldID( pEnv, cls, "fRecord", "J");
634*4904Srs200217 OpContext *pContext = NULL;
635*4904Srs200217 DNSServiceErrorType err = kDNSServiceErr_NoError;
636*4904Srs200217 jbyte *pBytes;
637*4904Srs200217 jsize numBytes;
638*4904Srs200217 DNSRecordRef recRef = NULL;
639*4904Srs200217
640*4904Srs200217 if ( ownerField != 0)
641*4904Srs200217 {
642*4904Srs200217 jobject ownerObj = (*pEnv)->GetObjectField( pEnv, pThis, ownerField);
643*4904Srs200217 jclass ownerClass = (*pEnv)->GetObjectClass( pEnv, ownerObj);
644*4904Srs200217 jfieldID contextField = (*pEnv)->GetFieldID( pEnv, ownerClass, "fNativeContext", "J");
645*4904Srs200217 if ( contextField != 0)
646*4904Srs200217 pContext = (OpContext*) (*pEnv)->GetLongField( pEnv, ownerObj, contextField);
647*4904Srs200217 }
648*4904Srs200217 if ( recField != 0)
649*4904Srs200217 recRef = (DNSRecordRef) (*pEnv)->GetLongField( pEnv, pThis, recField);
650*4904Srs200217 if ( pContext == NULL || pContext->ServiceRef == NULL)
651*4904Srs200217 return kDNSServiceErr_BadParam;
652*4904Srs200217
653*4904Srs200217 pBytes = (*pEnv)->GetByteArrayElements( pEnv, rData, NULL);
654*4904Srs200217 numBytes = (*pEnv)->GetArrayLength( pEnv, rData);
655*4904Srs200217
656*4904Srs200217 err = DNSServiceUpdateRecord( pContext->ServiceRef, recRef, flags, numBytes, pBytes, ttl);
657*4904Srs200217
658*4904Srs200217 if ( pBytes != NULL)
659*4904Srs200217 (*pEnv)->ReleaseByteArrayElements( pEnv, rData, pBytes, 0);
660*4904Srs200217
661*4904Srs200217 return err;
662*4904Srs200217 }
663*4904Srs200217
Java_com_apple_dnssd_AppleDNSRecord_Remove(JNIEnv * pEnv,jobject pThis)664*4904Srs200217 JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDNSRecord_Remove( JNIEnv *pEnv, jobject pThis)
665*4904Srs200217 {
666*4904Srs200217 jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
667*4904Srs200217 jfieldID ownerField = (*pEnv)->GetFieldID( pEnv, cls, "fOwner", "Lcom/apple/dnssd/AppleService;");
668*4904Srs200217 jfieldID recField = (*pEnv)->GetFieldID( pEnv, cls, "fRecord", "J");
669*4904Srs200217 OpContext *pContext = NULL;
670*4904Srs200217 DNSServiceErrorType err = kDNSServiceErr_NoError;
671*4904Srs200217 DNSRecordRef recRef = NULL;
672*4904Srs200217
673*4904Srs200217 if ( ownerField != 0)
674*4904Srs200217 {
675*4904Srs200217 jobject ownerObj = (*pEnv)->GetObjectField( pEnv, pThis, ownerField);
676*4904Srs200217 jclass ownerClass = (*pEnv)->GetObjectClass( pEnv, ownerObj);
677*4904Srs200217 jfieldID contextField = (*pEnv)->GetFieldID( pEnv, ownerClass, "fNativeContext", "J");
678*4904Srs200217 if ( contextField != 0)
679*4904Srs200217 pContext = (OpContext*) (*pEnv)->GetLongField( pEnv, ownerObj, contextField);
680*4904Srs200217 }
681*4904Srs200217 if ( recField != 0)
682*4904Srs200217 recRef = (DNSRecordRef) (*pEnv)->GetLongField( pEnv, pThis, recField);
683*4904Srs200217 if ( pContext == NULL || pContext->ServiceRef == NULL)
684*4904Srs200217 return kDNSServiceErr_BadParam;
685*4904Srs200217
686*4904Srs200217 err = DNSServiceRemoveRecord( pContext->ServiceRef, recRef, 0);
687*4904Srs200217
688*4904Srs200217 return err;
689*4904Srs200217 }
690*4904Srs200217
691*4904Srs200217
Java_com_apple_dnssd_AppleRecordRegistrar_CreateConnection(JNIEnv * pEnv,jobject pThis)692*4904Srs200217 JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleRecordRegistrar_CreateConnection( JNIEnv *pEnv, jobject pThis)
693*4904Srs200217 {
694*4904Srs200217 jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
695*4904Srs200217 jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
696*4904Srs200217 OpContext *pContext = NULL;
697*4904Srs200217 DNSServiceErrorType err = kDNSServiceErr_NoError;
698*4904Srs200217
699*4904Srs200217 if ( contextField != 0)
700*4904Srs200217 pContext = NewContext( pEnv, pThis, "recordRegistered", "(Lcom/apple/dnssd/DNSRecord;I)V");
701*4904Srs200217 else
702*4904Srs200217 err = kDNSServiceErr_BadParam;
703*4904Srs200217
704*4904Srs200217 if ( pContext != NULL)
705*4904Srs200217 {
706*4904Srs200217 err = DNSServiceCreateConnection( &pContext->ServiceRef);
707*4904Srs200217 if ( err == kDNSServiceErr_NoError)
708*4904Srs200217 {
709*4904Srs200217 (*pEnv)->SetLongField( pEnv, pThis, contextField, (jlong) pContext);
710*4904Srs200217 }
711*4904Srs200217 }
712*4904Srs200217 else
713*4904Srs200217 err = kDNSServiceErr_NoMemory;
714*4904Srs200217
715*4904Srs200217 return err;
716*4904Srs200217 }
717*4904Srs200217
718*4904Srs200217 struct RecordRegistrationRef
719*4904Srs200217 {
720*4904Srs200217 OpContext *Context;
721*4904Srs200217 jobject RecordObj;
722*4904Srs200217 };
723*4904Srs200217 typedef struct RecordRegistrationRef RecordRegistrationRef;
724*4904Srs200217
RegisterRecordReply(DNSServiceRef sdRef _UNUSED,DNSRecordRef recordRef _UNUSED,DNSServiceFlags flags,DNSServiceErrorType errorCode,void * context)725*4904Srs200217 static void DNSSD_API RegisterRecordReply( DNSServiceRef sdRef _UNUSED,
726*4904Srs200217 DNSRecordRef recordRef _UNUSED, DNSServiceFlags flags,
727*4904Srs200217 DNSServiceErrorType errorCode, void *context)
728*4904Srs200217 {
729*4904Srs200217 RecordRegistrationRef *regEnvelope = (RecordRegistrationRef*) context;
730*4904Srs200217 OpContext *pContext = regEnvelope->Context;
731*4904Srs200217
732*4904Srs200217 SetupCallbackState( &pContext->Env);
733*4904Srs200217
734*4904Srs200217 if ( pContext->ClientObj != NULL && pContext->Callback != NULL)
735*4904Srs200217 {
736*4904Srs200217 if ( errorCode == kDNSServiceErr_NoError)
737*4904Srs200217 {
738*4904Srs200217 (*pContext->Env)->CallVoidMethod( pContext->Env, pContext->ClientObj, pContext->Callback,
739*4904Srs200217 regEnvelope->RecordObj, flags);
740*4904Srs200217 }
741*4904Srs200217 else
742*4904Srs200217 ReportError( pContext->Env, pContext->ClientObj, pContext->JavaObj, errorCode);
743*4904Srs200217 }
744*4904Srs200217
745*4904Srs200217 (*pContext->Env)->DeleteWeakGlobalRef( pContext->Env, regEnvelope->RecordObj);
746*4904Srs200217 free( regEnvelope);
747*4904Srs200217
748*4904Srs200217 TeardownCallbackState();
749*4904Srs200217 }
750*4904Srs200217
Java_com_apple_dnssd_AppleRecordRegistrar_RegisterRecord(JNIEnv * pEnv,jobject pThis,jint flags,jint ifIndex,jstring fullname,jint rrType,jint rrClass,jbyteArray rData,jint ttl,jobject destObj)751*4904Srs200217 JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleRecordRegistrar_RegisterRecord( JNIEnv *pEnv, jobject pThis,
752*4904Srs200217 jint flags, jint ifIndex, jstring fullname, jint rrType, jint rrClass,
753*4904Srs200217 jbyteArray rData, jint ttl, jobject destObj)
754*4904Srs200217 {
755*4904Srs200217 jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
756*4904Srs200217 jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
757*4904Srs200217 jclass destCls = (*pEnv)->GetObjectClass( pEnv, destObj);
758*4904Srs200217 jfieldID recField = (*pEnv)->GetFieldID( pEnv, destCls, "fRecord", "J");
759*4904Srs200217 const char *nameStr = SafeGetUTFChars( pEnv, fullname);
760*4904Srs200217 OpContext *pContext = NULL;
761*4904Srs200217 DNSServiceErrorType err = kDNSServiceErr_NoError;
762*4904Srs200217 jbyte *pBytes;
763*4904Srs200217 jsize numBytes;
764*4904Srs200217 DNSRecordRef recRef;
765*4904Srs200217 RecordRegistrationRef *regEnvelope;
766*4904Srs200217
767*4904Srs200217 if ( contextField != 0)
768*4904Srs200217 pContext = (OpContext*) (*pEnv)->GetLongField( pEnv, pThis, contextField);
769*4904Srs200217 if ( pContext == NULL || pContext->ServiceRef == NULL || nameStr == NULL)
770*4904Srs200217 return kDNSServiceErr_BadParam;
771*4904Srs200217
772*4904Srs200217 regEnvelope = calloc( 1, sizeof *regEnvelope);
773*4904Srs200217 if ( regEnvelope == NULL)
774*4904Srs200217 return kDNSServiceErr_NoMemory;
775*4904Srs200217 regEnvelope->Context = pContext;
776*4904Srs200217 regEnvelope->RecordObj = (*pEnv)->NewWeakGlobalRef( pEnv, destObj); // must convert local ref to global to cache
777*4904Srs200217
778*4904Srs200217 pBytes = (*pEnv)->GetByteArrayElements( pEnv, rData, NULL);
779*4904Srs200217 numBytes = (*pEnv)->GetArrayLength( pEnv, rData);
780*4904Srs200217
781*4904Srs200217 err = DNSServiceRegisterRecord( pContext->ServiceRef, &recRef, flags, ifIndex,
782*4904Srs200217 nameStr, rrType, rrClass, numBytes, pBytes, ttl,
783*4904Srs200217 RegisterRecordReply, regEnvelope);
784*4904Srs200217
785*4904Srs200217 if ( err == kDNSServiceErr_NoError)
786*4904Srs200217 {
787*4904Srs200217 (*pEnv)->SetLongField( pEnv, destObj, recField, (jlong) recRef);
788*4904Srs200217 }
789*4904Srs200217 else
790*4904Srs200217 {
791*4904Srs200217 if ( regEnvelope->RecordObj != NULL)
792*4904Srs200217 (*pEnv)->DeleteWeakGlobalRef( pEnv, regEnvelope->RecordObj);
793*4904Srs200217 free( regEnvelope);
794*4904Srs200217 }
795*4904Srs200217
796*4904Srs200217 if ( pBytes != NULL)
797*4904Srs200217 (*pEnv)->ReleaseByteArrayElements( pEnv, rData, pBytes, 0);
798*4904Srs200217
799*4904Srs200217 SafeReleaseUTFChars( pEnv, fullname, nameStr);
800*4904Srs200217
801*4904Srs200217 return err;
802*4904Srs200217 }
803*4904Srs200217
804*4904Srs200217
ServiceQueryReply(DNSServiceRef sdRef _UNUSED,DNSServiceFlags flags,uint32_t interfaceIndex,DNSServiceErrorType errorCode,const char * serviceName,uint16_t rrtype,uint16_t rrclass,uint16_t rdlen,const void * rdata,uint32_t ttl,void * context)805*4904Srs200217 static void DNSSD_API ServiceQueryReply( DNSServiceRef sdRef _UNUSED, DNSServiceFlags flags, uint32_t interfaceIndex,
806*4904Srs200217 DNSServiceErrorType errorCode, const char *serviceName,
807*4904Srs200217 uint16_t rrtype, uint16_t rrclass, uint16_t rdlen,
808*4904Srs200217 const void *rdata, uint32_t ttl, void *context)
809*4904Srs200217 {
810*4904Srs200217 OpContext *pContext = (OpContext*) context;
811*4904Srs200217 jbyteArray rDataObj;
812*4904Srs200217 jbyte *pBytes;
813*4904Srs200217
814*4904Srs200217 SetupCallbackState( &pContext->Env);
815*4904Srs200217
816*4904Srs200217 if ( pContext->ClientObj != NULL && pContext->Callback != NULL &&
817*4904Srs200217 NULL != ( rDataObj = (*pContext->Env)->NewByteArray( pContext->Env, rdlen)))
818*4904Srs200217 {
819*4904Srs200217 if ( errorCode == kDNSServiceErr_NoError)
820*4904Srs200217 {
821*4904Srs200217 // Initialize rDataObj with contents of rdata
822*4904Srs200217 pBytes = (*pContext->Env)->GetByteArrayElements( pContext->Env, rDataObj, NULL);
823*4904Srs200217 memcpy( pBytes, rdata, rdlen);
824*4904Srs200217 (*pContext->Env)->ReleaseByteArrayElements( pContext->Env, rDataObj, pBytes, JNI_COMMIT);
825*4904Srs200217
826*4904Srs200217 (*pContext->Env)->CallVoidMethod( pContext->Env, pContext->ClientObj, pContext->Callback,
827*4904Srs200217 pContext->JavaObj, flags, interfaceIndex,
828*4904Srs200217 (*pContext->Env)->NewStringUTF( pContext->Env, serviceName),
829*4904Srs200217 rrtype, rrclass, rDataObj, ttl);
830*4904Srs200217 }
831*4904Srs200217 else
832*4904Srs200217 ReportError( pContext->Env, pContext->ClientObj, pContext->JavaObj, errorCode);
833*4904Srs200217 }
834*4904Srs200217 TeardownCallbackState();
835*4904Srs200217 }
836*4904Srs200217
Java_com_apple_dnssd_AppleQuery_CreateQuery(JNIEnv * pEnv,jobject pThis,jint flags,jint ifIndex,jstring serviceName,jint rrtype,jint rrclass)837*4904Srs200217 JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleQuery_CreateQuery( JNIEnv *pEnv, jobject pThis,
838*4904Srs200217 jint flags, jint ifIndex, jstring serviceName, jint rrtype, jint rrclass)
839*4904Srs200217 {
840*4904Srs200217 jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
841*4904Srs200217 jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
842*4904Srs200217 OpContext *pContext = NULL;
843*4904Srs200217 DNSServiceErrorType err = kDNSServiceErr_NoError;
844*4904Srs200217
845*4904Srs200217 if ( contextField != 0)
846*4904Srs200217 pContext = NewContext( pEnv, pThis, "queryAnswered",
847*4904Srs200217 "(Lcom/apple/dnssd/DNSSDService;IILjava/lang/String;II[BI)V");
848*4904Srs200217 else
849*4904Srs200217 err = kDNSServiceErr_BadParam;
850*4904Srs200217
851*4904Srs200217 if ( pContext != NULL)
852*4904Srs200217 {
853*4904Srs200217 const char *servStr = SafeGetUTFChars( pEnv, serviceName);
854*4904Srs200217
855*4904Srs200217 err = DNSServiceQueryRecord( &pContext->ServiceRef, flags, ifIndex, servStr,
856*4904Srs200217 rrtype, rrclass, ServiceQueryReply, pContext);
857*4904Srs200217 if ( err == kDNSServiceErr_NoError)
858*4904Srs200217 {
859*4904Srs200217 (*pEnv)->SetLongField( pEnv, pThis, contextField, (jlong) pContext);
860*4904Srs200217 }
861*4904Srs200217
862*4904Srs200217 SafeReleaseUTFChars( pEnv, serviceName, servStr);
863*4904Srs200217 }
864*4904Srs200217 else
865*4904Srs200217 err = kDNSServiceErr_NoMemory;
866*4904Srs200217
867*4904Srs200217 return err;
868*4904Srs200217 }
869*4904Srs200217
870*4904Srs200217
DomainEnumReply(DNSServiceRef sdRef _UNUSED,DNSServiceFlags flags,uint32_t interfaceIndex,DNSServiceErrorType errorCode,const char * replyDomain,void * context)871*4904Srs200217 static void DNSSD_API DomainEnumReply( DNSServiceRef sdRef _UNUSED, DNSServiceFlags flags, uint32_t interfaceIndex,
872*4904Srs200217 DNSServiceErrorType errorCode, const char *replyDomain, void *context)
873*4904Srs200217 {
874*4904Srs200217 OpContext *pContext = (OpContext*) context;
875*4904Srs200217
876*4904Srs200217 SetupCallbackState( &pContext->Env);
877*4904Srs200217
878*4904Srs200217 if ( pContext->ClientObj != NULL && pContext->Callback != NULL)
879*4904Srs200217 {
880*4904Srs200217 if ( errorCode == kDNSServiceErr_NoError)
881*4904Srs200217 {
882*4904Srs200217 (*pContext->Env)->CallVoidMethod( pContext->Env, pContext->ClientObj,
883*4904Srs200217 ( flags & kDNSServiceFlagsAdd) != 0 ? pContext->Callback : pContext->Callback2,
884*4904Srs200217 pContext->JavaObj, flags, interfaceIndex,
885*4904Srs200217 (*pContext->Env)->NewStringUTF( pContext->Env, replyDomain));
886*4904Srs200217 }
887*4904Srs200217 else
888*4904Srs200217 ReportError( pContext->Env, pContext->ClientObj, pContext->JavaObj, errorCode);
889*4904Srs200217 }
890*4904Srs200217 TeardownCallbackState();
891*4904Srs200217 }
892*4904Srs200217
Java_com_apple_dnssd_AppleDomainEnum_BeginEnum(JNIEnv * pEnv,jobject pThis,jint flags,jint ifIndex)893*4904Srs200217 JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDomainEnum_BeginEnum( JNIEnv *pEnv, jobject pThis,
894*4904Srs200217 jint flags, jint ifIndex)
895*4904Srs200217 {
896*4904Srs200217 jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
897*4904Srs200217 jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
898*4904Srs200217 OpContext *pContext = NULL;
899*4904Srs200217 DNSServiceErrorType err = kDNSServiceErr_NoError;
900*4904Srs200217
901*4904Srs200217 if ( contextField != 0)
902*4904Srs200217 pContext = NewContext( pEnv, pThis, "domainFound",
903*4904Srs200217 "(Lcom/apple/dnssd/DNSSDService;IILjava/lang/String;)V");
904*4904Srs200217 else
905*4904Srs200217 err = kDNSServiceErr_BadParam;
906*4904Srs200217
907*4904Srs200217 if ( pContext != NULL)
908*4904Srs200217 {
909*4904Srs200217 pContext->Callback2 = (*pEnv)->GetMethodID( pEnv,
910*4904Srs200217 (*pEnv)->GetObjectClass( pEnv, pContext->ClientObj),
911*4904Srs200217 "domainLost", "(Lcom/apple/dnssd/DNSSDService;IILjava/lang/String;)V");
912*4904Srs200217
913*4904Srs200217 err = DNSServiceEnumerateDomains( &pContext->ServiceRef, flags, ifIndex,
914*4904Srs200217 DomainEnumReply, pContext);
915*4904Srs200217 if ( err == kDNSServiceErr_NoError)
916*4904Srs200217 {
917*4904Srs200217 (*pEnv)->SetLongField( pEnv, pThis, contextField, (jlong) pContext);
918*4904Srs200217 }
919*4904Srs200217 }
920*4904Srs200217 else
921*4904Srs200217 err = kDNSServiceErr_NoMemory;
922*4904Srs200217
923*4904Srs200217 return err;
924*4904Srs200217 }
925*4904Srs200217
926*4904Srs200217
Java_com_apple_dnssd_AppleDNSSD_ConstructName(JNIEnv * pEnv,jobject pThis _UNUSED,jstring serviceName,jstring regtype,jstring domain,jobjectArray pOut)927*4904Srs200217 JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDNSSD_ConstructName( JNIEnv *pEnv, jobject pThis _UNUSED,
928*4904Srs200217 jstring serviceName, jstring regtype, jstring domain, jobjectArray pOut)
929*4904Srs200217 {
930*4904Srs200217 DNSServiceErrorType err = kDNSServiceErr_NoError;
931*4904Srs200217 const char *nameStr = SafeGetUTFChars( pEnv, serviceName);
932*4904Srs200217 const char *regStr = SafeGetUTFChars( pEnv, regtype);
933*4904Srs200217 const char *domStr = SafeGetUTFChars( pEnv, domain);
934*4904Srs200217 char buff[ kDNSServiceMaxDomainName + 1];
935*4904Srs200217
936*4904Srs200217 err = DNSServiceConstructFullName( buff, nameStr, regStr, domStr);
937*4904Srs200217
938*4904Srs200217 if ( err == kDNSServiceErr_NoError)
939*4904Srs200217 {
940*4904Srs200217 // pOut is expected to be a String[1] array.
941*4904Srs200217 (*pEnv)->SetObjectArrayElement( pEnv, pOut, 0, (*pEnv)->NewStringUTF( pEnv, buff));
942*4904Srs200217 }
943*4904Srs200217
944*4904Srs200217 SafeReleaseUTFChars( pEnv, serviceName, nameStr);
945*4904Srs200217 SafeReleaseUTFChars( pEnv, regtype, regStr);
946*4904Srs200217 SafeReleaseUTFChars( pEnv, domain, domStr);
947*4904Srs200217
948*4904Srs200217 return err;
949*4904Srs200217 }
950*4904Srs200217
Java_com_apple_dnssd_AppleDNSSD_ReconfirmRecord(JNIEnv * pEnv,jobject pThis _UNUSED,jint flags,jint ifIndex,jstring fullName,jint rrtype,jint rrclass,jbyteArray rdata)951*4904Srs200217 JNIEXPORT void JNICALL Java_com_apple_dnssd_AppleDNSSD_ReconfirmRecord( JNIEnv *pEnv, jobject pThis _UNUSED,
952*4904Srs200217 jint flags, jint ifIndex, jstring fullName,
953*4904Srs200217 jint rrtype, jint rrclass, jbyteArray rdata)
954*4904Srs200217 {
955*4904Srs200217 jbyte *pBytes;
956*4904Srs200217 jsize numBytes;
957*4904Srs200217 const char *nameStr = SafeGetUTFChars( pEnv, fullName);
958*4904Srs200217
959*4904Srs200217 pBytes = (*pEnv)->GetByteArrayElements( pEnv, rdata, NULL);
960*4904Srs200217 numBytes = (*pEnv)->GetArrayLength( pEnv, rdata);
961*4904Srs200217
962*4904Srs200217 DNSServiceReconfirmRecord( flags, ifIndex, nameStr, rrtype, rrclass, numBytes, pBytes);
963*4904Srs200217
964*4904Srs200217 if ( pBytes != NULL)
965*4904Srs200217 (*pEnv)->ReleaseByteArrayElements( pEnv, rdata, pBytes, 0);
966*4904Srs200217
967*4904Srs200217 SafeReleaseUTFChars( pEnv, fullName, nameStr);
968*4904Srs200217 }
969*4904Srs200217
970*4904Srs200217 #define LOCAL_ONLY_NAME "loo"
971*4904Srs200217
Java_com_apple_dnssd_AppleDNSSD_GetNameForIfIndex(JNIEnv * pEnv,jobject pThis _UNUSED,jint ifIndex)972*4904Srs200217 JNIEXPORT jstring JNICALL Java_com_apple_dnssd_AppleDNSSD_GetNameForIfIndex( JNIEnv *pEnv, jobject pThis _UNUSED,
973*4904Srs200217 jint ifIndex)
974*4904Srs200217 {
975*4904Srs200217 char *p = LOCAL_ONLY_NAME, nameBuff[IF_NAMESIZE];
976*4904Srs200217
977*4904Srs200217 if (ifIndex != (jint) kDNSServiceInterfaceIndexLocalOnly)
978*4904Srs200217 p = if_indextoname( ifIndex, nameBuff );
979*4904Srs200217
980*4904Srs200217 return (*pEnv)->NewStringUTF( pEnv, p);
981*4904Srs200217 }
982*4904Srs200217
983*4904Srs200217
Java_com_apple_dnssd_AppleDNSSD_GetIfIndexForName(JNIEnv * pEnv,jobject pThis _UNUSED,jstring ifName)984*4904Srs200217 JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDNSSD_GetIfIndexForName( JNIEnv *pEnv, jobject pThis _UNUSED,
985*4904Srs200217 jstring ifName)
986*4904Srs200217 {
987*4904Srs200217 uint32_t ifIndex = kDNSServiceInterfaceIndexLocalOnly;
988*4904Srs200217 const char *nameStr = SafeGetUTFChars( pEnv, ifName);
989*4904Srs200217
990*4904Srs200217 if (strcmp(nameStr, LOCAL_ONLY_NAME))
991*4904Srs200217 ifIndex = if_nametoindex( nameStr);
992*4904Srs200217
993*4904Srs200217 SafeReleaseUTFChars( pEnv, ifName, nameStr);
994*4904Srs200217
995*4904Srs200217 return ifIndex;
996*4904Srs200217 }
997*4904Srs200217
998*4904Srs200217
999*4904Srs200217 #if defined(_WIN32)
1000*4904Srs200217 static char*
if_indextoname(DWORD ifIndex,char * nameBuff)1001*4904Srs200217 if_indextoname( DWORD ifIndex, char * nameBuff)
1002*4904Srs200217 {
1003*4904Srs200217 PIP_ADAPTER_INFO pAdapterInfo = NULL;
1004*4904Srs200217 PIP_ADAPTER_INFO pAdapter = NULL;
1005*4904Srs200217 DWORD dwRetVal = 0;
1006*4904Srs200217 char * ifName = NULL;
1007*4904Srs200217 ULONG ulOutBufLen = 0;
1008*4904Srs200217
1009*4904Srs200217 if (GetAdaptersInfo( NULL, &ulOutBufLen) != ERROR_BUFFER_OVERFLOW)
1010*4904Srs200217 {
1011*4904Srs200217 goto exit;
1012*4904Srs200217 }
1013*4904Srs200217
1014*4904Srs200217 pAdapterInfo = (IP_ADAPTER_INFO *) malloc(ulOutBufLen);
1015*4904Srs200217
1016*4904Srs200217 if (pAdapterInfo == NULL)
1017*4904Srs200217 {
1018*4904Srs200217 goto exit;
1019*4904Srs200217 }
1020*4904Srs200217
1021*4904Srs200217 dwRetVal = GetAdaptersInfo( pAdapterInfo, &ulOutBufLen );
1022*4904Srs200217
1023*4904Srs200217 if (dwRetVal != NO_ERROR)
1024*4904Srs200217 {
1025*4904Srs200217 goto exit;
1026*4904Srs200217 }
1027*4904Srs200217
1028*4904Srs200217 pAdapter = pAdapterInfo;
1029*4904Srs200217 while (pAdapter)
1030*4904Srs200217 {
1031*4904Srs200217 if (pAdapter->Index == ifIndex)
1032*4904Srs200217 {
1033*4904Srs200217 // It would be better if we passed in the length of nameBuff to this
1034*4904Srs200217 // function, so we would have absolute certainty that no buffer
1035*4904Srs200217 // overflows would occur. Buffer overflows *shouldn't* occur because
1036*4904Srs200217 // nameBuff is of size MAX_ADAPTER_NAME_LENGTH.
1037*4904Srs200217 strcpy( nameBuff, pAdapter->AdapterName );
1038*4904Srs200217 ifName = nameBuff;
1039*4904Srs200217 break;
1040*4904Srs200217 }
1041*4904Srs200217
1042*4904Srs200217 pAdapter = pAdapter->Next;
1043*4904Srs200217 }
1044*4904Srs200217
1045*4904Srs200217 exit:
1046*4904Srs200217
1047*4904Srs200217 if (pAdapterInfo != NULL)
1048*4904Srs200217 {
1049*4904Srs200217 free( pAdapterInfo );
1050*4904Srs200217 pAdapterInfo = NULL;
1051*4904Srs200217 }
1052*4904Srs200217
1053*4904Srs200217 return ifName;
1054*4904Srs200217 }
1055*4904Srs200217
1056*4904Srs200217
1057*4904Srs200217 static DWORD
if_nametoindex(const char * nameStr)1058*4904Srs200217 if_nametoindex( const char * nameStr )
1059*4904Srs200217 {
1060*4904Srs200217 PIP_ADAPTER_INFO pAdapterInfo = NULL;
1061*4904Srs200217 PIP_ADAPTER_INFO pAdapter = NULL;
1062*4904Srs200217 DWORD dwRetVal = 0;
1063*4904Srs200217 DWORD ifIndex = 0;
1064*4904Srs200217 ULONG ulOutBufLen = 0;
1065*4904Srs200217
1066*4904Srs200217 if (GetAdaptersInfo( NULL, &ulOutBufLen) != ERROR_BUFFER_OVERFLOW)
1067*4904Srs200217 {
1068*4904Srs200217 goto exit;
1069*4904Srs200217 }
1070*4904Srs200217
1071*4904Srs200217 pAdapterInfo = (IP_ADAPTER_INFO *) malloc(ulOutBufLen);
1072*4904Srs200217
1073*4904Srs200217 if (pAdapterInfo == NULL)
1074*4904Srs200217 {
1075*4904Srs200217 goto exit;
1076*4904Srs200217 }
1077*4904Srs200217
1078*4904Srs200217 dwRetVal = GetAdaptersInfo( pAdapterInfo, &ulOutBufLen );
1079*4904Srs200217
1080*4904Srs200217 if (dwRetVal != NO_ERROR)
1081*4904Srs200217 {
1082*4904Srs200217 goto exit;
1083*4904Srs200217 }
1084*4904Srs200217
1085*4904Srs200217 pAdapter = pAdapterInfo;
1086*4904Srs200217 while (pAdapter)
1087*4904Srs200217 {
1088*4904Srs200217 if (strcmp(pAdapter->AdapterName, nameStr) == 0)
1089*4904Srs200217 {
1090*4904Srs200217 ifIndex = pAdapter->Index;
1091*4904Srs200217 break;
1092*4904Srs200217 }
1093*4904Srs200217
1094*4904Srs200217 pAdapter = pAdapter->Next;
1095*4904Srs200217 }
1096*4904Srs200217
1097*4904Srs200217 exit:
1098*4904Srs200217
1099*4904Srs200217 if (pAdapterInfo != NULL)
1100*4904Srs200217 {
1101*4904Srs200217 free( pAdapterInfo );
1102*4904Srs200217 pAdapterInfo = NULL;
1103*4904Srs200217 }
1104*4904Srs200217
1105*4904Srs200217 return ifIndex;
1106*4904Srs200217 }
1107*4904Srs200217 #endif
1108