xref: /aosp_15_r20/external/mdnsresponder/mDNSWindows/mdnsNSP/mdnsNSP.c (revision 48a54d368dc4fa860885eef7b70b6c53499e7c25)
1*48a54d36SAndroid Build Coastguard Worker /* -*- Mode: C; tab-width: 4 -*-
2*48a54d36SAndroid Build Coastguard Worker  *
3*48a54d36SAndroid Build Coastguard Worker  * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
4*48a54d36SAndroid Build Coastguard Worker  *
5*48a54d36SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
6*48a54d36SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
7*48a54d36SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
8*48a54d36SAndroid Build Coastguard Worker  *
9*48a54d36SAndroid Build Coastguard Worker  *     http://www.apache.org/licenses/LICENSE-2.0
10*48a54d36SAndroid Build Coastguard Worker  *
11*48a54d36SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
12*48a54d36SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
13*48a54d36SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*48a54d36SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
15*48a54d36SAndroid Build Coastguard Worker  * limitations under the License.
16*48a54d36SAndroid Build Coastguard Worker  */
17*48a54d36SAndroid Build Coastguard Worker 
18*48a54d36SAndroid Build Coastguard Worker 
19*48a54d36SAndroid Build Coastguard Worker #include	<stdio.h>
20*48a54d36SAndroid Build Coastguard Worker #include	<stdlib.h>
21*48a54d36SAndroid Build Coastguard Worker #include	<string.h>
22*48a54d36SAndroid Build Coastguard Worker 
23*48a54d36SAndroid Build Coastguard Worker #include	"ClientCommon.h"
24*48a54d36SAndroid Build Coastguard Worker #include	"CommonServices.h"
25*48a54d36SAndroid Build Coastguard Worker #include	"DebugServices.h"
26*48a54d36SAndroid Build Coastguard Worker 
27*48a54d36SAndroid Build Coastguard Worker #include	<iphlpapi.h>
28*48a54d36SAndroid Build Coastguard Worker #include	<guiddef.h>
29*48a54d36SAndroid Build Coastguard Worker #include	<ws2spi.h>
30*48a54d36SAndroid Build Coastguard Worker #include	<shlwapi.h>
31*48a54d36SAndroid Build Coastguard Worker 
32*48a54d36SAndroid Build Coastguard Worker 
33*48a54d36SAndroid Build Coastguard Worker 
34*48a54d36SAndroid Build Coastguard Worker #include	"dns_sd.h"
35*48a54d36SAndroid Build Coastguard Worker 
36*48a54d36SAndroid Build Coastguard Worker #pragma comment(lib, "DelayImp.lib")
37*48a54d36SAndroid Build Coastguard Worker 
38*48a54d36SAndroid Build Coastguard Worker #ifdef _MSC_VER
39*48a54d36SAndroid Build Coastguard Worker #define swprintf _snwprintf
40*48a54d36SAndroid Build Coastguard Worker #define snprintf _snprintf
41*48a54d36SAndroid Build Coastguard Worker #endif
42*48a54d36SAndroid Build Coastguard Worker 
43*48a54d36SAndroid Build Coastguard Worker #define MAX_LABELS 128
44*48a54d36SAndroid Build Coastguard Worker 
45*48a54d36SAndroid Build Coastguard Worker #if 0
46*48a54d36SAndroid Build Coastguard Worker #pragma mark == Structures ==
47*48a54d36SAndroid Build Coastguard Worker #endif
48*48a54d36SAndroid Build Coastguard Worker 
49*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
50*48a54d36SAndroid Build Coastguard Worker //	Structures
51*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
52*48a54d36SAndroid Build Coastguard Worker 
53*48a54d36SAndroid Build Coastguard Worker typedef struct	Query *		QueryRef;
54*48a54d36SAndroid Build Coastguard Worker typedef struct	Query		Query;
55*48a54d36SAndroid Build Coastguard Worker struct	Query
56*48a54d36SAndroid Build Coastguard Worker {
57*48a54d36SAndroid Build Coastguard Worker 	QueryRef			next;
58*48a54d36SAndroid Build Coastguard Worker 	int					refCount;
59*48a54d36SAndroid Build Coastguard Worker 	DWORD				querySetFlags;
60*48a54d36SAndroid Build Coastguard Worker 	WSAQUERYSETW *		querySet;
61*48a54d36SAndroid Build Coastguard Worker 	size_t				querySetSize;
62*48a54d36SAndroid Build Coastguard Worker 	HANDLE				data4Event;
63*48a54d36SAndroid Build Coastguard Worker 	HANDLE				data6Event;
64*48a54d36SAndroid Build Coastguard Worker 	HANDLE				cancelEvent;
65*48a54d36SAndroid Build Coastguard Worker 	HANDLE				waitHandles[ 3 ];
66*48a54d36SAndroid Build Coastguard Worker 	DWORD				waitCount;
67*48a54d36SAndroid Build Coastguard Worker 	DNSServiceRef		resolver4;
68*48a54d36SAndroid Build Coastguard Worker 	DNSServiceRef		resolver6;
69*48a54d36SAndroid Build Coastguard Worker 	char				name[ kDNSServiceMaxDomainName ];
70*48a54d36SAndroid Build Coastguard Worker 	size_t				nameSize;
71*48a54d36SAndroid Build Coastguard Worker 	uint8_t				numValidAddrs;
72*48a54d36SAndroid Build Coastguard Worker 	uint32_t			addr4;
73*48a54d36SAndroid Build Coastguard Worker 	bool				addr4Valid;
74*48a54d36SAndroid Build Coastguard Worker 	uint8_t				addr6[16];
75*48a54d36SAndroid Build Coastguard Worker 	u_long				addr6ScopeId;
76*48a54d36SAndroid Build Coastguard Worker 	bool				addr6Valid;
77*48a54d36SAndroid Build Coastguard Worker };
78*48a54d36SAndroid Build Coastguard Worker 
79*48a54d36SAndroid Build Coastguard Worker #define BUFFER_INITIAL_SIZE		4192
80*48a54d36SAndroid Build Coastguard Worker #define ALIASES_INITIAL_SIZE	5
81*48a54d36SAndroid Build Coastguard Worker 
82*48a54d36SAndroid Build Coastguard Worker typedef struct HostsFile
83*48a54d36SAndroid Build Coastguard Worker {
84*48a54d36SAndroid Build Coastguard Worker 	int			m_bufferSize;
85*48a54d36SAndroid Build Coastguard Worker 	char	*	m_buffer;
86*48a54d36SAndroid Build Coastguard Worker 	FILE	*	m_fp;
87*48a54d36SAndroid Build Coastguard Worker } HostsFile;
88*48a54d36SAndroid Build Coastguard Worker 
89*48a54d36SAndroid Build Coastguard Worker 
90*48a54d36SAndroid Build Coastguard Worker typedef struct HostsFileInfo
91*48a54d36SAndroid Build Coastguard Worker {
92*48a54d36SAndroid Build Coastguard Worker 	struct hostent		m_host;
93*48a54d36SAndroid Build Coastguard Worker 	struct HostsFileInfo	*	m_next;
94*48a54d36SAndroid Build Coastguard Worker } HostsFileInfo;
95*48a54d36SAndroid Build Coastguard Worker 
96*48a54d36SAndroid Build Coastguard Worker 
97*48a54d36SAndroid Build Coastguard Worker #if 0
98*48a54d36SAndroid Build Coastguard Worker #pragma mark == Prototypes ==
99*48a54d36SAndroid Build Coastguard Worker #endif
100*48a54d36SAndroid Build Coastguard Worker 
101*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
102*48a54d36SAndroid Build Coastguard Worker //	Prototypes
103*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
104*48a54d36SAndroid Build Coastguard Worker 
105*48a54d36SAndroid Build Coastguard Worker // DLL Exports
106*48a54d36SAndroid Build Coastguard Worker 
107*48a54d36SAndroid Build Coastguard Worker BOOL WINAPI		DllMain( HINSTANCE inInstance, DWORD inReason, LPVOID inReserved );
108*48a54d36SAndroid Build Coastguard Worker STDAPI			DllRegisterServer( void );
109*48a54d36SAndroid Build Coastguard Worker STDAPI			DllRegisterServer( void );
110*48a54d36SAndroid Build Coastguard Worker 
111*48a54d36SAndroid Build Coastguard Worker 
112*48a54d36SAndroid Build Coastguard Worker // NSP SPIs
113*48a54d36SAndroid Build Coastguard Worker 
114*48a54d36SAndroid Build Coastguard Worker int	WSPAPI	NSPCleanup( LPGUID inProviderID );
115*48a54d36SAndroid Build Coastguard Worker 
116*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL int WSPAPI
117*48a54d36SAndroid Build Coastguard Worker 	NSPLookupServiceBegin(
118*48a54d36SAndroid Build Coastguard Worker 		LPGUID					inProviderID,
119*48a54d36SAndroid Build Coastguard Worker 		LPWSAQUERYSETW			inQuerySet,
120*48a54d36SAndroid Build Coastguard Worker 		LPWSASERVICECLASSINFOW	inServiceClassInfo,
121*48a54d36SAndroid Build Coastguard Worker 		DWORD					inFlags,
122*48a54d36SAndroid Build Coastguard Worker 		LPHANDLE				outLookup );
123*48a54d36SAndroid Build Coastguard Worker 
124*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL int WSPAPI
125*48a54d36SAndroid Build Coastguard Worker 	NSPLookupServiceNext(
126*48a54d36SAndroid Build Coastguard Worker 		HANDLE			inLookup,
127*48a54d36SAndroid Build Coastguard Worker 		DWORD			inFlags,
128*48a54d36SAndroid Build Coastguard Worker 		LPDWORD			ioBufferLength,
129*48a54d36SAndroid Build Coastguard Worker 		LPWSAQUERYSETW	outResults );
130*48a54d36SAndroid Build Coastguard Worker 
131*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL int WSPAPI	NSPLookupServiceEnd( HANDLE inLookup );
132*48a54d36SAndroid Build Coastguard Worker 
133*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL int WSPAPI
134*48a54d36SAndroid Build Coastguard Worker 	NSPSetService(
135*48a54d36SAndroid Build Coastguard Worker 		LPGUID					inProviderID,
136*48a54d36SAndroid Build Coastguard Worker 		LPWSASERVICECLASSINFOW	inServiceClassInfo,
137*48a54d36SAndroid Build Coastguard Worker 		LPWSAQUERYSETW			inRegInfo,
138*48a54d36SAndroid Build Coastguard Worker 		WSAESETSERVICEOP		inOperation,
139*48a54d36SAndroid Build Coastguard Worker 		DWORD					inFlags );
140*48a54d36SAndroid Build Coastguard Worker 
141*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL int WSPAPI	NSPInstallServiceClass( LPGUID inProviderID, LPWSASERVICECLASSINFOW inServiceClassInfo );
142*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL int WSPAPI	NSPRemoveServiceClass( LPGUID inProviderID, LPGUID inServiceClassID );
143*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL int WSPAPI	NSPGetServiceClassInfo(	LPGUID inProviderID, LPDWORD ioBufSize, LPWSASERVICECLASSINFOW ioServiceClassInfo );
144*48a54d36SAndroid Build Coastguard Worker 
145*48a54d36SAndroid Build Coastguard Worker // Private
146*48a54d36SAndroid Build Coastguard Worker 
147*48a54d36SAndroid Build Coastguard Worker #define	NSPLock()		EnterCriticalSection( &gLock );
148*48a54d36SAndroid Build Coastguard Worker #define	NSPUnlock()		LeaveCriticalSection( &gLock );
149*48a54d36SAndroid Build Coastguard Worker 
150*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL OSStatus	QueryCreate( const WSAQUERYSETW *inQuerySet, DWORD inQuerySetFlags, QueryRef *outRef );
151*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL OSStatus	QueryRetain( QueryRef inRef );
152*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL OSStatus	QueryRelease( QueryRef inRef );
153*48a54d36SAndroid Build Coastguard Worker 
154*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL void CALLBACK_COMPAT
155*48a54d36SAndroid Build Coastguard Worker 	QueryRecordCallback4(
156*48a54d36SAndroid Build Coastguard Worker 		DNSServiceRef		inRef,
157*48a54d36SAndroid Build Coastguard Worker 		DNSServiceFlags		inFlags,
158*48a54d36SAndroid Build Coastguard Worker 		uint32_t			inInterfaceIndex,
159*48a54d36SAndroid Build Coastguard Worker 		DNSServiceErrorType	inErrorCode,
160*48a54d36SAndroid Build Coastguard Worker 		const char *		inName,
161*48a54d36SAndroid Build Coastguard Worker 		uint16_t			inRRType,
162*48a54d36SAndroid Build Coastguard Worker 		uint16_t			inRRClass,
163*48a54d36SAndroid Build Coastguard Worker 		uint16_t			inRDataSize,
164*48a54d36SAndroid Build Coastguard Worker 		const void *		inRData,
165*48a54d36SAndroid Build Coastguard Worker 		uint32_t			inTTL,
166*48a54d36SAndroid Build Coastguard Worker 		void *				inContext );
167*48a54d36SAndroid Build Coastguard Worker 
168*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL void CALLBACK_COMPAT
169*48a54d36SAndroid Build Coastguard Worker 	QueryRecordCallback6(
170*48a54d36SAndroid Build Coastguard Worker 		DNSServiceRef		inRef,
171*48a54d36SAndroid Build Coastguard Worker 		DNSServiceFlags		inFlags,
172*48a54d36SAndroid Build Coastguard Worker 		uint32_t			inInterfaceIndex,
173*48a54d36SAndroid Build Coastguard Worker 		DNSServiceErrorType	inErrorCode,
174*48a54d36SAndroid Build Coastguard Worker 		const char *		inName,
175*48a54d36SAndroid Build Coastguard Worker 		uint16_t			inRRType,
176*48a54d36SAndroid Build Coastguard Worker 		uint16_t			inRRClass,
177*48a54d36SAndroid Build Coastguard Worker 		uint16_t			inRDataSize,
178*48a54d36SAndroid Build Coastguard Worker 		const void *		inRData,
179*48a54d36SAndroid Build Coastguard Worker 		uint32_t			inTTL,
180*48a54d36SAndroid Build Coastguard Worker 		void *				inContext );
181*48a54d36SAndroid Build Coastguard Worker 
182*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL OSStatus
183*48a54d36SAndroid Build Coastguard Worker 	QueryCopyQuerySet(
184*48a54d36SAndroid Build Coastguard Worker 		QueryRef 				inRef,
185*48a54d36SAndroid Build Coastguard Worker 		const WSAQUERYSETW *	inQuerySet,
186*48a54d36SAndroid Build Coastguard Worker 		DWORD 					inQuerySetFlags,
187*48a54d36SAndroid Build Coastguard Worker 		WSAQUERYSETW **			outQuerySet,
188*48a54d36SAndroid Build Coastguard Worker 		size_t *				outSize );
189*48a54d36SAndroid Build Coastguard Worker 
190*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL void
191*48a54d36SAndroid Build Coastguard Worker 	QueryCopyQuerySetTo(
192*48a54d36SAndroid Build Coastguard Worker 		QueryRef 				inRef,
193*48a54d36SAndroid Build Coastguard Worker 		const WSAQUERYSETW *	inQuerySet,
194*48a54d36SAndroid Build Coastguard Worker 		DWORD 					inQuerySetFlags,
195*48a54d36SAndroid Build Coastguard Worker 		WSAQUERYSETW *			outQuerySet );
196*48a54d36SAndroid Build Coastguard Worker 
197*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL size_t	QueryCopyQuerySetSize( QueryRef inRef, const WSAQUERYSETW *inQuerySet, DWORD inQuerySetFlags );
198*48a54d36SAndroid Build Coastguard Worker 
199*48a54d36SAndroid Build Coastguard Worker #if( DEBUG )
200*48a54d36SAndroid Build Coastguard Worker 	void	DebugDumpQuerySet( DebugLevel inLevel, const WSAQUERYSETW *inQuerySet );
201*48a54d36SAndroid Build Coastguard Worker 
202*48a54d36SAndroid Build Coastguard Worker 	#define	dlog_query_set( LEVEL, SET )		DebugDumpQuerySet( LEVEL, SET )
203*48a54d36SAndroid Build Coastguard Worker #else
204*48a54d36SAndroid Build Coastguard Worker 	#define	dlog_query_set( LEVEL, SET )
205*48a54d36SAndroid Build Coastguard Worker #endif
206*48a54d36SAndroid Build Coastguard Worker 
207*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL BOOL		InHostsTable( const char * name );
208*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL BOOL		IsLocalName( HostsFileInfo * node );
209*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL BOOL		IsSameName( HostsFileInfo * node, const char * name );
210*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL OSStatus	HostsFileOpen( HostsFile ** self, const char * fname );
211*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL OSStatus	HostsFileClose( HostsFile * self );
212*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL void		HostsFileInfoFree( HostsFileInfo * info );
213*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL OSStatus	HostsFileNext( HostsFile * self, HostsFileInfo ** hInfo );
214*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL DWORD		GetScopeId( DWORD ifIndex );
215*48a54d36SAndroid Build Coastguard Worker 
216*48a54d36SAndroid Build Coastguard Worker #ifdef ENABLE_REVERSE_LOOKUP
217*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL OSStatus	IsReverseLookup( LPCWSTR name, size_t size );
218*48a54d36SAndroid Build Coastguard Worker #endif
219*48a54d36SAndroid Build Coastguard Worker 
220*48a54d36SAndroid Build Coastguard Worker 
221*48a54d36SAndroid Build Coastguard Worker #if 0
222*48a54d36SAndroid Build Coastguard Worker #pragma mark == Globals ==
223*48a54d36SAndroid Build Coastguard Worker #endif
224*48a54d36SAndroid Build Coastguard Worker 
225*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
226*48a54d36SAndroid Build Coastguard Worker //	Globals
227*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
228*48a54d36SAndroid Build Coastguard Worker 
229*48a54d36SAndroid Build Coastguard Worker // {B600E6E9-553B-4a19-8696-335E5C896153}
230*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL HINSTANCE				gInstance			= NULL;
231*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL wchar_t				*	gNSPName			= L"mdnsNSP";
232*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL GUID					gNSPGUID			= { 0xb600e6e9, 0x553b, 0x4a19, { 0x86, 0x96, 0x33, 0x5e, 0x5c, 0x89, 0x61, 0x53 } };
233*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL LONG					gRefCount			= 0;
234*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL CRITICAL_SECTION		gLock;
235*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL bool					gLockInitialized 	= false;
236*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL QueryRef				gQueryList	 		= NULL;
237*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL HostsFileInfo		*	gHostsFileInfo		= NULL;
238*48a54d36SAndroid Build Coastguard Worker typedef DWORD
239*48a54d36SAndroid Build Coastguard Worker 	( WINAPI * GetAdaptersAddressesFunctionPtr )(
240*48a54d36SAndroid Build Coastguard Worker 			ULONG 					inFamily,
241*48a54d36SAndroid Build Coastguard Worker 			DWORD 					inFlags,
242*48a54d36SAndroid Build Coastguard Worker 			PVOID 					inReserved,
243*48a54d36SAndroid Build Coastguard Worker 			PIP_ADAPTER_ADDRESSES 	inAdapter,
244*48a54d36SAndroid Build Coastguard Worker 			PULONG					outBufferSize );
245*48a54d36SAndroid Build Coastguard Worker 
246*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL HMODULE								gIPHelperLibraryInstance			= NULL;
247*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL GetAdaptersAddressesFunctionPtr		gGetAdaptersAddressesFunctionPtr	= NULL;
248*48a54d36SAndroid Build Coastguard Worker 
249*48a54d36SAndroid Build Coastguard Worker 
250*48a54d36SAndroid Build Coastguard Worker 
251*48a54d36SAndroid Build Coastguard Worker #if 0
252*48a54d36SAndroid Build Coastguard Worker #pragma mark -
253*48a54d36SAndroid Build Coastguard Worker #endif
254*48a54d36SAndroid Build Coastguard Worker 
255*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
256*48a54d36SAndroid Build Coastguard Worker //	DllMain
257*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
258*48a54d36SAndroid Build Coastguard Worker 
DllMain(HINSTANCE inInstance,DWORD inReason,LPVOID inReserved)259*48a54d36SAndroid Build Coastguard Worker BOOL APIENTRY	DllMain( HINSTANCE inInstance, DWORD inReason, LPVOID inReserved )
260*48a54d36SAndroid Build Coastguard Worker {
261*48a54d36SAndroid Build Coastguard Worker 	DEBUG_USE_ONLY( inInstance );
262*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( inReserved );
263*48a54d36SAndroid Build Coastguard Worker 
264*48a54d36SAndroid Build Coastguard Worker 	switch( inReason )
265*48a54d36SAndroid Build Coastguard Worker 	{
266*48a54d36SAndroid Build Coastguard Worker 		case DLL_PROCESS_ATTACH:
267*48a54d36SAndroid Build Coastguard Worker 			gInstance = inInstance;
268*48a54d36SAndroid Build Coastguard Worker 			gHostsFileInfo	= NULL;
269*48a54d36SAndroid Build Coastguard Worker 			debug_initialize( kDebugOutputTypeWindowsEventLog, "mDNS NSP", inInstance );
270*48a54d36SAndroid Build Coastguard Worker 			debug_set_property( kDebugPropertyTagPrintLevel, kDebugLevelNotice );
271*48a54d36SAndroid Build Coastguard Worker 			dlog( kDebugLevelTrace, "\n" );
272*48a54d36SAndroid Build Coastguard Worker 			dlog( kDebugLevelVerbose, "%s: process attach\n", __ROUTINE__ );
273*48a54d36SAndroid Build Coastguard Worker 
274*48a54d36SAndroid Build Coastguard Worker 			break;
275*48a54d36SAndroid Build Coastguard Worker 
276*48a54d36SAndroid Build Coastguard Worker 		case DLL_PROCESS_DETACH:
277*48a54d36SAndroid Build Coastguard Worker 			HostsFileInfoFree( gHostsFileInfo );
278*48a54d36SAndroid Build Coastguard Worker 			gHostsFileInfo = NULL;
279*48a54d36SAndroid Build Coastguard Worker 			dlog( kDebugLevelVerbose, "%s: process detach\n", __ROUTINE__ );
280*48a54d36SAndroid Build Coastguard Worker 			break;
281*48a54d36SAndroid Build Coastguard Worker 
282*48a54d36SAndroid Build Coastguard Worker 		case DLL_THREAD_ATTACH:
283*48a54d36SAndroid Build Coastguard Worker 			dlog( kDebugLevelVerbose, "%s: thread attach\n", __ROUTINE__ );
284*48a54d36SAndroid Build Coastguard Worker 			break;
285*48a54d36SAndroid Build Coastguard Worker 
286*48a54d36SAndroid Build Coastguard Worker 		case DLL_THREAD_DETACH:
287*48a54d36SAndroid Build Coastguard Worker 			dlog( kDebugLevelVerbose, "%s: thread detach\n", __ROUTINE__ );
288*48a54d36SAndroid Build Coastguard Worker 			break;
289*48a54d36SAndroid Build Coastguard Worker 
290*48a54d36SAndroid Build Coastguard Worker 		default:
291*48a54d36SAndroid Build Coastguard Worker 			dlog( kDebugLevelNotice, "%s: unknown reason code (%d)\n", __ROUTINE__, inReason );
292*48a54d36SAndroid Build Coastguard Worker 			break;
293*48a54d36SAndroid Build Coastguard Worker 	}
294*48a54d36SAndroid Build Coastguard Worker 
295*48a54d36SAndroid Build Coastguard Worker 	return( TRUE );
296*48a54d36SAndroid Build Coastguard Worker }
297*48a54d36SAndroid Build Coastguard Worker 
298*48a54d36SAndroid Build Coastguard Worker 
299*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
300*48a54d36SAndroid Build Coastguard Worker //	DllRegisterServer
301*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
302*48a54d36SAndroid Build Coastguard Worker 
DllRegisterServer(void)303*48a54d36SAndroid Build Coastguard Worker STDAPI	DllRegisterServer( void )
304*48a54d36SAndroid Build Coastguard Worker {
305*48a54d36SAndroid Build Coastguard Worker 	WSADATA		wsd;
306*48a54d36SAndroid Build Coastguard Worker 	WCHAR		path[ MAX_PATH ];
307*48a54d36SAndroid Build Coastguard Worker 	HRESULT		err;
308*48a54d36SAndroid Build Coastguard Worker 
309*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, "DllRegisterServer\n" );
310*48a54d36SAndroid Build Coastguard Worker 
311*48a54d36SAndroid Build Coastguard Worker 	err = WSAStartup( MAKEWORD( 2, 2 ), &wsd );
312*48a54d36SAndroid Build Coastguard Worker 	err = translate_errno( err == 0, errno_compat(), WSAEINVAL );
313*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
314*48a54d36SAndroid Build Coastguard Worker 
315*48a54d36SAndroid Build Coastguard Worker 	// Unregister before registering to workaround an installer
316*48a54d36SAndroid Build Coastguard Worker 	// problem during upgrade installs.
317*48a54d36SAndroid Build Coastguard Worker 
318*48a54d36SAndroid Build Coastguard Worker 	WSCUnInstallNameSpace( &gNSPGUID );
319*48a54d36SAndroid Build Coastguard Worker 
320*48a54d36SAndroid Build Coastguard Worker 	err = GetModuleFileNameW( gInstance, path, MAX_PATH );
321*48a54d36SAndroid Build Coastguard Worker 	err = translate_errno( err != 0, errno_compat(), kUnknownErr );
322*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
323*48a54d36SAndroid Build Coastguard Worker 
324*48a54d36SAndroid Build Coastguard Worker 	err = WSCInstallNameSpace( gNSPName, path, NS_DNS, 1, &gNSPGUID );
325*48a54d36SAndroid Build Coastguard Worker 	err = translate_errno( err == 0, errno_compat(), WSAEINVAL );
326*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
327*48a54d36SAndroid Build Coastguard Worker 
328*48a54d36SAndroid Build Coastguard Worker exit:
329*48a54d36SAndroid Build Coastguard Worker 
330*48a54d36SAndroid Build Coastguard Worker 	WSACleanup();
331*48a54d36SAndroid Build Coastguard Worker 	return( err );
332*48a54d36SAndroid Build Coastguard Worker }
333*48a54d36SAndroid Build Coastguard Worker 
334*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
335*48a54d36SAndroid Build Coastguard Worker //	DllUnregisterServer
336*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
337*48a54d36SAndroid Build Coastguard Worker 
DllUnregisterServer(void)338*48a54d36SAndroid Build Coastguard Worker STDAPI	DllUnregisterServer( void )
339*48a54d36SAndroid Build Coastguard Worker {
340*48a54d36SAndroid Build Coastguard Worker 	WSADATA		wsd;
341*48a54d36SAndroid Build Coastguard Worker 	HRESULT err;
342*48a54d36SAndroid Build Coastguard Worker 
343*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, "DllUnregisterServer\n" );
344*48a54d36SAndroid Build Coastguard Worker 
345*48a54d36SAndroid Build Coastguard Worker 	err = WSAStartup( MAKEWORD( 2, 2 ), &wsd );
346*48a54d36SAndroid Build Coastguard Worker 	err = translate_errno( err == 0, errno_compat(), WSAEINVAL );
347*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
348*48a54d36SAndroid Build Coastguard Worker 
349*48a54d36SAndroid Build Coastguard Worker 	err = WSCUnInstallNameSpace( &gNSPGUID );
350*48a54d36SAndroid Build Coastguard Worker 	err = translate_errno( err == 0, errno_compat(), WSAEINVAL );
351*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
352*48a54d36SAndroid Build Coastguard Worker 
353*48a54d36SAndroid Build Coastguard Worker exit:
354*48a54d36SAndroid Build Coastguard Worker 
355*48a54d36SAndroid Build Coastguard Worker 	WSACleanup();
356*48a54d36SAndroid Build Coastguard Worker 	return err;
357*48a54d36SAndroid Build Coastguard Worker }
358*48a54d36SAndroid Build Coastguard Worker 
359*48a54d36SAndroid Build Coastguard Worker 
360*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
361*48a54d36SAndroid Build Coastguard Worker //	NSPStartup
362*48a54d36SAndroid Build Coastguard Worker //
363*48a54d36SAndroid Build Coastguard Worker //	This function is called when our namespace DLL is loaded. It sets up the NSP functions we implement and initializes us.
364*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
365*48a54d36SAndroid Build Coastguard Worker 
NSPStartup(LPGUID inProviderID,LPNSP_ROUTINE outRoutines)366*48a54d36SAndroid Build Coastguard Worker int WSPAPI	NSPStartup( LPGUID inProviderID, LPNSP_ROUTINE outRoutines )
367*48a54d36SAndroid Build Coastguard Worker {
368*48a54d36SAndroid Build Coastguard Worker 	OSStatus		err;
369*48a54d36SAndroid Build Coastguard Worker 
370*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, "%s begin (ticks=%d)\n", __ROUTINE__, GetTickCount() );
371*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, "%s (GUID=%U, refCount=%ld)\n", __ROUTINE__, inProviderID, gRefCount );
372*48a54d36SAndroid Build Coastguard Worker 
373*48a54d36SAndroid Build Coastguard Worker 	// Only initialize if this is the first time NSPStartup is called.
374*48a54d36SAndroid Build Coastguard Worker 
375*48a54d36SAndroid Build Coastguard Worker 	if( InterlockedIncrement( &gRefCount ) != 1 )
376*48a54d36SAndroid Build Coastguard Worker 	{
377*48a54d36SAndroid Build Coastguard Worker 		err = NO_ERROR;
378*48a54d36SAndroid Build Coastguard Worker 		goto exit;
379*48a54d36SAndroid Build Coastguard Worker 	}
380*48a54d36SAndroid Build Coastguard Worker 
381*48a54d36SAndroid Build Coastguard Worker 	// Initialize our internal state.
382*48a54d36SAndroid Build Coastguard Worker 
383*48a54d36SAndroid Build Coastguard Worker 	InitializeCriticalSection( &gLock );
384*48a54d36SAndroid Build Coastguard Worker 	gLockInitialized = true;
385*48a54d36SAndroid Build Coastguard Worker 
386*48a54d36SAndroid Build Coastguard Worker 	// Set the size to exclude NSPIoctl because we don't implement it.
387*48a54d36SAndroid Build Coastguard Worker 
388*48a54d36SAndroid Build Coastguard Worker 	outRoutines->cbSize					= FIELD_OFFSET( NSP_ROUTINE, NSPIoctl );
389*48a54d36SAndroid Build Coastguard Worker 	outRoutines->dwMajorVersion			= 4;
390*48a54d36SAndroid Build Coastguard Worker 	outRoutines->dwMinorVersion			= 4;
391*48a54d36SAndroid Build Coastguard Worker 	outRoutines->NSPCleanup				= NSPCleanup;
392*48a54d36SAndroid Build Coastguard Worker 	outRoutines->NSPLookupServiceBegin	= NSPLookupServiceBegin;
393*48a54d36SAndroid Build Coastguard Worker 	outRoutines->NSPLookupServiceNext	= NSPLookupServiceNext;
394*48a54d36SAndroid Build Coastguard Worker 	outRoutines->NSPLookupServiceEnd	= NSPLookupServiceEnd;
395*48a54d36SAndroid Build Coastguard Worker 	outRoutines->NSPSetService			= NSPSetService;
396*48a54d36SAndroid Build Coastguard Worker 	outRoutines->NSPInstallServiceClass	= NSPInstallServiceClass;
397*48a54d36SAndroid Build Coastguard Worker 	outRoutines->NSPRemoveServiceClass	= NSPRemoveServiceClass;
398*48a54d36SAndroid Build Coastguard Worker 	outRoutines->NSPGetServiceClassInfo	= NSPGetServiceClassInfo;
399*48a54d36SAndroid Build Coastguard Worker 
400*48a54d36SAndroid Build Coastguard Worker 	// See if we can get the address for the GetAdaptersAddresses() API.  This is only in XP, but we want our
401*48a54d36SAndroid Build Coastguard Worker 	// code to run on older versions of Windows
402*48a54d36SAndroid Build Coastguard Worker 
403*48a54d36SAndroid Build Coastguard Worker 	if ( !gIPHelperLibraryInstance )
404*48a54d36SAndroid Build Coastguard Worker 	{
405*48a54d36SAndroid Build Coastguard Worker 		gIPHelperLibraryInstance = LoadLibrary( TEXT( "Iphlpapi" ) );
406*48a54d36SAndroid Build Coastguard Worker 		if( gIPHelperLibraryInstance )
407*48a54d36SAndroid Build Coastguard Worker 		{
408*48a54d36SAndroid Build Coastguard Worker 			gGetAdaptersAddressesFunctionPtr = (GetAdaptersAddressesFunctionPtr) GetProcAddress( gIPHelperLibraryInstance, "GetAdaptersAddresses" );
409*48a54d36SAndroid Build Coastguard Worker 		}
410*48a54d36SAndroid Build Coastguard Worker 	}
411*48a54d36SAndroid Build Coastguard Worker 
412*48a54d36SAndroid Build Coastguard Worker 	err = NO_ERROR;
413*48a54d36SAndroid Build Coastguard Worker 
414*48a54d36SAndroid Build Coastguard Worker exit:
415*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, "%s end   (ticks=%d)\n", __ROUTINE__, GetTickCount() );
416*48a54d36SAndroid Build Coastguard Worker 	if( err != NO_ERROR )
417*48a54d36SAndroid Build Coastguard Worker 	{
418*48a54d36SAndroid Build Coastguard Worker 		NSPCleanup( inProviderID );
419*48a54d36SAndroid Build Coastguard Worker 		SetLastError( (DWORD) err );
420*48a54d36SAndroid Build Coastguard Worker 		return( SOCKET_ERROR );
421*48a54d36SAndroid Build Coastguard Worker 	}
422*48a54d36SAndroid Build Coastguard Worker 	return( NO_ERROR );
423*48a54d36SAndroid Build Coastguard Worker }
424*48a54d36SAndroid Build Coastguard Worker 
425*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
426*48a54d36SAndroid Build Coastguard Worker //	NSPCleanup
427*48a54d36SAndroid Build Coastguard Worker //
428*48a54d36SAndroid Build Coastguard Worker //	This function is called when our namespace DLL is unloaded. It cleans up anything we set up in NSPStartup.
429*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
430*48a54d36SAndroid Build Coastguard Worker 
NSPCleanup(LPGUID inProviderID)431*48a54d36SAndroid Build Coastguard Worker int	WSPAPI	NSPCleanup( LPGUID inProviderID )
432*48a54d36SAndroid Build Coastguard Worker {
433*48a54d36SAndroid Build Coastguard Worker 	DEBUG_USE_ONLY( inProviderID );
434*48a54d36SAndroid Build Coastguard Worker 
435*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, "%s begin (ticks=%d)\n", __ROUTINE__, GetTickCount() );
436*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, "%s (GUID=%U, refCount=%ld)\n", __ROUTINE__, inProviderID, gRefCount );
437*48a54d36SAndroid Build Coastguard Worker 
438*48a54d36SAndroid Build Coastguard Worker 	// Only initialize if this is the first time NSPStartup is called.
439*48a54d36SAndroid Build Coastguard Worker 
440*48a54d36SAndroid Build Coastguard Worker 	if( InterlockedDecrement( &gRefCount ) != 0 )
441*48a54d36SAndroid Build Coastguard Worker 	{
442*48a54d36SAndroid Build Coastguard Worker 		goto exit;
443*48a54d36SAndroid Build Coastguard Worker 	}
444*48a54d36SAndroid Build Coastguard Worker 
445*48a54d36SAndroid Build Coastguard Worker 	// Stop any outstanding queries.
446*48a54d36SAndroid Build Coastguard Worker 
447*48a54d36SAndroid Build Coastguard Worker 	if( gLockInitialized )
448*48a54d36SAndroid Build Coastguard Worker 	{
449*48a54d36SAndroid Build Coastguard Worker 		NSPLock();
450*48a54d36SAndroid Build Coastguard Worker 	}
451*48a54d36SAndroid Build Coastguard Worker 	while( gQueryList )
452*48a54d36SAndroid Build Coastguard Worker 	{
453*48a54d36SAndroid Build Coastguard Worker 		check_string( gQueryList->refCount == 1, "NSPCleanup with outstanding queries!" );
454*48a54d36SAndroid Build Coastguard Worker 		QueryRelease( gQueryList );
455*48a54d36SAndroid Build Coastguard Worker 	}
456*48a54d36SAndroid Build Coastguard Worker 	if( gLockInitialized )
457*48a54d36SAndroid Build Coastguard Worker 	{
458*48a54d36SAndroid Build Coastguard Worker 		NSPUnlock();
459*48a54d36SAndroid Build Coastguard Worker 	}
460*48a54d36SAndroid Build Coastguard Worker 
461*48a54d36SAndroid Build Coastguard Worker 	if( gLockInitialized )
462*48a54d36SAndroid Build Coastguard Worker 	{
463*48a54d36SAndroid Build Coastguard Worker 		gLockInitialized = false;
464*48a54d36SAndroid Build Coastguard Worker 		DeleteCriticalSection( &gLock );
465*48a54d36SAndroid Build Coastguard Worker 	}
466*48a54d36SAndroid Build Coastguard Worker 
467*48a54d36SAndroid Build Coastguard Worker 	if( gIPHelperLibraryInstance )
468*48a54d36SAndroid Build Coastguard Worker 	{
469*48a54d36SAndroid Build Coastguard Worker 		BOOL ok;
470*48a54d36SAndroid Build Coastguard Worker 
471*48a54d36SAndroid Build Coastguard Worker 		ok = FreeLibrary( gIPHelperLibraryInstance );
472*48a54d36SAndroid Build Coastguard Worker 		check_translated_errno( ok, GetLastError(), kUnknownErr );
473*48a54d36SAndroid Build Coastguard Worker 		gIPHelperLibraryInstance = NULL;
474*48a54d36SAndroid Build Coastguard Worker 	}
475*48a54d36SAndroid Build Coastguard Worker 
476*48a54d36SAndroid Build Coastguard Worker exit:
477*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, "%s end   (ticks=%d)\n", __ROUTINE__, GetTickCount() );
478*48a54d36SAndroid Build Coastguard Worker 	return( NO_ERROR );
479*48a54d36SAndroid Build Coastguard Worker }
480*48a54d36SAndroid Build Coastguard Worker 
481*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
482*48a54d36SAndroid Build Coastguard Worker //	NSPLookupServiceBegin
483*48a54d36SAndroid Build Coastguard Worker //
484*48a54d36SAndroid Build Coastguard Worker //	This function maps to the WinSock WSALookupServiceBegin function. It starts the lookup process and returns a HANDLE
485*48a54d36SAndroid Build Coastguard Worker //	that can be used in subsequent operations. Subsequent calls only need to refer to this query by the handle as
486*48a54d36SAndroid Build Coastguard Worker //	opposed to specifying the query parameters each time.
487*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
488*48a54d36SAndroid Build Coastguard Worker 
489*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL int WSPAPI
NSPLookupServiceBegin(LPGUID inProviderID,LPWSAQUERYSETW inQuerySet,LPWSASERVICECLASSINFOW inServiceClassInfo,DWORD inFlags,LPHANDLE outLookup)490*48a54d36SAndroid Build Coastguard Worker 	NSPLookupServiceBegin(
491*48a54d36SAndroid Build Coastguard Worker 		LPGUID					inProviderID,
492*48a54d36SAndroid Build Coastguard Worker 		LPWSAQUERYSETW			inQuerySet,
493*48a54d36SAndroid Build Coastguard Worker 		LPWSASERVICECLASSINFOW	inServiceClassInfo,
494*48a54d36SAndroid Build Coastguard Worker 		DWORD					inFlags,
495*48a54d36SAndroid Build Coastguard Worker 		LPHANDLE				outLookup )
496*48a54d36SAndroid Build Coastguard Worker {
497*48a54d36SAndroid Build Coastguard Worker 	OSStatus		err;
498*48a54d36SAndroid Build Coastguard Worker 	QueryRef		obj;
499*48a54d36SAndroid Build Coastguard Worker 	LPCWSTR			name;
500*48a54d36SAndroid Build Coastguard Worker 	size_t			size;
501*48a54d36SAndroid Build Coastguard Worker 	LPCWSTR			p;
502*48a54d36SAndroid Build Coastguard Worker 	DWORD           type;
503*48a54d36SAndroid Build Coastguard Worker 	DWORD			n;
504*48a54d36SAndroid Build Coastguard Worker 	DWORD			i;
505*48a54d36SAndroid Build Coastguard Worker 	INT				family;
506*48a54d36SAndroid Build Coastguard Worker 	INT				protocol;
507*48a54d36SAndroid Build Coastguard Worker 
508*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( inProviderID );
509*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( inServiceClassInfo );
510*48a54d36SAndroid Build Coastguard Worker 
511*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, "%s begin (ticks=%d)\n", __ROUTINE__, GetTickCount() );
512*48a54d36SAndroid Build Coastguard Worker 
513*48a54d36SAndroid Build Coastguard Worker 	obj = NULL;
514*48a54d36SAndroid Build Coastguard Worker 	require_action( inQuerySet, exit, err = WSAEINVAL );
515*48a54d36SAndroid Build Coastguard Worker 	name = inQuerySet->lpszServiceInstanceName;
516*48a54d36SAndroid Build Coastguard Worker 	require_action_quiet( name, exit, err = WSAEINVAL );
517*48a54d36SAndroid Build Coastguard Worker 	require_action( outLookup, exit, err = WSAEINVAL );
518*48a54d36SAndroid Build Coastguard Worker 
519*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, "%s (flags=0x%08X, name=\"%S\")\n", __ROUTINE__, inFlags, name );
520*48a54d36SAndroid Build Coastguard Worker 	dlog_query_set( kDebugLevelVerbose, inQuerySet );
521*48a54d36SAndroid Build Coastguard Worker 
522*48a54d36SAndroid Build Coastguard Worker 	// Check if we can handle this type of request and if we support any of the protocols being requested.
523*48a54d36SAndroid Build Coastguard Worker 	// We only support the DNS namespace, TCP and UDP protocols, and IPv4. Only blob results are supported.
524*48a54d36SAndroid Build Coastguard Worker 
525*48a54d36SAndroid Build Coastguard Worker 	require_action_quiet( inFlags & (LUP_RETURN_ADDR|LUP_RETURN_BLOB), exit, err = WSASERVICE_NOT_FOUND );
526*48a54d36SAndroid Build Coastguard Worker 
527*48a54d36SAndroid Build Coastguard Worker 	type = inQuerySet->dwNameSpace;
528*48a54d36SAndroid Build Coastguard Worker 	require_action_quiet( ( type == NS_DNS ) || ( type == NS_ALL ), exit, err = WSASERVICE_NOT_FOUND );
529*48a54d36SAndroid Build Coastguard Worker 
530*48a54d36SAndroid Build Coastguard Worker 	n = inQuerySet->dwNumberOfProtocols;
531*48a54d36SAndroid Build Coastguard Worker 	if( n > 0 )
532*48a54d36SAndroid Build Coastguard Worker 	{
533*48a54d36SAndroid Build Coastguard Worker 		require_action( inQuerySet->lpafpProtocols, exit, err = WSAEINVAL );
534*48a54d36SAndroid Build Coastguard Worker 		for( i = 0; i < n; ++i )
535*48a54d36SAndroid Build Coastguard Worker 		{
536*48a54d36SAndroid Build Coastguard Worker 			family = inQuerySet->lpafpProtocols[ i ].iAddressFamily;
537*48a54d36SAndroid Build Coastguard Worker 			protocol = inQuerySet->lpafpProtocols[ i ].iProtocol;
538*48a54d36SAndroid Build Coastguard Worker 			if( ( family == AF_INET ) && ( ( protocol == IPPROTO_UDP ) || ( protocol == IPPROTO_TCP ) ) )
539*48a54d36SAndroid Build Coastguard Worker 			{
540*48a54d36SAndroid Build Coastguard Worker 				break;
541*48a54d36SAndroid Build Coastguard Worker 			}
542*48a54d36SAndroid Build Coastguard Worker 		}
543*48a54d36SAndroid Build Coastguard Worker 		require_action_quiet( i < n, exit, err = WSASERVICE_NOT_FOUND );
544*48a54d36SAndroid Build Coastguard Worker 	}
545*48a54d36SAndroid Build Coastguard Worker 
546*48a54d36SAndroid Build Coastguard Worker 	// Check if the name ends in ".local" and if not, exit with an error since we only resolve .local names.
547*48a54d36SAndroid Build Coastguard Worker 	// The name may or may not end with a "." (fully qualified) so handle both cases. DNS is also case
548*48a54d36SAndroid Build Coastguard Worker 	// insensitive the check for .local has to be case insensitive (.LoCaL is equivalent to .local). This
549*48a54d36SAndroid Build Coastguard Worker 	// manually does the wchar_t strlen and stricmp to avoid needing any special wchar_t versions of the
550*48a54d36SAndroid Build Coastguard Worker 	// libraries. It is probably faster to do the inline compare than invoke functions to do it anyway.
551*48a54d36SAndroid Build Coastguard Worker 
552*48a54d36SAndroid Build Coastguard Worker 	for( p = name; *p; ++p ) {}		// Find end of string
553*48a54d36SAndroid Build Coastguard Worker 	size = (size_t)( p - name );
554*48a54d36SAndroid Build Coastguard Worker 	require_action_quiet( size > sizeof_string( ".local" ), exit, err = WSASERVICE_NOT_FOUND );
555*48a54d36SAndroid Build Coastguard Worker 
556*48a54d36SAndroid Build Coastguard Worker 	p = name + ( size - 1 );
557*48a54d36SAndroid Build Coastguard Worker 	p = ( *p == '.' ) ? ( p - sizeof_string( ".local" ) ) : ( ( p - sizeof_string( ".local" ) ) + 1 );
558*48a54d36SAndroid Build Coastguard Worker 	if	( ( ( p[ 0 ] != '.' )						||
559*48a54d36SAndroid Build Coastguard Worker 		( ( p[ 1 ] != 'L' ) && ( p[ 1 ] != 'l' ) )	||
560*48a54d36SAndroid Build Coastguard Worker 		( ( p[ 2 ] != 'O' ) && ( p[ 2 ] != 'o' ) )	||
561*48a54d36SAndroid Build Coastguard Worker 		( ( p[ 3 ] != 'C' ) && ( p[ 3 ] != 'c' ) )	||
562*48a54d36SAndroid Build Coastguard Worker 		( ( p[ 4 ] != 'A' ) && ( p[ 4 ] != 'a' ) )	||
563*48a54d36SAndroid Build Coastguard Worker 		( ( p[ 5 ] != 'L' ) && ( p[ 5 ] != 'l' ) ) ) )
564*48a54d36SAndroid Build Coastguard Worker 	{
565*48a54d36SAndroid Build Coastguard Worker #ifdef ENABLE_REVERSE_LOOKUP
566*48a54d36SAndroid Build Coastguard Worker 
567*48a54d36SAndroid Build Coastguard Worker 		err = IsReverseLookup( name, size );
568*48a54d36SAndroid Build Coastguard Worker 
569*48a54d36SAndroid Build Coastguard Worker #else
570*48a54d36SAndroid Build Coastguard Worker 
571*48a54d36SAndroid Build Coastguard Worker 		err = WSASERVICE_NOT_FOUND;
572*48a54d36SAndroid Build Coastguard Worker 
573*48a54d36SAndroid Build Coastguard Worker #endif
574*48a54d36SAndroid Build Coastguard Worker 
575*48a54d36SAndroid Build Coastguard Worker 		require_noerr( err, exit );
576*48a54d36SAndroid Build Coastguard Worker 	}
577*48a54d36SAndroid Build Coastguard Worker 	else
578*48a54d36SAndroid Build Coastguard Worker 	{
579*48a54d36SAndroid Build Coastguard Worker 		const char	*	replyDomain;
580*48a54d36SAndroid Build Coastguard Worker 		char			translated[ kDNSServiceMaxDomainName ];
581*48a54d36SAndroid Build Coastguard Worker 		int				n;
582*48a54d36SAndroid Build Coastguard Worker 		int				labels		= 0;
583*48a54d36SAndroid Build Coastguard Worker 		const char	*	label[MAX_LABELS];
584*48a54d36SAndroid Build Coastguard Worker 		char			text[64];
585*48a54d36SAndroid Build Coastguard Worker 
586*48a54d36SAndroid Build Coastguard Worker 		n = WideCharToMultiByte( CP_UTF8, 0, name, -1, translated, sizeof( translated ), NULL, NULL );
587*48a54d36SAndroid Build Coastguard Worker 		require_action( n > 0, exit, err = WSASERVICE_NOT_FOUND );
588*48a54d36SAndroid Build Coastguard Worker 
589*48a54d36SAndroid Build Coastguard Worker 		// <rdar://problem/4050633>
590*48a54d36SAndroid Build Coastguard Worker 
591*48a54d36SAndroid Build Coastguard Worker 		// Don't resolve multi-label name
592*48a54d36SAndroid Build Coastguard Worker 
593*48a54d36SAndroid Build Coastguard Worker 		// <rdar://problem/5914160> Eliminate use of GetNextLabel in mdnsNSP
594*48a54d36SAndroid Build Coastguard Worker 		// Add checks for GetNextLabel returning NULL, individual labels being greater than
595*48a54d36SAndroid Build Coastguard Worker 		// 64 bytes, and the number of labels being greater than MAX_LABELS
596*48a54d36SAndroid Build Coastguard Worker 		replyDomain = translated;
597*48a54d36SAndroid Build Coastguard Worker 
598*48a54d36SAndroid Build Coastguard Worker 		while (replyDomain && *replyDomain && labels < MAX_LABELS)
599*48a54d36SAndroid Build Coastguard Worker 		{
600*48a54d36SAndroid Build Coastguard Worker 			label[labels++]	= replyDomain;
601*48a54d36SAndroid Build Coastguard Worker 			replyDomain		= GetNextLabel(replyDomain, text);
602*48a54d36SAndroid Build Coastguard Worker 		}
603*48a54d36SAndroid Build Coastguard Worker 
604*48a54d36SAndroid Build Coastguard Worker 		require_action( labels == 2, exit, err = WSASERVICE_NOT_FOUND );
605*48a54d36SAndroid Build Coastguard Worker 
606*48a54d36SAndroid Build Coastguard Worker 		// <rdar://problem/3936771>
607*48a54d36SAndroid Build Coastguard Worker 		//
608*48a54d36SAndroid Build Coastguard Worker 		// Check to see if the name of this host is in the hosts table. If so,
609*48a54d36SAndroid Build Coastguard Worker 		// don't try and resolve it
610*48a54d36SAndroid Build Coastguard Worker 
611*48a54d36SAndroid Build Coastguard Worker 		require_action( InHostsTable( translated ) == FALSE, exit, err = WSASERVICE_NOT_FOUND );
612*48a54d36SAndroid Build Coastguard Worker 	}
613*48a54d36SAndroid Build Coastguard Worker 
614*48a54d36SAndroid Build Coastguard Worker 	// The name ends in .local ( and isn't in the hosts table ), .0.8.e.f.ip6.arpa, or .254.169.in-addr.arpa so start the resolve operation. Lazy initialize DNS-SD if needed.
615*48a54d36SAndroid Build Coastguard Worker 
616*48a54d36SAndroid Build Coastguard Worker 	NSPLock();
617*48a54d36SAndroid Build Coastguard Worker 
618*48a54d36SAndroid Build Coastguard Worker 	err = QueryCreate( inQuerySet, inFlags, &obj );
619*48a54d36SAndroid Build Coastguard Worker 	NSPUnlock();
620*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
621*48a54d36SAndroid Build Coastguard Worker 
622*48a54d36SAndroid Build Coastguard Worker 	*outLookup = (HANDLE) obj;
623*48a54d36SAndroid Build Coastguard Worker 
624*48a54d36SAndroid Build Coastguard Worker exit:
625*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, "%s end   (ticks=%d)\n", __ROUTINE__, GetTickCount() );
626*48a54d36SAndroid Build Coastguard Worker 	if( err != NO_ERROR )
627*48a54d36SAndroid Build Coastguard Worker 	{
628*48a54d36SAndroid Build Coastguard Worker 		SetLastError( (DWORD) err );
629*48a54d36SAndroid Build Coastguard Worker 		return( SOCKET_ERROR );
630*48a54d36SAndroid Build Coastguard Worker 	}
631*48a54d36SAndroid Build Coastguard Worker 	return( NO_ERROR );
632*48a54d36SAndroid Build Coastguard Worker }
633*48a54d36SAndroid Build Coastguard Worker 
634*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
635*48a54d36SAndroid Build Coastguard Worker //	NSPLookupServiceNext
636*48a54d36SAndroid Build Coastguard Worker //
637*48a54d36SAndroid Build Coastguard Worker //	This function maps to the Winsock call WSALookupServiceNext. This routine takes a handle to a previously defined
638*48a54d36SAndroid Build Coastguard Worker //	query and attempts to locate a service matching the criteria defined by the query. If so, that instance is returned
639*48a54d36SAndroid Build Coastguard Worker //	in the lpqsResults parameter.
640*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
641*48a54d36SAndroid Build Coastguard Worker 
642*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL int WSPAPI
NSPLookupServiceNext(HANDLE inLookup,DWORD inFlags,LPDWORD ioSize,LPWSAQUERYSETW outResults)643*48a54d36SAndroid Build Coastguard Worker 	NSPLookupServiceNext(
644*48a54d36SAndroid Build Coastguard Worker 		HANDLE			inLookup,
645*48a54d36SAndroid Build Coastguard Worker 		DWORD			inFlags,
646*48a54d36SAndroid Build Coastguard Worker 		LPDWORD			ioSize,
647*48a54d36SAndroid Build Coastguard Worker 		LPWSAQUERYSETW	outResults )
648*48a54d36SAndroid Build Coastguard Worker {
649*48a54d36SAndroid Build Coastguard Worker 	BOOL			data4;
650*48a54d36SAndroid Build Coastguard Worker 	BOOL			data6;
651*48a54d36SAndroid Build Coastguard Worker 	OSStatus		err;
652*48a54d36SAndroid Build Coastguard Worker 	QueryRef		obj;
653*48a54d36SAndroid Build Coastguard Worker 	DWORD			waitResult;
654*48a54d36SAndroid Build Coastguard Worker 	size_t			size;
655*48a54d36SAndroid Build Coastguard Worker 
656*48a54d36SAndroid Build Coastguard Worker 	DEBUG_USE_ONLY( inFlags );
657*48a54d36SAndroid Build Coastguard Worker 
658*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, "%s begin (ticks=%d)\n", __ROUTINE__, GetTickCount() );
659*48a54d36SAndroid Build Coastguard Worker 
660*48a54d36SAndroid Build Coastguard Worker 	data4 = FALSE;
661*48a54d36SAndroid Build Coastguard Worker 	data6 = FALSE;
662*48a54d36SAndroid Build Coastguard Worker 	obj = NULL;
663*48a54d36SAndroid Build Coastguard Worker 	NSPLock();
664*48a54d36SAndroid Build Coastguard Worker 	err = QueryRetain( (QueryRef) inLookup );
665*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
666*48a54d36SAndroid Build Coastguard Worker 	obj = (QueryRef) inLookup;
667*48a54d36SAndroid Build Coastguard Worker 	require_action( ioSize, exit, err = WSAEINVAL );
668*48a54d36SAndroid Build Coastguard Worker 	require_action( outResults, exit, err = WSAEINVAL );
669*48a54d36SAndroid Build Coastguard Worker 
670*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, "%s (lookup=%#p, flags=0x%08X, *ioSize=%d)\n", __ROUTINE__, inLookup, inFlags, *ioSize );
671*48a54d36SAndroid Build Coastguard Worker 
672*48a54d36SAndroid Build Coastguard Worker 	// Wait for data or a cancel. Release the lock while waiting. This is safe because we've retained the query.
673*48a54d36SAndroid Build Coastguard Worker 
674*48a54d36SAndroid Build Coastguard Worker 	NSPUnlock();
675*48a54d36SAndroid Build Coastguard Worker 	waitResult = WaitForMultipleObjects( obj->waitCount, obj->waitHandles, FALSE, 2 * 1000 );
676*48a54d36SAndroid Build Coastguard Worker 	NSPLock();
677*48a54d36SAndroid Build Coastguard Worker 	require_action_quiet( waitResult != ( WAIT_OBJECT_0 ), exit, err = WSA_E_CANCELLED );
678*48a54d36SAndroid Build Coastguard Worker 	err = translate_errno( ( waitResult == WAIT_OBJECT_0 + 1 ) || ( waitResult == WAIT_OBJECT_0 + 2 ), (OSStatus) GetLastError(), WSASERVICE_NOT_FOUND );
679*48a54d36SAndroid Build Coastguard Worker 	require_noerr_quiet( err, exit );
680*48a54d36SAndroid Build Coastguard Worker 
681*48a54d36SAndroid Build Coastguard Worker 	// If we've received an IPv4 reply, then hang out briefly for an IPv6 reply
682*48a54d36SAndroid Build Coastguard Worker 
683*48a54d36SAndroid Build Coastguard Worker 	if ( waitResult == WAIT_OBJECT_0 + 1 )
684*48a54d36SAndroid Build Coastguard Worker 	{
685*48a54d36SAndroid Build Coastguard Worker 		data4 = TRUE;
686*48a54d36SAndroid Build Coastguard Worker 		data6 = WaitForSingleObject( obj->data6Event, 100 ) == WAIT_OBJECT_0 ? TRUE : FALSE;
687*48a54d36SAndroid Build Coastguard Worker 	}
688*48a54d36SAndroid Build Coastguard Worker 
689*48a54d36SAndroid Build Coastguard Worker 	// Else we've received an IPv6 reply, so hang out briefly for an IPv4 reply
690*48a54d36SAndroid Build Coastguard Worker 
691*48a54d36SAndroid Build Coastguard Worker 	else if ( waitResult == WAIT_OBJECT_0 + 2 )
692*48a54d36SAndroid Build Coastguard Worker 	{
693*48a54d36SAndroid Build Coastguard Worker 		data4 = WaitForSingleObject( obj->data4Event, 100 ) == WAIT_OBJECT_0 ? TRUE : FALSE;
694*48a54d36SAndroid Build Coastguard Worker 		data6 = TRUE;
695*48a54d36SAndroid Build Coastguard Worker 	}
696*48a54d36SAndroid Build Coastguard Worker 
697*48a54d36SAndroid Build Coastguard Worker 	if ( data4 )
698*48a54d36SAndroid Build Coastguard Worker 	{
699*48a54d36SAndroid Build Coastguard Worker 		__try
700*48a54d36SAndroid Build Coastguard Worker 		{
701*48a54d36SAndroid Build Coastguard Worker 			err = DNSServiceProcessResult(obj->resolver4);
702*48a54d36SAndroid Build Coastguard Worker 		}
703*48a54d36SAndroid Build Coastguard Worker 		__except( EXCEPTION_EXECUTE_HANDLER )
704*48a54d36SAndroid Build Coastguard Worker 		{
705*48a54d36SAndroid Build Coastguard Worker 			err = kUnknownErr;
706*48a54d36SAndroid Build Coastguard Worker 		}
707*48a54d36SAndroid Build Coastguard Worker 
708*48a54d36SAndroid Build Coastguard Worker 		require_noerr( err, exit );
709*48a54d36SAndroid Build Coastguard Worker 	}
710*48a54d36SAndroid Build Coastguard Worker 
711*48a54d36SAndroid Build Coastguard Worker 	if ( data6 )
712*48a54d36SAndroid Build Coastguard Worker 	{
713*48a54d36SAndroid Build Coastguard Worker 		__try
714*48a54d36SAndroid Build Coastguard Worker 		{
715*48a54d36SAndroid Build Coastguard Worker 			err = DNSServiceProcessResult( obj->resolver6 );
716*48a54d36SAndroid Build Coastguard Worker 		}
717*48a54d36SAndroid Build Coastguard Worker 		__except( EXCEPTION_EXECUTE_HANDLER )
718*48a54d36SAndroid Build Coastguard Worker 		{
719*48a54d36SAndroid Build Coastguard Worker 			err = kUnknownErr;
720*48a54d36SAndroid Build Coastguard Worker 		}
721*48a54d36SAndroid Build Coastguard Worker 
722*48a54d36SAndroid Build Coastguard Worker 		require_noerr( err, exit );
723*48a54d36SAndroid Build Coastguard Worker 	}
724*48a54d36SAndroid Build Coastguard Worker 
725*48a54d36SAndroid Build Coastguard Worker 	require_action_quiet( obj->addr4Valid || obj->addr6Valid, exit, err = WSA_E_NO_MORE );
726*48a54d36SAndroid Build Coastguard Worker 
727*48a54d36SAndroid Build Coastguard Worker 	// Copy the externalized query results to the callers buffer (if it fits).
728*48a54d36SAndroid Build Coastguard Worker 
729*48a54d36SAndroid Build Coastguard Worker 	size = QueryCopyQuerySetSize( obj, obj->querySet, obj->querySetFlags );
730*48a54d36SAndroid Build Coastguard Worker 	require_action( size <= (size_t) *ioSize, exit, err = WSAEFAULT );
731*48a54d36SAndroid Build Coastguard Worker 
732*48a54d36SAndroid Build Coastguard Worker 	QueryCopyQuerySetTo( obj, obj->querySet, obj->querySetFlags, outResults );
733*48a54d36SAndroid Build Coastguard Worker 	outResults->dwOutputFlags = RESULT_IS_ADDED;
734*48a54d36SAndroid Build Coastguard Worker 	obj->addr4Valid = false;
735*48a54d36SAndroid Build Coastguard Worker 	obj->addr6Valid = false;
736*48a54d36SAndroid Build Coastguard Worker 
737*48a54d36SAndroid Build Coastguard Worker exit:
738*48a54d36SAndroid Build Coastguard Worker 	if( obj )
739*48a54d36SAndroid Build Coastguard Worker 	{
740*48a54d36SAndroid Build Coastguard Worker 		QueryRelease( obj );
741*48a54d36SAndroid Build Coastguard Worker 	}
742*48a54d36SAndroid Build Coastguard Worker 	NSPUnlock();
743*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, "%s end   (ticks=%d)\n", __ROUTINE__, GetTickCount() );
744*48a54d36SAndroid Build Coastguard Worker 	if( err != NO_ERROR )
745*48a54d36SAndroid Build Coastguard Worker 	{
746*48a54d36SAndroid Build Coastguard Worker 		SetLastError( (DWORD) err );
747*48a54d36SAndroid Build Coastguard Worker 		return( SOCKET_ERROR );
748*48a54d36SAndroid Build Coastguard Worker 	}
749*48a54d36SAndroid Build Coastguard Worker 	return( NO_ERROR );
750*48a54d36SAndroid Build Coastguard Worker }
751*48a54d36SAndroid Build Coastguard Worker 
752*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
753*48a54d36SAndroid Build Coastguard Worker //	NSPLookupServiceEnd
754*48a54d36SAndroid Build Coastguard Worker //
755*48a54d36SAndroid Build Coastguard Worker //	This function maps to the Winsock call WSALookupServiceEnd. Once the user process has finished is query (usually
756*48a54d36SAndroid Build Coastguard Worker //	indicated when WSALookupServiceNext returns the error WSA_E_NO_MORE) a call to this function is made to release any
757*48a54d36SAndroid Build Coastguard Worker //	allocated resources associated with the query.
758*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
759*48a54d36SAndroid Build Coastguard Worker 
NSPLookupServiceEnd(HANDLE inLookup)760*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL int WSPAPI	NSPLookupServiceEnd( HANDLE inLookup )
761*48a54d36SAndroid Build Coastguard Worker {
762*48a54d36SAndroid Build Coastguard Worker 	OSStatus		err;
763*48a54d36SAndroid Build Coastguard Worker 
764*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, "%s begin (ticks=%d)\n", __ROUTINE__, GetTickCount() );
765*48a54d36SAndroid Build Coastguard Worker 
766*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, "%s (lookup=%#p)\n", __ROUTINE__, inLookup );
767*48a54d36SAndroid Build Coastguard Worker 
768*48a54d36SAndroid Build Coastguard Worker 	NSPLock();
769*48a54d36SAndroid Build Coastguard Worker 	err = QueryRelease( (QueryRef) inLookup );
770*48a54d36SAndroid Build Coastguard Worker 	NSPUnlock();
771*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
772*48a54d36SAndroid Build Coastguard Worker 
773*48a54d36SAndroid Build Coastguard Worker exit:
774*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, "%s end   (ticks=%d)\n", __ROUTINE__, GetTickCount() );
775*48a54d36SAndroid Build Coastguard Worker 	if( err != NO_ERROR )
776*48a54d36SAndroid Build Coastguard Worker 	{
777*48a54d36SAndroid Build Coastguard Worker 		SetLastError( (DWORD) err );
778*48a54d36SAndroid Build Coastguard Worker 		return( SOCKET_ERROR );
779*48a54d36SAndroid Build Coastguard Worker 	}
780*48a54d36SAndroid Build Coastguard Worker 	return( NO_ERROR );
781*48a54d36SAndroid Build Coastguard Worker }
782*48a54d36SAndroid Build Coastguard Worker 
783*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
784*48a54d36SAndroid Build Coastguard Worker //	NSPSetService
785*48a54d36SAndroid Build Coastguard Worker //
786*48a54d36SAndroid Build Coastguard Worker //	This function maps to the Winsock call WSASetService. This routine is called when the user wants to register or
787*48a54d36SAndroid Build Coastguard Worker //	deregister an instance of a server with our service. For registration, the user needs to associate the server with a
788*48a54d36SAndroid Build Coastguard Worker //	service class. For deregistration the service class is required along with the servicename. The inRegInfo parameter
789*48a54d36SAndroid Build Coastguard Worker //	contains a WSAQUERYSET structure defining the server (such as protocol and address where it is).
790*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
791*48a54d36SAndroid Build Coastguard Worker 
792*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL int WSPAPI
NSPSetService(LPGUID inProviderID,LPWSASERVICECLASSINFOW inServiceClassInfo,LPWSAQUERYSETW inRegInfo,WSAESETSERVICEOP inOperation,DWORD inFlags)793*48a54d36SAndroid Build Coastguard Worker 	NSPSetService(
794*48a54d36SAndroid Build Coastguard Worker 		LPGUID					inProviderID,
795*48a54d36SAndroid Build Coastguard Worker 		LPWSASERVICECLASSINFOW	inServiceClassInfo,
796*48a54d36SAndroid Build Coastguard Worker 		LPWSAQUERYSETW			inRegInfo,
797*48a54d36SAndroid Build Coastguard Worker 		WSAESETSERVICEOP		inOperation,
798*48a54d36SAndroid Build Coastguard Worker 		DWORD					inFlags )
799*48a54d36SAndroid Build Coastguard Worker {
800*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( inProviderID );
801*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( inServiceClassInfo );
802*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( inRegInfo );
803*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( inOperation );
804*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( inFlags );
805*48a54d36SAndroid Build Coastguard Worker 
806*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, "%s begin (ticks=%d)\n", __ROUTINE__, GetTickCount() );
807*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, "%s\n", __ROUTINE__ );
808*48a54d36SAndroid Build Coastguard Worker 
809*48a54d36SAndroid Build Coastguard Worker 	// We don't allow services to be registered so always return an error.
810*48a54d36SAndroid Build Coastguard Worker 
811*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, "%s end   (ticks=%d)\n", __ROUTINE__, GetTickCount() );
812*48a54d36SAndroid Build Coastguard Worker 	return( WSAEINVAL );
813*48a54d36SAndroid Build Coastguard Worker }
814*48a54d36SAndroid Build Coastguard Worker 
815*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
816*48a54d36SAndroid Build Coastguard Worker //	NSPInstallServiceClass
817*48a54d36SAndroid Build Coastguard Worker //
818*48a54d36SAndroid Build Coastguard Worker //	This function maps to the Winsock call WSAInstallServiceClass. This routine is used to install a service class which
819*48a54d36SAndroid Build Coastguard Worker //	is used to define certain characteristics for a group of services. After a service class is registered, an actual
820*48a54d36SAndroid Build Coastguard Worker //	instance of a server may be registered.
821*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
822*48a54d36SAndroid Build Coastguard Worker 
NSPInstallServiceClass(LPGUID inProviderID,LPWSASERVICECLASSINFOW inServiceClassInfo)823*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL int WSPAPI	NSPInstallServiceClass( LPGUID inProviderID, LPWSASERVICECLASSINFOW inServiceClassInfo )
824*48a54d36SAndroid Build Coastguard Worker {
825*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( inProviderID );
826*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( inServiceClassInfo );
827*48a54d36SAndroid Build Coastguard Worker 
828*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, "%s begin (ticks=%d)\n", __ROUTINE__, GetTickCount() );
829*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, "%s\n", __ROUTINE__ );
830*48a54d36SAndroid Build Coastguard Worker 
831*48a54d36SAndroid Build Coastguard Worker 	// We don't allow service classes to be installed so always return an error.
832*48a54d36SAndroid Build Coastguard Worker 
833*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, "%s end   (ticks=%d)\n", __ROUTINE__, GetTickCount() );
834*48a54d36SAndroid Build Coastguard Worker 	return( WSA_INVALID_PARAMETER );
835*48a54d36SAndroid Build Coastguard Worker }
836*48a54d36SAndroid Build Coastguard Worker 
837*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
838*48a54d36SAndroid Build Coastguard Worker //	NSPRemoveServiceClass
839*48a54d36SAndroid Build Coastguard Worker //
840*48a54d36SAndroid Build Coastguard Worker //	This function maps to the Winsock call WSARemoveServiceClass. This routine removes a previously registered service
841*48a54d36SAndroid Build Coastguard Worker //	class. This is accomplished by connecting to the namespace service and writing the GUID which defines the given
842*48a54d36SAndroid Build Coastguard Worker //	service class.
843*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
844*48a54d36SAndroid Build Coastguard Worker 
NSPRemoveServiceClass(LPGUID inProviderID,LPGUID inServiceClassID)845*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL int WSPAPI	NSPRemoveServiceClass( LPGUID inProviderID, LPGUID inServiceClassID )
846*48a54d36SAndroid Build Coastguard Worker {
847*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( inProviderID );
848*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( inServiceClassID );
849*48a54d36SAndroid Build Coastguard Worker 
850*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, "%s begin (ticks=%d)\n", __ROUTINE__, GetTickCount() );
851*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, "%s\n", __ROUTINE__ );
852*48a54d36SAndroid Build Coastguard Worker 
853*48a54d36SAndroid Build Coastguard Worker 	// We don't allow service classes to be installed so always return an error.
854*48a54d36SAndroid Build Coastguard Worker 
855*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, "%s end   (ticks=%d)\n", __ROUTINE__, GetTickCount() );
856*48a54d36SAndroid Build Coastguard Worker 	return( WSATYPE_NOT_FOUND );
857*48a54d36SAndroid Build Coastguard Worker }
858*48a54d36SAndroid Build Coastguard Worker 
859*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
860*48a54d36SAndroid Build Coastguard Worker //	NSPGetServiceClassInfo
861*48a54d36SAndroid Build Coastguard Worker //
862*48a54d36SAndroid Build Coastguard Worker //	This function maps to the Winsock call WSAGetServiceClassInfo. This routine returns the information associated with
863*48a54d36SAndroid Build Coastguard Worker //	a given service class.
864*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
865*48a54d36SAndroid Build Coastguard Worker 
NSPGetServiceClassInfo(LPGUID inProviderID,LPDWORD ioSize,LPWSASERVICECLASSINFOW ioServiceClassInfo)866*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL int WSPAPI	NSPGetServiceClassInfo(	LPGUID inProviderID, LPDWORD ioSize, LPWSASERVICECLASSINFOW ioServiceClassInfo )
867*48a54d36SAndroid Build Coastguard Worker {
868*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( inProviderID );
869*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( ioSize );
870*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( ioServiceClassInfo );
871*48a54d36SAndroid Build Coastguard Worker 
872*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, "%s begin (ticks=%d)\n", __ROUTINE__, GetTickCount() );
873*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, "%s\n", __ROUTINE__ );
874*48a54d36SAndroid Build Coastguard Worker 
875*48a54d36SAndroid Build Coastguard Worker 	// We don't allow service classes to be installed so always return an error.
876*48a54d36SAndroid Build Coastguard Worker 
877*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, "%s end   (ticks=%d)\n", __ROUTINE__, GetTickCount() );
878*48a54d36SAndroid Build Coastguard Worker 	return( WSATYPE_NOT_FOUND );
879*48a54d36SAndroid Build Coastguard Worker }
880*48a54d36SAndroid Build Coastguard Worker 
881*48a54d36SAndroid Build Coastguard Worker #if 0
882*48a54d36SAndroid Build Coastguard Worker #pragma mark -
883*48a54d36SAndroid Build Coastguard Worker #endif
884*48a54d36SAndroid Build Coastguard Worker 
885*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
886*48a54d36SAndroid Build Coastguard Worker //	QueryCreate
887*48a54d36SAndroid Build Coastguard Worker //
888*48a54d36SAndroid Build Coastguard Worker //	Warning: Assumes the NSP lock is held.
889*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
890*48a54d36SAndroid Build Coastguard Worker 
QueryCreate(const WSAQUERYSETW * inQuerySet,DWORD inQuerySetFlags,QueryRef * outRef)891*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL OSStatus	QueryCreate( const WSAQUERYSETW *inQuerySet, DWORD inQuerySetFlags, QueryRef *outRef )
892*48a54d36SAndroid Build Coastguard Worker {
893*48a54d36SAndroid Build Coastguard Worker 	OSStatus		err;
894*48a54d36SAndroid Build Coastguard Worker 	QueryRef		obj;
895*48a54d36SAndroid Build Coastguard Worker 	char			name[ kDNSServiceMaxDomainName ];
896*48a54d36SAndroid Build Coastguard Worker 	int				n;
897*48a54d36SAndroid Build Coastguard Worker 	QueryRef *		p;
898*48a54d36SAndroid Build Coastguard Worker 	SOCKET			s4;
899*48a54d36SAndroid Build Coastguard Worker 	SOCKET			s6;
900*48a54d36SAndroid Build Coastguard Worker 
901*48a54d36SAndroid Build Coastguard Worker 	obj = NULL;
902*48a54d36SAndroid Build Coastguard Worker 	check( inQuerySet );
903*48a54d36SAndroid Build Coastguard Worker 	check( inQuerySet->lpszServiceInstanceName );
904*48a54d36SAndroid Build Coastguard Worker 	check( outRef );
905*48a54d36SAndroid Build Coastguard Worker 
906*48a54d36SAndroid Build Coastguard Worker 	// Convert the wchar_t name to UTF-8.
907*48a54d36SAndroid Build Coastguard Worker 
908*48a54d36SAndroid Build Coastguard Worker 	n = WideCharToMultiByte( CP_UTF8, 0, inQuerySet->lpszServiceInstanceName, -1, name, sizeof( name ), NULL, NULL );
909*48a54d36SAndroid Build Coastguard Worker 	err = translate_errno( n > 0, (OSStatus) GetLastError(), WSAEINVAL );
910*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
911*48a54d36SAndroid Build Coastguard Worker 
912*48a54d36SAndroid Build Coastguard Worker 	// Allocate the object and append it to the list. Append immediately so releases of partial objects work.
913*48a54d36SAndroid Build Coastguard Worker 
914*48a54d36SAndroid Build Coastguard Worker 	obj = (QueryRef) calloc( 1, sizeof( *obj ) );
915*48a54d36SAndroid Build Coastguard Worker 	require_action( obj, exit, err = WSA_NOT_ENOUGH_MEMORY );
916*48a54d36SAndroid Build Coastguard Worker 
917*48a54d36SAndroid Build Coastguard Worker 	obj->refCount = 1;
918*48a54d36SAndroid Build Coastguard Worker 
919*48a54d36SAndroid Build Coastguard Worker 	for( p = &gQueryList; *p; p = &( *p )->next ) {}	// Find the end of the list.
920*48a54d36SAndroid Build Coastguard Worker 	*p = obj;
921*48a54d36SAndroid Build Coastguard Worker 
922*48a54d36SAndroid Build Coastguard Worker 	// Set up cancel event
923*48a54d36SAndroid Build Coastguard Worker 
924*48a54d36SAndroid Build Coastguard Worker 	obj->cancelEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
925*48a54d36SAndroid Build Coastguard Worker 	require_action( obj->cancelEvent, exit, err = WSA_NOT_ENOUGH_MEMORY );
926*48a54d36SAndroid Build Coastguard Worker 
927*48a54d36SAndroid Build Coastguard Worker 	// Set up events to signal when A record data is ready
928*48a54d36SAndroid Build Coastguard Worker 
929*48a54d36SAndroid Build Coastguard Worker 	obj->data4Event = CreateEvent( NULL, TRUE, FALSE, NULL );
930*48a54d36SAndroid Build Coastguard Worker 	require_action( obj->data4Event, exit, err = WSA_NOT_ENOUGH_MEMORY );
931*48a54d36SAndroid Build Coastguard Worker 
932*48a54d36SAndroid Build Coastguard Worker 	// Start the query.  Handle delay loaded DLL errors.
933*48a54d36SAndroid Build Coastguard Worker 
934*48a54d36SAndroid Build Coastguard Worker 	__try
935*48a54d36SAndroid Build Coastguard Worker 	{
936*48a54d36SAndroid Build Coastguard Worker 		err = DNSServiceQueryRecord( &obj->resolver4, 0, 0, name, kDNSServiceType_A, kDNSServiceClass_IN, QueryRecordCallback4, obj );
937*48a54d36SAndroid Build Coastguard Worker 	}
938*48a54d36SAndroid Build Coastguard Worker 	__except( EXCEPTION_EXECUTE_HANDLER )
939*48a54d36SAndroid Build Coastguard Worker 	{
940*48a54d36SAndroid Build Coastguard Worker 		err = kUnknownErr;
941*48a54d36SAndroid Build Coastguard Worker 	}
942*48a54d36SAndroid Build Coastguard Worker 
943*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
944*48a54d36SAndroid Build Coastguard Worker 
945*48a54d36SAndroid Build Coastguard Worker 	// Attach the socket to the event
946*48a54d36SAndroid Build Coastguard Worker 
947*48a54d36SAndroid Build Coastguard Worker 	__try
948*48a54d36SAndroid Build Coastguard Worker 	{
949*48a54d36SAndroid Build Coastguard Worker 		s4 = DNSServiceRefSockFD(obj->resolver4);
950*48a54d36SAndroid Build Coastguard Worker 	}
951*48a54d36SAndroid Build Coastguard Worker 	__except( EXCEPTION_EXECUTE_HANDLER )
952*48a54d36SAndroid Build Coastguard Worker 	{
953*48a54d36SAndroid Build Coastguard Worker 		s4 = INVALID_SOCKET;
954*48a54d36SAndroid Build Coastguard Worker 	}
955*48a54d36SAndroid Build Coastguard Worker 
956*48a54d36SAndroid Build Coastguard Worker 	err = translate_errno( s4 != INVALID_SOCKET, errno_compat(), kUnknownErr );
957*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
958*48a54d36SAndroid Build Coastguard Worker 
959*48a54d36SAndroid Build Coastguard Worker 	WSAEventSelect(s4, obj->data4Event, FD_READ|FD_CLOSE);
960*48a54d36SAndroid Build Coastguard Worker 
961*48a54d36SAndroid Build Coastguard Worker 	// Set up events to signal when AAAA record data is ready
962*48a54d36SAndroid Build Coastguard Worker 
963*48a54d36SAndroid Build Coastguard Worker 	obj->data6Event = CreateEvent( NULL, TRUE, FALSE, NULL );
964*48a54d36SAndroid Build Coastguard Worker 	require_action( obj->data6Event, exit, err = WSA_NOT_ENOUGH_MEMORY );
965*48a54d36SAndroid Build Coastguard Worker 
966*48a54d36SAndroid Build Coastguard Worker 	// Start the query.  Handle delay loaded DLL errors.
967*48a54d36SAndroid Build Coastguard Worker 
968*48a54d36SAndroid Build Coastguard Worker 	__try
969*48a54d36SAndroid Build Coastguard Worker 	{
970*48a54d36SAndroid Build Coastguard Worker 		err = DNSServiceQueryRecord( &obj->resolver6, 0, 0, name, kDNSServiceType_AAAA, kDNSServiceClass_IN, QueryRecordCallback6, obj );
971*48a54d36SAndroid Build Coastguard Worker 	}
972*48a54d36SAndroid Build Coastguard Worker 	__except( EXCEPTION_EXECUTE_HANDLER )
973*48a54d36SAndroid Build Coastguard Worker 	{
974*48a54d36SAndroid Build Coastguard Worker 		err = kUnknownErr;
975*48a54d36SAndroid Build Coastguard Worker 	}
976*48a54d36SAndroid Build Coastguard Worker 
977*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
978*48a54d36SAndroid Build Coastguard Worker 
979*48a54d36SAndroid Build Coastguard Worker 	// Attach the socket to the event
980*48a54d36SAndroid Build Coastguard Worker 
981*48a54d36SAndroid Build Coastguard Worker 	__try
982*48a54d36SAndroid Build Coastguard Worker 	{
983*48a54d36SAndroid Build Coastguard Worker 		s6 = DNSServiceRefSockFD(obj->resolver6);
984*48a54d36SAndroid Build Coastguard Worker 	}
985*48a54d36SAndroid Build Coastguard Worker 	__except( EXCEPTION_EXECUTE_HANDLER )
986*48a54d36SAndroid Build Coastguard Worker 	{
987*48a54d36SAndroid Build Coastguard Worker 		s6 = INVALID_SOCKET;
988*48a54d36SAndroid Build Coastguard Worker 	}
989*48a54d36SAndroid Build Coastguard Worker 
990*48a54d36SAndroid Build Coastguard Worker 	err = translate_errno( s6 != INVALID_SOCKET, errno_compat(), kUnknownErr );
991*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
992*48a54d36SAndroid Build Coastguard Worker 
993*48a54d36SAndroid Build Coastguard Worker 	WSAEventSelect(s6, obj->data6Event, FD_READ|FD_CLOSE);
994*48a54d36SAndroid Build Coastguard Worker 
995*48a54d36SAndroid Build Coastguard Worker 	obj->waitCount = 0;
996*48a54d36SAndroid Build Coastguard Worker 	obj->waitHandles[ obj->waitCount++ ] = obj->cancelEvent;
997*48a54d36SAndroid Build Coastguard Worker 	obj->waitHandles[ obj->waitCount++ ] = obj->data4Event;
998*48a54d36SAndroid Build Coastguard Worker 	obj->waitHandles[ obj->waitCount++ ] = obj->data6Event;
999*48a54d36SAndroid Build Coastguard Worker 
1000*48a54d36SAndroid Build Coastguard Worker 	check( obj->waitCount == sizeof_array( obj->waitHandles ) );
1001*48a54d36SAndroid Build Coastguard Worker 
1002*48a54d36SAndroid Build Coastguard Worker 	// Copy the QuerySet so it can be returned later.
1003*48a54d36SAndroid Build Coastguard Worker 
1004*48a54d36SAndroid Build Coastguard Worker 	obj->querySetFlags = inQuerySetFlags;
1005*48a54d36SAndroid Build Coastguard Worker 	inQuerySetFlags = ( inQuerySetFlags & ~( LUP_RETURN_ADDR | LUP_RETURN_BLOB ) ) | LUP_RETURN_NAME;
1006*48a54d36SAndroid Build Coastguard Worker 	err = QueryCopyQuerySet( obj, inQuerySet, inQuerySetFlags, &obj->querySet, &obj->querySetSize );
1007*48a54d36SAndroid Build Coastguard Worker 	require_noerr( err, exit );
1008*48a54d36SAndroid Build Coastguard Worker 
1009*48a54d36SAndroid Build Coastguard Worker 	// Success!
1010*48a54d36SAndroid Build Coastguard Worker 
1011*48a54d36SAndroid Build Coastguard Worker 	*outRef	= obj;
1012*48a54d36SAndroid Build Coastguard Worker 	obj 	= NULL;
1013*48a54d36SAndroid Build Coastguard Worker 	err 	= NO_ERROR;
1014*48a54d36SAndroid Build Coastguard Worker 
1015*48a54d36SAndroid Build Coastguard Worker exit:
1016*48a54d36SAndroid Build Coastguard Worker 	if( obj )
1017*48a54d36SAndroid Build Coastguard Worker 	{
1018*48a54d36SAndroid Build Coastguard Worker 		QueryRelease( obj );
1019*48a54d36SAndroid Build Coastguard Worker 	}
1020*48a54d36SAndroid Build Coastguard Worker 	return( err );
1021*48a54d36SAndroid Build Coastguard Worker }
1022*48a54d36SAndroid Build Coastguard Worker 
1023*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1024*48a54d36SAndroid Build Coastguard Worker //	QueryRetain
1025*48a54d36SAndroid Build Coastguard Worker //
1026*48a54d36SAndroid Build Coastguard Worker //	Warning: Assumes the NSP lock is held.
1027*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1028*48a54d36SAndroid Build Coastguard Worker 
QueryRetain(QueryRef inRef)1029*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL OSStatus	QueryRetain( QueryRef inRef )
1030*48a54d36SAndroid Build Coastguard Worker {
1031*48a54d36SAndroid Build Coastguard Worker 	OSStatus		err;
1032*48a54d36SAndroid Build Coastguard Worker 	QueryRef		obj;
1033*48a54d36SAndroid Build Coastguard Worker 
1034*48a54d36SAndroid Build Coastguard Worker 	for( obj = gQueryList; obj; obj = obj->next )
1035*48a54d36SAndroid Build Coastguard Worker 	{
1036*48a54d36SAndroid Build Coastguard Worker 		if( obj == inRef )
1037*48a54d36SAndroid Build Coastguard Worker 		{
1038*48a54d36SAndroid Build Coastguard Worker 			break;
1039*48a54d36SAndroid Build Coastguard Worker 		}
1040*48a54d36SAndroid Build Coastguard Worker 	}
1041*48a54d36SAndroid Build Coastguard Worker 	require_action( obj, exit, err = WSA_INVALID_HANDLE );
1042*48a54d36SAndroid Build Coastguard Worker 
1043*48a54d36SAndroid Build Coastguard Worker 	++inRef->refCount;
1044*48a54d36SAndroid Build Coastguard Worker 	err = NO_ERROR;
1045*48a54d36SAndroid Build Coastguard Worker 
1046*48a54d36SAndroid Build Coastguard Worker exit:
1047*48a54d36SAndroid Build Coastguard Worker 	return( err );
1048*48a54d36SAndroid Build Coastguard Worker }
1049*48a54d36SAndroid Build Coastguard Worker 
1050*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1051*48a54d36SAndroid Build Coastguard Worker //	QueryRelease
1052*48a54d36SAndroid Build Coastguard Worker //
1053*48a54d36SAndroid Build Coastguard Worker //	Warning: Assumes the NSP lock is held.
1054*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1055*48a54d36SAndroid Build Coastguard Worker 
QueryRelease(QueryRef inRef)1056*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL OSStatus	QueryRelease( QueryRef inRef )
1057*48a54d36SAndroid Build Coastguard Worker {
1058*48a54d36SAndroid Build Coastguard Worker 	OSStatus		err;
1059*48a54d36SAndroid Build Coastguard Worker 	QueryRef *		p;
1060*48a54d36SAndroid Build Coastguard Worker 	BOOL			ok;
1061*48a54d36SAndroid Build Coastguard Worker 
1062*48a54d36SAndroid Build Coastguard Worker 	// Find the item in the list.
1063*48a54d36SAndroid Build Coastguard Worker 
1064*48a54d36SAndroid Build Coastguard Worker 	for( p = &gQueryList; *p; p = &( *p )->next )
1065*48a54d36SAndroid Build Coastguard Worker 	{
1066*48a54d36SAndroid Build Coastguard Worker 		if( *p == inRef )
1067*48a54d36SAndroid Build Coastguard Worker 		{
1068*48a54d36SAndroid Build Coastguard Worker 			break;
1069*48a54d36SAndroid Build Coastguard Worker 		}
1070*48a54d36SAndroid Build Coastguard Worker 	}
1071*48a54d36SAndroid Build Coastguard Worker 	require_action( *p, exit, err = WSA_INVALID_HANDLE );
1072*48a54d36SAndroid Build Coastguard Worker 
1073*48a54d36SAndroid Build Coastguard Worker 	// Signal a cancel to unblock any threads waiting for results.
1074*48a54d36SAndroid Build Coastguard Worker 
1075*48a54d36SAndroid Build Coastguard Worker 	if( inRef->cancelEvent )
1076*48a54d36SAndroid Build Coastguard Worker 	{
1077*48a54d36SAndroid Build Coastguard Worker 		ok = SetEvent( inRef->cancelEvent );
1078*48a54d36SAndroid Build Coastguard Worker 		check_translated_errno( ok, GetLastError(), WSAEINVAL );
1079*48a54d36SAndroid Build Coastguard Worker 	}
1080*48a54d36SAndroid Build Coastguard Worker 
1081*48a54d36SAndroid Build Coastguard Worker 	// Stop the query.
1082*48a54d36SAndroid Build Coastguard Worker 
1083*48a54d36SAndroid Build Coastguard Worker 	if( inRef->resolver4 )
1084*48a54d36SAndroid Build Coastguard Worker 	{
1085*48a54d36SAndroid Build Coastguard Worker 		__try
1086*48a54d36SAndroid Build Coastguard Worker 		{
1087*48a54d36SAndroid Build Coastguard Worker 			DNSServiceRefDeallocate( inRef->resolver4 );
1088*48a54d36SAndroid Build Coastguard Worker 		}
1089*48a54d36SAndroid Build Coastguard Worker 		__except( EXCEPTION_EXECUTE_HANDLER )
1090*48a54d36SAndroid Build Coastguard Worker 		{
1091*48a54d36SAndroid Build Coastguard Worker 		}
1092*48a54d36SAndroid Build Coastguard Worker 
1093*48a54d36SAndroid Build Coastguard Worker 		inRef->resolver4 = NULL;
1094*48a54d36SAndroid Build Coastguard Worker 	}
1095*48a54d36SAndroid Build Coastguard Worker 
1096*48a54d36SAndroid Build Coastguard Worker 	if ( inRef->resolver6 )
1097*48a54d36SAndroid Build Coastguard Worker 	{
1098*48a54d36SAndroid Build Coastguard Worker 		__try
1099*48a54d36SAndroid Build Coastguard Worker 		{
1100*48a54d36SAndroid Build Coastguard Worker 			DNSServiceRefDeallocate( inRef->resolver6 );
1101*48a54d36SAndroid Build Coastguard Worker 		}
1102*48a54d36SAndroid Build Coastguard Worker 		__except( EXCEPTION_EXECUTE_HANDLER )
1103*48a54d36SAndroid Build Coastguard Worker 		{
1104*48a54d36SAndroid Build Coastguard Worker 		}
1105*48a54d36SAndroid Build Coastguard Worker 
1106*48a54d36SAndroid Build Coastguard Worker 		inRef->resolver6 = NULL;
1107*48a54d36SAndroid Build Coastguard Worker 	}
1108*48a54d36SAndroid Build Coastguard Worker 
1109*48a54d36SAndroid Build Coastguard Worker 	// Decrement the refCount. Fully release if it drops to 0. If still referenced, just exit.
1110*48a54d36SAndroid Build Coastguard Worker 
1111*48a54d36SAndroid Build Coastguard Worker 	if( --inRef->refCount != 0 )
1112*48a54d36SAndroid Build Coastguard Worker 	{
1113*48a54d36SAndroid Build Coastguard Worker 		err = NO_ERROR;
1114*48a54d36SAndroid Build Coastguard Worker 		goto exit;
1115*48a54d36SAndroid Build Coastguard Worker 	}
1116*48a54d36SAndroid Build Coastguard Worker 	*p = inRef->next;
1117*48a54d36SAndroid Build Coastguard Worker 
1118*48a54d36SAndroid Build Coastguard Worker 	// Release resources.
1119*48a54d36SAndroid Build Coastguard Worker 
1120*48a54d36SAndroid Build Coastguard Worker 	if( inRef->cancelEvent )
1121*48a54d36SAndroid Build Coastguard Worker 	{
1122*48a54d36SAndroid Build Coastguard Worker 		ok = CloseHandle( inRef->cancelEvent );
1123*48a54d36SAndroid Build Coastguard Worker 		check_translated_errno( ok, GetLastError(), WSAEINVAL );
1124*48a54d36SAndroid Build Coastguard Worker 	}
1125*48a54d36SAndroid Build Coastguard Worker 	if( inRef->data4Event )
1126*48a54d36SAndroid Build Coastguard Worker 	{
1127*48a54d36SAndroid Build Coastguard Worker 		ok = CloseHandle( inRef->data4Event );
1128*48a54d36SAndroid Build Coastguard Worker 		check_translated_errno( ok, GetLastError(), WSAEINVAL );
1129*48a54d36SAndroid Build Coastguard Worker 	}
1130*48a54d36SAndroid Build Coastguard Worker 	if( inRef->data6Event )
1131*48a54d36SAndroid Build Coastguard Worker 	{
1132*48a54d36SAndroid Build Coastguard Worker 		ok = CloseHandle( inRef->data6Event );
1133*48a54d36SAndroid Build Coastguard Worker 		check_translated_errno( ok, GetLastError(), WSAEINVAL );
1134*48a54d36SAndroid Build Coastguard Worker 	}
1135*48a54d36SAndroid Build Coastguard Worker 	if( inRef->querySet )
1136*48a54d36SAndroid Build Coastguard Worker 	{
1137*48a54d36SAndroid Build Coastguard Worker 		free( inRef->querySet );
1138*48a54d36SAndroid Build Coastguard Worker 	}
1139*48a54d36SAndroid Build Coastguard Worker 	free( inRef );
1140*48a54d36SAndroid Build Coastguard Worker 	err = NO_ERROR;
1141*48a54d36SAndroid Build Coastguard Worker 
1142*48a54d36SAndroid Build Coastguard Worker exit:
1143*48a54d36SAndroid Build Coastguard Worker 	return( err );
1144*48a54d36SAndroid Build Coastguard Worker }
1145*48a54d36SAndroid Build Coastguard Worker 
1146*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1147*48a54d36SAndroid Build Coastguard Worker //	QueryRecordCallback4
1148*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1149*48a54d36SAndroid Build Coastguard Worker 
1150*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL void CALLBACK_COMPAT
QueryRecordCallback4(DNSServiceRef inRef,DNSServiceFlags inFlags,uint32_t inInterfaceIndex,DNSServiceErrorType inErrorCode,const char * inName,uint16_t inRRType,uint16_t inRRClass,uint16_t inRDataSize,const void * inRData,uint32_t inTTL,void * inContext)1151*48a54d36SAndroid Build Coastguard Worker 	QueryRecordCallback4(
1152*48a54d36SAndroid Build Coastguard Worker 		DNSServiceRef		inRef,
1153*48a54d36SAndroid Build Coastguard Worker 		DNSServiceFlags		inFlags,
1154*48a54d36SAndroid Build Coastguard Worker 		uint32_t			inInterfaceIndex,
1155*48a54d36SAndroid Build Coastguard Worker 		DNSServiceErrorType	inErrorCode,
1156*48a54d36SAndroid Build Coastguard Worker 		const char *		inName,
1157*48a54d36SAndroid Build Coastguard Worker 		uint16_t			inRRType,
1158*48a54d36SAndroid Build Coastguard Worker 		uint16_t			inRRClass,
1159*48a54d36SAndroid Build Coastguard Worker 		uint16_t			inRDataSize,
1160*48a54d36SAndroid Build Coastguard Worker 		const void *		inRData,
1161*48a54d36SAndroid Build Coastguard Worker 		uint32_t			inTTL,
1162*48a54d36SAndroid Build Coastguard Worker 		void *				inContext )
1163*48a54d36SAndroid Build Coastguard Worker {
1164*48a54d36SAndroid Build Coastguard Worker 	QueryRef			obj;
1165*48a54d36SAndroid Build Coastguard Worker 	const char *		src;
1166*48a54d36SAndroid Build Coastguard Worker 	char *				dst;
1167*48a54d36SAndroid Build Coastguard Worker 	BOOL				ok;
1168*48a54d36SAndroid Build Coastguard Worker 
1169*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( inFlags );
1170*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( inInterfaceIndex );
1171*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( inTTL );
1172*48a54d36SAndroid Build Coastguard Worker 
1173*48a54d36SAndroid Build Coastguard Worker 	NSPLock();
1174*48a54d36SAndroid Build Coastguard Worker 	obj = (QueryRef) inContext;
1175*48a54d36SAndroid Build Coastguard Worker 	check( obj );
1176*48a54d36SAndroid Build Coastguard Worker 	require_noerr( inErrorCode, exit );
1177*48a54d36SAndroid Build Coastguard Worker 	require_quiet( inFlags & kDNSServiceFlagsAdd, exit );
1178*48a54d36SAndroid Build Coastguard Worker 	require( inRRClass   == kDNSServiceClass_IN, exit );
1179*48a54d36SAndroid Build Coastguard Worker 	require( inRRType    == kDNSServiceType_A, exit );
1180*48a54d36SAndroid Build Coastguard Worker 	require( inRDataSize == 4, exit );
1181*48a54d36SAndroid Build Coastguard Worker 
1182*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, "%s (flags=0x%08X, name=%s, rrType=%d, rDataSize=%d)\n",
1183*48a54d36SAndroid Build Coastguard Worker 		__ROUTINE__, inFlags, inName, inRRType, inRDataSize );
1184*48a54d36SAndroid Build Coastguard Worker 
1185*48a54d36SAndroid Build Coastguard Worker 	// Copy the name if needed.
1186*48a54d36SAndroid Build Coastguard Worker 
1187*48a54d36SAndroid Build Coastguard Worker 	if( obj->name[ 0 ] == '\0' )
1188*48a54d36SAndroid Build Coastguard Worker 	{
1189*48a54d36SAndroid Build Coastguard Worker 		src = inName;
1190*48a54d36SAndroid Build Coastguard Worker 		dst = obj->name;
1191*48a54d36SAndroid Build Coastguard Worker 		while( *src != '\0' )
1192*48a54d36SAndroid Build Coastguard Worker 		{
1193*48a54d36SAndroid Build Coastguard Worker 			*dst++ = *src++;
1194*48a54d36SAndroid Build Coastguard Worker 		}
1195*48a54d36SAndroid Build Coastguard Worker 		*dst = '\0';
1196*48a54d36SAndroid Build Coastguard Worker 		obj->nameSize = (size_t)( dst - obj->name );
1197*48a54d36SAndroid Build Coastguard Worker 		check( obj->nameSize < sizeof( obj->name ) );
1198*48a54d36SAndroid Build Coastguard Worker 	}
1199*48a54d36SAndroid Build Coastguard Worker 
1200*48a54d36SAndroid Build Coastguard Worker 	// Copy the data.
1201*48a54d36SAndroid Build Coastguard Worker 
1202*48a54d36SAndroid Build Coastguard Worker 	memcpy( &obj->addr4, inRData, inRDataSize );
1203*48a54d36SAndroid Build Coastguard Worker 	obj->addr4Valid = true;
1204*48a54d36SAndroid Build Coastguard Worker 	obj->numValidAddrs++;
1205*48a54d36SAndroid Build Coastguard Worker 
1206*48a54d36SAndroid Build Coastguard Worker 	// Signal that a result is ready.
1207*48a54d36SAndroid Build Coastguard Worker 
1208*48a54d36SAndroid Build Coastguard Worker 	check( obj->data4Event );
1209*48a54d36SAndroid Build Coastguard Worker 	ok = SetEvent( obj->data4Event );
1210*48a54d36SAndroid Build Coastguard Worker 	check_translated_errno( ok, GetLastError(), WSAEINVAL );
1211*48a54d36SAndroid Build Coastguard Worker 
1212*48a54d36SAndroid Build Coastguard Worker 	// Stop the resolver after the first response.
1213*48a54d36SAndroid Build Coastguard Worker 
1214*48a54d36SAndroid Build Coastguard Worker 	__try
1215*48a54d36SAndroid Build Coastguard Worker 	{
1216*48a54d36SAndroid Build Coastguard Worker 		DNSServiceRefDeallocate( inRef );
1217*48a54d36SAndroid Build Coastguard Worker 	}
1218*48a54d36SAndroid Build Coastguard Worker 	__except( EXCEPTION_EXECUTE_HANDLER )
1219*48a54d36SAndroid Build Coastguard Worker 	{
1220*48a54d36SAndroid Build Coastguard Worker 	}
1221*48a54d36SAndroid Build Coastguard Worker 
1222*48a54d36SAndroid Build Coastguard Worker 	obj->resolver4 = NULL;
1223*48a54d36SAndroid Build Coastguard Worker 
1224*48a54d36SAndroid Build Coastguard Worker exit:
1225*48a54d36SAndroid Build Coastguard Worker 	NSPUnlock();
1226*48a54d36SAndroid Build Coastguard Worker }
1227*48a54d36SAndroid Build Coastguard Worker 
1228*48a54d36SAndroid Build Coastguard Worker #if 0
1229*48a54d36SAndroid Build Coastguard Worker #pragma mark -
1230*48a54d36SAndroid Build Coastguard Worker #endif
1231*48a54d36SAndroid Build Coastguard Worker 
1232*48a54d36SAndroid Build Coastguard Worker 
1233*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1234*48a54d36SAndroid Build Coastguard Worker //	QueryRecordCallback6
1235*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1236*48a54d36SAndroid Build Coastguard Worker 
1237*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL void CALLBACK_COMPAT
QueryRecordCallback6(DNSServiceRef inRef,DNSServiceFlags inFlags,uint32_t inInterfaceIndex,DNSServiceErrorType inErrorCode,const char * inName,uint16_t inRRType,uint16_t inRRClass,uint16_t inRDataSize,const void * inRData,uint32_t inTTL,void * inContext)1238*48a54d36SAndroid Build Coastguard Worker 	QueryRecordCallback6(
1239*48a54d36SAndroid Build Coastguard Worker 		DNSServiceRef		inRef,
1240*48a54d36SAndroid Build Coastguard Worker 		DNSServiceFlags		inFlags,
1241*48a54d36SAndroid Build Coastguard Worker 		uint32_t			inInterfaceIndex,
1242*48a54d36SAndroid Build Coastguard Worker 		DNSServiceErrorType	inErrorCode,
1243*48a54d36SAndroid Build Coastguard Worker 		const char *		inName,
1244*48a54d36SAndroid Build Coastguard Worker 		uint16_t			inRRType,
1245*48a54d36SAndroid Build Coastguard Worker 		uint16_t			inRRClass,
1246*48a54d36SAndroid Build Coastguard Worker 		uint16_t			inRDataSize,
1247*48a54d36SAndroid Build Coastguard Worker 		const void *		inRData,
1248*48a54d36SAndroid Build Coastguard Worker 		uint32_t			inTTL,
1249*48a54d36SAndroid Build Coastguard Worker 		void *				inContext )
1250*48a54d36SAndroid Build Coastguard Worker {
1251*48a54d36SAndroid Build Coastguard Worker 	QueryRef			obj;
1252*48a54d36SAndroid Build Coastguard Worker 	const char *		src;
1253*48a54d36SAndroid Build Coastguard Worker 	char *				dst;
1254*48a54d36SAndroid Build Coastguard Worker 	BOOL				ok;
1255*48a54d36SAndroid Build Coastguard Worker 
1256*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( inFlags );
1257*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( inInterfaceIndex );
1258*48a54d36SAndroid Build Coastguard Worker 	DEBUG_UNUSED( inTTL );
1259*48a54d36SAndroid Build Coastguard Worker 
1260*48a54d36SAndroid Build Coastguard Worker 	NSPLock();
1261*48a54d36SAndroid Build Coastguard Worker 	obj = (QueryRef) inContext;
1262*48a54d36SAndroid Build Coastguard Worker 	check( obj );
1263*48a54d36SAndroid Build Coastguard Worker 	require_noerr( inErrorCode, exit );
1264*48a54d36SAndroid Build Coastguard Worker 	require_quiet( inFlags & kDNSServiceFlagsAdd, exit );
1265*48a54d36SAndroid Build Coastguard Worker 	require( inRRClass   == kDNSServiceClass_IN, exit );
1266*48a54d36SAndroid Build Coastguard Worker 	require( inRRType    == kDNSServiceType_AAAA, exit );
1267*48a54d36SAndroid Build Coastguard Worker 	require( inRDataSize == 16, exit );
1268*48a54d36SAndroid Build Coastguard Worker 
1269*48a54d36SAndroid Build Coastguard Worker 	dlog( kDebugLevelTrace, "%s (flags=0x%08X, name=%s, rrType=%d, rDataSize=%d)\n",
1270*48a54d36SAndroid Build Coastguard Worker 		__ROUTINE__, inFlags, inName, inRRType, inRDataSize );
1271*48a54d36SAndroid Build Coastguard Worker 
1272*48a54d36SAndroid Build Coastguard Worker 	// Copy the name if needed.
1273*48a54d36SAndroid Build Coastguard Worker 
1274*48a54d36SAndroid Build Coastguard Worker 	if( obj->name[ 0 ] == '\0' )
1275*48a54d36SAndroid Build Coastguard Worker 	{
1276*48a54d36SAndroid Build Coastguard Worker 		src = inName;
1277*48a54d36SAndroid Build Coastguard Worker 		dst = obj->name;
1278*48a54d36SAndroid Build Coastguard Worker 		while( *src != '\0' )
1279*48a54d36SAndroid Build Coastguard Worker 		{
1280*48a54d36SAndroid Build Coastguard Worker 			*dst++ = *src++;
1281*48a54d36SAndroid Build Coastguard Worker 		}
1282*48a54d36SAndroid Build Coastguard Worker 		*dst = '\0';
1283*48a54d36SAndroid Build Coastguard Worker 		obj->nameSize = (size_t)( dst - obj->name );
1284*48a54d36SAndroid Build Coastguard Worker 		check( obj->nameSize < sizeof( obj->name ) );
1285*48a54d36SAndroid Build Coastguard Worker 	}
1286*48a54d36SAndroid Build Coastguard Worker 
1287*48a54d36SAndroid Build Coastguard Worker 	// Copy the data.
1288*48a54d36SAndroid Build Coastguard Worker 
1289*48a54d36SAndroid Build Coastguard Worker 	memcpy( &obj->addr6, inRData, inRDataSize );
1290*48a54d36SAndroid Build Coastguard Worker 
1291*48a54d36SAndroid Build Coastguard Worker 	obj->addr6ScopeId = GetScopeId( inInterfaceIndex );
1292*48a54d36SAndroid Build Coastguard Worker 	require( obj->addr6ScopeId, exit );
1293*48a54d36SAndroid Build Coastguard Worker 	obj->addr6Valid	  = true;
1294*48a54d36SAndroid Build Coastguard Worker 	obj->numValidAddrs++;
1295*48a54d36SAndroid Build Coastguard Worker 
1296*48a54d36SAndroid Build Coastguard Worker 	// Signal that we're done
1297*48a54d36SAndroid Build Coastguard Worker 
1298*48a54d36SAndroid Build Coastguard Worker 	check( obj->data6Event );
1299*48a54d36SAndroid Build Coastguard Worker 	ok = SetEvent( obj->data6Event );
1300*48a54d36SAndroid Build Coastguard Worker 	check_translated_errno( ok, GetLastError(), WSAEINVAL );
1301*48a54d36SAndroid Build Coastguard Worker 
1302*48a54d36SAndroid Build Coastguard Worker 	// Stop the resolver after the first response.
1303*48a54d36SAndroid Build Coastguard Worker 
1304*48a54d36SAndroid Build Coastguard Worker 	__try
1305*48a54d36SAndroid Build Coastguard Worker 	{
1306*48a54d36SAndroid Build Coastguard Worker 		DNSServiceRefDeallocate( inRef );
1307*48a54d36SAndroid Build Coastguard Worker 	}
1308*48a54d36SAndroid Build Coastguard Worker 	__except( EXCEPTION_EXECUTE_HANDLER )
1309*48a54d36SAndroid Build Coastguard Worker 	{
1310*48a54d36SAndroid Build Coastguard Worker 	}
1311*48a54d36SAndroid Build Coastguard Worker 
1312*48a54d36SAndroid Build Coastguard Worker 	obj->resolver6 = NULL;
1313*48a54d36SAndroid Build Coastguard Worker 
1314*48a54d36SAndroid Build Coastguard Worker exit:
1315*48a54d36SAndroid Build Coastguard Worker 
1316*48a54d36SAndroid Build Coastguard Worker 
1317*48a54d36SAndroid Build Coastguard Worker 
1318*48a54d36SAndroid Build Coastguard Worker 	NSPUnlock();
1319*48a54d36SAndroid Build Coastguard Worker }
1320*48a54d36SAndroid Build Coastguard Worker 
1321*48a54d36SAndroid Build Coastguard Worker 
1322*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1323*48a54d36SAndroid Build Coastguard Worker //	QueryCopyQuerySet
1324*48a54d36SAndroid Build Coastguard Worker //
1325*48a54d36SAndroid Build Coastguard Worker //	Warning: Assumes the NSP lock is held.
1326*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1327*48a54d36SAndroid Build Coastguard Worker 
1328*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL OSStatus
QueryCopyQuerySet(QueryRef inRef,const WSAQUERYSETW * inQuerySet,DWORD inQuerySetFlags,WSAQUERYSETW ** outQuerySet,size_t * outSize)1329*48a54d36SAndroid Build Coastguard Worker 	QueryCopyQuerySet(
1330*48a54d36SAndroid Build Coastguard Worker 		QueryRef 				inRef,
1331*48a54d36SAndroid Build Coastguard Worker 		const WSAQUERYSETW *	inQuerySet,
1332*48a54d36SAndroid Build Coastguard Worker 		DWORD 					inQuerySetFlags,
1333*48a54d36SAndroid Build Coastguard Worker 		WSAQUERYSETW **			outQuerySet,
1334*48a54d36SAndroid Build Coastguard Worker 		size_t *				outSize )
1335*48a54d36SAndroid Build Coastguard Worker {
1336*48a54d36SAndroid Build Coastguard Worker 	OSStatus			err;
1337*48a54d36SAndroid Build Coastguard Worker 	size_t				size;
1338*48a54d36SAndroid Build Coastguard Worker 	WSAQUERYSETW *		qs;
1339*48a54d36SAndroid Build Coastguard Worker 
1340*48a54d36SAndroid Build Coastguard Worker 	check( inQuerySet );
1341*48a54d36SAndroid Build Coastguard Worker 	check( outQuerySet );
1342*48a54d36SAndroid Build Coastguard Worker 
1343*48a54d36SAndroid Build Coastguard Worker 	size  = QueryCopyQuerySetSize( inRef, inQuerySet, inQuerySetFlags );
1344*48a54d36SAndroid Build Coastguard Worker 	qs = (WSAQUERYSETW *) calloc( 1, size );
1345*48a54d36SAndroid Build Coastguard Worker 	require_action( qs, exit, err = WSA_NOT_ENOUGH_MEMORY  );
1346*48a54d36SAndroid Build Coastguard Worker 
1347*48a54d36SAndroid Build Coastguard Worker 	QueryCopyQuerySetTo( inRef, inQuerySet, inQuerySetFlags, qs );
1348*48a54d36SAndroid Build Coastguard Worker 
1349*48a54d36SAndroid Build Coastguard Worker 	*outQuerySet = qs;
1350*48a54d36SAndroid Build Coastguard Worker 	if( outSize )
1351*48a54d36SAndroid Build Coastguard Worker 	{
1352*48a54d36SAndroid Build Coastguard Worker 		*outSize = size;
1353*48a54d36SAndroid Build Coastguard Worker 	}
1354*48a54d36SAndroid Build Coastguard Worker 	qs = NULL;
1355*48a54d36SAndroid Build Coastguard Worker 	err = NO_ERROR;
1356*48a54d36SAndroid Build Coastguard Worker 
1357*48a54d36SAndroid Build Coastguard Worker exit:
1358*48a54d36SAndroid Build Coastguard Worker 	if( qs )
1359*48a54d36SAndroid Build Coastguard Worker 	{
1360*48a54d36SAndroid Build Coastguard Worker 		free( qs );
1361*48a54d36SAndroid Build Coastguard Worker 	}
1362*48a54d36SAndroid Build Coastguard Worker 	return( err );
1363*48a54d36SAndroid Build Coastguard Worker }
1364*48a54d36SAndroid Build Coastguard Worker 
1365*48a54d36SAndroid Build Coastguard Worker 
1366*48a54d36SAndroid Build Coastguard Worker 
1367*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1368*48a54d36SAndroid Build Coastguard Worker //	QueryCopyQuerySetTo
1369*48a54d36SAndroid Build Coastguard Worker //
1370*48a54d36SAndroid Build Coastguard Worker //	Warning: Assumes the NSP lock is held.
1371*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1372*48a54d36SAndroid Build Coastguard Worker 
1373*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL void
QueryCopyQuerySetTo(QueryRef inRef,const WSAQUERYSETW * inQuerySet,DWORD inQuerySetFlags,WSAQUERYSETW * outQuerySet)1374*48a54d36SAndroid Build Coastguard Worker 	QueryCopyQuerySetTo(
1375*48a54d36SAndroid Build Coastguard Worker 		QueryRef 				inRef,
1376*48a54d36SAndroid Build Coastguard Worker 		const WSAQUERYSETW *	inQuerySet,
1377*48a54d36SAndroid Build Coastguard Worker 		DWORD 					inQuerySetFlags,
1378*48a54d36SAndroid Build Coastguard Worker 		WSAQUERYSETW *			outQuerySet )
1379*48a54d36SAndroid Build Coastguard Worker {
1380*48a54d36SAndroid Build Coastguard Worker 	uint8_t *		dst;
1381*48a54d36SAndroid Build Coastguard Worker 	LPCWSTR			s;
1382*48a54d36SAndroid Build Coastguard Worker 	LPWSTR			q;
1383*48a54d36SAndroid Build Coastguard Worker 	DWORD			n;
1384*48a54d36SAndroid Build Coastguard Worker 	DWORD			i;
1385*48a54d36SAndroid Build Coastguard Worker 
1386*48a54d36SAndroid Build Coastguard Worker #if( DEBUG )
1387*48a54d36SAndroid Build Coastguard Worker 	size_t			debugSize;
1388*48a54d36SAndroid Build Coastguard Worker 
1389*48a54d36SAndroid Build Coastguard Worker 	debugSize = QueryCopyQuerySetSize( inRef, inQuerySet, inQuerySetFlags );
1390*48a54d36SAndroid Build Coastguard Worker #endif
1391*48a54d36SAndroid Build Coastguard Worker 
1392*48a54d36SAndroid Build Coastguard Worker 	check( inQuerySet );
1393*48a54d36SAndroid Build Coastguard Worker 	check( outQuerySet );
1394*48a54d36SAndroid Build Coastguard Worker 
1395*48a54d36SAndroid Build Coastguard Worker 	dst = (uint8_t *) outQuerySet;
1396*48a54d36SAndroid Build Coastguard Worker 
1397*48a54d36SAndroid Build Coastguard Worker 	// Copy the static portion of the results.
1398*48a54d36SAndroid Build Coastguard Worker 
1399*48a54d36SAndroid Build Coastguard Worker 	*outQuerySet = *inQuerySet;
1400*48a54d36SAndroid Build Coastguard Worker 	dst += sizeof( *inQuerySet );
1401*48a54d36SAndroid Build Coastguard Worker 
1402*48a54d36SAndroid Build Coastguard Worker 	if( inQuerySetFlags & LUP_RETURN_NAME )
1403*48a54d36SAndroid Build Coastguard Worker 	{
1404*48a54d36SAndroid Build Coastguard Worker 		s = inQuerySet->lpszServiceInstanceName;
1405*48a54d36SAndroid Build Coastguard Worker 		if( s )
1406*48a54d36SAndroid Build Coastguard Worker 		{
1407*48a54d36SAndroid Build Coastguard Worker 			outQuerySet->lpszServiceInstanceName = (LPWSTR) dst;
1408*48a54d36SAndroid Build Coastguard Worker 			q = (LPWSTR) dst;
1409*48a54d36SAndroid Build Coastguard Worker 			while( ( *q++ = *s++ ) != 0 ) {}
1410*48a54d36SAndroid Build Coastguard Worker 			dst = (uint8_t *) q;
1411*48a54d36SAndroid Build Coastguard Worker 		}
1412*48a54d36SAndroid Build Coastguard Worker 	}
1413*48a54d36SAndroid Build Coastguard Worker 	else
1414*48a54d36SAndroid Build Coastguard Worker 	{
1415*48a54d36SAndroid Build Coastguard Worker 		outQuerySet->lpszServiceInstanceName = NULL;
1416*48a54d36SAndroid Build Coastguard Worker 	}
1417*48a54d36SAndroid Build Coastguard Worker 
1418*48a54d36SAndroid Build Coastguard Worker 	if( inQuerySet->lpServiceClassId )
1419*48a54d36SAndroid Build Coastguard Worker 	{
1420*48a54d36SAndroid Build Coastguard Worker 		outQuerySet->lpServiceClassId  = (LPGUID) dst;
1421*48a54d36SAndroid Build Coastguard Worker 		*outQuerySet->lpServiceClassId = *inQuerySet->lpServiceClassId;
1422*48a54d36SAndroid Build Coastguard Worker 		dst += sizeof( *inQuerySet->lpServiceClassId );
1423*48a54d36SAndroid Build Coastguard Worker 	}
1424*48a54d36SAndroid Build Coastguard Worker 
1425*48a54d36SAndroid Build Coastguard Worker 	if( inQuerySet->lpVersion )
1426*48a54d36SAndroid Build Coastguard Worker 	{
1427*48a54d36SAndroid Build Coastguard Worker 		outQuerySet->lpVersion  = (LPWSAVERSION) dst;
1428*48a54d36SAndroid Build Coastguard Worker 		*outQuerySet->lpVersion = *inQuerySet->lpVersion;
1429*48a54d36SAndroid Build Coastguard Worker 		dst += sizeof( *inQuerySet->lpVersion );
1430*48a54d36SAndroid Build Coastguard Worker 	}
1431*48a54d36SAndroid Build Coastguard Worker 
1432*48a54d36SAndroid Build Coastguard Worker 	s = inQuerySet->lpszComment;
1433*48a54d36SAndroid Build Coastguard Worker 	if( s )
1434*48a54d36SAndroid Build Coastguard Worker 	{
1435*48a54d36SAndroid Build Coastguard Worker 		outQuerySet->lpszComment = (LPWSTR) dst;
1436*48a54d36SAndroid Build Coastguard Worker 		q = (LPWSTR) dst;
1437*48a54d36SAndroid Build Coastguard Worker 		while( ( *q++ = *s++ ) != 0 ) {}
1438*48a54d36SAndroid Build Coastguard Worker 		dst = (uint8_t *) q;
1439*48a54d36SAndroid Build Coastguard Worker 	}
1440*48a54d36SAndroid Build Coastguard Worker 
1441*48a54d36SAndroid Build Coastguard Worker 	if( inQuerySet->lpNSProviderId )
1442*48a54d36SAndroid Build Coastguard Worker 	{
1443*48a54d36SAndroid Build Coastguard Worker 		outQuerySet->lpNSProviderId  = (LPGUID) dst;
1444*48a54d36SAndroid Build Coastguard Worker 		*outQuerySet->lpNSProviderId = *inQuerySet->lpNSProviderId;
1445*48a54d36SAndroid Build Coastguard Worker 		dst += sizeof( *inQuerySet->lpNSProviderId );
1446*48a54d36SAndroid Build Coastguard Worker 	}
1447*48a54d36SAndroid Build Coastguard Worker 
1448*48a54d36SAndroid Build Coastguard Worker 	s = inQuerySet->lpszContext;
1449*48a54d36SAndroid Build Coastguard Worker 	if( s )
1450*48a54d36SAndroid Build Coastguard Worker 	{
1451*48a54d36SAndroid Build Coastguard Worker 		outQuerySet->lpszContext = (LPWSTR) dst;
1452*48a54d36SAndroid Build Coastguard Worker 		q = (LPWSTR) dst;
1453*48a54d36SAndroid Build Coastguard Worker 		while( ( *q++ = *s++ ) != 0 ) {}
1454*48a54d36SAndroid Build Coastguard Worker 		dst = (uint8_t *) q;
1455*48a54d36SAndroid Build Coastguard Worker 	}
1456*48a54d36SAndroid Build Coastguard Worker 
1457*48a54d36SAndroid Build Coastguard Worker 	n = inQuerySet->dwNumberOfProtocols;
1458*48a54d36SAndroid Build Coastguard Worker 
1459*48a54d36SAndroid Build Coastguard Worker 	if( n > 0 )
1460*48a54d36SAndroid Build Coastguard Worker 	{
1461*48a54d36SAndroid Build Coastguard Worker 		check( inQuerySet->lpafpProtocols );
1462*48a54d36SAndroid Build Coastguard Worker 
1463*48a54d36SAndroid Build Coastguard Worker 		outQuerySet->lpafpProtocols = (LPAFPROTOCOLS) dst;
1464*48a54d36SAndroid Build Coastguard Worker 		for( i = 0; i < n; ++i )
1465*48a54d36SAndroid Build Coastguard Worker 		{
1466*48a54d36SAndroid Build Coastguard Worker 			outQuerySet->lpafpProtocols[ i ] = inQuerySet->lpafpProtocols[ i ];
1467*48a54d36SAndroid Build Coastguard Worker 			dst += sizeof( *inQuerySet->lpafpProtocols );
1468*48a54d36SAndroid Build Coastguard Worker 		}
1469*48a54d36SAndroid Build Coastguard Worker 	}
1470*48a54d36SAndroid Build Coastguard Worker 
1471*48a54d36SAndroid Build Coastguard Worker 	s = inQuerySet->lpszQueryString;
1472*48a54d36SAndroid Build Coastguard Worker 	if( s )
1473*48a54d36SAndroid Build Coastguard Worker 	{
1474*48a54d36SAndroid Build Coastguard Worker 		outQuerySet->lpszQueryString = (LPWSTR) dst;
1475*48a54d36SAndroid Build Coastguard Worker 		q = (LPWSTR) dst;
1476*48a54d36SAndroid Build Coastguard Worker 		while( ( *q++ = *s++ ) != 0 ) {}
1477*48a54d36SAndroid Build Coastguard Worker 		dst = (uint8_t *) q;
1478*48a54d36SAndroid Build Coastguard Worker 	}
1479*48a54d36SAndroid Build Coastguard Worker 
1480*48a54d36SAndroid Build Coastguard Worker 	// Copy the address(es).
1481*48a54d36SAndroid Build Coastguard Worker 
1482*48a54d36SAndroid Build Coastguard Worker 	if( ( inQuerySetFlags & LUP_RETURN_ADDR ) && ( inRef->numValidAddrs > 0 ) )
1483*48a54d36SAndroid Build Coastguard Worker 	{
1484*48a54d36SAndroid Build Coastguard Worker 		struct sockaddr_in	*	addr4;
1485*48a54d36SAndroid Build Coastguard Worker 		struct sockaddr_in6	*	addr6;
1486*48a54d36SAndroid Build Coastguard Worker 		int						index;
1487*48a54d36SAndroid Build Coastguard Worker 
1488*48a54d36SAndroid Build Coastguard Worker 		outQuerySet->dwNumberOfCsAddrs	= inRef->numValidAddrs;
1489*48a54d36SAndroid Build Coastguard Worker 		outQuerySet->lpcsaBuffer 		= (LPCSADDR_INFO) dst;
1490*48a54d36SAndroid Build Coastguard Worker 		dst 							+= ( sizeof( *outQuerySet->lpcsaBuffer ) ) * ( inRef->numValidAddrs ) ;
1491*48a54d36SAndroid Build Coastguard Worker 		index							= 0;
1492*48a54d36SAndroid Build Coastguard Worker 
1493*48a54d36SAndroid Build Coastguard Worker 		if ( inRef->addr4Valid )
1494*48a54d36SAndroid Build Coastguard Worker 		{
1495*48a54d36SAndroid Build Coastguard Worker 			outQuerySet->lpcsaBuffer[ index ].LocalAddr.lpSockaddr 			= NULL;
1496*48a54d36SAndroid Build Coastguard Worker 			outQuerySet->lpcsaBuffer[ index ].LocalAddr.iSockaddrLength		= 0;
1497*48a54d36SAndroid Build Coastguard Worker 
1498*48a54d36SAndroid Build Coastguard Worker 			outQuerySet->lpcsaBuffer[ index ].RemoteAddr.lpSockaddr 		= (LPSOCKADDR) dst;
1499*48a54d36SAndroid Build Coastguard Worker 			outQuerySet->lpcsaBuffer[ index ].RemoteAddr.iSockaddrLength	= sizeof( struct sockaddr_in );
1500*48a54d36SAndroid Build Coastguard Worker 
1501*48a54d36SAndroid Build Coastguard Worker 			addr4 															= (struct sockaddr_in *) dst;
1502*48a54d36SAndroid Build Coastguard Worker 			memset( addr4, 0, sizeof( *addr4 ) );
1503*48a54d36SAndroid Build Coastguard Worker 			addr4->sin_family												= AF_INET;
1504*48a54d36SAndroid Build Coastguard Worker 			memcpy( &addr4->sin_addr, &inRef->addr4, 4 );
1505*48a54d36SAndroid Build Coastguard Worker 			dst 															+= sizeof( *addr4 );
1506*48a54d36SAndroid Build Coastguard Worker 
1507*48a54d36SAndroid Build Coastguard Worker 			outQuerySet->lpcsaBuffer[ index ].iSocketType 					= AF_INET;		// Emulate Tcpip NSP
1508*48a54d36SAndroid Build Coastguard Worker 			outQuerySet->lpcsaBuffer[ index ].iProtocol						= IPPROTO_UDP;	// Emulate Tcpip NSP
1509*48a54d36SAndroid Build Coastguard Worker 
1510*48a54d36SAndroid Build Coastguard Worker 			index++;
1511*48a54d36SAndroid Build Coastguard Worker 		}
1512*48a54d36SAndroid Build Coastguard Worker 
1513*48a54d36SAndroid Build Coastguard Worker 		if ( inRef->addr6Valid )
1514*48a54d36SAndroid Build Coastguard Worker 		{
1515*48a54d36SAndroid Build Coastguard Worker 			outQuerySet->lpcsaBuffer[ index ].LocalAddr.lpSockaddr 			= NULL;
1516*48a54d36SAndroid Build Coastguard Worker 			outQuerySet->lpcsaBuffer[ index ].LocalAddr.iSockaddrLength		= 0;
1517*48a54d36SAndroid Build Coastguard Worker 
1518*48a54d36SAndroid Build Coastguard Worker 			outQuerySet->lpcsaBuffer[ index ].RemoteAddr.lpSockaddr 		= (LPSOCKADDR) dst;
1519*48a54d36SAndroid Build Coastguard Worker 			outQuerySet->lpcsaBuffer[ index ].RemoteAddr.iSockaddrLength	= sizeof( struct sockaddr_in6 );
1520*48a54d36SAndroid Build Coastguard Worker 
1521*48a54d36SAndroid Build Coastguard Worker 			addr6 															= (struct sockaddr_in6 *) dst;
1522*48a54d36SAndroid Build Coastguard Worker 			memset( addr6, 0, sizeof( *addr6 ) );
1523*48a54d36SAndroid Build Coastguard Worker 			addr6->sin6_family												= AF_INET6;
1524*48a54d36SAndroid Build Coastguard Worker 			addr6->sin6_scope_id											= inRef->addr6ScopeId;
1525*48a54d36SAndroid Build Coastguard Worker 			memcpy( &addr6->sin6_addr, &inRef->addr6, 16 );
1526*48a54d36SAndroid Build Coastguard Worker 			dst 															+= sizeof( *addr6 );
1527*48a54d36SAndroid Build Coastguard Worker 
1528*48a54d36SAndroid Build Coastguard Worker 			outQuerySet->lpcsaBuffer[ index ].iSocketType 					= AF_INET6;		// Emulate Tcpip NSP
1529*48a54d36SAndroid Build Coastguard Worker 			outQuerySet->lpcsaBuffer[ index ].iProtocol						= IPPROTO_UDP;	// Emulate Tcpip NSP
1530*48a54d36SAndroid Build Coastguard Worker 		}
1531*48a54d36SAndroid Build Coastguard Worker 	}
1532*48a54d36SAndroid Build Coastguard Worker 	else
1533*48a54d36SAndroid Build Coastguard Worker 	{
1534*48a54d36SAndroid Build Coastguard Worker 		outQuerySet->dwNumberOfCsAddrs	= 0;
1535*48a54d36SAndroid Build Coastguard Worker 		outQuerySet->lpcsaBuffer 		= NULL;
1536*48a54d36SAndroid Build Coastguard Worker 	}
1537*48a54d36SAndroid Build Coastguard Worker 
1538*48a54d36SAndroid Build Coastguard Worker 	// Copy the hostent blob.
1539*48a54d36SAndroid Build Coastguard Worker 
1540*48a54d36SAndroid Build Coastguard Worker 	if( ( inQuerySetFlags & LUP_RETURN_BLOB ) && inRef->addr4Valid )
1541*48a54d36SAndroid Build Coastguard Worker 	{
1542*48a54d36SAndroid Build Coastguard Worker 		uint8_t *				base;
1543*48a54d36SAndroid Build Coastguard Worker 		struct hostent *		he;
1544*48a54d36SAndroid Build Coastguard Worker 		uintptr_t *				p;
1545*48a54d36SAndroid Build Coastguard Worker 
1546*48a54d36SAndroid Build Coastguard Worker 		outQuerySet->lpBlob	 = (LPBLOB) dst;
1547*48a54d36SAndroid Build Coastguard Worker 		dst 				+= sizeof( *outQuerySet->lpBlob );
1548*48a54d36SAndroid Build Coastguard Worker 
1549*48a54d36SAndroid Build Coastguard Worker 		base = dst;
1550*48a54d36SAndroid Build Coastguard Worker 		he	 = (struct hostent *) dst;
1551*48a54d36SAndroid Build Coastguard Worker 		dst += sizeof( *he );
1552*48a54d36SAndroid Build Coastguard Worker 
1553*48a54d36SAndroid Build Coastguard Worker 		he->h_name = (char *)( dst - base );
1554*48a54d36SAndroid Build Coastguard Worker 		memcpy( dst, inRef->name, inRef->nameSize + 1 );
1555*48a54d36SAndroid Build Coastguard Worker 		dst += ( inRef->nameSize + 1 );
1556*48a54d36SAndroid Build Coastguard Worker 
1557*48a54d36SAndroid Build Coastguard Worker 		he->h_aliases 	= (char **)( dst - base );
1558*48a54d36SAndroid Build Coastguard Worker 		p	  			= (uintptr_t *) dst;
1559*48a54d36SAndroid Build Coastguard Worker 		*p++  			= 0;
1560*48a54d36SAndroid Build Coastguard Worker 		dst 		 	= (uint8_t *) p;
1561*48a54d36SAndroid Build Coastguard Worker 
1562*48a54d36SAndroid Build Coastguard Worker 		he->h_addrtype 	= AF_INET;
1563*48a54d36SAndroid Build Coastguard Worker 		he->h_length	= 4;
1564*48a54d36SAndroid Build Coastguard Worker 
1565*48a54d36SAndroid Build Coastguard Worker 		he->h_addr_list	= (char **)( dst - base );
1566*48a54d36SAndroid Build Coastguard Worker 		p	  			= (uintptr_t *) dst;
1567*48a54d36SAndroid Build Coastguard Worker 		dst 		   += ( 2 * sizeof( *p ) );
1568*48a54d36SAndroid Build Coastguard Worker 		*p++			= (uintptr_t)( dst - base );
1569*48a54d36SAndroid Build Coastguard Worker 		*p++			= 0;
1570*48a54d36SAndroid Build Coastguard Worker 		p	  			= (uintptr_t *) dst;
1571*48a54d36SAndroid Build Coastguard Worker 		*p++			= (uintptr_t) inRef->addr4;
1572*48a54d36SAndroid Build Coastguard Worker 		dst 		 	= (uint8_t *) p;
1573*48a54d36SAndroid Build Coastguard Worker 
1574*48a54d36SAndroid Build Coastguard Worker 		outQuerySet->lpBlob->cbSize 	= (ULONG)( dst - base );
1575*48a54d36SAndroid Build Coastguard Worker 		outQuerySet->lpBlob->pBlobData	= (BYTE *) base;
1576*48a54d36SAndroid Build Coastguard Worker 	}
1577*48a54d36SAndroid Build Coastguard Worker 	dlog_query_set( kDebugLevelVerbose, outQuerySet );
1578*48a54d36SAndroid Build Coastguard Worker 
1579*48a54d36SAndroid Build Coastguard Worker 	check( (size_t)( dst - ( (uint8_t *) outQuerySet ) ) == debugSize );
1580*48a54d36SAndroid Build Coastguard Worker }
1581*48a54d36SAndroid Build Coastguard Worker 
1582*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1583*48a54d36SAndroid Build Coastguard Worker //	QueryCopyQuerySetSize
1584*48a54d36SAndroid Build Coastguard Worker //
1585*48a54d36SAndroid Build Coastguard Worker //	Warning: Assumes the NSP lock is held.
1586*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1587*48a54d36SAndroid Build Coastguard Worker 
QueryCopyQuerySetSize(QueryRef inRef,const WSAQUERYSETW * inQuerySet,DWORD inQuerySetFlags)1588*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL size_t	QueryCopyQuerySetSize( QueryRef inRef, const WSAQUERYSETW *inQuerySet, DWORD inQuerySetFlags )
1589*48a54d36SAndroid Build Coastguard Worker {
1590*48a54d36SAndroid Build Coastguard Worker 	size_t		size;
1591*48a54d36SAndroid Build Coastguard Worker 	LPCWSTR		s;
1592*48a54d36SAndroid Build Coastguard Worker 	LPCWSTR		p;
1593*48a54d36SAndroid Build Coastguard Worker 
1594*48a54d36SAndroid Build Coastguard Worker 	check( inRef );
1595*48a54d36SAndroid Build Coastguard Worker 	check( inQuerySet );
1596*48a54d36SAndroid Build Coastguard Worker 
1597*48a54d36SAndroid Build Coastguard Worker 	// Calculate the size of the static portion of the results.
1598*48a54d36SAndroid Build Coastguard Worker 
1599*48a54d36SAndroid Build Coastguard Worker 	size = sizeof( *inQuerySet );
1600*48a54d36SAndroid Build Coastguard Worker 
1601*48a54d36SAndroid Build Coastguard Worker 	if( inQuerySetFlags & LUP_RETURN_NAME )
1602*48a54d36SAndroid Build Coastguard Worker 	{
1603*48a54d36SAndroid Build Coastguard Worker 		s = inQuerySet->lpszServiceInstanceName;
1604*48a54d36SAndroid Build Coastguard Worker 		if( s )
1605*48a54d36SAndroid Build Coastguard Worker 		{
1606*48a54d36SAndroid Build Coastguard Worker 			for( p = s; *p; ++p ) {}
1607*48a54d36SAndroid Build Coastguard Worker 			size += (size_t)( ( ( p - s ) + 1 ) * sizeof( *p ) );
1608*48a54d36SAndroid Build Coastguard Worker 		}
1609*48a54d36SAndroid Build Coastguard Worker 	}
1610*48a54d36SAndroid Build Coastguard Worker 
1611*48a54d36SAndroid Build Coastguard Worker 	if( inQuerySet->lpServiceClassId )
1612*48a54d36SAndroid Build Coastguard Worker 	{
1613*48a54d36SAndroid Build Coastguard Worker 		size += sizeof( *inQuerySet->lpServiceClassId );
1614*48a54d36SAndroid Build Coastguard Worker 	}
1615*48a54d36SAndroid Build Coastguard Worker 
1616*48a54d36SAndroid Build Coastguard Worker 	if( inQuerySet->lpVersion )
1617*48a54d36SAndroid Build Coastguard Worker 	{
1618*48a54d36SAndroid Build Coastguard Worker 		size += sizeof( *inQuerySet->lpVersion );
1619*48a54d36SAndroid Build Coastguard Worker 	}
1620*48a54d36SAndroid Build Coastguard Worker 
1621*48a54d36SAndroid Build Coastguard Worker 	s = inQuerySet->lpszComment;
1622*48a54d36SAndroid Build Coastguard Worker 	if( s )
1623*48a54d36SAndroid Build Coastguard Worker 	{
1624*48a54d36SAndroid Build Coastguard Worker 		for( p = s; *p; ++p ) {}
1625*48a54d36SAndroid Build Coastguard Worker 		size += (size_t)( ( ( p - s ) + 1 ) * sizeof( *p ) );
1626*48a54d36SAndroid Build Coastguard Worker 	}
1627*48a54d36SAndroid Build Coastguard Worker 
1628*48a54d36SAndroid Build Coastguard Worker 	if( inQuerySet->lpNSProviderId )
1629*48a54d36SAndroid Build Coastguard Worker 	{
1630*48a54d36SAndroid Build Coastguard Worker 		size += sizeof( *inQuerySet->lpNSProviderId );
1631*48a54d36SAndroid Build Coastguard Worker 	}
1632*48a54d36SAndroid Build Coastguard Worker 
1633*48a54d36SAndroid Build Coastguard Worker 	s = inQuerySet->lpszContext;
1634*48a54d36SAndroid Build Coastguard Worker 	if( s )
1635*48a54d36SAndroid Build Coastguard Worker 	{
1636*48a54d36SAndroid Build Coastguard Worker 		for( p = s; *p; ++p ) {}
1637*48a54d36SAndroid Build Coastguard Worker 		size += (size_t)( ( ( p - s ) + 1 ) * sizeof( *p ) );
1638*48a54d36SAndroid Build Coastguard Worker 	}
1639*48a54d36SAndroid Build Coastguard Worker 
1640*48a54d36SAndroid Build Coastguard Worker 	size += ( inQuerySet->dwNumberOfProtocols * sizeof( *inQuerySet->lpafpProtocols ) );
1641*48a54d36SAndroid Build Coastguard Worker 
1642*48a54d36SAndroid Build Coastguard Worker 	s = inQuerySet->lpszQueryString;
1643*48a54d36SAndroid Build Coastguard Worker 	if( s )
1644*48a54d36SAndroid Build Coastguard Worker 	{
1645*48a54d36SAndroid Build Coastguard Worker 		for( p = s; *p; ++p ) {}
1646*48a54d36SAndroid Build Coastguard Worker 		size += (size_t)( ( ( p - s ) + 1 ) * sizeof( *p ) );
1647*48a54d36SAndroid Build Coastguard Worker 	}
1648*48a54d36SAndroid Build Coastguard Worker 
1649*48a54d36SAndroid Build Coastguard Worker 	// Calculate the size of the address(es).
1650*48a54d36SAndroid Build Coastguard Worker 
1651*48a54d36SAndroid Build Coastguard Worker 	if( ( inQuerySetFlags & LUP_RETURN_ADDR ) && inRef->addr4Valid )
1652*48a54d36SAndroid Build Coastguard Worker 	{
1653*48a54d36SAndroid Build Coastguard Worker 		size += sizeof( *inQuerySet->lpcsaBuffer );
1654*48a54d36SAndroid Build Coastguard Worker 		size += sizeof( struct sockaddr_in );
1655*48a54d36SAndroid Build Coastguard Worker 	}
1656*48a54d36SAndroid Build Coastguard Worker 
1657*48a54d36SAndroid Build Coastguard Worker 	if( ( inQuerySetFlags & LUP_RETURN_ADDR ) && inRef->addr6Valid )
1658*48a54d36SAndroid Build Coastguard Worker 	{
1659*48a54d36SAndroid Build Coastguard Worker 		size += sizeof( *inQuerySet->lpcsaBuffer );
1660*48a54d36SAndroid Build Coastguard Worker 		size += sizeof( struct sockaddr_in6 );
1661*48a54d36SAndroid Build Coastguard Worker 	}
1662*48a54d36SAndroid Build Coastguard Worker 
1663*48a54d36SAndroid Build Coastguard Worker 	// Calculate the size of the hostent blob.
1664*48a54d36SAndroid Build Coastguard Worker 
1665*48a54d36SAndroid Build Coastguard Worker 	if( ( inQuerySetFlags & LUP_RETURN_BLOB ) && inRef->addr4Valid )
1666*48a54d36SAndroid Build Coastguard Worker 	{
1667*48a54d36SAndroid Build Coastguard Worker 		size += sizeof( *inQuerySet->lpBlob );	// Blob ptr/size structure
1668*48a54d36SAndroid Build Coastguard Worker 		size += sizeof( struct hostent );		// Old-style hostent structure
1669*48a54d36SAndroid Build Coastguard Worker 		size += ( inRef->nameSize + 1 );		// Name and null terminator
1670*48a54d36SAndroid Build Coastguard Worker 		size += 4;								// Alias list terminator (0 offset)
1671*48a54d36SAndroid Build Coastguard Worker 		size += 4;								// Offset to address.
1672*48a54d36SAndroid Build Coastguard Worker 		size += 4;								// Address list terminator (0 offset)
1673*48a54d36SAndroid Build Coastguard Worker 		size += 4;								// IPv4 address
1674*48a54d36SAndroid Build Coastguard Worker 	}
1675*48a54d36SAndroid Build Coastguard Worker 	return( size );
1676*48a54d36SAndroid Build Coastguard Worker }
1677*48a54d36SAndroid Build Coastguard Worker 
1678*48a54d36SAndroid Build Coastguard Worker #if 0
1679*48a54d36SAndroid Build Coastguard Worker #pragma mark -
1680*48a54d36SAndroid Build Coastguard Worker #endif
1681*48a54d36SAndroid Build Coastguard Worker 
1682*48a54d36SAndroid Build Coastguard Worker #if( DEBUG )
1683*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1684*48a54d36SAndroid Build Coastguard Worker //	DebugDumpQuerySet
1685*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1686*48a54d36SAndroid Build Coastguard Worker 
1687*48a54d36SAndroid Build Coastguard Worker #define	DebugSocketFamilyToString( FAM )	( ( FAM ) == AF_INET )  ? "AF_INET"  : \
1688*48a54d36SAndroid Build Coastguard Worker 											( ( FAM ) == AF_INET6 ) ? "AF_INET6" : ""
1689*48a54d36SAndroid Build Coastguard Worker 
1690*48a54d36SAndroid Build Coastguard Worker #define	DebugSocketProtocolToString( PROTO )	( ( PROTO ) == IPPROTO_UDP ) ? "IPPROTO_UDP" : \
1691*48a54d36SAndroid Build Coastguard Worker 												( ( PROTO ) == IPPROTO_TCP ) ? "IPPROTO_TCP" : ""
1692*48a54d36SAndroid Build Coastguard Worker 
1693*48a54d36SAndroid Build Coastguard Worker #define	DebugNameSpaceToString( NS )			( ( NS ) == NS_DNS ) ? "NS_DNS" : ( ( NS ) == NS_ALL ) ? "NS_ALL" : ""
1694*48a54d36SAndroid Build Coastguard Worker 
DebugDumpQuerySet(DebugLevel inLevel,const WSAQUERYSETW * inQuerySet)1695*48a54d36SAndroid Build Coastguard Worker void	DebugDumpQuerySet( DebugLevel inLevel, const WSAQUERYSETW *inQuerySet )
1696*48a54d36SAndroid Build Coastguard Worker {
1697*48a54d36SAndroid Build Coastguard Worker 	DWORD		i;
1698*48a54d36SAndroid Build Coastguard Worker 
1699*48a54d36SAndroid Build Coastguard Worker 	check( inQuerySet );
1700*48a54d36SAndroid Build Coastguard Worker 
1701*48a54d36SAndroid Build Coastguard Worker 	// Fixed portion of the QuerySet.
1702*48a54d36SAndroid Build Coastguard Worker 
1703*48a54d36SAndroid Build Coastguard Worker 	dlog( inLevel, "QuerySet:\n" );
1704*48a54d36SAndroid Build Coastguard Worker 	dlog( inLevel, "    dwSize:                  %d (expected %d)\n", inQuerySet->dwSize, sizeof( *inQuerySet ) );
1705*48a54d36SAndroid Build Coastguard Worker 	if( inQuerySet->lpszServiceInstanceName )
1706*48a54d36SAndroid Build Coastguard Worker 	{
1707*48a54d36SAndroid Build Coastguard Worker 		dlog( inLevel, "    lpszServiceInstanceName: %S\n", inQuerySet->lpszServiceInstanceName );
1708*48a54d36SAndroid Build Coastguard Worker 	}
1709*48a54d36SAndroid Build Coastguard Worker 	else
1710*48a54d36SAndroid Build Coastguard Worker 	{
1711*48a54d36SAndroid Build Coastguard Worker 		dlog( inLevel, "    lpszServiceInstanceName: <null>\n" );
1712*48a54d36SAndroid Build Coastguard Worker 	}
1713*48a54d36SAndroid Build Coastguard Worker 	if( inQuerySet->lpServiceClassId )
1714*48a54d36SAndroid Build Coastguard Worker 	{
1715*48a54d36SAndroid Build Coastguard Worker 		dlog( inLevel, "    lpServiceClassId:        %U\n", inQuerySet->lpServiceClassId );
1716*48a54d36SAndroid Build Coastguard Worker 	}
1717*48a54d36SAndroid Build Coastguard Worker 	else
1718*48a54d36SAndroid Build Coastguard Worker 	{
1719*48a54d36SAndroid Build Coastguard Worker 		dlog( inLevel, "    lpServiceClassId:        <null>\n" );
1720*48a54d36SAndroid Build Coastguard Worker 	}
1721*48a54d36SAndroid Build Coastguard Worker 	if( inQuerySet->lpVersion )
1722*48a54d36SAndroid Build Coastguard Worker 	{
1723*48a54d36SAndroid Build Coastguard Worker 		dlog( inLevel, "    lpVersion:\n" );
1724*48a54d36SAndroid Build Coastguard Worker 		dlog( inLevel, "        dwVersion:               %d\n", inQuerySet->lpVersion->dwVersion );
1725*48a54d36SAndroid Build Coastguard Worker 		dlog( inLevel, "        dwVersion:               %d\n", inQuerySet->lpVersion->ecHow );
1726*48a54d36SAndroid Build Coastguard Worker 	}
1727*48a54d36SAndroid Build Coastguard Worker 	else
1728*48a54d36SAndroid Build Coastguard Worker 	{
1729*48a54d36SAndroid Build Coastguard Worker 		dlog( inLevel, "    lpVersion:               <null>\n" );
1730*48a54d36SAndroid Build Coastguard Worker 	}
1731*48a54d36SAndroid Build Coastguard Worker 	if( inQuerySet->lpszComment )
1732*48a54d36SAndroid Build Coastguard Worker 	{
1733*48a54d36SAndroid Build Coastguard Worker 		dlog( inLevel, "    lpszComment:             %S\n", inQuerySet->lpszComment );
1734*48a54d36SAndroid Build Coastguard Worker 	}
1735*48a54d36SAndroid Build Coastguard Worker 	else
1736*48a54d36SAndroid Build Coastguard Worker 	{
1737*48a54d36SAndroid Build Coastguard Worker 		dlog( inLevel, "    lpszComment:             <null>\n" );
1738*48a54d36SAndroid Build Coastguard Worker 	}
1739*48a54d36SAndroid Build Coastguard Worker 	dlog( inLevel, "    dwNameSpace:             %d %s\n", inQuerySet->dwNameSpace,
1740*48a54d36SAndroid Build Coastguard Worker 		DebugNameSpaceToString( inQuerySet->dwNameSpace ) );
1741*48a54d36SAndroid Build Coastguard Worker 	if( inQuerySet->lpNSProviderId )
1742*48a54d36SAndroid Build Coastguard Worker 	{
1743*48a54d36SAndroid Build Coastguard Worker 		dlog( inLevel, "    lpNSProviderId:          %U\n", inQuerySet->lpNSProviderId );
1744*48a54d36SAndroid Build Coastguard Worker 	}
1745*48a54d36SAndroid Build Coastguard Worker 	else
1746*48a54d36SAndroid Build Coastguard Worker 	{
1747*48a54d36SAndroid Build Coastguard Worker 		dlog( inLevel, "    lpNSProviderId:          <null>\n" );
1748*48a54d36SAndroid Build Coastguard Worker 	}
1749*48a54d36SAndroid Build Coastguard Worker 	if( inQuerySet->lpszContext )
1750*48a54d36SAndroid Build Coastguard Worker 	{
1751*48a54d36SAndroid Build Coastguard Worker 		dlog( inLevel, "    lpszContext:             %S\n", inQuerySet->lpszContext );
1752*48a54d36SAndroid Build Coastguard Worker 	}
1753*48a54d36SAndroid Build Coastguard Worker 	else
1754*48a54d36SAndroid Build Coastguard Worker 	{
1755*48a54d36SAndroid Build Coastguard Worker 		dlog( inLevel, "    lpszContext:             <null>\n" );
1756*48a54d36SAndroid Build Coastguard Worker 	}
1757*48a54d36SAndroid Build Coastguard Worker 	dlog( inLevel, "    dwNumberOfProtocols:     %d\n", inQuerySet->dwNumberOfProtocols );
1758*48a54d36SAndroid Build Coastguard Worker 	dlog( inLevel, "    lpafpProtocols:          %s\n", inQuerySet->lpafpProtocols ? "" : "<null>" );
1759*48a54d36SAndroid Build Coastguard Worker 	for( i = 0; i < inQuerySet->dwNumberOfProtocols; ++i )
1760*48a54d36SAndroid Build Coastguard Worker 	{
1761*48a54d36SAndroid Build Coastguard Worker 		if( i != 0 )
1762*48a54d36SAndroid Build Coastguard Worker 		{
1763*48a54d36SAndroid Build Coastguard Worker 			dlog( inLevel, "\n" );
1764*48a54d36SAndroid Build Coastguard Worker 		}
1765*48a54d36SAndroid Build Coastguard Worker 		dlog( inLevel, "        iAddressFamily:          %d %s\n", inQuerySet->lpafpProtocols[ i ].iAddressFamily,
1766*48a54d36SAndroid Build Coastguard Worker 			DebugSocketFamilyToString( inQuerySet->lpafpProtocols[ i ].iAddressFamily ) );
1767*48a54d36SAndroid Build Coastguard Worker 		dlog( inLevel, "        iProtocol:               %d %s\n", inQuerySet->lpafpProtocols[ i ].iProtocol,
1768*48a54d36SAndroid Build Coastguard Worker 			DebugSocketProtocolToString( inQuerySet->lpafpProtocols[ i ].iProtocol ) );
1769*48a54d36SAndroid Build Coastguard Worker 	}
1770*48a54d36SAndroid Build Coastguard Worker 	if( inQuerySet->lpszQueryString )
1771*48a54d36SAndroid Build Coastguard Worker 	{
1772*48a54d36SAndroid Build Coastguard Worker 		dlog( inLevel, "    lpszQueryString:         %S\n", inQuerySet->lpszQueryString );
1773*48a54d36SAndroid Build Coastguard Worker 	}
1774*48a54d36SAndroid Build Coastguard Worker 	else
1775*48a54d36SAndroid Build Coastguard Worker 	{
1776*48a54d36SAndroid Build Coastguard Worker 		dlog( inLevel, "    lpszQueryString:         <null>\n" );
1777*48a54d36SAndroid Build Coastguard Worker 	}
1778*48a54d36SAndroid Build Coastguard Worker 	dlog( inLevel, "    dwNumberOfCsAddrs:       %d\n", inQuerySet->dwNumberOfCsAddrs );
1779*48a54d36SAndroid Build Coastguard Worker 	dlog( inLevel, "    lpcsaBuffer:             %s\n", inQuerySet->lpcsaBuffer ? "" : "<null>" );
1780*48a54d36SAndroid Build Coastguard Worker 	for( i = 0; i < inQuerySet->dwNumberOfCsAddrs; ++i )
1781*48a54d36SAndroid Build Coastguard Worker 	{
1782*48a54d36SAndroid Build Coastguard Worker 		if( i != 0 )
1783*48a54d36SAndroid Build Coastguard Worker 		{
1784*48a54d36SAndroid Build Coastguard Worker 			dlog( inLevel, "\n" );
1785*48a54d36SAndroid Build Coastguard Worker 		}
1786*48a54d36SAndroid Build Coastguard Worker 		if( inQuerySet->lpcsaBuffer[ i ].LocalAddr.lpSockaddr &&
1787*48a54d36SAndroid Build Coastguard Worker 			( inQuerySet->lpcsaBuffer[ i ].LocalAddr.iSockaddrLength > 0 ) )
1788*48a54d36SAndroid Build Coastguard Worker 		{
1789*48a54d36SAndroid Build Coastguard Worker 			dlog( inLevel, "        LocalAddr:               %##a\n",
1790*48a54d36SAndroid Build Coastguard Worker 				inQuerySet->lpcsaBuffer[ i ].LocalAddr.lpSockaddr );
1791*48a54d36SAndroid Build Coastguard Worker 		}
1792*48a54d36SAndroid Build Coastguard Worker 		else
1793*48a54d36SAndroid Build Coastguard Worker 		{
1794*48a54d36SAndroid Build Coastguard Worker 			dlog( inLevel, "        LocalAddr:               <null/empty>\n" );
1795*48a54d36SAndroid Build Coastguard Worker 		}
1796*48a54d36SAndroid Build Coastguard Worker 		if( inQuerySet->lpcsaBuffer[ i ].RemoteAddr.lpSockaddr &&
1797*48a54d36SAndroid Build Coastguard Worker 			( inQuerySet->lpcsaBuffer[ i ].RemoteAddr.iSockaddrLength > 0 ) )
1798*48a54d36SAndroid Build Coastguard Worker 		{
1799*48a54d36SAndroid Build Coastguard Worker 			dlog( inLevel, "        RemoteAddr:              %##a\n",
1800*48a54d36SAndroid Build Coastguard Worker 				inQuerySet->lpcsaBuffer[ i ].RemoteAddr.lpSockaddr );
1801*48a54d36SAndroid Build Coastguard Worker 		}
1802*48a54d36SAndroid Build Coastguard Worker 		else
1803*48a54d36SAndroid Build Coastguard Worker 		{
1804*48a54d36SAndroid Build Coastguard Worker 			dlog( inLevel, "        RemoteAddr:              <null/empty>\n" );
1805*48a54d36SAndroid Build Coastguard Worker 		}
1806*48a54d36SAndroid Build Coastguard Worker 		dlog( inLevel, "        iSocketType:             %d\n", inQuerySet->lpcsaBuffer[ i ].iSocketType );
1807*48a54d36SAndroid Build Coastguard Worker 		dlog( inLevel, "        iProtocol:               %d\n", inQuerySet->lpcsaBuffer[ i ].iProtocol );
1808*48a54d36SAndroid Build Coastguard Worker 	}
1809*48a54d36SAndroid Build Coastguard Worker 	dlog( inLevel, "    dwOutputFlags:           %d\n", inQuerySet->dwOutputFlags );
1810*48a54d36SAndroid Build Coastguard Worker 
1811*48a54d36SAndroid Build Coastguard Worker 	// Blob portion of the QuerySet.
1812*48a54d36SAndroid Build Coastguard Worker 
1813*48a54d36SAndroid Build Coastguard Worker 	if( inQuerySet->lpBlob )
1814*48a54d36SAndroid Build Coastguard Worker 	{
1815*48a54d36SAndroid Build Coastguard Worker 		dlog( inLevel, "    lpBlob:\n" );
1816*48a54d36SAndroid Build Coastguard Worker 		dlog( inLevel, "        cbSize:                  %ld\n", inQuerySet->lpBlob->cbSize );
1817*48a54d36SAndroid Build Coastguard Worker 		dlog( inLevel, "        pBlobData:               %#p\n", inQuerySet->lpBlob->pBlobData );
1818*48a54d36SAndroid Build Coastguard Worker 		dloghex( inLevel, 12, NULL, 0, 0, NULL, 0,
1819*48a54d36SAndroid Build Coastguard Worker 			inQuerySet->lpBlob->pBlobData, inQuerySet->lpBlob->pBlobData, inQuerySet->lpBlob->cbSize,
1820*48a54d36SAndroid Build Coastguard Worker 			kDebugFlagsNone, NULL, 0 );
1821*48a54d36SAndroid Build Coastguard Worker 	}
1822*48a54d36SAndroid Build Coastguard Worker 	else
1823*48a54d36SAndroid Build Coastguard Worker 	{
1824*48a54d36SAndroid Build Coastguard Worker 		dlog( inLevel, "    lpBlob:                  <null>\n" );
1825*48a54d36SAndroid Build Coastguard Worker 	}
1826*48a54d36SAndroid Build Coastguard Worker }
1827*48a54d36SAndroid Build Coastguard Worker #endif
1828*48a54d36SAndroid Build Coastguard Worker 
1829*48a54d36SAndroid Build Coastguard Worker 
1830*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1831*48a54d36SAndroid Build Coastguard Worker //	InHostsTable
1832*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1833*48a54d36SAndroid Build Coastguard Worker 
1834*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL BOOL
InHostsTable(const char * name)1835*48a54d36SAndroid Build Coastguard Worker InHostsTable( const char * name )
1836*48a54d36SAndroid Build Coastguard Worker {
1837*48a54d36SAndroid Build Coastguard Worker 	HostsFileInfo	*	node;
1838*48a54d36SAndroid Build Coastguard Worker 	BOOL				ret = FALSE;
1839*48a54d36SAndroid Build Coastguard Worker 	OSStatus			err;
1840*48a54d36SAndroid Build Coastguard Worker 
1841*48a54d36SAndroid Build Coastguard Worker 	check( name );
1842*48a54d36SAndroid Build Coastguard Worker 
1843*48a54d36SAndroid Build Coastguard Worker 	if ( gHostsFileInfo == NULL )
1844*48a54d36SAndroid Build Coastguard Worker 	{
1845*48a54d36SAndroid Build Coastguard Worker 		TCHAR				systemDirectory[MAX_PATH];
1846*48a54d36SAndroid Build Coastguard Worker 		TCHAR				hFileName[MAX_PATH];
1847*48a54d36SAndroid Build Coastguard Worker 		HostsFile		*	hFile;
1848*48a54d36SAndroid Build Coastguard Worker 
1849*48a54d36SAndroid Build Coastguard Worker 		GetSystemDirectory( systemDirectory, sizeof( systemDirectory ) );
1850*48a54d36SAndroid Build Coastguard Worker 		sprintf( hFileName, "%s\\drivers\\etc\\hosts", systemDirectory );
1851*48a54d36SAndroid Build Coastguard Worker 		err = HostsFileOpen( &hFile, hFileName );
1852*48a54d36SAndroid Build Coastguard Worker 		require_noerr( err, exit );
1853*48a54d36SAndroid Build Coastguard Worker 
1854*48a54d36SAndroid Build Coastguard Worker 		while ( HostsFileNext( hFile, &node ) == 0 )
1855*48a54d36SAndroid Build Coastguard Worker 		{
1856*48a54d36SAndroid Build Coastguard Worker 			if ( IsLocalName( node ) )
1857*48a54d36SAndroid Build Coastguard Worker 			{
1858*48a54d36SAndroid Build Coastguard Worker 				node->m_next = gHostsFileInfo;
1859*48a54d36SAndroid Build Coastguard Worker 				gHostsFileInfo = node;
1860*48a54d36SAndroid Build Coastguard Worker 			}
1861*48a54d36SAndroid Build Coastguard Worker 			else
1862*48a54d36SAndroid Build Coastguard Worker 			{
1863*48a54d36SAndroid Build Coastguard Worker 				HostsFileInfoFree( node );
1864*48a54d36SAndroid Build Coastguard Worker 			}
1865*48a54d36SAndroid Build Coastguard Worker 		}
1866*48a54d36SAndroid Build Coastguard Worker 
1867*48a54d36SAndroid Build Coastguard Worker 		HostsFileClose( hFile );
1868*48a54d36SAndroid Build Coastguard Worker 	}
1869*48a54d36SAndroid Build Coastguard Worker 
1870*48a54d36SAndroid Build Coastguard Worker 	for ( node = gHostsFileInfo; node; node = node->m_next )
1871*48a54d36SAndroid Build Coastguard Worker 	{
1872*48a54d36SAndroid Build Coastguard Worker 		if ( IsSameName( node, name ) )
1873*48a54d36SAndroid Build Coastguard Worker 		{
1874*48a54d36SAndroid Build Coastguard Worker 			ret = TRUE;
1875*48a54d36SAndroid Build Coastguard Worker 			break;
1876*48a54d36SAndroid Build Coastguard Worker 		}
1877*48a54d36SAndroid Build Coastguard Worker 	}
1878*48a54d36SAndroid Build Coastguard Worker 
1879*48a54d36SAndroid Build Coastguard Worker exit:
1880*48a54d36SAndroid Build Coastguard Worker 
1881*48a54d36SAndroid Build Coastguard Worker 	return ret;
1882*48a54d36SAndroid Build Coastguard Worker }
1883*48a54d36SAndroid Build Coastguard Worker 
1884*48a54d36SAndroid Build Coastguard Worker 
1885*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1886*48a54d36SAndroid Build Coastguard Worker //	IsLocalName
1887*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1888*48a54d36SAndroid Build Coastguard Worker 
1889*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL BOOL
IsLocalName(HostsFileInfo * node)1890*48a54d36SAndroid Build Coastguard Worker IsLocalName( HostsFileInfo * node )
1891*48a54d36SAndroid Build Coastguard Worker {
1892*48a54d36SAndroid Build Coastguard Worker 	BOOL ret = TRUE;
1893*48a54d36SAndroid Build Coastguard Worker 
1894*48a54d36SAndroid Build Coastguard Worker 	check( node );
1895*48a54d36SAndroid Build Coastguard Worker 
1896*48a54d36SAndroid Build Coastguard Worker 	if ( strstr( node->m_host.h_name, ".local" ) == NULL )
1897*48a54d36SAndroid Build Coastguard Worker 	{
1898*48a54d36SAndroid Build Coastguard Worker 		int i;
1899*48a54d36SAndroid Build Coastguard Worker 
1900*48a54d36SAndroid Build Coastguard Worker 		for ( i = 0; node->m_host.h_aliases[i]; i++ )
1901*48a54d36SAndroid Build Coastguard Worker 		{
1902*48a54d36SAndroid Build Coastguard Worker 			if ( strstr( node->m_host.h_aliases[i], ".local" ) )
1903*48a54d36SAndroid Build Coastguard Worker 			{
1904*48a54d36SAndroid Build Coastguard Worker 				goto exit;
1905*48a54d36SAndroid Build Coastguard Worker 			}
1906*48a54d36SAndroid Build Coastguard Worker 		}
1907*48a54d36SAndroid Build Coastguard Worker 
1908*48a54d36SAndroid Build Coastguard Worker 		ret = FALSE;
1909*48a54d36SAndroid Build Coastguard Worker 	}
1910*48a54d36SAndroid Build Coastguard Worker 
1911*48a54d36SAndroid Build Coastguard Worker exit:
1912*48a54d36SAndroid Build Coastguard Worker 
1913*48a54d36SAndroid Build Coastguard Worker 	return ret;
1914*48a54d36SAndroid Build Coastguard Worker }
1915*48a54d36SAndroid Build Coastguard Worker 
1916*48a54d36SAndroid Build Coastguard Worker 
1917*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1918*48a54d36SAndroid Build Coastguard Worker //	IsSameName
1919*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1920*48a54d36SAndroid Build Coastguard Worker 
1921*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL BOOL
IsSameName(HostsFileInfo * node,const char * name)1922*48a54d36SAndroid Build Coastguard Worker IsSameName( HostsFileInfo * node, const char * name )
1923*48a54d36SAndroid Build Coastguard Worker {
1924*48a54d36SAndroid Build Coastguard Worker 	BOOL ret = TRUE;
1925*48a54d36SAndroid Build Coastguard Worker 
1926*48a54d36SAndroid Build Coastguard Worker 	check( node );
1927*48a54d36SAndroid Build Coastguard Worker 	check( name );
1928*48a54d36SAndroid Build Coastguard Worker 
1929*48a54d36SAndroid Build Coastguard Worker 	if ( strcmp( node->m_host.h_name, name ) != 0 )
1930*48a54d36SAndroid Build Coastguard Worker 	{
1931*48a54d36SAndroid Build Coastguard Worker 		int i;
1932*48a54d36SAndroid Build Coastguard Worker 
1933*48a54d36SAndroid Build Coastguard Worker 		for ( i = 0; node->m_host.h_aliases[i]; i++ )
1934*48a54d36SAndroid Build Coastguard Worker 		{
1935*48a54d36SAndroid Build Coastguard Worker 			if ( strcmp( node->m_host.h_aliases[i], name ) == 0 )
1936*48a54d36SAndroid Build Coastguard Worker 			{
1937*48a54d36SAndroid Build Coastguard Worker 				goto exit;
1938*48a54d36SAndroid Build Coastguard Worker 			}
1939*48a54d36SAndroid Build Coastguard Worker 		}
1940*48a54d36SAndroid Build Coastguard Worker 
1941*48a54d36SAndroid Build Coastguard Worker 		ret = FALSE;
1942*48a54d36SAndroid Build Coastguard Worker 	}
1943*48a54d36SAndroid Build Coastguard Worker 
1944*48a54d36SAndroid Build Coastguard Worker exit:
1945*48a54d36SAndroid Build Coastguard Worker 
1946*48a54d36SAndroid Build Coastguard Worker 	return ret;
1947*48a54d36SAndroid Build Coastguard Worker }
1948*48a54d36SAndroid Build Coastguard Worker 
1949*48a54d36SAndroid Build Coastguard Worker 
1950*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1951*48a54d36SAndroid Build Coastguard Worker //	HostsFileOpen
1952*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1953*48a54d36SAndroid Build Coastguard Worker 
1954*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL OSStatus
HostsFileOpen(HostsFile ** self,const char * fname)1955*48a54d36SAndroid Build Coastguard Worker HostsFileOpen( HostsFile ** self, const char * fname )
1956*48a54d36SAndroid Build Coastguard Worker {
1957*48a54d36SAndroid Build Coastguard Worker 	OSStatus err = kNoErr;
1958*48a54d36SAndroid Build Coastguard Worker 
1959*48a54d36SAndroid Build Coastguard Worker 	*self = (HostsFile*) malloc( sizeof( HostsFile ) );
1960*48a54d36SAndroid Build Coastguard Worker 	require_action( *self, exit, err = kNoMemoryErr );
1961*48a54d36SAndroid Build Coastguard Worker 	memset( *self, 0, sizeof( HostsFile ) );
1962*48a54d36SAndroid Build Coastguard Worker 
1963*48a54d36SAndroid Build Coastguard Worker 	(*self)->m_bufferSize = BUFFER_INITIAL_SIZE;
1964*48a54d36SAndroid Build Coastguard Worker 	(*self)->m_buffer = (char*) malloc( (*self)->m_bufferSize );
1965*48a54d36SAndroid Build Coastguard Worker 	require_action( (*self)->m_buffer, exit, err = kNoMemoryErr );
1966*48a54d36SAndroid Build Coastguard Worker 
1967*48a54d36SAndroid Build Coastguard Worker 	// check malloc
1968*48a54d36SAndroid Build Coastguard Worker 
1969*48a54d36SAndroid Build Coastguard Worker 	(*self)->m_fp = fopen( fname, "r" );
1970*48a54d36SAndroid Build Coastguard Worker 	require_action( (*self)->m_fp, exit, err = kUnknownErr );
1971*48a54d36SAndroid Build Coastguard Worker 
1972*48a54d36SAndroid Build Coastguard Worker exit:
1973*48a54d36SAndroid Build Coastguard Worker 
1974*48a54d36SAndroid Build Coastguard Worker 	if ( err && *self )
1975*48a54d36SAndroid Build Coastguard Worker 	{
1976*48a54d36SAndroid Build Coastguard Worker 		HostsFileClose( *self );
1977*48a54d36SAndroid Build Coastguard Worker 		*self = NULL;
1978*48a54d36SAndroid Build Coastguard Worker 	}
1979*48a54d36SAndroid Build Coastguard Worker 
1980*48a54d36SAndroid Build Coastguard Worker 	return err;
1981*48a54d36SAndroid Build Coastguard Worker }
1982*48a54d36SAndroid Build Coastguard Worker 
1983*48a54d36SAndroid Build Coastguard Worker 
1984*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1985*48a54d36SAndroid Build Coastguard Worker //	HostsFileClose
1986*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1987*48a54d36SAndroid Build Coastguard Worker 
1988*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL OSStatus
HostsFileClose(HostsFile * self)1989*48a54d36SAndroid Build Coastguard Worker HostsFileClose( HostsFile * self )
1990*48a54d36SAndroid Build Coastguard Worker {
1991*48a54d36SAndroid Build Coastguard Worker 	check( self );
1992*48a54d36SAndroid Build Coastguard Worker 
1993*48a54d36SAndroid Build Coastguard Worker 	if ( self->m_buffer )
1994*48a54d36SAndroid Build Coastguard Worker 	{
1995*48a54d36SAndroid Build Coastguard Worker 		free( self->m_buffer );
1996*48a54d36SAndroid Build Coastguard Worker 		self->m_buffer = NULL;
1997*48a54d36SAndroid Build Coastguard Worker 	}
1998*48a54d36SAndroid Build Coastguard Worker 
1999*48a54d36SAndroid Build Coastguard Worker 	if ( self->m_fp )
2000*48a54d36SAndroid Build Coastguard Worker 	{
2001*48a54d36SAndroid Build Coastguard Worker 		fclose( self->m_fp );
2002*48a54d36SAndroid Build Coastguard Worker 		self->m_fp = NULL;
2003*48a54d36SAndroid Build Coastguard Worker 	}
2004*48a54d36SAndroid Build Coastguard Worker 
2005*48a54d36SAndroid Build Coastguard Worker 	free( self );
2006*48a54d36SAndroid Build Coastguard Worker 
2007*48a54d36SAndroid Build Coastguard Worker 	return kNoErr;
2008*48a54d36SAndroid Build Coastguard Worker }
2009*48a54d36SAndroid Build Coastguard Worker 
2010*48a54d36SAndroid Build Coastguard Worker 
2011*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2012*48a54d36SAndroid Build Coastguard Worker //	HostsFileInfoFree
2013*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2014*48a54d36SAndroid Build Coastguard Worker 
2015*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL void
HostsFileInfoFree(HostsFileInfo * info)2016*48a54d36SAndroid Build Coastguard Worker HostsFileInfoFree( HostsFileInfo * info )
2017*48a54d36SAndroid Build Coastguard Worker {
2018*48a54d36SAndroid Build Coastguard Worker 	while ( info )
2019*48a54d36SAndroid Build Coastguard Worker 	{
2020*48a54d36SAndroid Build Coastguard Worker 		HostsFileInfo * next = info->m_next;
2021*48a54d36SAndroid Build Coastguard Worker 
2022*48a54d36SAndroid Build Coastguard Worker 		if ( info->m_host.h_addr_list )
2023*48a54d36SAndroid Build Coastguard Worker 		{
2024*48a54d36SAndroid Build Coastguard Worker 			if ( info->m_host.h_addr_list[0] )
2025*48a54d36SAndroid Build Coastguard Worker 			{
2026*48a54d36SAndroid Build Coastguard Worker 				free( info->m_host.h_addr_list[0] );
2027*48a54d36SAndroid Build Coastguard Worker 				info->m_host.h_addr_list[0] = NULL;
2028*48a54d36SAndroid Build Coastguard Worker 			}
2029*48a54d36SAndroid Build Coastguard Worker 
2030*48a54d36SAndroid Build Coastguard Worker 			free( info->m_host.h_addr_list );
2031*48a54d36SAndroid Build Coastguard Worker 			info->m_host.h_addr_list = NULL;
2032*48a54d36SAndroid Build Coastguard Worker 		}
2033*48a54d36SAndroid Build Coastguard Worker 
2034*48a54d36SAndroid Build Coastguard Worker 		if ( info->m_host.h_aliases )
2035*48a54d36SAndroid Build Coastguard Worker 		{
2036*48a54d36SAndroid Build Coastguard Worker 			int i;
2037*48a54d36SAndroid Build Coastguard Worker 
2038*48a54d36SAndroid Build Coastguard Worker 			for ( i = 0; info->m_host.h_aliases[i]; i++ )
2039*48a54d36SAndroid Build Coastguard Worker 			{
2040*48a54d36SAndroid Build Coastguard Worker 				free( info->m_host.h_aliases[i] );
2041*48a54d36SAndroid Build Coastguard Worker 			}
2042*48a54d36SAndroid Build Coastguard Worker 
2043*48a54d36SAndroid Build Coastguard Worker 			free( info->m_host.h_aliases );
2044*48a54d36SAndroid Build Coastguard Worker 		}
2045*48a54d36SAndroid Build Coastguard Worker 
2046*48a54d36SAndroid Build Coastguard Worker 		if ( info->m_host.h_name )
2047*48a54d36SAndroid Build Coastguard Worker 		{
2048*48a54d36SAndroid Build Coastguard Worker 			free( info->m_host.h_name );
2049*48a54d36SAndroid Build Coastguard Worker 			info->m_host.h_name = NULL;
2050*48a54d36SAndroid Build Coastguard Worker 		}
2051*48a54d36SAndroid Build Coastguard Worker 
2052*48a54d36SAndroid Build Coastguard Worker 		free( info );
2053*48a54d36SAndroid Build Coastguard Worker 
2054*48a54d36SAndroid Build Coastguard Worker 		info = next;
2055*48a54d36SAndroid Build Coastguard Worker 	}
2056*48a54d36SAndroid Build Coastguard Worker }
2057*48a54d36SAndroid Build Coastguard Worker 
2058*48a54d36SAndroid Build Coastguard Worker 
2059*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2060*48a54d36SAndroid Build Coastguard Worker //	HostsFileNext
2061*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2062*48a54d36SAndroid Build Coastguard Worker 
2063*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL OSStatus
HostsFileNext(HostsFile * self,HostsFileInfo ** hInfo)2064*48a54d36SAndroid Build Coastguard Worker HostsFileNext( HostsFile * self, HostsFileInfo ** hInfo )
2065*48a54d36SAndroid Build Coastguard Worker {
2066*48a54d36SAndroid Build Coastguard Worker 	struct sockaddr_in6	addr_6;
2067*48a54d36SAndroid Build Coastguard Worker 	struct sockaddr_in	addr_4;
2068*48a54d36SAndroid Build Coastguard Worker 	int					numAliases = ALIASES_INITIAL_SIZE;
2069*48a54d36SAndroid Build Coastguard Worker 	char			*	line;
2070*48a54d36SAndroid Build Coastguard Worker 	char			*	tok;
2071*48a54d36SAndroid Build Coastguard Worker 	int					dwSize;
2072*48a54d36SAndroid Build Coastguard Worker 	int					idx;
2073*48a54d36SAndroid Build Coastguard Worker 	int					i;
2074*48a54d36SAndroid Build Coastguard Worker 	short				family;
2075*48a54d36SAndroid Build Coastguard Worker 	OSStatus			err = kNoErr;
2076*48a54d36SAndroid Build Coastguard Worker 
2077*48a54d36SAndroid Build Coastguard Worker 	check( self );
2078*48a54d36SAndroid Build Coastguard Worker 	check( self->m_fp );
2079*48a54d36SAndroid Build Coastguard Worker 	check( hInfo );
2080*48a54d36SAndroid Build Coastguard Worker 
2081*48a54d36SAndroid Build Coastguard Worker 	idx	= 0;
2082*48a54d36SAndroid Build Coastguard Worker 
2083*48a54d36SAndroid Build Coastguard Worker 	*hInfo = (HostsFileInfo*) malloc( sizeof( HostsFileInfo ) );
2084*48a54d36SAndroid Build Coastguard Worker 	require_action( *hInfo, exit, err = kNoMemoryErr );
2085*48a54d36SAndroid Build Coastguard Worker 	memset( *hInfo, 0, sizeof( HostsFileInfo ) );
2086*48a54d36SAndroid Build Coastguard Worker 
2087*48a54d36SAndroid Build Coastguard Worker 	for ( ; ; )
2088*48a54d36SAndroid Build Coastguard Worker 	{
2089*48a54d36SAndroid Build Coastguard Worker 		line = fgets( self->m_buffer + idx, self->m_bufferSize - idx, self->m_fp );
2090*48a54d36SAndroid Build Coastguard Worker 
2091*48a54d36SAndroid Build Coastguard Worker 		if ( line == NULL )
2092*48a54d36SAndroid Build Coastguard Worker 		{
2093*48a54d36SAndroid Build Coastguard Worker 			err = 1;
2094*48a54d36SAndroid Build Coastguard Worker 			goto exit;
2095*48a54d36SAndroid Build Coastguard Worker 		}
2096*48a54d36SAndroid Build Coastguard Worker 
2097*48a54d36SAndroid Build Coastguard Worker 		// If there's no eol and no eof, then we didn't get the whole line
2098*48a54d36SAndroid Build Coastguard Worker 
2099*48a54d36SAndroid Build Coastguard Worker 		if ( !strchr( line, '\n' ) && !feof( self->m_fp ) )
2100*48a54d36SAndroid Build Coastguard Worker 		{
2101*48a54d36SAndroid Build Coastguard Worker 			int			bufferSize;
2102*48a54d36SAndroid Build Coastguard Worker 			char	*	buffer;
2103*48a54d36SAndroid Build Coastguard Worker 
2104*48a54d36SAndroid Build Coastguard Worker 			/* Try and allocate space for longer line */
2105*48a54d36SAndroid Build Coastguard Worker 
2106*48a54d36SAndroid Build Coastguard Worker 			bufferSize	= self->m_bufferSize * 2;
2107*48a54d36SAndroid Build Coastguard Worker 			buffer		= (char*) realloc( self->m_buffer, bufferSize );
2108*48a54d36SAndroid Build Coastguard Worker 			require_action( buffer, exit, err = kNoMemoryErr );
2109*48a54d36SAndroid Build Coastguard Worker 			self->m_bufferSize	= bufferSize;
2110*48a54d36SAndroid Build Coastguard Worker 			self->m_buffer		= buffer;
2111*48a54d36SAndroid Build Coastguard Worker 			idx					= (int) strlen( self->m_buffer );
2112*48a54d36SAndroid Build Coastguard Worker 
2113*48a54d36SAndroid Build Coastguard Worker 			continue;
2114*48a54d36SAndroid Build Coastguard Worker 		}
2115*48a54d36SAndroid Build Coastguard Worker 
2116*48a54d36SAndroid Build Coastguard Worker 		line	= self->m_buffer;
2117*48a54d36SAndroid Build Coastguard Worker 		idx		= 0;
2118*48a54d36SAndroid Build Coastguard Worker 
2119*48a54d36SAndroid Build Coastguard Worker 		if (*line == '#')
2120*48a54d36SAndroid Build Coastguard Worker 		{
2121*48a54d36SAndroid Build Coastguard Worker 			continue;
2122*48a54d36SAndroid Build Coastguard Worker 		}
2123*48a54d36SAndroid Build Coastguard Worker 
2124*48a54d36SAndroid Build Coastguard Worker 		// Get rid of either comments or eol characters
2125*48a54d36SAndroid Build Coastguard Worker 
2126*48a54d36SAndroid Build Coastguard Worker 		if (( tok = strpbrk(line, "#\n")) != NULL )
2127*48a54d36SAndroid Build Coastguard Worker 		{
2128*48a54d36SAndroid Build Coastguard Worker 			*tok = '\0';
2129*48a54d36SAndroid Build Coastguard Worker 		}
2130*48a54d36SAndroid Build Coastguard Worker 
2131*48a54d36SAndroid Build Coastguard Worker 		// Make sure there is some whitespace on this line
2132*48a54d36SAndroid Build Coastguard Worker 
2133*48a54d36SAndroid Build Coastguard Worker 		if (( tok = strpbrk(line, " \t")) == NULL )
2134*48a54d36SAndroid Build Coastguard Worker 		{
2135*48a54d36SAndroid Build Coastguard Worker 			continue;
2136*48a54d36SAndroid Build Coastguard Worker 		}
2137*48a54d36SAndroid Build Coastguard Worker 
2138*48a54d36SAndroid Build Coastguard Worker 		// Create two strings, where p == the IP Address and tok is the name list
2139*48a54d36SAndroid Build Coastguard Worker 
2140*48a54d36SAndroid Build Coastguard Worker 		*tok++ = '\0';
2141*48a54d36SAndroid Build Coastguard Worker 
2142*48a54d36SAndroid Build Coastguard Worker 		while ( *tok == ' ' || *tok == '\t')
2143*48a54d36SAndroid Build Coastguard Worker 		{
2144*48a54d36SAndroid Build Coastguard Worker 			tok++;
2145*48a54d36SAndroid Build Coastguard Worker 		}
2146*48a54d36SAndroid Build Coastguard Worker 
2147*48a54d36SAndroid Build Coastguard Worker 		// Now we have the name
2148*48a54d36SAndroid Build Coastguard Worker 
2149*48a54d36SAndroid Build Coastguard Worker 		(*hInfo)->m_host.h_name = (char*) malloc( strlen( tok ) + 1 );
2150*48a54d36SAndroid Build Coastguard Worker 		require_action( (*hInfo)->m_host.h_name, exit, err = kNoMemoryErr );
2151*48a54d36SAndroid Build Coastguard Worker 		strcpy( (*hInfo)->m_host.h_name, tok );
2152*48a54d36SAndroid Build Coastguard Worker 
2153*48a54d36SAndroid Build Coastguard Worker 		// Now create the address (IPv6/IPv4)
2154*48a54d36SAndroid Build Coastguard Worker 
2155*48a54d36SAndroid Build Coastguard Worker 		addr_6.sin6_family	= family = AF_INET6;
2156*48a54d36SAndroid Build Coastguard Worker 		dwSize				= sizeof( addr_6 );
2157*48a54d36SAndroid Build Coastguard Worker 
2158*48a54d36SAndroid Build Coastguard Worker 		if ( WSAStringToAddress( line, AF_INET6, NULL, ( struct sockaddr*) &addr_6, &dwSize ) != 0 )
2159*48a54d36SAndroid Build Coastguard Worker 		{
2160*48a54d36SAndroid Build Coastguard Worker 			addr_4.sin_family = family = AF_INET;
2161*48a54d36SAndroid Build Coastguard Worker 			dwSize = sizeof( addr_4 );
2162*48a54d36SAndroid Build Coastguard Worker 
2163*48a54d36SAndroid Build Coastguard Worker 			if (WSAStringToAddress( line, AF_INET, NULL, ( struct sockaddr*) &addr_4, &dwSize ) != 0 )
2164*48a54d36SAndroid Build Coastguard Worker 			{
2165*48a54d36SAndroid Build Coastguard Worker 				continue;
2166*48a54d36SAndroid Build Coastguard Worker 			}
2167*48a54d36SAndroid Build Coastguard Worker 		}
2168*48a54d36SAndroid Build Coastguard Worker 
2169*48a54d36SAndroid Build Coastguard Worker 		(*hInfo)->m_host.h_addr_list = (char**) malloc( sizeof( char**) * 2 );
2170*48a54d36SAndroid Build Coastguard Worker 		require_action( (*hInfo)->m_host.h_addr_list, exit, err = kNoMemoryErr );
2171*48a54d36SAndroid Build Coastguard Worker 
2172*48a54d36SAndroid Build Coastguard Worker 		if ( family == AF_INET6 )
2173*48a54d36SAndroid Build Coastguard Worker 		{
2174*48a54d36SAndroid Build Coastguard Worker 			(*hInfo)->m_host.h_length		= (short) sizeof( addr_6.sin6_addr );
2175*48a54d36SAndroid Build Coastguard Worker 			(*hInfo)->m_host.h_addr_list[0] = (char*) malloc( (*hInfo)->m_host.h_length );
2176*48a54d36SAndroid Build Coastguard Worker 			require_action( (*hInfo)->m_host.h_addr_list[0], exit, err = kNoMemoryErr );
2177*48a54d36SAndroid Build Coastguard Worker 			memmove( (*hInfo)->m_host.h_addr_list[0], &addr_6.sin6_addr, sizeof( addr_6.sin6_addr ) );
2178*48a54d36SAndroid Build Coastguard Worker 
2179*48a54d36SAndroid Build Coastguard Worker 		}
2180*48a54d36SAndroid Build Coastguard Worker 		else
2181*48a54d36SAndroid Build Coastguard Worker 		{
2182*48a54d36SAndroid Build Coastguard Worker 			(*hInfo)->m_host.h_length		= (short) sizeof( addr_4.sin_addr );
2183*48a54d36SAndroid Build Coastguard Worker 			(*hInfo)->m_host.h_addr_list[0] = (char*) malloc( (*hInfo)->m_host.h_length );
2184*48a54d36SAndroid Build Coastguard Worker 			require_action( (*hInfo)->m_host.h_addr_list[0], exit, err = kNoMemoryErr );
2185*48a54d36SAndroid Build Coastguard Worker 			memmove( (*hInfo)->m_host.h_addr_list[0], &addr_4.sin_addr, sizeof( addr_4.sin_addr ) );
2186*48a54d36SAndroid Build Coastguard Worker 		}
2187*48a54d36SAndroid Build Coastguard Worker 
2188*48a54d36SAndroid Build Coastguard Worker 		(*hInfo)->m_host.h_addr_list[1] = NULL;
2189*48a54d36SAndroid Build Coastguard Worker 		(*hInfo)->m_host.h_addrtype		= family;
2190*48a54d36SAndroid Build Coastguard Worker 
2191*48a54d36SAndroid Build Coastguard Worker 		// Now get the aliases
2192*48a54d36SAndroid Build Coastguard Worker 
2193*48a54d36SAndroid Build Coastguard Worker 		if ((tok = strpbrk(tok, " \t")) != NULL)
2194*48a54d36SAndroid Build Coastguard Worker 		{
2195*48a54d36SAndroid Build Coastguard Worker 			*tok++ = '\0';
2196*48a54d36SAndroid Build Coastguard Worker 		}
2197*48a54d36SAndroid Build Coastguard Worker 
2198*48a54d36SAndroid Build Coastguard Worker 		i = 0;
2199*48a54d36SAndroid Build Coastguard Worker 
2200*48a54d36SAndroid Build Coastguard Worker 		(*hInfo)->m_host.h_aliases		= (char**) malloc( sizeof(char**) * numAliases );
2201*48a54d36SAndroid Build Coastguard Worker 		require_action( (*hInfo)->m_host.h_aliases, exit, err = kNoMemoryErr );
2202*48a54d36SAndroid Build Coastguard Worker 		(*hInfo)->m_host.h_aliases[0]	= NULL;
2203*48a54d36SAndroid Build Coastguard Worker 
2204*48a54d36SAndroid Build Coastguard Worker 		while ( tok && *tok )
2205*48a54d36SAndroid Build Coastguard Worker 		{
2206*48a54d36SAndroid Build Coastguard Worker 			// Skip over the whitespace, waiting for the start of the next alias name
2207*48a54d36SAndroid Build Coastguard Worker 
2208*48a54d36SAndroid Build Coastguard Worker 			if (*tok == ' ' || *tok == '\t')
2209*48a54d36SAndroid Build Coastguard Worker 			{
2210*48a54d36SAndroid Build Coastguard Worker 				tok++;
2211*48a54d36SAndroid Build Coastguard Worker 				continue;
2212*48a54d36SAndroid Build Coastguard Worker 			}
2213*48a54d36SAndroid Build Coastguard Worker 
2214*48a54d36SAndroid Build Coastguard Worker 			// Check to make sure we don't exhaust the alias buffer
2215*48a54d36SAndroid Build Coastguard Worker 
2216*48a54d36SAndroid Build Coastguard Worker 			if ( i >= ( numAliases - 1 ) )
2217*48a54d36SAndroid Build Coastguard Worker 			{
2218*48a54d36SAndroid Build Coastguard Worker 				numAliases = numAliases * 2;
2219*48a54d36SAndroid Build Coastguard Worker 				(*hInfo)->m_host.h_aliases = (char**) realloc( (*hInfo)->m_host.h_aliases, numAliases * sizeof( char** ) );
2220*48a54d36SAndroid Build Coastguard Worker 				require_action( (*hInfo)->m_host.h_aliases, exit, err = kNoMemoryErr );
2221*48a54d36SAndroid Build Coastguard Worker 			}
2222*48a54d36SAndroid Build Coastguard Worker 
2223*48a54d36SAndroid Build Coastguard Worker 			(*hInfo)->m_host.h_aliases[i] = (char*) malloc( strlen( tok ) + 1 );
2224*48a54d36SAndroid Build Coastguard Worker 			require_action( (*hInfo)->m_host.h_aliases[i], exit, err = kNoMemoryErr );
2225*48a54d36SAndroid Build Coastguard Worker 
2226*48a54d36SAndroid Build Coastguard Worker 			strcpy( (*hInfo)->m_host.h_aliases[i], tok );
2227*48a54d36SAndroid Build Coastguard Worker 
2228*48a54d36SAndroid Build Coastguard Worker 			if (( tok = strpbrk( tok, " \t")) != NULL )
2229*48a54d36SAndroid Build Coastguard Worker 			{
2230*48a54d36SAndroid Build Coastguard Worker 				*tok++ = '\0';
2231*48a54d36SAndroid Build Coastguard Worker 			}
2232*48a54d36SAndroid Build Coastguard Worker 
2233*48a54d36SAndroid Build Coastguard Worker 			(*hInfo)->m_host.h_aliases[++i] = NULL;
2234*48a54d36SAndroid Build Coastguard Worker 		}
2235*48a54d36SAndroid Build Coastguard Worker 
2236*48a54d36SAndroid Build Coastguard Worker 		break;
2237*48a54d36SAndroid Build Coastguard Worker 	}
2238*48a54d36SAndroid Build Coastguard Worker 
2239*48a54d36SAndroid Build Coastguard Worker exit:
2240*48a54d36SAndroid Build Coastguard Worker 
2241*48a54d36SAndroid Build Coastguard Worker 	if ( err && ( *hInfo ) )
2242*48a54d36SAndroid Build Coastguard Worker 	{
2243*48a54d36SAndroid Build Coastguard Worker 		HostsFileInfoFree( *hInfo );
2244*48a54d36SAndroid Build Coastguard Worker 		*hInfo = NULL;
2245*48a54d36SAndroid Build Coastguard Worker 	}
2246*48a54d36SAndroid Build Coastguard Worker 
2247*48a54d36SAndroid Build Coastguard Worker 	return err;
2248*48a54d36SAndroid Build Coastguard Worker }
2249*48a54d36SAndroid Build Coastguard Worker 
2250*48a54d36SAndroid Build Coastguard Worker 
2251*48a54d36SAndroid Build Coastguard Worker #ifdef ENABLE_REVERSE_LOOKUP
2252*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2253*48a54d36SAndroid Build Coastguard Worker //	IsReverseLookup
2254*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2255*48a54d36SAndroid Build Coastguard Worker 
2256*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL OSStatus
IsReverseLookup(LPCWSTR name,size_t size)2257*48a54d36SAndroid Build Coastguard Worker IsReverseLookup( LPCWSTR name, size_t size )
2258*48a54d36SAndroid Build Coastguard Worker {
2259*48a54d36SAndroid Build Coastguard Worker 	LPCWSTR		p;
2260*48a54d36SAndroid Build Coastguard Worker 	OSStatus	err = kNoErr;
2261*48a54d36SAndroid Build Coastguard Worker 
2262*48a54d36SAndroid Build Coastguard Worker 	// IPv6LL Reverse-mapping domains are {8,9,A,B}.E.F.ip6.arpa
2263*48a54d36SAndroid Build Coastguard Worker 	require_action_quiet( size > sizeof_string( ".0.8.e.f.ip6.arpa" ), exit, err = WSASERVICE_NOT_FOUND );
2264*48a54d36SAndroid Build Coastguard Worker 
2265*48a54d36SAndroid Build Coastguard Worker 	p = name + ( size - 1 );
2266*48a54d36SAndroid Build Coastguard Worker 	p = ( *p == '.' ) ? ( p - sizeof_string( ".0.8.e.f.ip6.arpa" ) ) : ( ( p - sizeof_string( ".0.8.e.f.ip6.arpa" ) ) + 1 );
2267*48a54d36SAndroid Build Coastguard Worker 
2268*48a54d36SAndroid Build Coastguard Worker 	if	( ( ( p[ 0 ] != '.' )							||
2269*48a54d36SAndroid Build Coastguard Worker 		( ( p[ 1 ] != '0' ) )							||
2270*48a54d36SAndroid Build Coastguard Worker 		( ( p[ 2 ] != '.' ) )							||
2271*48a54d36SAndroid Build Coastguard Worker 		( ( p[ 3 ] != '8' ) )							||
2272*48a54d36SAndroid Build Coastguard Worker 		( ( p[ 4 ] != '.' ) )							||
2273*48a54d36SAndroid Build Coastguard Worker 		( ( p[ 5 ] != 'E' ) && ( p[ 5 ] != 'e' ) )		||
2274*48a54d36SAndroid Build Coastguard Worker 		( ( p[ 6 ] != '.' ) )							||
2275*48a54d36SAndroid Build Coastguard Worker 		( ( p[ 7 ] != 'F' ) && ( p[ 7 ] != 'f' ) )		||
2276*48a54d36SAndroid Build Coastguard Worker 		( ( p[ 8 ] != '.' ) )							||
2277*48a54d36SAndroid Build Coastguard Worker 		( ( p[ 9 ] != 'I' ) && ( p[ 9 ] != 'i' ) )		||
2278*48a54d36SAndroid Build Coastguard Worker 		( ( p[ 10 ] != 'P' ) && ( p[ 10 ] != 'p' ) )	||
2279*48a54d36SAndroid Build Coastguard Worker 		( ( p[ 11 ] != '6' ) )							||
2280*48a54d36SAndroid Build Coastguard Worker 		( ( p[ 12 ] != '.' ) )							||
2281*48a54d36SAndroid Build Coastguard Worker 		( ( p[ 13 ] != 'A' ) && ( p[ 13 ] != 'a' ) )	||
2282*48a54d36SAndroid Build Coastguard Worker 		( ( p[ 14 ] != 'R' ) && ( p[ 14 ] != 'r' ) )	||
2283*48a54d36SAndroid Build Coastguard Worker 		( ( p[ 15 ] != 'P' ) && ( p[ 15 ] != 'p' ) )	||
2284*48a54d36SAndroid Build Coastguard Worker 		( ( p[ 16 ] != 'A' ) && ( p[ 16 ] != 'a' ) ) ) )
2285*48a54d36SAndroid Build Coastguard Worker 	{
2286*48a54d36SAndroid Build Coastguard Worker 		require_action_quiet( size > sizeof_string( ".254.169.in-addr.arpa" ), exit, err = WSASERVICE_NOT_FOUND );
2287*48a54d36SAndroid Build Coastguard Worker 
2288*48a54d36SAndroid Build Coastguard Worker 		p = name + ( size - 1 );
2289*48a54d36SAndroid Build Coastguard Worker 		p = ( *p == '.' ) ? ( p - sizeof_string( ".254.169.in-addr.arpa" ) ) : ( ( p - sizeof_string( ".254.169.in-addr.arpa" ) ) + 1 );
2290*48a54d36SAndroid Build Coastguard Worker 
2291*48a54d36SAndroid Build Coastguard Worker 		require_action_quiet( ( ( p[ 0 ] == '.' )						 &&
2292*48a54d36SAndroid Build Coastguard Worker 								( ( p[ 1 ] == '2' ) )							&&
2293*48a54d36SAndroid Build Coastguard Worker 								( ( p[ 2 ] == '5' ) )							&&
2294*48a54d36SAndroid Build Coastguard Worker 								( ( p[ 3 ] == '4' ) )							&&
2295*48a54d36SAndroid Build Coastguard Worker 								( ( p[ 4 ] == '.' ) )							&&
2296*48a54d36SAndroid Build Coastguard Worker 								( ( p[ 5 ] == '1' ) )							&&
2297*48a54d36SAndroid Build Coastguard Worker 								( ( p[ 6 ] == '6' ) )							&&
2298*48a54d36SAndroid Build Coastguard Worker 								( ( p[ 7 ] == '9' ) )							&&
2299*48a54d36SAndroid Build Coastguard Worker 								( ( p[ 8 ] == '.' ) )							&&
2300*48a54d36SAndroid Build Coastguard Worker 								( ( p[ 9 ] == 'I' ) || ( p[ 9 ] == 'i' ) )		&&
2301*48a54d36SAndroid Build Coastguard Worker 								( ( p[ 10 ] == 'N' ) || ( p[ 10 ] == 'n' ) )	&&
2302*48a54d36SAndroid Build Coastguard Worker 								( ( p[ 11 ] == '-' ) )							&&
2303*48a54d36SAndroid Build Coastguard Worker 								( ( p[ 12 ] == 'A' ) || ( p[ 12 ] == 'a' ) )	&&
2304*48a54d36SAndroid Build Coastguard Worker 								( ( p[ 13 ] == 'D' ) || ( p[ 13 ] == 'd' ) )	&&
2305*48a54d36SAndroid Build Coastguard Worker 								( ( p[ 14 ] == 'D' ) || ( p[ 14 ] == 'd' ) )	&&
2306*48a54d36SAndroid Build Coastguard Worker 								( ( p[ 15 ] == 'R' ) || ( p[ 15 ] == 'r' ) )	&&
2307*48a54d36SAndroid Build Coastguard Worker 								( ( p[ 16 ] == '.' ) )							&&
2308*48a54d36SAndroid Build Coastguard Worker 								( ( p[ 17 ] == 'A' ) || ( p[ 17 ] == 'a' ) )	&&
2309*48a54d36SAndroid Build Coastguard Worker 								( ( p[ 18 ] == 'R' ) || ( p[ 18 ] == 'r' ) )	&&
2310*48a54d36SAndroid Build Coastguard Worker 								( ( p[ 19 ] == 'P' ) || ( p[ 19 ] == 'p' ) )	&&
2311*48a54d36SAndroid Build Coastguard Worker 								( ( p[ 20 ] == 'A' ) || ( p[ 20 ] == 'a' ) ) ),
2312*48a54d36SAndroid Build Coastguard Worker 								exit, err = WSASERVICE_NOT_FOUND );
2313*48a54d36SAndroid Build Coastguard Worker 	}
2314*48a54d36SAndroid Build Coastguard Worker 
2315*48a54d36SAndroid Build Coastguard Worker 	// It's a reverse lookup
2316*48a54d36SAndroid Build Coastguard Worker 
2317*48a54d36SAndroid Build Coastguard Worker 	check( err == kNoErr );
2318*48a54d36SAndroid Build Coastguard Worker 
2319*48a54d36SAndroid Build Coastguard Worker exit:
2320*48a54d36SAndroid Build Coastguard Worker 
2321*48a54d36SAndroid Build Coastguard Worker 	return err;
2322*48a54d36SAndroid Build Coastguard Worker }
2323*48a54d36SAndroid Build Coastguard Worker #endif
2324*48a54d36SAndroid Build Coastguard Worker 
2325*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2326*48a54d36SAndroid Build Coastguard Worker //	GetScopeId
2327*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2328*48a54d36SAndroid Build Coastguard Worker 
2329*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL DWORD
GetScopeId(DWORD ifIndex)2330*48a54d36SAndroid Build Coastguard Worker GetScopeId( DWORD ifIndex )
2331*48a54d36SAndroid Build Coastguard Worker {
2332*48a54d36SAndroid Build Coastguard Worker 	DWORD						err;
2333*48a54d36SAndroid Build Coastguard Worker 	int							i;
2334*48a54d36SAndroid Build Coastguard Worker 	DWORD						flags;
2335*48a54d36SAndroid Build Coastguard Worker 	struct ifaddrs *			head;
2336*48a54d36SAndroid Build Coastguard Worker 	struct ifaddrs **			next;
2337*48a54d36SAndroid Build Coastguard Worker 	IP_ADAPTER_ADDRESSES *		iaaList;
2338*48a54d36SAndroid Build Coastguard Worker 	ULONG						iaaListSize;
2339*48a54d36SAndroid Build Coastguard Worker 	IP_ADAPTER_ADDRESSES *		iaa;
2340*48a54d36SAndroid Build Coastguard Worker 	DWORD						scopeId = 0;
2341*48a54d36SAndroid Build Coastguard Worker 
2342*48a54d36SAndroid Build Coastguard Worker 	head	= NULL;
2343*48a54d36SAndroid Build Coastguard Worker 	next	= &head;
2344*48a54d36SAndroid Build Coastguard Worker 	iaaList	= NULL;
2345*48a54d36SAndroid Build Coastguard Worker 
2346*48a54d36SAndroid Build Coastguard Worker 	require( gGetAdaptersAddressesFunctionPtr, exit );
2347*48a54d36SAndroid Build Coastguard Worker 
2348*48a54d36SAndroid Build Coastguard Worker 	// Get the list of interfaces. The first call gets the size and the second call gets the actual data.
2349*48a54d36SAndroid Build Coastguard Worker 	// This loops to handle the case where the interface changes in the window after getting the size, but before the
2350*48a54d36SAndroid Build Coastguard Worker 	// second call completes. A limit of 100 retries is enforced to prevent infinite loops if something else is wrong.
2351*48a54d36SAndroid Build Coastguard Worker 
2352*48a54d36SAndroid Build Coastguard Worker 	flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME;
2353*48a54d36SAndroid Build Coastguard Worker 	i = 0;
2354*48a54d36SAndroid Build Coastguard Worker 	for( ;; )
2355*48a54d36SAndroid Build Coastguard Worker 	{
2356*48a54d36SAndroid Build Coastguard Worker 		iaaListSize = 0;
2357*48a54d36SAndroid Build Coastguard Worker 		err = gGetAdaptersAddressesFunctionPtr( AF_UNSPEC, flags, NULL, NULL, &iaaListSize );
2358*48a54d36SAndroid Build Coastguard Worker 		check( err == ERROR_BUFFER_OVERFLOW );
2359*48a54d36SAndroid Build Coastguard Worker 		check( iaaListSize >= sizeof( IP_ADAPTER_ADDRESSES ) );
2360*48a54d36SAndroid Build Coastguard Worker 
2361*48a54d36SAndroid Build Coastguard Worker 		iaaList = (IP_ADAPTER_ADDRESSES *) malloc( iaaListSize );
2362*48a54d36SAndroid Build Coastguard Worker 		require_action( iaaList, exit, err = ERROR_NOT_ENOUGH_MEMORY );
2363*48a54d36SAndroid Build Coastguard Worker 
2364*48a54d36SAndroid Build Coastguard Worker 		err = gGetAdaptersAddressesFunctionPtr( AF_UNSPEC, flags, NULL, iaaList, &iaaListSize );
2365*48a54d36SAndroid Build Coastguard Worker 		if( err == ERROR_SUCCESS ) break;
2366*48a54d36SAndroid Build Coastguard Worker 
2367*48a54d36SAndroid Build Coastguard Worker 		free( iaaList );
2368*48a54d36SAndroid Build Coastguard Worker 		iaaList = NULL;
2369*48a54d36SAndroid Build Coastguard Worker 		++i;
2370*48a54d36SAndroid Build Coastguard Worker 		require( i < 100, exit );
2371*48a54d36SAndroid Build Coastguard Worker 		dlog( kDebugLevelWarning, "%s: retrying GetAdaptersAddresses after %d failure(s) (%d %m)\n", __ROUTINE__, i, err, err );
2372*48a54d36SAndroid Build Coastguard Worker 	}
2373*48a54d36SAndroid Build Coastguard Worker 
2374*48a54d36SAndroid Build Coastguard Worker 	for( iaa = iaaList; iaa; iaa = iaa->Next )
2375*48a54d36SAndroid Build Coastguard Worker 	{
2376*48a54d36SAndroid Build Coastguard Worker 		DWORD ipv6IfIndex;
2377*48a54d36SAndroid Build Coastguard Worker 
2378*48a54d36SAndroid Build Coastguard Worker 		if ( iaa->IfIndex > 0xFFFFFF )
2379*48a54d36SAndroid Build Coastguard Worker 		{
2380*48a54d36SAndroid Build Coastguard Worker 			continue;
2381*48a54d36SAndroid Build Coastguard Worker 		}
2382*48a54d36SAndroid Build Coastguard Worker 		if ( iaa->Ipv6IfIndex > 0xFF )
2383*48a54d36SAndroid Build Coastguard Worker 		{
2384*48a54d36SAndroid Build Coastguard Worker 			continue;
2385*48a54d36SAndroid Build Coastguard Worker 		}
2386*48a54d36SAndroid Build Coastguard Worker 
2387*48a54d36SAndroid Build Coastguard Worker 		// For IPv4 interfaces, there seems to be a bug in iphlpapi.dll that causes the
2388*48a54d36SAndroid Build Coastguard Worker 		// following code to crash when iterating through the prefix list.  This seems
2389*48a54d36SAndroid Build Coastguard Worker 		// to occur when iaa->Ipv6IfIndex != 0 when IPv6 is not installed on the host.
2390*48a54d36SAndroid Build Coastguard Worker 		// This shouldn't happen according to Microsoft docs which states:
2391*48a54d36SAndroid Build Coastguard Worker 		//
2392*48a54d36SAndroid Build Coastguard Worker 		//     "Ipv6IfIndex contains 0 if IPv6 is not available on the interface."
2393*48a54d36SAndroid Build Coastguard Worker 		//
2394*48a54d36SAndroid Build Coastguard Worker 		// So the data structure seems to be corrupted when we return from
2395*48a54d36SAndroid Build Coastguard Worker 		// GetAdaptersAddresses(). The bug seems to occur when iaa->Length <
2396*48a54d36SAndroid Build Coastguard Worker 		// sizeof(IP_ADAPTER_ADDRESSES), so when that happens, we'll manually
2397*48a54d36SAndroid Build Coastguard Worker 		// modify iaa to have the correct values.
2398*48a54d36SAndroid Build Coastguard Worker 
2399*48a54d36SAndroid Build Coastguard Worker 		if ( iaa->Length >= sizeof( IP_ADAPTER_ADDRESSES ) )
2400*48a54d36SAndroid Build Coastguard Worker 		{
2401*48a54d36SAndroid Build Coastguard Worker 			ipv6IfIndex = iaa->Ipv6IfIndex;
2402*48a54d36SAndroid Build Coastguard Worker 		}
2403*48a54d36SAndroid Build Coastguard Worker 		else
2404*48a54d36SAndroid Build Coastguard Worker 		{
2405*48a54d36SAndroid Build Coastguard Worker 			ipv6IfIndex	= 0;
2406*48a54d36SAndroid Build Coastguard Worker 		}
2407*48a54d36SAndroid Build Coastguard Worker 
2408*48a54d36SAndroid Build Coastguard Worker 		// Skip psuedo and tunnel interfaces.
2409*48a54d36SAndroid Build Coastguard Worker 
2410*48a54d36SAndroid Build Coastguard Worker 		if( ( ipv6IfIndex == 1 ) || ( iaa->IfType == IF_TYPE_TUNNEL ) )
2411*48a54d36SAndroid Build Coastguard Worker 		{
2412*48a54d36SAndroid Build Coastguard Worker 			continue;
2413*48a54d36SAndroid Build Coastguard Worker 		}
2414*48a54d36SAndroid Build Coastguard Worker 
2415*48a54d36SAndroid Build Coastguard Worker 		if ( iaa->IfIndex == ifIndex )
2416*48a54d36SAndroid Build Coastguard Worker 		{
2417*48a54d36SAndroid Build Coastguard Worker 			scopeId = iaa->Ipv6IfIndex;
2418*48a54d36SAndroid Build Coastguard Worker 			break;
2419*48a54d36SAndroid Build Coastguard Worker 		}
2420*48a54d36SAndroid Build Coastguard Worker 	}
2421*48a54d36SAndroid Build Coastguard Worker 
2422*48a54d36SAndroid Build Coastguard Worker exit:
2423*48a54d36SAndroid Build Coastguard Worker 
2424*48a54d36SAndroid Build Coastguard Worker 	if( iaaList )
2425*48a54d36SAndroid Build Coastguard Worker 	{
2426*48a54d36SAndroid Build Coastguard Worker 		free( iaaList );
2427*48a54d36SAndroid Build Coastguard Worker 	}
2428*48a54d36SAndroid Build Coastguard Worker 
2429*48a54d36SAndroid Build Coastguard Worker 	return scopeId;
2430*48a54d36SAndroid Build Coastguard Worker }
2431