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 #include <stdio.h>
19*48a54d36SAndroid Build Coastguard Worker #include <stdlib.h>
20*48a54d36SAndroid Build Coastguard Worker #include <crtdbg.h>
21*48a54d36SAndroid Build Coastguard Worker #include <stdarg.h>
22*48a54d36SAndroid Build Coastguard Worker #include <stddef.h>
23*48a54d36SAndroid Build Coastguard Worker
24*48a54d36SAndroid Build Coastguard Worker
25*48a54d36SAndroid Build Coastguard Worker #include "CommonServices.h"
26*48a54d36SAndroid Build Coastguard Worker #include "DebugServices.h"
27*48a54d36SAndroid Build Coastguard Worker #include "RegNames.h"
28*48a54d36SAndroid Build Coastguard Worker
29*48a54d36SAndroid Build Coastguard Worker #include "uds_daemon.h"
30*48a54d36SAndroid Build Coastguard Worker #include "GenLinkedList.h"
31*48a54d36SAndroid Build Coastguard Worker #include "Service.h"
32*48a54d36SAndroid Build Coastguard Worker #include "mDNSWindows/SystemService/EventLog.h"
33*48a54d36SAndroid Build Coastguard Worker
34*48a54d36SAndroid Build Coastguard Worker #include "Resource.h"
35*48a54d36SAndroid Build Coastguard Worker
36*48a54d36SAndroid Build Coastguard Worker #include "mDNSEmbeddedAPI.h"
37*48a54d36SAndroid Build Coastguard Worker #include "uDNS.h"
38*48a54d36SAndroid Build Coastguard Worker #include "mDNSWin32.h"
39*48a54d36SAndroid Build Coastguard Worker
40*48a54d36SAndroid Build Coastguard Worker #include "Firewall.h"
41*48a54d36SAndroid Build Coastguard Worker
42*48a54d36SAndroid Build Coastguard Worker #if( !TARGET_OS_WINDOWS_CE )
43*48a54d36SAndroid Build Coastguard Worker #include <mswsock.h>
44*48a54d36SAndroid Build Coastguard Worker #include <process.h>
45*48a54d36SAndroid Build Coastguard Worker #include <ipExport.h>
46*48a54d36SAndroid Build Coastguard Worker #include <ws2def.h>
47*48a54d36SAndroid Build Coastguard Worker #include <ws2ipdef.h>
48*48a54d36SAndroid Build Coastguard Worker #include <iphlpapi.h>
49*48a54d36SAndroid Build Coastguard Worker #include <netioapi.h>
50*48a54d36SAndroid Build Coastguard Worker #include <iptypes.h>
51*48a54d36SAndroid Build Coastguard Worker #include <powrprof.h>
52*48a54d36SAndroid Build Coastguard Worker #endif
53*48a54d36SAndroid Build Coastguard Worker
54*48a54d36SAndroid Build Coastguard Worker #ifndef HeapEnableTerminationOnCorruption
55*48a54d36SAndroid Build Coastguard Worker # define HeapEnableTerminationOnCorruption (HEAP_INFORMATION_CLASS)1
56*48a54d36SAndroid Build Coastguard Worker #endif
57*48a54d36SAndroid Build Coastguard Worker
58*48a54d36SAndroid Build Coastguard Worker #if 0
59*48a54d36SAndroid Build Coastguard Worker #pragma mark == Constants ==
60*48a54d36SAndroid Build Coastguard Worker #endif
61*48a54d36SAndroid Build Coastguard Worker
62*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
63*48a54d36SAndroid Build Coastguard Worker // Constants
64*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
65*48a54d36SAndroid Build Coastguard Worker
66*48a54d36SAndroid Build Coastguard Worker #define DEBUG_NAME "[mDNSWin32] "
67*48a54d36SAndroid Build Coastguard Worker #define kServiceFirewallName L"Bonjour"
68*48a54d36SAndroid Build Coastguard Worker #define kServiceDependencies TEXT("Tcpip\0\0")
69*48a54d36SAndroid Build Coastguard Worker #define kDNSServiceCacheEntryCountDefault 512
70*48a54d36SAndroid Build Coastguard Worker #define kRetryFirewallPeriod 30 * 1000
71*48a54d36SAndroid Build Coastguard Worker #define kDefValueSize MAX_PATH + 1
72*48a54d36SAndroid Build Coastguard Worker #define kZeroIndex 0
73*48a54d36SAndroid Build Coastguard Worker #define kDefaultRouteMetric 399
74*48a54d36SAndroid Build Coastguard Worker #define kSecondsTo100NSUnits ( 10 * 1000 * 1000 )
75*48a54d36SAndroid Build Coastguard Worker #define kSPSMaintenanceWakePeriod -30
76*48a54d36SAndroid Build Coastguard Worker
77*48a54d36SAndroid Build Coastguard Worker #define RR_CACHE_SIZE 500
78*48a54d36SAndroid Build Coastguard Worker static CacheEntity gRRCache[RR_CACHE_SIZE];
79*48a54d36SAndroid Build Coastguard Worker #if 0
80*48a54d36SAndroid Build Coastguard Worker #pragma mark == Structures ==
81*48a54d36SAndroid Build Coastguard Worker #endif
82*48a54d36SAndroid Build Coastguard Worker
83*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
84*48a54d36SAndroid Build Coastguard Worker // Structures
85*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
86*48a54d36SAndroid Build Coastguard Worker
87*48a54d36SAndroid Build Coastguard Worker typedef struct EventSource
88*48a54d36SAndroid Build Coastguard Worker {
89*48a54d36SAndroid Build Coastguard Worker HANDLE event;
90*48a54d36SAndroid Build Coastguard Worker void * context;
91*48a54d36SAndroid Build Coastguard Worker RegisterWaitableEventHandler handler;
92*48a54d36SAndroid Build Coastguard Worker struct EventSource * next;
93*48a54d36SAndroid Build Coastguard Worker } EventSource;
94*48a54d36SAndroid Build Coastguard Worker
95*48a54d36SAndroid Build Coastguard Worker static BOOL gEventSourceListChanged = FALSE;
96*48a54d36SAndroid Build Coastguard Worker static EventSource * gEventSourceList = NULL;
97*48a54d36SAndroid Build Coastguard Worker static EventSource * gCurrentSource = NULL;
98*48a54d36SAndroid Build Coastguard Worker static int gEventSources = 0;
99*48a54d36SAndroid Build Coastguard Worker
100*48a54d36SAndroid Build Coastguard Worker #define kWaitListStopEvent ( WAIT_OBJECT_0 + 0 )
101*48a54d36SAndroid Build Coastguard Worker #define kWaitListInterfaceListChangedEvent ( WAIT_OBJECT_0 + 1 )
102*48a54d36SAndroid Build Coastguard Worker #define kWaitListComputerDescriptionEvent ( WAIT_OBJECT_0 + 2 )
103*48a54d36SAndroid Build Coastguard Worker #define kWaitListTCPIPEvent ( WAIT_OBJECT_0 + 3 )
104*48a54d36SAndroid Build Coastguard Worker #define kWaitListDynDNSEvent ( WAIT_OBJECT_0 + 4 )
105*48a54d36SAndroid Build Coastguard Worker #define kWaitListFileShareEvent ( WAIT_OBJECT_0 + 5 )
106*48a54d36SAndroid Build Coastguard Worker #define kWaitListFirewallEvent ( WAIT_OBJECT_0 + 6 )
107*48a54d36SAndroid Build Coastguard Worker #define kWaitListAdvertisedServicesEvent ( WAIT_OBJECT_0 + 7 )
108*48a54d36SAndroid Build Coastguard Worker #define kWaitListSPSWakeupEvent ( WAIT_OBJECT_0 + 8 )
109*48a54d36SAndroid Build Coastguard Worker #define kWaitListSPSSleepEvent ( WAIT_OBJECT_0 + 9 )
110*48a54d36SAndroid Build Coastguard Worker #define kWaitListFixedItemCount 10
111*48a54d36SAndroid Build Coastguard Worker
112*48a54d36SAndroid Build Coastguard Worker
113*48a54d36SAndroid Build Coastguard Worker #if 0
114*48a54d36SAndroid Build Coastguard Worker #pragma mark == Prototypes ==
115*48a54d36SAndroid Build Coastguard Worker #endif
116*48a54d36SAndroid Build Coastguard Worker
117*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
118*48a54d36SAndroid Build Coastguard Worker // Prototypes
119*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
120*48a54d36SAndroid Build Coastguard Worker static void Usage( void );
121*48a54d36SAndroid Build Coastguard Worker static BOOL WINAPI ConsoleControlHandler( DWORD inControlEvent );
122*48a54d36SAndroid Build Coastguard Worker static OSStatus InstallService( LPCTSTR inName, LPCTSTR inDisplayName, LPCTSTR inDescription, LPCTSTR inPath );
123*48a54d36SAndroid Build Coastguard Worker static OSStatus RemoveService( LPCTSTR inName );
124*48a54d36SAndroid Build Coastguard Worker static OSStatus SetServiceParameters();
125*48a54d36SAndroid Build Coastguard Worker static OSStatus GetServiceParameters();
126*48a54d36SAndroid Build Coastguard Worker static OSStatus CheckFirewall();
127*48a54d36SAndroid Build Coastguard Worker static OSStatus SetServiceInfo( SC_HANDLE inSCM, LPCTSTR inServiceName, LPCTSTR inDescription );
128*48a54d36SAndroid Build Coastguard Worker static void ReportStatus( int inType, const char *inFormat, ... );
129*48a54d36SAndroid Build Coastguard Worker
130*48a54d36SAndroid Build Coastguard Worker static void WINAPI ServiceMain( DWORD argc, LPTSTR argv[] );
131*48a54d36SAndroid Build Coastguard Worker static OSStatus ServiceSetupEventLogging( void );
132*48a54d36SAndroid Build Coastguard Worker static DWORD WINAPI ServiceControlHandler( DWORD inControl, DWORD inEventType, LPVOID inEventData, LPVOID inContext );
133*48a54d36SAndroid Build Coastguard Worker
134*48a54d36SAndroid Build Coastguard Worker static OSStatus ServiceRun( int argc, LPTSTR argv[] );
135*48a54d36SAndroid Build Coastguard Worker static void ServiceStop( void );
136*48a54d36SAndroid Build Coastguard Worker
137*48a54d36SAndroid Build Coastguard Worker static OSStatus ServiceSpecificInitialize( int argc, LPTSTR argv[] );
138*48a54d36SAndroid Build Coastguard Worker static OSStatus ServiceSpecificRun( int argc, LPTSTR argv[] );
139*48a54d36SAndroid Build Coastguard Worker static OSStatus ServiceSpecificStop( void );
140*48a54d36SAndroid Build Coastguard Worker static void ServiceSpecificFinalize( int argc, LPTSTR argv[] );
141*48a54d36SAndroid Build Coastguard Worker static mStatus SetupNotifications();
142*48a54d36SAndroid Build Coastguard Worker static mStatus TearDownNotifications();
143*48a54d36SAndroid Build Coastguard Worker static mStatus RegisterWaitableEvent( mDNS * const inMDNS, HANDLE event, void * context, RegisterWaitableEventHandler handler );
144*48a54d36SAndroid Build Coastguard Worker static void UnregisterWaitableEvent( mDNS * const inMDNS, HANDLE event );
145*48a54d36SAndroid Build Coastguard Worker static mStatus SetupWaitList( mDNS * const inMDNS, HANDLE **outWaitList, int *outWaitListCount );
146*48a54d36SAndroid Build Coastguard Worker static void UDSCanAccept( mDNS * const inMDNS, HANDLE event, void * context );
147*48a54d36SAndroid Build Coastguard Worker static void UDSCanRead( TCPSocket * sock );
148*48a54d36SAndroid Build Coastguard Worker static void HandlePowerSuspend( void * v );
149*48a54d36SAndroid Build Coastguard Worker static void HandlePowerResumeSuspend( void * v );
150*48a54d36SAndroid Build Coastguard Worker static void CoreCallback(mDNS * const inMDNS, mStatus result);
151*48a54d36SAndroid Build Coastguard Worker static mDNSu8 SystemWakeForNetworkAccess( LARGE_INTEGER * timeout );
152*48a54d36SAndroid Build Coastguard Worker static OSStatus GetRouteDestination(DWORD * ifIndex, DWORD * address);
153*48a54d36SAndroid Build Coastguard Worker static OSStatus SetLLRoute( mDNS * const inMDNS );
154*48a54d36SAndroid Build Coastguard Worker static bool HaveRoute( PMIB_IPFORWARDROW rowExtant, unsigned long addr, unsigned long metric );
155*48a54d36SAndroid Build Coastguard Worker static bool IsValidAddress( const char * addr );
156*48a54d36SAndroid Build Coastguard Worker static bool IsNortelVPN( IP_ADAPTER_INFO * pAdapter );
157*48a54d36SAndroid Build Coastguard Worker static bool IsJuniperVPN( IP_ADAPTER_INFO * pAdapter );
158*48a54d36SAndroid Build Coastguard Worker static bool IsCiscoVPN( IP_ADAPTER_INFO * pAdapter );
159*48a54d36SAndroid Build Coastguard Worker static const char * strnistr( const char * string, const char * subString, size_t max );
160*48a54d36SAndroid Build Coastguard Worker
161*48a54d36SAndroid Build Coastguard Worker #if defined(UNICODE)
162*48a54d36SAndroid Build Coastguard Worker # define StrLen(X) wcslen(X)
163*48a54d36SAndroid Build Coastguard Worker # define StrCmp(X,Y) wcscmp(X,Y)
164*48a54d36SAndroid Build Coastguard Worker #else
165*48a54d36SAndroid Build Coastguard Worker # define StrLen(X) strlen(X)
166*48a54d36SAndroid Build Coastguard Worker # define StrCmp(X,Y) strcmp(X,Y)
167*48a54d36SAndroid Build Coastguard Worker #endif
168*48a54d36SAndroid Build Coastguard Worker
169*48a54d36SAndroid Build Coastguard Worker
170*48a54d36SAndroid Build Coastguard Worker #define kLLNetworkAddr "169.254.0.0"
171*48a54d36SAndroid Build Coastguard Worker #define kLLNetworkAddrMask "255.255.0.0"
172*48a54d36SAndroid Build Coastguard Worker
173*48a54d36SAndroid Build Coastguard Worker
174*48a54d36SAndroid Build Coastguard Worker #include "mDNSEmbeddedAPI.h"
175*48a54d36SAndroid Build Coastguard Worker
176*48a54d36SAndroid Build Coastguard Worker #if 0
177*48a54d36SAndroid Build Coastguard Worker #pragma mark == Globals ==
178*48a54d36SAndroid Build Coastguard Worker #endif
179*48a54d36SAndroid Build Coastguard Worker
180*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
181*48a54d36SAndroid Build Coastguard Worker // Globals
182*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
183*48a54d36SAndroid Build Coastguard Worker #define gMDNSRecord mDNSStorage
184*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL mDNS_PlatformSupport gPlatformStorage;
185*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL BOOL gServiceQuietMode = FALSE;
186*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL SERVICE_TABLE_ENTRY gServiceDispatchTable[] =
187*48a54d36SAndroid Build Coastguard Worker {
188*48a54d36SAndroid Build Coastguard Worker { kServiceName, ServiceMain },
189*48a54d36SAndroid Build Coastguard Worker { NULL, NULL }
190*48a54d36SAndroid Build Coastguard Worker };
191*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL SOCKET gInterfaceListChangedSocket = INVALID_SOCKET;
192*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL HANDLE gInterfaceListChangedEvent = NULL;
193*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL HKEY gDescKey = NULL;
194*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL HANDLE gDescChangedEvent = NULL; // Computer description changed event
195*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL HKEY gTcpipKey = NULL;
196*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL HANDLE gTcpipChangedEvent = NULL; // TCP/IP config changed
197*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL HKEY gDdnsKey = NULL;
198*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL HANDLE gDdnsChangedEvent = NULL; // DynDNS config changed
199*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL HKEY gFileSharingKey = NULL;
200*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL HANDLE gFileSharingChangedEvent = NULL; // File Sharing changed
201*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL HKEY gFirewallKey = NULL;
202*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL HANDLE gFirewallChangedEvent = NULL; // Firewall changed
203*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL HKEY gAdvertisedServicesKey = NULL;
204*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL HANDLE gAdvertisedServicesChangedEvent = NULL; // Advertised services changed
205*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL SERVICE_STATUS gServiceStatus;
206*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL SERVICE_STATUS_HANDLE gServiceStatusHandle = NULL;
207*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL HANDLE gServiceEventSource = NULL;
208*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL bool gServiceAllowRemote = false;
209*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL int gServiceCacheEntryCount = 0; // 0 means to use the DNS-SD default.
210*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL bool gServiceManageLLRouting = true;
211*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL int gWaitCount = 0;
212*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL HANDLE * gWaitList = NULL;
213*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL HANDLE gStopEvent = NULL;
214*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL HANDLE gSPSWakeupEvent = NULL;
215*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL HANDLE gSPSSleepEvent = NULL;
216*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL HANDLE gUDSEvent = NULL;
217*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL SocketRef gUDSSocket = 0;
218*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL udsEventCallback gUDSCallback = NULL;
219*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL BOOL gRetryFirewall = FALSE;
220*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL DWORD gOSMajorVersion;
221*48a54d36SAndroid Build Coastguard Worker DEBUG_LOCAL DWORD gOSMinorVersion;
222*48a54d36SAndroid Build Coastguard Worker
223*48a54d36SAndroid Build Coastguard Worker typedef DWORD ( WINAPI * GetIpInterfaceEntryFunctionPtr )( PMIB_IPINTERFACE_ROW );
224*48a54d36SAndroid Build Coastguard Worker mDNSlocal HMODULE gIPHelperLibraryInstance = NULL;
225*48a54d36SAndroid Build Coastguard Worker mDNSlocal GetIpInterfaceEntryFunctionPtr gGetIpInterfaceEntryFunctionPtr = NULL;
226*48a54d36SAndroid Build Coastguard Worker
227*48a54d36SAndroid Build Coastguard Worker
228*48a54d36SAndroid Build Coastguard Worker #if 0
229*48a54d36SAndroid Build Coastguard Worker #pragma mark -
230*48a54d36SAndroid Build Coastguard Worker #endif
231*48a54d36SAndroid Build Coastguard Worker
232*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
233*48a54d36SAndroid Build Coastguard Worker // Main
234*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
Main(int argc,LPTSTR argv[])235*48a54d36SAndroid Build Coastguard Worker int Main( int argc, LPTSTR argv[] )
236*48a54d36SAndroid Build Coastguard Worker {
237*48a54d36SAndroid Build Coastguard Worker OSStatus err;
238*48a54d36SAndroid Build Coastguard Worker BOOL ok;
239*48a54d36SAndroid Build Coastguard Worker BOOL start;
240*48a54d36SAndroid Build Coastguard Worker int i;
241*48a54d36SAndroid Build Coastguard Worker
242*48a54d36SAndroid Build Coastguard Worker HeapSetInformation( NULL, HeapEnableTerminationOnCorruption, NULL, 0 );
243*48a54d36SAndroid Build Coastguard Worker
244*48a54d36SAndroid Build Coastguard Worker debug_initialize( kDebugOutputTypeMetaConsole );
245*48a54d36SAndroid Build Coastguard Worker debug_set_property( kDebugPropertyTagPrintLevel, kDebugLevelVerbose );
246*48a54d36SAndroid Build Coastguard Worker
247*48a54d36SAndroid Build Coastguard Worker // Default to automatically starting the service dispatcher if no extra arguments are specified.
248*48a54d36SAndroid Build Coastguard Worker
249*48a54d36SAndroid Build Coastguard Worker start = ( argc <= 1 );
250*48a54d36SAndroid Build Coastguard Worker
251*48a54d36SAndroid Build Coastguard Worker // Parse arguments.
252*48a54d36SAndroid Build Coastguard Worker
253*48a54d36SAndroid Build Coastguard Worker for( i = 1; i < argc; ++i )
254*48a54d36SAndroid Build Coastguard Worker {
255*48a54d36SAndroid Build Coastguard Worker if( StrCmp( argv[ i ], TEXT("-install") ) == 0 ) // Install
256*48a54d36SAndroid Build Coastguard Worker {
257*48a54d36SAndroid Build Coastguard Worker TCHAR desc[ 256 ];
258*48a54d36SAndroid Build Coastguard Worker
259*48a54d36SAndroid Build Coastguard Worker desc[ 0 ] = 0;
260*48a54d36SAndroid Build Coastguard Worker LoadString( GetModuleHandle( NULL ), IDS_SERVICE_DESCRIPTION, desc, sizeof( desc ) );
261*48a54d36SAndroid Build Coastguard Worker err = InstallService( kServiceName, kServiceName, desc, argv[0] );
262*48a54d36SAndroid Build Coastguard Worker if( err )
263*48a54d36SAndroid Build Coastguard Worker {
264*48a54d36SAndroid Build Coastguard Worker ReportStatus( EVENTLOG_ERROR_TYPE, "install service failed (%d)\n", err );
265*48a54d36SAndroid Build Coastguard Worker goto exit;
266*48a54d36SAndroid Build Coastguard Worker }
267*48a54d36SAndroid Build Coastguard Worker }
268*48a54d36SAndroid Build Coastguard Worker else if( StrCmp( argv[ i ], TEXT("-remove") ) == 0 ) // Remove
269*48a54d36SAndroid Build Coastguard Worker {
270*48a54d36SAndroid Build Coastguard Worker err = RemoveService( kServiceName );
271*48a54d36SAndroid Build Coastguard Worker if( err )
272*48a54d36SAndroid Build Coastguard Worker {
273*48a54d36SAndroid Build Coastguard Worker ReportStatus( EVENTLOG_ERROR_TYPE, "remove service failed (%d)\n", err );
274*48a54d36SAndroid Build Coastguard Worker goto exit;
275*48a54d36SAndroid Build Coastguard Worker }
276*48a54d36SAndroid Build Coastguard Worker }
277*48a54d36SAndroid Build Coastguard Worker else if( StrCmp( argv[ i ], TEXT("-start") ) == 0 ) // Start
278*48a54d36SAndroid Build Coastguard Worker {
279*48a54d36SAndroid Build Coastguard Worker start = TRUE;
280*48a54d36SAndroid Build Coastguard Worker }
281*48a54d36SAndroid Build Coastguard Worker else if( StrCmp( argv[ i ], TEXT("-server") ) == 0 ) // Server
282*48a54d36SAndroid Build Coastguard Worker {
283*48a54d36SAndroid Build Coastguard Worker err = RunDirect( argc, argv );
284*48a54d36SAndroid Build Coastguard Worker if( err )
285*48a54d36SAndroid Build Coastguard Worker {
286*48a54d36SAndroid Build Coastguard Worker ReportStatus( EVENTLOG_ERROR_TYPE, "run service directly failed (%d)\n", err );
287*48a54d36SAndroid Build Coastguard Worker }
288*48a54d36SAndroid Build Coastguard Worker goto exit;
289*48a54d36SAndroid Build Coastguard Worker }
290*48a54d36SAndroid Build Coastguard Worker else if( StrCmp( argv[ i ], TEXT("-q") ) == 0 ) // Quiet Mode (toggle)
291*48a54d36SAndroid Build Coastguard Worker {
292*48a54d36SAndroid Build Coastguard Worker gServiceQuietMode = !gServiceQuietMode;
293*48a54d36SAndroid Build Coastguard Worker }
294*48a54d36SAndroid Build Coastguard Worker else if( ( StrCmp( argv[ i ], TEXT("-help") ) == 0 ) || // Help
295*48a54d36SAndroid Build Coastguard Worker ( StrCmp( argv[ i ], TEXT("-h") ) == 0 ) )
296*48a54d36SAndroid Build Coastguard Worker {
297*48a54d36SAndroid Build Coastguard Worker Usage();
298*48a54d36SAndroid Build Coastguard Worker err = 0;
299*48a54d36SAndroid Build Coastguard Worker break;
300*48a54d36SAndroid Build Coastguard Worker }
301*48a54d36SAndroid Build Coastguard Worker else
302*48a54d36SAndroid Build Coastguard Worker {
303*48a54d36SAndroid Build Coastguard Worker Usage();
304*48a54d36SAndroid Build Coastguard Worker err = kParamErr;
305*48a54d36SAndroid Build Coastguard Worker break;
306*48a54d36SAndroid Build Coastguard Worker }
307*48a54d36SAndroid Build Coastguard Worker }
308*48a54d36SAndroid Build Coastguard Worker
309*48a54d36SAndroid Build Coastguard Worker // Start the service dispatcher if requested. This does not return until all services have terminated. If any
310*48a54d36SAndroid Build Coastguard Worker // global initialization is needed, it should be done before starting the service dispatcher, but only if it
311*48a54d36SAndroid Build Coastguard Worker // will take less than 30 seconds. Otherwise, use a separate thread for it and start the dispatcher immediately.
312*48a54d36SAndroid Build Coastguard Worker
313*48a54d36SAndroid Build Coastguard Worker if( start )
314*48a54d36SAndroid Build Coastguard Worker {
315*48a54d36SAndroid Build Coastguard Worker ok = StartServiceCtrlDispatcher( gServiceDispatchTable );
316*48a54d36SAndroid Build Coastguard Worker err = translate_errno( ok, (OSStatus) GetLastError(), kInUseErr );
317*48a54d36SAndroid Build Coastguard Worker if( err != kNoErr )
318*48a54d36SAndroid Build Coastguard Worker {
319*48a54d36SAndroid Build Coastguard Worker ReportStatus( EVENTLOG_ERROR_TYPE, "start service dispatcher failed (%d)\n", err );
320*48a54d36SAndroid Build Coastguard Worker goto exit;
321*48a54d36SAndroid Build Coastguard Worker }
322*48a54d36SAndroid Build Coastguard Worker }
323*48a54d36SAndroid Build Coastguard Worker err = 0;
324*48a54d36SAndroid Build Coastguard Worker
325*48a54d36SAndroid Build Coastguard Worker exit:
326*48a54d36SAndroid Build Coastguard Worker dlog( kDebugLevelTrace, DEBUG_NAME "exited (%d %m)\n", err, err );
327*48a54d36SAndroid Build Coastguard Worker _CrtDumpMemoryLeaks();
328*48a54d36SAndroid Build Coastguard Worker return( (int) err );
329*48a54d36SAndroid Build Coastguard Worker }
330*48a54d36SAndroid Build Coastguard Worker
331*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
332*48a54d36SAndroid Build Coastguard Worker // Usage
333*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
334*48a54d36SAndroid Build Coastguard Worker
Usage(void)335*48a54d36SAndroid Build Coastguard Worker static void Usage( void )
336*48a54d36SAndroid Build Coastguard Worker {
337*48a54d36SAndroid Build Coastguard Worker fprintf( stderr, "\n" );
338*48a54d36SAndroid Build Coastguard Worker fprintf( stderr, "mDNSResponder 1.0d1\n" );
339*48a54d36SAndroid Build Coastguard Worker fprintf( stderr, "\n" );
340*48a54d36SAndroid Build Coastguard Worker fprintf( stderr, " <no args> Runs the service normally\n" );
341*48a54d36SAndroid Build Coastguard Worker fprintf( stderr, " -install Creates the service and starts it\n" );
342*48a54d36SAndroid Build Coastguard Worker fprintf( stderr, " -remove Stops the service and deletes it\n" );
343*48a54d36SAndroid Build Coastguard Worker fprintf( stderr, " -start Starts the service dispatcher after processing all other arguments\n" );
344*48a54d36SAndroid Build Coastguard Worker fprintf( stderr, " -server Runs the service directly as a server (for debugging)\n" );
345*48a54d36SAndroid Build Coastguard Worker fprintf( stderr, " -q Toggles Quiet Mode (no events or output)\n" );
346*48a54d36SAndroid Build Coastguard Worker fprintf( stderr, " -remote Allow remote connections\n" );
347*48a54d36SAndroid Build Coastguard Worker fprintf( stderr, " -cache n Number of mDNS cache entries (defaults to %d)\n", kDNSServiceCacheEntryCountDefault );
348*48a54d36SAndroid Build Coastguard Worker fprintf( stderr, " -h[elp] Display Help/Usage\n" );
349*48a54d36SAndroid Build Coastguard Worker fprintf( stderr, "\n" );
350*48a54d36SAndroid Build Coastguard Worker }
351*48a54d36SAndroid Build Coastguard Worker
352*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
353*48a54d36SAndroid Build Coastguard Worker // ConsoleControlHandler
354*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
355*48a54d36SAndroid Build Coastguard Worker
ConsoleControlHandler(DWORD inControlEvent)356*48a54d36SAndroid Build Coastguard Worker static BOOL WINAPI ConsoleControlHandler( DWORD inControlEvent )
357*48a54d36SAndroid Build Coastguard Worker {
358*48a54d36SAndroid Build Coastguard Worker BOOL handled;
359*48a54d36SAndroid Build Coastguard Worker OSStatus err;
360*48a54d36SAndroid Build Coastguard Worker
361*48a54d36SAndroid Build Coastguard Worker handled = FALSE;
362*48a54d36SAndroid Build Coastguard Worker switch( inControlEvent )
363*48a54d36SAndroid Build Coastguard Worker {
364*48a54d36SAndroid Build Coastguard Worker case CTRL_C_EVENT:
365*48a54d36SAndroid Build Coastguard Worker case CTRL_BREAK_EVENT:
366*48a54d36SAndroid Build Coastguard Worker case CTRL_CLOSE_EVENT:
367*48a54d36SAndroid Build Coastguard Worker case CTRL_LOGOFF_EVENT:
368*48a54d36SAndroid Build Coastguard Worker case CTRL_SHUTDOWN_EVENT:
369*48a54d36SAndroid Build Coastguard Worker err = ServiceSpecificStop();
370*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
371*48a54d36SAndroid Build Coastguard Worker
372*48a54d36SAndroid Build Coastguard Worker handled = TRUE;
373*48a54d36SAndroid Build Coastguard Worker break;
374*48a54d36SAndroid Build Coastguard Worker
375*48a54d36SAndroid Build Coastguard Worker default:
376*48a54d36SAndroid Build Coastguard Worker break;
377*48a54d36SAndroid Build Coastguard Worker }
378*48a54d36SAndroid Build Coastguard Worker
379*48a54d36SAndroid Build Coastguard Worker exit:
380*48a54d36SAndroid Build Coastguard Worker return( handled );
381*48a54d36SAndroid Build Coastguard Worker }
382*48a54d36SAndroid Build Coastguard Worker
383*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
384*48a54d36SAndroid Build Coastguard Worker // InstallService
385*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
386*48a54d36SAndroid Build Coastguard Worker
InstallService(LPCTSTR inName,LPCTSTR inDisplayName,LPCTSTR inDescription,LPCTSTR inPath)387*48a54d36SAndroid Build Coastguard Worker static OSStatus InstallService( LPCTSTR inName, LPCTSTR inDisplayName, LPCTSTR inDescription, LPCTSTR inPath )
388*48a54d36SAndroid Build Coastguard Worker {
389*48a54d36SAndroid Build Coastguard Worker OSStatus err;
390*48a54d36SAndroid Build Coastguard Worker SC_HANDLE scm;
391*48a54d36SAndroid Build Coastguard Worker SC_HANDLE service;
392*48a54d36SAndroid Build Coastguard Worker BOOL ok;
393*48a54d36SAndroid Build Coastguard Worker TCHAR fullPath[ MAX_PATH ];
394*48a54d36SAndroid Build Coastguard Worker TCHAR * namePtr;
395*48a54d36SAndroid Build Coastguard Worker DWORD size;
396*48a54d36SAndroid Build Coastguard Worker
397*48a54d36SAndroid Build Coastguard Worker scm = NULL;
398*48a54d36SAndroid Build Coastguard Worker service = NULL;
399*48a54d36SAndroid Build Coastguard Worker
400*48a54d36SAndroid Build Coastguard Worker // Get a full path to the executable since a relative path may have been specified.
401*48a54d36SAndroid Build Coastguard Worker
402*48a54d36SAndroid Build Coastguard Worker size = GetFullPathName( inPath, MAX_PATH, fullPath, &namePtr );
403*48a54d36SAndroid Build Coastguard Worker err = translate_errno( size > 0, (OSStatus) GetLastError(), kPathErr );
404*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
405*48a54d36SAndroid Build Coastguard Worker
406*48a54d36SAndroid Build Coastguard Worker // Create the service and start it.
407*48a54d36SAndroid Build Coastguard Worker
408*48a54d36SAndroid Build Coastguard Worker scm = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
409*48a54d36SAndroid Build Coastguard Worker err = translate_errno( scm, (OSStatus) GetLastError(), kOpenErr );
410*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
411*48a54d36SAndroid Build Coastguard Worker
412*48a54d36SAndroid Build Coastguard Worker service = CreateService( scm, inName, inDisplayName, SERVICE_ALL_ACCESS, SERVICE_WIN32_SHARE_PROCESS,
413*48a54d36SAndroid Build Coastguard Worker SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, fullPath, NULL, NULL, kServiceDependencies,
414*48a54d36SAndroid Build Coastguard Worker NULL, NULL );
415*48a54d36SAndroid Build Coastguard Worker err = translate_errno( service, (OSStatus) GetLastError(), kDuplicateErr );
416*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
417*48a54d36SAndroid Build Coastguard Worker
418*48a54d36SAndroid Build Coastguard Worker err = SetServiceParameters();
419*48a54d36SAndroid Build Coastguard Worker check_noerr( err );
420*48a54d36SAndroid Build Coastguard Worker
421*48a54d36SAndroid Build Coastguard Worker if( inDescription )
422*48a54d36SAndroid Build Coastguard Worker {
423*48a54d36SAndroid Build Coastguard Worker err = SetServiceInfo( scm, inName, inDescription );
424*48a54d36SAndroid Build Coastguard Worker check_noerr( err );
425*48a54d36SAndroid Build Coastguard Worker }
426*48a54d36SAndroid Build Coastguard Worker
427*48a54d36SAndroid Build Coastguard Worker ok = StartService( service, 0, NULL );
428*48a54d36SAndroid Build Coastguard Worker err = translate_errno( ok, (OSStatus) GetLastError(), kInUseErr );
429*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
430*48a54d36SAndroid Build Coastguard Worker
431*48a54d36SAndroid Build Coastguard Worker ReportStatus( EVENTLOG_SUCCESS, "installed service\n" );
432*48a54d36SAndroid Build Coastguard Worker err = kNoErr;
433*48a54d36SAndroid Build Coastguard Worker
434*48a54d36SAndroid Build Coastguard Worker exit:
435*48a54d36SAndroid Build Coastguard Worker if( service )
436*48a54d36SAndroid Build Coastguard Worker {
437*48a54d36SAndroid Build Coastguard Worker CloseServiceHandle( service );
438*48a54d36SAndroid Build Coastguard Worker }
439*48a54d36SAndroid Build Coastguard Worker if( scm )
440*48a54d36SAndroid Build Coastguard Worker {
441*48a54d36SAndroid Build Coastguard Worker CloseServiceHandle( scm );
442*48a54d36SAndroid Build Coastguard Worker }
443*48a54d36SAndroid Build Coastguard Worker return( err );
444*48a54d36SAndroid Build Coastguard Worker }
445*48a54d36SAndroid Build Coastguard Worker
446*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
447*48a54d36SAndroid Build Coastguard Worker // RemoveService
448*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
449*48a54d36SAndroid Build Coastguard Worker
RemoveService(LPCTSTR inName)450*48a54d36SAndroid Build Coastguard Worker static OSStatus RemoveService( LPCTSTR inName )
451*48a54d36SAndroid Build Coastguard Worker {
452*48a54d36SAndroid Build Coastguard Worker OSStatus err;
453*48a54d36SAndroid Build Coastguard Worker SC_HANDLE scm;
454*48a54d36SAndroid Build Coastguard Worker SC_HANDLE service;
455*48a54d36SAndroid Build Coastguard Worker BOOL ok;
456*48a54d36SAndroid Build Coastguard Worker SERVICE_STATUS status;
457*48a54d36SAndroid Build Coastguard Worker
458*48a54d36SAndroid Build Coastguard Worker scm = NULL;
459*48a54d36SAndroid Build Coastguard Worker service = NULL;
460*48a54d36SAndroid Build Coastguard Worker
461*48a54d36SAndroid Build Coastguard Worker // Open a connection to the service.
462*48a54d36SAndroid Build Coastguard Worker
463*48a54d36SAndroid Build Coastguard Worker scm = OpenSCManager( 0, 0, SC_MANAGER_ALL_ACCESS );
464*48a54d36SAndroid Build Coastguard Worker err = translate_errno( scm, (OSStatus) GetLastError(), kOpenErr );
465*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
466*48a54d36SAndroid Build Coastguard Worker
467*48a54d36SAndroid Build Coastguard Worker service = OpenService( scm, inName, SERVICE_STOP | SERVICE_QUERY_STATUS | DELETE );
468*48a54d36SAndroid Build Coastguard Worker err = translate_errno( service, (OSStatus) GetLastError(), kNotFoundErr );
469*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
470*48a54d36SAndroid Build Coastguard Worker
471*48a54d36SAndroid Build Coastguard Worker // Stop the service, if it is not already stopped, then delete it.
472*48a54d36SAndroid Build Coastguard Worker
473*48a54d36SAndroid Build Coastguard Worker ok = QueryServiceStatus( service, &status );
474*48a54d36SAndroid Build Coastguard Worker err = translate_errno( ok, (OSStatus) GetLastError(), kAuthenticationErr );
475*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
476*48a54d36SAndroid Build Coastguard Worker
477*48a54d36SAndroid Build Coastguard Worker if( status.dwCurrentState != SERVICE_STOPPED )
478*48a54d36SAndroid Build Coastguard Worker {
479*48a54d36SAndroid Build Coastguard Worker ok = ControlService( service, SERVICE_CONTROL_STOP, &status );
480*48a54d36SAndroid Build Coastguard Worker check_translated_errno( ok, (OSStatus) GetLastError(), kAuthenticationErr );
481*48a54d36SAndroid Build Coastguard Worker }
482*48a54d36SAndroid Build Coastguard Worker
483*48a54d36SAndroid Build Coastguard Worker ok = DeleteService( service );
484*48a54d36SAndroid Build Coastguard Worker err = translate_errno( ok, (OSStatus) GetLastError(), kDeletedErr );
485*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
486*48a54d36SAndroid Build Coastguard Worker
487*48a54d36SAndroid Build Coastguard Worker ReportStatus( EVENTLOG_SUCCESS, "Removed service\n" );
488*48a54d36SAndroid Build Coastguard Worker err = ERROR_SUCCESS;
489*48a54d36SAndroid Build Coastguard Worker
490*48a54d36SAndroid Build Coastguard Worker exit:
491*48a54d36SAndroid Build Coastguard Worker if( service )
492*48a54d36SAndroid Build Coastguard Worker {
493*48a54d36SAndroid Build Coastguard Worker CloseServiceHandle( service );
494*48a54d36SAndroid Build Coastguard Worker }
495*48a54d36SAndroid Build Coastguard Worker if( scm )
496*48a54d36SAndroid Build Coastguard Worker {
497*48a54d36SAndroid Build Coastguard Worker CloseServiceHandle( scm );
498*48a54d36SAndroid Build Coastguard Worker }
499*48a54d36SAndroid Build Coastguard Worker return( err );
500*48a54d36SAndroid Build Coastguard Worker }
501*48a54d36SAndroid Build Coastguard Worker
502*48a54d36SAndroid Build Coastguard Worker
503*48a54d36SAndroid Build Coastguard Worker
504*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
505*48a54d36SAndroid Build Coastguard Worker // SetServiceParameters
506*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
507*48a54d36SAndroid Build Coastguard Worker
SetServiceParameters()508*48a54d36SAndroid Build Coastguard Worker static OSStatus SetServiceParameters()
509*48a54d36SAndroid Build Coastguard Worker {
510*48a54d36SAndroid Build Coastguard Worker DWORD value;
511*48a54d36SAndroid Build Coastguard Worker DWORD valueLen = sizeof(DWORD);
512*48a54d36SAndroid Build Coastguard Worker DWORD type;
513*48a54d36SAndroid Build Coastguard Worker OSStatus err;
514*48a54d36SAndroid Build Coastguard Worker HKEY key;
515*48a54d36SAndroid Build Coastguard Worker
516*48a54d36SAndroid Build Coastguard Worker key = NULL;
517*48a54d36SAndroid Build Coastguard Worker
518*48a54d36SAndroid Build Coastguard Worker //
519*48a54d36SAndroid Build Coastguard Worker // Add/Open Parameters section under service entry in registry
520*48a54d36SAndroid Build Coastguard Worker //
521*48a54d36SAndroid Build Coastguard Worker err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode, &key );
522*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
523*48a54d36SAndroid Build Coastguard Worker
524*48a54d36SAndroid Build Coastguard Worker //
525*48a54d36SAndroid Build Coastguard Worker // If the value isn't already there, then we create it
526*48a54d36SAndroid Build Coastguard Worker //
527*48a54d36SAndroid Build Coastguard Worker err = RegQueryValueEx(key, kServiceManageLLRouting, 0, &type, (LPBYTE) &value, &valueLen);
528*48a54d36SAndroid Build Coastguard Worker
529*48a54d36SAndroid Build Coastguard Worker if (err != ERROR_SUCCESS)
530*48a54d36SAndroid Build Coastguard Worker {
531*48a54d36SAndroid Build Coastguard Worker value = 1;
532*48a54d36SAndroid Build Coastguard Worker
533*48a54d36SAndroid Build Coastguard Worker err = RegSetValueEx( key, kServiceManageLLRouting, 0, REG_DWORD, (const LPBYTE) &value, sizeof(DWORD) );
534*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
535*48a54d36SAndroid Build Coastguard Worker }
536*48a54d36SAndroid Build Coastguard Worker
537*48a54d36SAndroid Build Coastguard Worker exit:
538*48a54d36SAndroid Build Coastguard Worker
539*48a54d36SAndroid Build Coastguard Worker if ( key )
540*48a54d36SAndroid Build Coastguard Worker {
541*48a54d36SAndroid Build Coastguard Worker RegCloseKey( key );
542*48a54d36SAndroid Build Coastguard Worker }
543*48a54d36SAndroid Build Coastguard Worker
544*48a54d36SAndroid Build Coastguard Worker return( err );
545*48a54d36SAndroid Build Coastguard Worker }
546*48a54d36SAndroid Build Coastguard Worker
547*48a54d36SAndroid Build Coastguard Worker
548*48a54d36SAndroid Build Coastguard Worker
549*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
550*48a54d36SAndroid Build Coastguard Worker // GetServiceParameters
551*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
552*48a54d36SAndroid Build Coastguard Worker
GetServiceParameters()553*48a54d36SAndroid Build Coastguard Worker static OSStatus GetServiceParameters()
554*48a54d36SAndroid Build Coastguard Worker {
555*48a54d36SAndroid Build Coastguard Worker DWORD value;
556*48a54d36SAndroid Build Coastguard Worker DWORD valueLen;
557*48a54d36SAndroid Build Coastguard Worker DWORD type;
558*48a54d36SAndroid Build Coastguard Worker OSStatus err;
559*48a54d36SAndroid Build Coastguard Worker HKEY key;
560*48a54d36SAndroid Build Coastguard Worker
561*48a54d36SAndroid Build Coastguard Worker key = NULL;
562*48a54d36SAndroid Build Coastguard Worker
563*48a54d36SAndroid Build Coastguard Worker //
564*48a54d36SAndroid Build Coastguard Worker // Add/Open Parameters section under service entry in registry
565*48a54d36SAndroid Build Coastguard Worker //
566*48a54d36SAndroid Build Coastguard Worker err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode, &key );
567*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
568*48a54d36SAndroid Build Coastguard Worker
569*48a54d36SAndroid Build Coastguard Worker valueLen = sizeof(DWORD);
570*48a54d36SAndroid Build Coastguard Worker err = RegQueryValueEx(key, kServiceManageLLRouting, 0, &type, (LPBYTE) &value, &valueLen);
571*48a54d36SAndroid Build Coastguard Worker if (err == ERROR_SUCCESS)
572*48a54d36SAndroid Build Coastguard Worker {
573*48a54d36SAndroid Build Coastguard Worker gServiceManageLLRouting = (value) ? true : false;
574*48a54d36SAndroid Build Coastguard Worker }
575*48a54d36SAndroid Build Coastguard Worker
576*48a54d36SAndroid Build Coastguard Worker valueLen = sizeof(DWORD);
577*48a54d36SAndroid Build Coastguard Worker err = RegQueryValueEx(key, kServiceCacheEntryCount, 0, &type, (LPBYTE) &value, &valueLen);
578*48a54d36SAndroid Build Coastguard Worker if (err == ERROR_SUCCESS)
579*48a54d36SAndroid Build Coastguard Worker {
580*48a54d36SAndroid Build Coastguard Worker gServiceCacheEntryCount = value;
581*48a54d36SAndroid Build Coastguard Worker }
582*48a54d36SAndroid Build Coastguard Worker
583*48a54d36SAndroid Build Coastguard Worker exit:
584*48a54d36SAndroid Build Coastguard Worker
585*48a54d36SAndroid Build Coastguard Worker if ( key )
586*48a54d36SAndroid Build Coastguard Worker {
587*48a54d36SAndroid Build Coastguard Worker RegCloseKey( key );
588*48a54d36SAndroid Build Coastguard Worker }
589*48a54d36SAndroid Build Coastguard Worker
590*48a54d36SAndroid Build Coastguard Worker return( err );
591*48a54d36SAndroid Build Coastguard Worker }
592*48a54d36SAndroid Build Coastguard Worker
593*48a54d36SAndroid Build Coastguard Worker
594*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
595*48a54d36SAndroid Build Coastguard Worker // CheckFirewall
596*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
597*48a54d36SAndroid Build Coastguard Worker
CheckFirewall()598*48a54d36SAndroid Build Coastguard Worker static OSStatus CheckFirewall()
599*48a54d36SAndroid Build Coastguard Worker {
600*48a54d36SAndroid Build Coastguard Worker DWORD value;
601*48a54d36SAndroid Build Coastguard Worker DWORD valueLen;
602*48a54d36SAndroid Build Coastguard Worker DWORD type;
603*48a54d36SAndroid Build Coastguard Worker ENUM_SERVICE_STATUS * lpService = NULL;
604*48a54d36SAndroid Build Coastguard Worker SC_HANDLE sc = NULL;
605*48a54d36SAndroid Build Coastguard Worker HKEY key = NULL;
606*48a54d36SAndroid Build Coastguard Worker BOOL ok;
607*48a54d36SAndroid Build Coastguard Worker DWORD bytesNeeded = 0;
608*48a54d36SAndroid Build Coastguard Worker DWORD srvCount;
609*48a54d36SAndroid Build Coastguard Worker DWORD resumeHandle = 0;
610*48a54d36SAndroid Build Coastguard Worker DWORD srvType;
611*48a54d36SAndroid Build Coastguard Worker DWORD srvState;
612*48a54d36SAndroid Build Coastguard Worker DWORD dwBytes = 0;
613*48a54d36SAndroid Build Coastguard Worker DWORD i;
614*48a54d36SAndroid Build Coastguard Worker BOOL isRunning = FALSE;
615*48a54d36SAndroid Build Coastguard Worker OSStatus err = kUnknownErr;
616*48a54d36SAndroid Build Coastguard Worker
617*48a54d36SAndroid Build Coastguard Worker // Check to see if the firewall service is running. If it isn't, then
618*48a54d36SAndroid Build Coastguard Worker // we want to return immediately
619*48a54d36SAndroid Build Coastguard Worker
620*48a54d36SAndroid Build Coastguard Worker sc = OpenSCManager( NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE );
621*48a54d36SAndroid Build Coastguard Worker err = translate_errno( sc, GetLastError(), kUnknownErr );
622*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
623*48a54d36SAndroid Build Coastguard Worker
624*48a54d36SAndroid Build Coastguard Worker srvType = SERVICE_WIN32;
625*48a54d36SAndroid Build Coastguard Worker srvState = SERVICE_STATE_ALL;
626*48a54d36SAndroid Build Coastguard Worker
627*48a54d36SAndroid Build Coastguard Worker for ( ;; )
628*48a54d36SAndroid Build Coastguard Worker {
629*48a54d36SAndroid Build Coastguard Worker // Call EnumServicesStatus using the handle returned by OpenSCManager
630*48a54d36SAndroid Build Coastguard Worker
631*48a54d36SAndroid Build Coastguard Worker ok = EnumServicesStatus ( sc, srvType, srvState, lpService, dwBytes, &bytesNeeded, &srvCount, &resumeHandle );
632*48a54d36SAndroid Build Coastguard Worker
633*48a54d36SAndroid Build Coastguard Worker if ( ok || ( GetLastError() != ERROR_MORE_DATA ) )
634*48a54d36SAndroid Build Coastguard Worker {
635*48a54d36SAndroid Build Coastguard Worker break;
636*48a54d36SAndroid Build Coastguard Worker }
637*48a54d36SAndroid Build Coastguard Worker
638*48a54d36SAndroid Build Coastguard Worker if ( lpService )
639*48a54d36SAndroid Build Coastguard Worker {
640*48a54d36SAndroid Build Coastguard Worker free( lpService );
641*48a54d36SAndroid Build Coastguard Worker }
642*48a54d36SAndroid Build Coastguard Worker
643*48a54d36SAndroid Build Coastguard Worker dwBytes = bytesNeeded;
644*48a54d36SAndroid Build Coastguard Worker
645*48a54d36SAndroid Build Coastguard Worker lpService = ( ENUM_SERVICE_STATUS* ) malloc( dwBytes );
646*48a54d36SAndroid Build Coastguard Worker require_action( lpService, exit, err = mStatus_NoMemoryErr );
647*48a54d36SAndroid Build Coastguard Worker }
648*48a54d36SAndroid Build Coastguard Worker
649*48a54d36SAndroid Build Coastguard Worker err = translate_errno( ok, GetLastError(), kUnknownErr );
650*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
651*48a54d36SAndroid Build Coastguard Worker
652*48a54d36SAndroid Build Coastguard Worker for ( i = 0; i < srvCount; i++ )
653*48a54d36SAndroid Build Coastguard Worker {
654*48a54d36SAndroid Build Coastguard Worker if ( wcscmp( lpService[i].lpServiceName, L"SharedAccess" ) == 0 )
655*48a54d36SAndroid Build Coastguard Worker {
656*48a54d36SAndroid Build Coastguard Worker if ( lpService[i].ServiceStatus.dwCurrentState == SERVICE_RUNNING )
657*48a54d36SAndroid Build Coastguard Worker {
658*48a54d36SAndroid Build Coastguard Worker isRunning = TRUE;
659*48a54d36SAndroid Build Coastguard Worker }
660*48a54d36SAndroid Build Coastguard Worker
661*48a54d36SAndroid Build Coastguard Worker break;
662*48a54d36SAndroid Build Coastguard Worker }
663*48a54d36SAndroid Build Coastguard Worker }
664*48a54d36SAndroid Build Coastguard Worker
665*48a54d36SAndroid Build Coastguard Worker require_action( isRunning, exit, err = kUnknownErr );
666*48a54d36SAndroid Build Coastguard Worker
667*48a54d36SAndroid Build Coastguard Worker // Check to see if we've managed the firewall.
668*48a54d36SAndroid Build Coastguard Worker // This package might have been installed, then
669*48a54d36SAndroid Build Coastguard Worker // the OS was upgraded to SP2 or above. If that's
670*48a54d36SAndroid Build Coastguard Worker // the case, then we need to manipulate the firewall
671*48a54d36SAndroid Build Coastguard Worker // so networking works correctly.
672*48a54d36SAndroid Build Coastguard Worker
673*48a54d36SAndroid Build Coastguard Worker err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode, &key );
674*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
675*48a54d36SAndroid Build Coastguard Worker
676*48a54d36SAndroid Build Coastguard Worker valueLen = sizeof(DWORD);
677*48a54d36SAndroid Build Coastguard Worker err = RegQueryValueEx(key, kServiceManageFirewall, 0, &type, (LPBYTE) &value, &valueLen);
678*48a54d36SAndroid Build Coastguard Worker
679*48a54d36SAndroid Build Coastguard Worker if ((err != ERROR_SUCCESS) || (value == 0))
680*48a54d36SAndroid Build Coastguard Worker {
681*48a54d36SAndroid Build Coastguard Worker wchar_t fullPath[ MAX_PATH ];
682*48a54d36SAndroid Build Coastguard Worker DWORD size;
683*48a54d36SAndroid Build Coastguard Worker
684*48a54d36SAndroid Build Coastguard Worker // Get a full path to the executable
685*48a54d36SAndroid Build Coastguard Worker
686*48a54d36SAndroid Build Coastguard Worker size = GetModuleFileNameW( NULL, fullPath, MAX_PATH );
687*48a54d36SAndroid Build Coastguard Worker err = translate_errno( size > 0, (OSStatus) GetLastError(), kPathErr );
688*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
689*48a54d36SAndroid Build Coastguard Worker
690*48a54d36SAndroid Build Coastguard Worker err = mDNSAddToFirewall(fullPath, kServiceFirewallName);
691*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
692*48a54d36SAndroid Build Coastguard Worker
693*48a54d36SAndroid Build Coastguard Worker value = 1;
694*48a54d36SAndroid Build Coastguard Worker err = RegSetValueEx( key, kServiceManageFirewall, 0, REG_DWORD, (const LPBYTE) &value, sizeof( DWORD ) );
695*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
696*48a54d36SAndroid Build Coastguard Worker }
697*48a54d36SAndroid Build Coastguard Worker
698*48a54d36SAndroid Build Coastguard Worker exit:
699*48a54d36SAndroid Build Coastguard Worker
700*48a54d36SAndroid Build Coastguard Worker if ( key )
701*48a54d36SAndroid Build Coastguard Worker {
702*48a54d36SAndroid Build Coastguard Worker RegCloseKey( key );
703*48a54d36SAndroid Build Coastguard Worker }
704*48a54d36SAndroid Build Coastguard Worker
705*48a54d36SAndroid Build Coastguard Worker if ( lpService )
706*48a54d36SAndroid Build Coastguard Worker {
707*48a54d36SAndroid Build Coastguard Worker free( lpService );
708*48a54d36SAndroid Build Coastguard Worker }
709*48a54d36SAndroid Build Coastguard Worker
710*48a54d36SAndroid Build Coastguard Worker if ( sc )
711*48a54d36SAndroid Build Coastguard Worker {
712*48a54d36SAndroid Build Coastguard Worker CloseServiceHandle ( sc );
713*48a54d36SAndroid Build Coastguard Worker }
714*48a54d36SAndroid Build Coastguard Worker
715*48a54d36SAndroid Build Coastguard Worker return( err );
716*48a54d36SAndroid Build Coastguard Worker }
717*48a54d36SAndroid Build Coastguard Worker
718*48a54d36SAndroid Build Coastguard Worker
719*48a54d36SAndroid Build Coastguard Worker
720*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
721*48a54d36SAndroid Build Coastguard Worker // SetServiceInfo
722*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
723*48a54d36SAndroid Build Coastguard Worker
SetServiceInfo(SC_HANDLE inSCM,LPCTSTR inServiceName,LPCTSTR inDescription)724*48a54d36SAndroid Build Coastguard Worker static OSStatus SetServiceInfo( SC_HANDLE inSCM, LPCTSTR inServiceName, LPCTSTR inDescription )
725*48a54d36SAndroid Build Coastguard Worker {
726*48a54d36SAndroid Build Coastguard Worker OSStatus err;
727*48a54d36SAndroid Build Coastguard Worker SC_LOCK lock;
728*48a54d36SAndroid Build Coastguard Worker SC_HANDLE service;
729*48a54d36SAndroid Build Coastguard Worker SERVICE_DESCRIPTION description;
730*48a54d36SAndroid Build Coastguard Worker SERVICE_FAILURE_ACTIONS actions;
731*48a54d36SAndroid Build Coastguard Worker SC_ACTION action;
732*48a54d36SAndroid Build Coastguard Worker BOOL ok;
733*48a54d36SAndroid Build Coastguard Worker
734*48a54d36SAndroid Build Coastguard Worker check( inServiceName );
735*48a54d36SAndroid Build Coastguard Worker check( inDescription );
736*48a54d36SAndroid Build Coastguard Worker
737*48a54d36SAndroid Build Coastguard Worker lock = NULL;
738*48a54d36SAndroid Build Coastguard Worker service = NULL;
739*48a54d36SAndroid Build Coastguard Worker
740*48a54d36SAndroid Build Coastguard Worker // Open the database (if not provided) and lock it to prevent other access while re-configuring.
741*48a54d36SAndroid Build Coastguard Worker
742*48a54d36SAndroid Build Coastguard Worker if( !inSCM )
743*48a54d36SAndroid Build Coastguard Worker {
744*48a54d36SAndroid Build Coastguard Worker inSCM = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
745*48a54d36SAndroid Build Coastguard Worker err = translate_errno( inSCM, (OSStatus) GetLastError(), kOpenErr );
746*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
747*48a54d36SAndroid Build Coastguard Worker }
748*48a54d36SAndroid Build Coastguard Worker
749*48a54d36SAndroid Build Coastguard Worker lock = LockServiceDatabase( inSCM );
750*48a54d36SAndroid Build Coastguard Worker err = translate_errno( lock, (OSStatus) GetLastError(), kInUseErr );
751*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
752*48a54d36SAndroid Build Coastguard Worker
753*48a54d36SAndroid Build Coastguard Worker // Open a handle to the service.
754*48a54d36SAndroid Build Coastguard Worker
755*48a54d36SAndroid Build Coastguard Worker service = OpenService( inSCM, inServiceName, SERVICE_CHANGE_CONFIG|SERVICE_START );
756*48a54d36SAndroid Build Coastguard Worker err = translate_errno( service, (OSStatus) GetLastError(), kNotFoundErr );
757*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
758*48a54d36SAndroid Build Coastguard Worker
759*48a54d36SAndroid Build Coastguard Worker // Change the description.
760*48a54d36SAndroid Build Coastguard Worker
761*48a54d36SAndroid Build Coastguard Worker description.lpDescription = (LPTSTR) inDescription;
762*48a54d36SAndroid Build Coastguard Worker ok = ChangeServiceConfig2( service, SERVICE_CONFIG_DESCRIPTION, &description );
763*48a54d36SAndroid Build Coastguard Worker err = translate_errno( ok, (OSStatus) GetLastError(), kParamErr );
764*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
765*48a54d36SAndroid Build Coastguard Worker
766*48a54d36SAndroid Build Coastguard Worker actions.dwResetPeriod = INFINITE;
767*48a54d36SAndroid Build Coastguard Worker actions.lpRebootMsg = NULL;
768*48a54d36SAndroid Build Coastguard Worker actions.lpCommand = NULL;
769*48a54d36SAndroid Build Coastguard Worker actions.cActions = 1;
770*48a54d36SAndroid Build Coastguard Worker actions.lpsaActions = &action;
771*48a54d36SAndroid Build Coastguard Worker action.Delay = 500;
772*48a54d36SAndroid Build Coastguard Worker action.Type = SC_ACTION_RESTART;
773*48a54d36SAndroid Build Coastguard Worker
774*48a54d36SAndroid Build Coastguard Worker ok = ChangeServiceConfig2( service, SERVICE_CONFIG_FAILURE_ACTIONS, &actions );
775*48a54d36SAndroid Build Coastguard Worker err = translate_errno( ok, (OSStatus) GetLastError(), kParamErr );
776*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
777*48a54d36SAndroid Build Coastguard Worker
778*48a54d36SAndroid Build Coastguard Worker err = ERROR_SUCCESS;
779*48a54d36SAndroid Build Coastguard Worker
780*48a54d36SAndroid Build Coastguard Worker exit:
781*48a54d36SAndroid Build Coastguard Worker // Close the service and release the lock.
782*48a54d36SAndroid Build Coastguard Worker
783*48a54d36SAndroid Build Coastguard Worker if( service )
784*48a54d36SAndroid Build Coastguard Worker {
785*48a54d36SAndroid Build Coastguard Worker CloseServiceHandle( service );
786*48a54d36SAndroid Build Coastguard Worker }
787*48a54d36SAndroid Build Coastguard Worker if( lock )
788*48a54d36SAndroid Build Coastguard Worker {
789*48a54d36SAndroid Build Coastguard Worker UnlockServiceDatabase( lock );
790*48a54d36SAndroid Build Coastguard Worker }
791*48a54d36SAndroid Build Coastguard Worker return( err );
792*48a54d36SAndroid Build Coastguard Worker }
793*48a54d36SAndroid Build Coastguard Worker
794*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
795*48a54d36SAndroid Build Coastguard Worker // ReportStatus
796*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
797*48a54d36SAndroid Build Coastguard Worker
ReportStatus(int inType,const char * inFormat,...)798*48a54d36SAndroid Build Coastguard Worker static void ReportStatus( int inType, const char *inFormat, ... )
799*48a54d36SAndroid Build Coastguard Worker {
800*48a54d36SAndroid Build Coastguard Worker if( !gServiceQuietMode )
801*48a54d36SAndroid Build Coastguard Worker {
802*48a54d36SAndroid Build Coastguard Worker va_list args;
803*48a54d36SAndroid Build Coastguard Worker
804*48a54d36SAndroid Build Coastguard Worker va_start( args, inFormat );
805*48a54d36SAndroid Build Coastguard Worker if( gServiceEventSource )
806*48a54d36SAndroid Build Coastguard Worker {
807*48a54d36SAndroid Build Coastguard Worker char s[ 1024 ];
808*48a54d36SAndroid Build Coastguard Worker BOOL ok;
809*48a54d36SAndroid Build Coastguard Worker const char * array[ 1 ];
810*48a54d36SAndroid Build Coastguard Worker
811*48a54d36SAndroid Build Coastguard Worker vsprintf( s, inFormat, args );
812*48a54d36SAndroid Build Coastguard Worker array[ 0 ] = s;
813*48a54d36SAndroid Build Coastguard Worker ok = ReportEventA( gServiceEventSource, (WORD) inType, 0, MDNSRESPONDER_LOG, NULL, 1, 0, array, NULL );
814*48a54d36SAndroid Build Coastguard Worker check_translated_errno( ok, GetLastError(), kUnknownErr );
815*48a54d36SAndroid Build Coastguard Worker }
816*48a54d36SAndroid Build Coastguard Worker else
817*48a54d36SAndroid Build Coastguard Worker {
818*48a54d36SAndroid Build Coastguard Worker int n;
819*48a54d36SAndroid Build Coastguard Worker
820*48a54d36SAndroid Build Coastguard Worker n = vfprintf( stderr, inFormat, args );
821*48a54d36SAndroid Build Coastguard Worker check( n >= 0 );
822*48a54d36SAndroid Build Coastguard Worker }
823*48a54d36SAndroid Build Coastguard Worker va_end( args );
824*48a54d36SAndroid Build Coastguard Worker }
825*48a54d36SAndroid Build Coastguard Worker }
826*48a54d36SAndroid Build Coastguard Worker
827*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
828*48a54d36SAndroid Build Coastguard Worker // RunDirect
829*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
830*48a54d36SAndroid Build Coastguard Worker
RunDirect(int argc,LPTSTR argv[])831*48a54d36SAndroid Build Coastguard Worker int RunDirect( int argc, LPTSTR argv[] )
832*48a54d36SAndroid Build Coastguard Worker {
833*48a54d36SAndroid Build Coastguard Worker OSStatus err;
834*48a54d36SAndroid Build Coastguard Worker BOOL initialized;
835*48a54d36SAndroid Build Coastguard Worker BOOL ok;
836*48a54d36SAndroid Build Coastguard Worker
837*48a54d36SAndroid Build Coastguard Worker initialized = FALSE;
838*48a54d36SAndroid Build Coastguard Worker
839*48a54d36SAndroid Build Coastguard Worker // Install a Console Control Handler to handle things like control-c signals.
840*48a54d36SAndroid Build Coastguard Worker
841*48a54d36SAndroid Build Coastguard Worker ok = SetConsoleCtrlHandler( ConsoleControlHandler, TRUE );
842*48a54d36SAndroid Build Coastguard Worker err = translate_errno( ok, (OSStatus) GetLastError(), kUnknownErr );
843*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
844*48a54d36SAndroid Build Coastguard Worker
845*48a54d36SAndroid Build Coastguard Worker err = ServiceSpecificInitialize( argc, argv );
846*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
847*48a54d36SAndroid Build Coastguard Worker initialized = TRUE;
848*48a54d36SAndroid Build Coastguard Worker
849*48a54d36SAndroid Build Coastguard Worker // Run the service. This does not return until the service quits or is stopped.
850*48a54d36SAndroid Build Coastguard Worker
851*48a54d36SAndroid Build Coastguard Worker ReportStatus( EVENTLOG_INFORMATION_TYPE, "Running service directly\n" );
852*48a54d36SAndroid Build Coastguard Worker
853*48a54d36SAndroid Build Coastguard Worker err = ServiceSpecificRun( argc, argv );
854*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
855*48a54d36SAndroid Build Coastguard Worker
856*48a54d36SAndroid Build Coastguard Worker // Clean up.
857*48a54d36SAndroid Build Coastguard Worker
858*48a54d36SAndroid Build Coastguard Worker exit:
859*48a54d36SAndroid Build Coastguard Worker if( initialized )
860*48a54d36SAndroid Build Coastguard Worker {
861*48a54d36SAndroid Build Coastguard Worker ServiceSpecificFinalize( argc, argv );
862*48a54d36SAndroid Build Coastguard Worker }
863*48a54d36SAndroid Build Coastguard Worker return( err );
864*48a54d36SAndroid Build Coastguard Worker }
865*48a54d36SAndroid Build Coastguard Worker
866*48a54d36SAndroid Build Coastguard Worker #if 0
867*48a54d36SAndroid Build Coastguard Worker #pragma mark -
868*48a54d36SAndroid Build Coastguard Worker #endif
869*48a54d36SAndroid Build Coastguard Worker
870*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
871*48a54d36SAndroid Build Coastguard Worker // ServiceMain
872*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
873*48a54d36SAndroid Build Coastguard Worker
ServiceMain(DWORD argc,LPTSTR argv[])874*48a54d36SAndroid Build Coastguard Worker static void WINAPI ServiceMain( DWORD argc, LPTSTR argv[] )
875*48a54d36SAndroid Build Coastguard Worker {
876*48a54d36SAndroid Build Coastguard Worker OSStatus err;
877*48a54d36SAndroid Build Coastguard Worker BOOL ok;
878*48a54d36SAndroid Build Coastguard Worker
879*48a54d36SAndroid Build Coastguard Worker err = ServiceSetupEventLogging();
880*48a54d36SAndroid Build Coastguard Worker check_noerr( err );
881*48a54d36SAndroid Build Coastguard Worker
882*48a54d36SAndroid Build Coastguard Worker err = GetServiceParameters();
883*48a54d36SAndroid Build Coastguard Worker check_noerr( err );
884*48a54d36SAndroid Build Coastguard Worker
885*48a54d36SAndroid Build Coastguard Worker // Initialize the service status and register the service control handler with the name of the service.
886*48a54d36SAndroid Build Coastguard Worker
887*48a54d36SAndroid Build Coastguard Worker gServiceStatus.dwServiceType = SERVICE_WIN32_SHARE_PROCESS;
888*48a54d36SAndroid Build Coastguard Worker gServiceStatus.dwCurrentState = 0;
889*48a54d36SAndroid Build Coastguard Worker gServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_SHUTDOWN|SERVICE_ACCEPT_POWEREVENT;
890*48a54d36SAndroid Build Coastguard Worker gServiceStatus.dwWin32ExitCode = NO_ERROR;
891*48a54d36SAndroid Build Coastguard Worker gServiceStatus.dwServiceSpecificExitCode = NO_ERROR;
892*48a54d36SAndroid Build Coastguard Worker gServiceStatus.dwCheckPoint = 0;
893*48a54d36SAndroid Build Coastguard Worker gServiceStatus.dwWaitHint = 0;
894*48a54d36SAndroid Build Coastguard Worker
895*48a54d36SAndroid Build Coastguard Worker gServiceStatusHandle = RegisterServiceCtrlHandlerEx( argv[ 0 ], ServiceControlHandler, NULL );
896*48a54d36SAndroid Build Coastguard Worker err = translate_errno( gServiceStatusHandle, (OSStatus) GetLastError(), kInUseErr );
897*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
898*48a54d36SAndroid Build Coastguard Worker
899*48a54d36SAndroid Build Coastguard Worker // Mark the service as starting.
900*48a54d36SAndroid Build Coastguard Worker
901*48a54d36SAndroid Build Coastguard Worker gServiceStatus.dwCurrentState = SERVICE_START_PENDING;
902*48a54d36SAndroid Build Coastguard Worker gServiceStatus.dwCheckPoint = 0;
903*48a54d36SAndroid Build Coastguard Worker gServiceStatus.dwWaitHint = 5000; // 5 seconds
904*48a54d36SAndroid Build Coastguard Worker ok = SetServiceStatus( gServiceStatusHandle, &gServiceStatus );
905*48a54d36SAndroid Build Coastguard Worker check_translated_errno( ok, GetLastError(), kParamErr );
906*48a54d36SAndroid Build Coastguard Worker
907*48a54d36SAndroid Build Coastguard Worker // Run the service. This does not return until the service quits or is stopped.
908*48a54d36SAndroid Build Coastguard Worker
909*48a54d36SAndroid Build Coastguard Worker err = ServiceRun( (int) argc, argv );
910*48a54d36SAndroid Build Coastguard Worker if( err != kNoErr )
911*48a54d36SAndroid Build Coastguard Worker {
912*48a54d36SAndroid Build Coastguard Worker gServiceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
913*48a54d36SAndroid Build Coastguard Worker gServiceStatus.dwServiceSpecificExitCode = (DWORD) err;
914*48a54d36SAndroid Build Coastguard Worker }
915*48a54d36SAndroid Build Coastguard Worker
916*48a54d36SAndroid Build Coastguard Worker // Service-specific work is done so mark the service as stopped.
917*48a54d36SAndroid Build Coastguard Worker
918*48a54d36SAndroid Build Coastguard Worker gServiceStatus.dwCurrentState = SERVICE_STOPPED;
919*48a54d36SAndroid Build Coastguard Worker ok = SetServiceStatus( gServiceStatusHandle, &gServiceStatus );
920*48a54d36SAndroid Build Coastguard Worker check_translated_errno( ok, GetLastError(), kParamErr );
921*48a54d36SAndroid Build Coastguard Worker
922*48a54d36SAndroid Build Coastguard Worker // Note: The service status handle should not be closed according to Microsoft documentation.
923*48a54d36SAndroid Build Coastguard Worker
924*48a54d36SAndroid Build Coastguard Worker exit:
925*48a54d36SAndroid Build Coastguard Worker if( gServiceEventSource )
926*48a54d36SAndroid Build Coastguard Worker {
927*48a54d36SAndroid Build Coastguard Worker ok = DeregisterEventSource( gServiceEventSource );
928*48a54d36SAndroid Build Coastguard Worker check_translated_errno( ok, GetLastError(), kUnknownErr );
929*48a54d36SAndroid Build Coastguard Worker gServiceEventSource = NULL;
930*48a54d36SAndroid Build Coastguard Worker }
931*48a54d36SAndroid Build Coastguard Worker }
932*48a54d36SAndroid Build Coastguard Worker
933*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
934*48a54d36SAndroid Build Coastguard Worker // ServiceSetupEventLogging
935*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
936*48a54d36SAndroid Build Coastguard Worker
ServiceSetupEventLogging(void)937*48a54d36SAndroid Build Coastguard Worker static OSStatus ServiceSetupEventLogging( void )
938*48a54d36SAndroid Build Coastguard Worker {
939*48a54d36SAndroid Build Coastguard Worker OSStatus err;
940*48a54d36SAndroid Build Coastguard Worker HKEY key;
941*48a54d36SAndroid Build Coastguard Worker LPCTSTR s;
942*48a54d36SAndroid Build Coastguard Worker DWORD typesSupported;
943*48a54d36SAndroid Build Coastguard Worker TCHAR path[ MAX_PATH ];
944*48a54d36SAndroid Build Coastguard Worker DWORD n;
945*48a54d36SAndroid Build Coastguard Worker
946*48a54d36SAndroid Build Coastguard Worker key = NULL;
947*48a54d36SAndroid Build Coastguard Worker
948*48a54d36SAndroid Build Coastguard Worker // Add/Open source name as a sub-key under the Application key in the EventLog registry key.
949*48a54d36SAndroid Build Coastguard Worker
950*48a54d36SAndroid Build Coastguard Worker s = TEXT("SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\") kServiceName;
951*48a54d36SAndroid Build Coastguard Worker err = RegCreateKey( HKEY_LOCAL_MACHINE, s, &key );
952*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
953*48a54d36SAndroid Build Coastguard Worker
954*48a54d36SAndroid Build Coastguard Worker // Add the name to the EventMessageFile subkey.
955*48a54d36SAndroid Build Coastguard Worker
956*48a54d36SAndroid Build Coastguard Worker path[ 0 ] = '\0';
957*48a54d36SAndroid Build Coastguard Worker GetModuleFileName( NULL, path, MAX_PATH );
958*48a54d36SAndroid Build Coastguard Worker n = (DWORD) ( ( StrLen( path ) + 1 ) * sizeof( TCHAR ) );
959*48a54d36SAndroid Build Coastguard Worker err = RegSetValueEx( key, TEXT("EventMessageFile"), 0, REG_EXPAND_SZ, (const LPBYTE) path, n );
960*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
961*48a54d36SAndroid Build Coastguard Worker
962*48a54d36SAndroid Build Coastguard Worker // Set the supported event types in the TypesSupported subkey.
963*48a54d36SAndroid Build Coastguard Worker
964*48a54d36SAndroid Build Coastguard Worker typesSupported = 0
965*48a54d36SAndroid Build Coastguard Worker | EVENTLOG_SUCCESS
966*48a54d36SAndroid Build Coastguard Worker | EVENTLOG_ERROR_TYPE
967*48a54d36SAndroid Build Coastguard Worker | EVENTLOG_WARNING_TYPE
968*48a54d36SAndroid Build Coastguard Worker | EVENTLOG_INFORMATION_TYPE
969*48a54d36SAndroid Build Coastguard Worker | EVENTLOG_AUDIT_SUCCESS
970*48a54d36SAndroid Build Coastguard Worker | EVENTLOG_AUDIT_FAILURE;
971*48a54d36SAndroid Build Coastguard Worker err = RegSetValueEx( key, TEXT("TypesSupported"), 0, REG_DWORD, (const LPBYTE) &typesSupported, sizeof( DWORD ) );
972*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
973*48a54d36SAndroid Build Coastguard Worker
974*48a54d36SAndroid Build Coastguard Worker // Set up the event source.
975*48a54d36SAndroid Build Coastguard Worker
976*48a54d36SAndroid Build Coastguard Worker gServiceEventSource = RegisterEventSource( NULL, kServiceName );
977*48a54d36SAndroid Build Coastguard Worker err = translate_errno( gServiceEventSource, (OSStatus) GetLastError(), kParamErr );
978*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
979*48a54d36SAndroid Build Coastguard Worker
980*48a54d36SAndroid Build Coastguard Worker exit:
981*48a54d36SAndroid Build Coastguard Worker if( key )
982*48a54d36SAndroid Build Coastguard Worker {
983*48a54d36SAndroid Build Coastguard Worker RegCloseKey( key );
984*48a54d36SAndroid Build Coastguard Worker }
985*48a54d36SAndroid Build Coastguard Worker return( err );
986*48a54d36SAndroid Build Coastguard Worker }
987*48a54d36SAndroid Build Coastguard Worker
988*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
989*48a54d36SAndroid Build Coastguard Worker // HandlePowerSuspend
990*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
991*48a54d36SAndroid Build Coastguard Worker
HandlePowerSuspend(void * v)992*48a54d36SAndroid Build Coastguard Worker static void HandlePowerSuspend( void * v )
993*48a54d36SAndroid Build Coastguard Worker {
994*48a54d36SAndroid Build Coastguard Worker LARGE_INTEGER timeout;
995*48a54d36SAndroid Build Coastguard Worker BOOL ok;
996*48a54d36SAndroid Build Coastguard Worker
997*48a54d36SAndroid Build Coastguard Worker ( void ) v;
998*48a54d36SAndroid Build Coastguard Worker
999*48a54d36SAndroid Build Coastguard Worker dlog( kDebugLevelInfo, DEBUG_NAME "HandlePowerSuspend\n" );
1000*48a54d36SAndroid Build Coastguard Worker
1001*48a54d36SAndroid Build Coastguard Worker gMDNSRecord.SystemWakeOnLANEnabled = SystemWakeForNetworkAccess( &timeout );
1002*48a54d36SAndroid Build Coastguard Worker
1003*48a54d36SAndroid Build Coastguard Worker if ( gMDNSRecord.SystemWakeOnLANEnabled )
1004*48a54d36SAndroid Build Coastguard Worker {
1005*48a54d36SAndroid Build Coastguard Worker ok = SetWaitableTimer( gSPSWakeupEvent, &timeout, 0, NULL, NULL, TRUE );
1006*48a54d36SAndroid Build Coastguard Worker check( ok );
1007*48a54d36SAndroid Build Coastguard Worker }
1008*48a54d36SAndroid Build Coastguard Worker
1009*48a54d36SAndroid Build Coastguard Worker mDNSCoreMachineSleep(&gMDNSRecord, TRUE);
1010*48a54d36SAndroid Build Coastguard Worker }
1011*48a54d36SAndroid Build Coastguard Worker
1012*48a54d36SAndroid Build Coastguard Worker
1013*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1014*48a54d36SAndroid Build Coastguard Worker // HandlePowerResumeSuspend
1015*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1016*48a54d36SAndroid Build Coastguard Worker
HandlePowerResumeSuspend(void * v)1017*48a54d36SAndroid Build Coastguard Worker static void HandlePowerResumeSuspend( void * v )
1018*48a54d36SAndroid Build Coastguard Worker {
1019*48a54d36SAndroid Build Coastguard Worker ( void ) v;
1020*48a54d36SAndroid Build Coastguard Worker
1021*48a54d36SAndroid Build Coastguard Worker dlog( kDebugLevelInfo, DEBUG_NAME "HandlePowerResumeSuspend\n" );
1022*48a54d36SAndroid Build Coastguard Worker
1023*48a54d36SAndroid Build Coastguard Worker if ( gSPSWakeupEvent )
1024*48a54d36SAndroid Build Coastguard Worker {
1025*48a54d36SAndroid Build Coastguard Worker CancelWaitableTimer( gSPSWakeupEvent );
1026*48a54d36SAndroid Build Coastguard Worker }
1027*48a54d36SAndroid Build Coastguard Worker
1028*48a54d36SAndroid Build Coastguard Worker if ( gSPSSleepEvent )
1029*48a54d36SAndroid Build Coastguard Worker {
1030*48a54d36SAndroid Build Coastguard Worker CancelWaitableTimer( gSPSSleepEvent );
1031*48a54d36SAndroid Build Coastguard Worker }
1032*48a54d36SAndroid Build Coastguard Worker
1033*48a54d36SAndroid Build Coastguard Worker mDNSCoreMachineSleep(&gMDNSRecord, FALSE);
1034*48a54d36SAndroid Build Coastguard Worker }
1035*48a54d36SAndroid Build Coastguard Worker
1036*48a54d36SAndroid Build Coastguard Worker
1037*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1038*48a54d36SAndroid Build Coastguard Worker // ServiceControlHandler
1039*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1040*48a54d36SAndroid Build Coastguard Worker
ServiceControlHandler(DWORD inControl,DWORD inEventType,LPVOID inEventData,LPVOID inContext)1041*48a54d36SAndroid Build Coastguard Worker static DWORD WINAPI ServiceControlHandler( DWORD inControl, DWORD inEventType, LPVOID inEventData, LPVOID inContext )
1042*48a54d36SAndroid Build Coastguard Worker {
1043*48a54d36SAndroid Build Coastguard Worker BOOL setStatus;
1044*48a54d36SAndroid Build Coastguard Worker BOOL ok;
1045*48a54d36SAndroid Build Coastguard Worker
1046*48a54d36SAndroid Build Coastguard Worker DEBUG_UNUSED( inEventData );
1047*48a54d36SAndroid Build Coastguard Worker DEBUG_UNUSED( inContext );
1048*48a54d36SAndroid Build Coastguard Worker
1049*48a54d36SAndroid Build Coastguard Worker setStatus = TRUE;
1050*48a54d36SAndroid Build Coastguard Worker switch( inControl )
1051*48a54d36SAndroid Build Coastguard Worker {
1052*48a54d36SAndroid Build Coastguard Worker case SERVICE_CONTROL_STOP:
1053*48a54d36SAndroid Build Coastguard Worker case SERVICE_CONTROL_SHUTDOWN:
1054*48a54d36SAndroid Build Coastguard Worker dlog( kDebugLevelInfo, DEBUG_NAME "ServiceControlHandler: SERVICE_CONTROL_STOP|SERVICE_CONTROL_SHUTDOWN\n" );
1055*48a54d36SAndroid Build Coastguard Worker
1056*48a54d36SAndroid Build Coastguard Worker ServiceStop();
1057*48a54d36SAndroid Build Coastguard Worker setStatus = FALSE;
1058*48a54d36SAndroid Build Coastguard Worker break;
1059*48a54d36SAndroid Build Coastguard Worker
1060*48a54d36SAndroid Build Coastguard Worker case SERVICE_CONTROL_POWEREVENT:
1061*48a54d36SAndroid Build Coastguard Worker
1062*48a54d36SAndroid Build Coastguard Worker if (inEventType == PBT_APMSUSPEND)
1063*48a54d36SAndroid Build Coastguard Worker {
1064*48a54d36SAndroid Build Coastguard Worker dlog( kDebugLevelInfo, DEBUG_NAME "ServiceControlHandler: PBT_APMSUSPEND\n" );
1065*48a54d36SAndroid Build Coastguard Worker
1066*48a54d36SAndroid Build Coastguard Worker QueueUserAPC( ( PAPCFUNC ) HandlePowerSuspend, gMDNSRecord.p->mainThread, ( ULONG_PTR ) NULL );
1067*48a54d36SAndroid Build Coastguard Worker }
1068*48a54d36SAndroid Build Coastguard Worker else if (inEventType == PBT_APMRESUMESUSPEND)
1069*48a54d36SAndroid Build Coastguard Worker {
1070*48a54d36SAndroid Build Coastguard Worker dlog( kDebugLevelInfo, DEBUG_NAME "ServiceControlHandler: PBT_APMRESUMESUSPEND\n" );
1071*48a54d36SAndroid Build Coastguard Worker
1072*48a54d36SAndroid Build Coastguard Worker QueueUserAPC( ( PAPCFUNC ) HandlePowerResumeSuspend, gMDNSRecord.p->mainThread, ( ULONG_PTR ) NULL );
1073*48a54d36SAndroid Build Coastguard Worker }
1074*48a54d36SAndroid Build Coastguard Worker
1075*48a54d36SAndroid Build Coastguard Worker break;
1076*48a54d36SAndroid Build Coastguard Worker
1077*48a54d36SAndroid Build Coastguard Worker default:
1078*48a54d36SAndroid Build Coastguard Worker dlog( kDebugLevelNotice, DEBUG_NAME "ServiceControlHandler: event (0x%08X)\n", inControl );
1079*48a54d36SAndroid Build Coastguard Worker break;
1080*48a54d36SAndroid Build Coastguard Worker }
1081*48a54d36SAndroid Build Coastguard Worker
1082*48a54d36SAndroid Build Coastguard Worker if( setStatus && gServiceStatusHandle )
1083*48a54d36SAndroid Build Coastguard Worker {
1084*48a54d36SAndroid Build Coastguard Worker ok = SetServiceStatus( gServiceStatusHandle, &gServiceStatus );
1085*48a54d36SAndroid Build Coastguard Worker check_translated_errno( ok, GetLastError(), kUnknownErr );
1086*48a54d36SAndroid Build Coastguard Worker }
1087*48a54d36SAndroid Build Coastguard Worker
1088*48a54d36SAndroid Build Coastguard Worker return NO_ERROR;
1089*48a54d36SAndroid Build Coastguard Worker }
1090*48a54d36SAndroid Build Coastguard Worker
1091*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1092*48a54d36SAndroid Build Coastguard Worker // ServiceRun
1093*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1094*48a54d36SAndroid Build Coastguard Worker
ServiceRun(int argc,LPTSTR argv[])1095*48a54d36SAndroid Build Coastguard Worker static OSStatus ServiceRun( int argc, LPTSTR argv[] )
1096*48a54d36SAndroid Build Coastguard Worker {
1097*48a54d36SAndroid Build Coastguard Worker OSStatus err;
1098*48a54d36SAndroid Build Coastguard Worker BOOL initialized;
1099*48a54d36SAndroid Build Coastguard Worker BOOL ok;
1100*48a54d36SAndroid Build Coastguard Worker
1101*48a54d36SAndroid Build Coastguard Worker DEBUG_UNUSED( argc );
1102*48a54d36SAndroid Build Coastguard Worker DEBUG_UNUSED( argv );
1103*48a54d36SAndroid Build Coastguard Worker
1104*48a54d36SAndroid Build Coastguard Worker initialized = FALSE;
1105*48a54d36SAndroid Build Coastguard Worker
1106*48a54d36SAndroid Build Coastguard Worker // <rdar://problem/5727548> Make the service as running before we call ServiceSpecificInitialize. We've
1107*48a54d36SAndroid Build Coastguard Worker // had reports that some machines with McAfee firewall installed cause a problem with iTunes installation.
1108*48a54d36SAndroid Build Coastguard Worker // We think that the firewall product is interferring with code in ServiceSpecificInitialize. So as a
1109*48a54d36SAndroid Build Coastguard Worker // simple workaround, we'll mark us as running *before* we call ServiceSpecificInitialize. This will unblock
1110*48a54d36SAndroid Build Coastguard Worker // any installers that are waiting for our state to change.
1111*48a54d36SAndroid Build Coastguard Worker
1112*48a54d36SAndroid Build Coastguard Worker gServiceStatus.dwCurrentState = SERVICE_RUNNING;
1113*48a54d36SAndroid Build Coastguard Worker ok = SetServiceStatus( gServiceStatusHandle, &gServiceStatus );
1114*48a54d36SAndroid Build Coastguard Worker check_translated_errno( ok, GetLastError(), kParamErr );
1115*48a54d36SAndroid Build Coastguard Worker
1116*48a54d36SAndroid Build Coastguard Worker // Initialize the service-specific stuff
1117*48a54d36SAndroid Build Coastguard Worker
1118*48a54d36SAndroid Build Coastguard Worker err = ServiceSpecificInitialize( argc, argv );
1119*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
1120*48a54d36SAndroid Build Coastguard Worker initialized = TRUE;
1121*48a54d36SAndroid Build Coastguard Worker
1122*48a54d36SAndroid Build Coastguard Worker err = CheckFirewall();
1123*48a54d36SAndroid Build Coastguard Worker check_noerr( err );
1124*48a54d36SAndroid Build Coastguard Worker
1125*48a54d36SAndroid Build Coastguard Worker if ( err )
1126*48a54d36SAndroid Build Coastguard Worker {
1127*48a54d36SAndroid Build Coastguard Worker gRetryFirewall = TRUE;
1128*48a54d36SAndroid Build Coastguard Worker }
1129*48a54d36SAndroid Build Coastguard Worker
1130*48a54d36SAndroid Build Coastguard Worker // Run the service-specific stuff. This does not return until the service quits or is stopped.
1131*48a54d36SAndroid Build Coastguard Worker
1132*48a54d36SAndroid Build Coastguard Worker ReportStatus( EVENTLOG_INFORMATION_TYPE, "Service started\n" );
1133*48a54d36SAndroid Build Coastguard Worker err = ServiceSpecificRun( argc, argv );
1134*48a54d36SAndroid Build Coastguard Worker ReportStatus( EVENTLOG_INFORMATION_TYPE, "Service stopped (%d)\n", err );
1135*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
1136*48a54d36SAndroid Build Coastguard Worker
1137*48a54d36SAndroid Build Coastguard Worker // Service stopped. Clean up and we're done.
1138*48a54d36SAndroid Build Coastguard Worker
1139*48a54d36SAndroid Build Coastguard Worker exit:
1140*48a54d36SAndroid Build Coastguard Worker if( initialized )
1141*48a54d36SAndroid Build Coastguard Worker {
1142*48a54d36SAndroid Build Coastguard Worker ServiceSpecificFinalize( argc, argv );
1143*48a54d36SAndroid Build Coastguard Worker }
1144*48a54d36SAndroid Build Coastguard Worker return( err );
1145*48a54d36SAndroid Build Coastguard Worker }
1146*48a54d36SAndroid Build Coastguard Worker
1147*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1148*48a54d36SAndroid Build Coastguard Worker // ServiceStop
1149*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1150*48a54d36SAndroid Build Coastguard Worker
ServiceStop(void)1151*48a54d36SAndroid Build Coastguard Worker static void ServiceStop( void )
1152*48a54d36SAndroid Build Coastguard Worker {
1153*48a54d36SAndroid Build Coastguard Worker BOOL ok;
1154*48a54d36SAndroid Build Coastguard Worker OSStatus err;
1155*48a54d36SAndroid Build Coastguard Worker
1156*48a54d36SAndroid Build Coastguard Worker // Signal the event to cause the service to exit.
1157*48a54d36SAndroid Build Coastguard Worker
1158*48a54d36SAndroid Build Coastguard Worker if( gServiceStatusHandle )
1159*48a54d36SAndroid Build Coastguard Worker {
1160*48a54d36SAndroid Build Coastguard Worker gServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
1161*48a54d36SAndroid Build Coastguard Worker ok = SetServiceStatus( gServiceStatusHandle, &gServiceStatus );
1162*48a54d36SAndroid Build Coastguard Worker check_translated_errno( ok, GetLastError(), kParamErr );
1163*48a54d36SAndroid Build Coastguard Worker }
1164*48a54d36SAndroid Build Coastguard Worker
1165*48a54d36SAndroid Build Coastguard Worker err = ServiceSpecificStop();
1166*48a54d36SAndroid Build Coastguard Worker check_noerr( err );
1167*48a54d36SAndroid Build Coastguard Worker }
1168*48a54d36SAndroid Build Coastguard Worker
1169*48a54d36SAndroid Build Coastguard Worker #if 0
1170*48a54d36SAndroid Build Coastguard Worker #pragma mark -
1171*48a54d36SAndroid Build Coastguard Worker #pragma mark == Service Specific ==
1172*48a54d36SAndroid Build Coastguard Worker #endif
1173*48a54d36SAndroid Build Coastguard Worker
1174*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1175*48a54d36SAndroid Build Coastguard Worker // ServiceSpecificInitialize
1176*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1177*48a54d36SAndroid Build Coastguard Worker
ServiceSpecificInitialize(int argc,LPTSTR argv[])1178*48a54d36SAndroid Build Coastguard Worker static OSStatus ServiceSpecificInitialize( int argc, LPTSTR argv[] )
1179*48a54d36SAndroid Build Coastguard Worker {
1180*48a54d36SAndroid Build Coastguard Worker OSVERSIONINFO osInfo;
1181*48a54d36SAndroid Build Coastguard Worker OSStatus err;
1182*48a54d36SAndroid Build Coastguard Worker BOOL ok;
1183*48a54d36SAndroid Build Coastguard Worker
1184*48a54d36SAndroid Build Coastguard Worker DEBUG_UNUSED( argc );
1185*48a54d36SAndroid Build Coastguard Worker DEBUG_UNUSED( argv );
1186*48a54d36SAndroid Build Coastguard Worker
1187*48a54d36SAndroid Build Coastguard Worker mDNSPlatformMemZero( &gMDNSRecord, sizeof gMDNSRecord);
1188*48a54d36SAndroid Build Coastguard Worker mDNSPlatformMemZero( &gPlatformStorage, sizeof gPlatformStorage);
1189*48a54d36SAndroid Build Coastguard Worker
1190*48a54d36SAndroid Build Coastguard Worker gPlatformStorage.registerWaitableEventFunc = RegisterWaitableEvent;
1191*48a54d36SAndroid Build Coastguard Worker gPlatformStorage.unregisterWaitableEventFunc = UnregisterWaitableEvent;
1192*48a54d36SAndroid Build Coastguard Worker gPlatformStorage.reportStatusFunc = ReportStatus;
1193*48a54d36SAndroid Build Coastguard Worker
1194*48a54d36SAndroid Build Coastguard Worker err = mDNS_Init( &gMDNSRecord, &gPlatformStorage, gRRCache, RR_CACHE_SIZE, mDNS_Init_AdvertiseLocalAddresses, CoreCallback, mDNS_Init_NoInitCallbackContext);
1195*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit);
1196*48a54d36SAndroid Build Coastguard Worker
1197*48a54d36SAndroid Build Coastguard Worker err = SetupNotifications();
1198*48a54d36SAndroid Build Coastguard Worker check_noerr( err );
1199*48a54d36SAndroid Build Coastguard Worker
1200*48a54d36SAndroid Build Coastguard Worker err = udsserver_init(mDNSNULL, 0);
1201*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit);
1202*48a54d36SAndroid Build Coastguard Worker
1203*48a54d36SAndroid Build Coastguard Worker //
1204*48a54d36SAndroid Build Coastguard Worker // Get the version of Windows that we're running on
1205*48a54d36SAndroid Build Coastguard Worker //
1206*48a54d36SAndroid Build Coastguard Worker osInfo.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
1207*48a54d36SAndroid Build Coastguard Worker ok = GetVersionEx( &osInfo );
1208*48a54d36SAndroid Build Coastguard Worker err = translate_errno( ok, (OSStatus) GetLastError(), kUnknownErr );
1209*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
1210*48a54d36SAndroid Build Coastguard Worker gOSMajorVersion = osInfo.dwMajorVersion;
1211*48a54d36SAndroid Build Coastguard Worker gOSMinorVersion = osInfo.dwMinorVersion;
1212*48a54d36SAndroid Build Coastguard Worker
1213*48a54d36SAndroid Build Coastguard Worker SetLLRoute( &gMDNSRecord );
1214*48a54d36SAndroid Build Coastguard Worker
1215*48a54d36SAndroid Build Coastguard Worker exit:
1216*48a54d36SAndroid Build Coastguard Worker if( err != kNoErr )
1217*48a54d36SAndroid Build Coastguard Worker {
1218*48a54d36SAndroid Build Coastguard Worker ServiceSpecificFinalize( argc, argv );
1219*48a54d36SAndroid Build Coastguard Worker }
1220*48a54d36SAndroid Build Coastguard Worker return( err );
1221*48a54d36SAndroid Build Coastguard Worker }
1222*48a54d36SAndroid Build Coastguard Worker
1223*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1224*48a54d36SAndroid Build Coastguard Worker // ServiceSpecificRun
1225*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1226*48a54d36SAndroid Build Coastguard Worker
ServiceSpecificRun(int argc,LPTSTR argv[])1227*48a54d36SAndroid Build Coastguard Worker static OSStatus ServiceSpecificRun( int argc, LPTSTR argv[] )
1228*48a54d36SAndroid Build Coastguard Worker {
1229*48a54d36SAndroid Build Coastguard Worker HANDLE * waitList;
1230*48a54d36SAndroid Build Coastguard Worker int waitListCount;
1231*48a54d36SAndroid Build Coastguard Worker DWORD timeout;
1232*48a54d36SAndroid Build Coastguard Worker DWORD result;
1233*48a54d36SAndroid Build Coastguard Worker BOOL done;
1234*48a54d36SAndroid Build Coastguard Worker mStatus err;
1235*48a54d36SAndroid Build Coastguard Worker
1236*48a54d36SAndroid Build Coastguard Worker DEBUG_UNUSED( argc );
1237*48a54d36SAndroid Build Coastguard Worker DEBUG_UNUSED( argv );
1238*48a54d36SAndroid Build Coastguard Worker
1239*48a54d36SAndroid Build Coastguard Worker timeout = ( gRetryFirewall ) ? kRetryFirewallPeriod : INFINITE;
1240*48a54d36SAndroid Build Coastguard Worker
1241*48a54d36SAndroid Build Coastguard Worker err = SetupInterfaceList( &gMDNSRecord );
1242*48a54d36SAndroid Build Coastguard Worker check( !err );
1243*48a54d36SAndroid Build Coastguard Worker
1244*48a54d36SAndroid Build Coastguard Worker err = uDNS_SetupDNSConfig( &gMDNSRecord );
1245*48a54d36SAndroid Build Coastguard Worker check( !err );
1246*48a54d36SAndroid Build Coastguard Worker
1247*48a54d36SAndroid Build Coastguard Worker done = FALSE;
1248*48a54d36SAndroid Build Coastguard Worker
1249*48a54d36SAndroid Build Coastguard Worker // Main event loop.
1250*48a54d36SAndroid Build Coastguard Worker
1251*48a54d36SAndroid Build Coastguard Worker while( !done )
1252*48a54d36SAndroid Build Coastguard Worker {
1253*48a54d36SAndroid Build Coastguard Worker waitList = NULL;
1254*48a54d36SAndroid Build Coastguard Worker waitListCount = 0;
1255*48a54d36SAndroid Build Coastguard Worker
1256*48a54d36SAndroid Build Coastguard Worker err = SetupWaitList( &gMDNSRecord, &waitList, &waitListCount );
1257*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
1258*48a54d36SAndroid Build Coastguard Worker
1259*48a54d36SAndroid Build Coastguard Worker gEventSourceListChanged = FALSE;
1260*48a54d36SAndroid Build Coastguard Worker
1261*48a54d36SAndroid Build Coastguard Worker while ( !gEventSourceListChanged )
1262*48a54d36SAndroid Build Coastguard Worker {
1263*48a54d36SAndroid Build Coastguard Worker static mDNSs32 RepeatedBusy = 0;
1264*48a54d36SAndroid Build Coastguard Worker mDNSs32 nextTimerEvent;
1265*48a54d36SAndroid Build Coastguard Worker
1266*48a54d36SAndroid Build Coastguard Worker // Give the mDNS core a chance to do its work and determine next event time.
1267*48a54d36SAndroid Build Coastguard Worker
1268*48a54d36SAndroid Build Coastguard Worker nextTimerEvent = udsserver_idle( mDNS_Execute( &gMDNSRecord ) - mDNS_TimeNow( &gMDNSRecord ) );
1269*48a54d36SAndroid Build Coastguard Worker
1270*48a54d36SAndroid Build Coastguard Worker if ( nextTimerEvent < 0) nextTimerEvent = 0;
1271*48a54d36SAndroid Build Coastguard Worker else if ( nextTimerEvent > (0x7FFFFFFF / 1000)) nextTimerEvent = 0x7FFFFFFF / mDNSPlatformOneSecond;
1272*48a54d36SAndroid Build Coastguard Worker else nextTimerEvent = ( nextTimerEvent * 1000) / mDNSPlatformOneSecond;
1273*48a54d36SAndroid Build Coastguard Worker
1274*48a54d36SAndroid Build Coastguard Worker // Debugging sanity check, to guard against CPU spins
1275*48a54d36SAndroid Build Coastguard Worker
1276*48a54d36SAndroid Build Coastguard Worker if ( nextTimerEvent > 0 )
1277*48a54d36SAndroid Build Coastguard Worker {
1278*48a54d36SAndroid Build Coastguard Worker RepeatedBusy = 0;
1279*48a54d36SAndroid Build Coastguard Worker }
1280*48a54d36SAndroid Build Coastguard Worker else
1281*48a54d36SAndroid Build Coastguard Worker {
1282*48a54d36SAndroid Build Coastguard Worker nextTimerEvent = 1;
1283*48a54d36SAndroid Build Coastguard Worker
1284*48a54d36SAndroid Build Coastguard Worker if ( ++RepeatedBusy >= mDNSPlatformOneSecond )
1285*48a54d36SAndroid Build Coastguard Worker {
1286*48a54d36SAndroid Build Coastguard Worker ShowTaskSchedulingError( &gMDNSRecord );
1287*48a54d36SAndroid Build Coastguard Worker RepeatedBusy = 0;
1288*48a54d36SAndroid Build Coastguard Worker }
1289*48a54d36SAndroid Build Coastguard Worker }
1290*48a54d36SAndroid Build Coastguard Worker
1291*48a54d36SAndroid Build Coastguard Worker if ( gMDNSRecord.ShutdownTime )
1292*48a54d36SAndroid Build Coastguard Worker {
1293*48a54d36SAndroid Build Coastguard Worker mDNSs32 now = mDNS_TimeNow( &gMDNSRecord );
1294*48a54d36SAndroid Build Coastguard Worker
1295*48a54d36SAndroid Build Coastguard Worker if ( mDNS_ExitNow( &gMDNSRecord, now ) )
1296*48a54d36SAndroid Build Coastguard Worker {
1297*48a54d36SAndroid Build Coastguard Worker mDNS_FinalExit( &gMDNSRecord );
1298*48a54d36SAndroid Build Coastguard Worker done = TRUE;
1299*48a54d36SAndroid Build Coastguard Worker break;
1300*48a54d36SAndroid Build Coastguard Worker }
1301*48a54d36SAndroid Build Coastguard Worker
1302*48a54d36SAndroid Build Coastguard Worker if ( nextTimerEvent - gMDNSRecord.ShutdownTime >= 0 )
1303*48a54d36SAndroid Build Coastguard Worker {
1304*48a54d36SAndroid Build Coastguard Worker nextTimerEvent = gMDNSRecord.ShutdownTime;
1305*48a54d36SAndroid Build Coastguard Worker }
1306*48a54d36SAndroid Build Coastguard Worker }
1307*48a54d36SAndroid Build Coastguard Worker
1308*48a54d36SAndroid Build Coastguard Worker // Wait until something occurs (e.g. cancel, incoming packet, or timeout).
1309*48a54d36SAndroid Build Coastguard Worker //
1310*48a54d36SAndroid Build Coastguard Worker // Note: There seems to be a bug in WinSock with respect to Alertable I/O. According
1311*48a54d36SAndroid Build Coastguard Worker // to MSDN <http://msdn.microsoft.com/en-us/library/aa363772(VS.85).aspx>, Alertable I/O
1312*48a54d36SAndroid Build Coastguard Worker // callbacks will only be invoked during the following calls (when the caller sets
1313*48a54d36SAndroid Build Coastguard Worker // the appropriate flag):
1314*48a54d36SAndroid Build Coastguard Worker //
1315*48a54d36SAndroid Build Coastguard Worker // - SleepEx
1316*48a54d36SAndroid Build Coastguard Worker // - WaitForSingleObjectEx
1317*48a54d36SAndroid Build Coastguard Worker // - WaitForMultipleObjectsEx
1318*48a54d36SAndroid Build Coastguard Worker // - SignalObjectAndWait
1319*48a54d36SAndroid Build Coastguard Worker // - MsgWaitForMultipleObjectsEx
1320*48a54d36SAndroid Build Coastguard Worker //
1321*48a54d36SAndroid Build Coastguard Worker // However, we have seen callbacks be invoked during calls to bind() (and maybe others). If there
1322*48a54d36SAndroid Build Coastguard Worker // weren't a bug, then socket events would only be queued during the call to WaitForMultipleObjects() and
1323*48a54d36SAndroid Build Coastguard Worker // we'd only have to check them once afterwards. However since that doesn't seem to be the case, we'll
1324*48a54d36SAndroid Build Coastguard Worker // check the queue both before we call WaitForMultipleObjects() and after.
1325*48a54d36SAndroid Build Coastguard Worker
1326*48a54d36SAndroid Build Coastguard Worker DispatchSocketEvents( &gMDNSRecord );
1327*48a54d36SAndroid Build Coastguard Worker result = WaitForMultipleObjectsEx( ( DWORD ) waitListCount, waitList, FALSE, (DWORD) nextTimerEvent, TRUE );
1328*48a54d36SAndroid Build Coastguard Worker check( result != WAIT_FAILED );
1329*48a54d36SAndroid Build Coastguard Worker DispatchSocketEvents( &gMDNSRecord );
1330*48a54d36SAndroid Build Coastguard Worker
1331*48a54d36SAndroid Build Coastguard Worker if ( result != WAIT_FAILED )
1332*48a54d36SAndroid Build Coastguard Worker {
1333*48a54d36SAndroid Build Coastguard Worker if ( result == WAIT_TIMEOUT )
1334*48a54d36SAndroid Build Coastguard Worker {
1335*48a54d36SAndroid Build Coastguard Worker // Next task timeout occurred. Loop back up to give mDNS core a chance to work.
1336*48a54d36SAndroid Build Coastguard Worker
1337*48a54d36SAndroid Build Coastguard Worker dlog( kDebugLevelChatty - 1, DEBUG_NAME "timeout\n" );
1338*48a54d36SAndroid Build Coastguard Worker continue;
1339*48a54d36SAndroid Build Coastguard Worker }
1340*48a54d36SAndroid Build Coastguard Worker else if ( result == WAIT_IO_COMPLETION )
1341*48a54d36SAndroid Build Coastguard Worker {
1342*48a54d36SAndroid Build Coastguard Worker dlog( kDebugLevelChatty - 1, DEBUG_NAME "i/o completion\n" );
1343*48a54d36SAndroid Build Coastguard Worker continue;
1344*48a54d36SAndroid Build Coastguard Worker }
1345*48a54d36SAndroid Build Coastguard Worker else if ( result == kWaitListStopEvent )
1346*48a54d36SAndroid Build Coastguard Worker {
1347*48a54d36SAndroid Build Coastguard Worker // Stop event. Set the done flag and break to exit.
1348*48a54d36SAndroid Build Coastguard Worker
1349*48a54d36SAndroid Build Coastguard Worker dlog( kDebugLevelVerbose, DEBUG_NAME "stopping...\n" );
1350*48a54d36SAndroid Build Coastguard Worker udsserver_exit();
1351*48a54d36SAndroid Build Coastguard Worker mDNS_StartExit( &gMDNSRecord );
1352*48a54d36SAndroid Build Coastguard Worker break;
1353*48a54d36SAndroid Build Coastguard Worker }
1354*48a54d36SAndroid Build Coastguard Worker else if( result == kWaitListInterfaceListChangedEvent )
1355*48a54d36SAndroid Build Coastguard Worker {
1356*48a54d36SAndroid Build Coastguard Worker int inBuffer;
1357*48a54d36SAndroid Build Coastguard Worker int outBuffer;
1358*48a54d36SAndroid Build Coastguard Worker DWORD outSize;
1359*48a54d36SAndroid Build Coastguard Worker
1360*48a54d36SAndroid Build Coastguard Worker // It would be nice to come up with a more elegant solution to this, but it seems that
1361*48a54d36SAndroid Build Coastguard Worker // GetAdaptersAddresses doesn't always stay in sync after network changed events. So as
1362*48a54d36SAndroid Build Coastguard Worker // as a simple workaround, we'll pause for a couple of seconds before processing the change.
1363*48a54d36SAndroid Build Coastguard Worker
1364*48a54d36SAndroid Build Coastguard Worker // We arrived at 2 secs by trial and error. We could reproduce the problem after sleeping
1365*48a54d36SAndroid Build Coastguard Worker // for 500 msec and 750 msec, but couldn't after sleeping for 1 sec. We added another
1366*48a54d36SAndroid Build Coastguard Worker // second on top of that to account for machine load or some other exigency.
1367*48a54d36SAndroid Build Coastguard Worker
1368*48a54d36SAndroid Build Coastguard Worker Sleep( 2000 );
1369*48a54d36SAndroid Build Coastguard Worker
1370*48a54d36SAndroid Build Coastguard Worker // Interface list changed event. Break out of the inner loop to re-setup the wait list.
1371*48a54d36SAndroid Build Coastguard Worker
1372*48a54d36SAndroid Build Coastguard Worker InterfaceListDidChange( &gMDNSRecord );
1373*48a54d36SAndroid Build Coastguard Worker
1374*48a54d36SAndroid Build Coastguard Worker // reset the event handler
1375*48a54d36SAndroid Build Coastguard Worker inBuffer = 0;
1376*48a54d36SAndroid Build Coastguard Worker outBuffer = 0;
1377*48a54d36SAndroid Build Coastguard Worker err = WSAIoctl( gInterfaceListChangedSocket, SIO_ADDRESS_LIST_CHANGE, &inBuffer, 0, &outBuffer, 0, &outSize, NULL, NULL );
1378*48a54d36SAndroid Build Coastguard Worker if( err < 0 )
1379*48a54d36SAndroid Build Coastguard Worker {
1380*48a54d36SAndroid Build Coastguard Worker check( errno_compat() == WSAEWOULDBLOCK );
1381*48a54d36SAndroid Build Coastguard Worker }
1382*48a54d36SAndroid Build Coastguard Worker }
1383*48a54d36SAndroid Build Coastguard Worker else if ( result == kWaitListComputerDescriptionEvent )
1384*48a54d36SAndroid Build Coastguard Worker {
1385*48a54d36SAndroid Build Coastguard Worker // The computer description might have changed
1386*48a54d36SAndroid Build Coastguard Worker
1387*48a54d36SAndroid Build Coastguard Worker ComputerDescriptionDidChange( &gMDNSRecord );
1388*48a54d36SAndroid Build Coastguard Worker udsserver_handle_configchange( &gMDNSRecord );
1389*48a54d36SAndroid Build Coastguard Worker
1390*48a54d36SAndroid Build Coastguard Worker // and reset the event handler
1391*48a54d36SAndroid Build Coastguard Worker if ( ( gDescKey != NULL ) && ( gDescChangedEvent != NULL ) )
1392*48a54d36SAndroid Build Coastguard Worker {
1393*48a54d36SAndroid Build Coastguard Worker err = RegNotifyChangeKeyValue( gDescKey, TRUE, REG_NOTIFY_CHANGE_LAST_SET, gDescChangedEvent, TRUE);
1394*48a54d36SAndroid Build Coastguard Worker check_noerr( err );
1395*48a54d36SAndroid Build Coastguard Worker }
1396*48a54d36SAndroid Build Coastguard Worker }
1397*48a54d36SAndroid Build Coastguard Worker else if ( result == kWaitListTCPIPEvent )
1398*48a54d36SAndroid Build Coastguard Worker {
1399*48a54d36SAndroid Build Coastguard Worker // The TCP/IP might have changed
1400*48a54d36SAndroid Build Coastguard Worker
1401*48a54d36SAndroid Build Coastguard Worker TCPIPConfigDidChange( &gMDNSRecord );
1402*48a54d36SAndroid Build Coastguard Worker udsserver_handle_configchange( &gMDNSRecord );
1403*48a54d36SAndroid Build Coastguard Worker
1404*48a54d36SAndroid Build Coastguard Worker // and reset the event handler
1405*48a54d36SAndroid Build Coastguard Worker
1406*48a54d36SAndroid Build Coastguard Worker if ( ( gTcpipKey != NULL ) && ( gTcpipChangedEvent ) )
1407*48a54d36SAndroid Build Coastguard Worker {
1408*48a54d36SAndroid Build Coastguard Worker err = RegNotifyChangeKeyValue( gTcpipKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, gTcpipChangedEvent, TRUE );
1409*48a54d36SAndroid Build Coastguard Worker check_noerr( err );
1410*48a54d36SAndroid Build Coastguard Worker }
1411*48a54d36SAndroid Build Coastguard Worker }
1412*48a54d36SAndroid Build Coastguard Worker else if ( result == kWaitListDynDNSEvent )
1413*48a54d36SAndroid Build Coastguard Worker {
1414*48a54d36SAndroid Build Coastguard Worker // The DynDNS config might have changed
1415*48a54d36SAndroid Build Coastguard Worker
1416*48a54d36SAndroid Build Coastguard Worker DynDNSConfigDidChange( &gMDNSRecord );
1417*48a54d36SAndroid Build Coastguard Worker udsserver_handle_configchange( &gMDNSRecord );
1418*48a54d36SAndroid Build Coastguard Worker
1419*48a54d36SAndroid Build Coastguard Worker // and reset the event handler
1420*48a54d36SAndroid Build Coastguard Worker
1421*48a54d36SAndroid Build Coastguard Worker if ((gDdnsKey != NULL) && (gDdnsChangedEvent))
1422*48a54d36SAndroid Build Coastguard Worker {
1423*48a54d36SAndroid Build Coastguard Worker err = RegNotifyChangeKeyValue(gDdnsKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, gDdnsChangedEvent, TRUE);
1424*48a54d36SAndroid Build Coastguard Worker check_noerr( err );
1425*48a54d36SAndroid Build Coastguard Worker }
1426*48a54d36SAndroid Build Coastguard Worker }
1427*48a54d36SAndroid Build Coastguard Worker else if ( result == kWaitListFileShareEvent )
1428*48a54d36SAndroid Build Coastguard Worker {
1429*48a54d36SAndroid Build Coastguard Worker // File sharing changed
1430*48a54d36SAndroid Build Coastguard Worker
1431*48a54d36SAndroid Build Coastguard Worker FileSharingDidChange( &gMDNSRecord );
1432*48a54d36SAndroid Build Coastguard Worker
1433*48a54d36SAndroid Build Coastguard Worker // and reset the event handler
1434*48a54d36SAndroid Build Coastguard Worker
1435*48a54d36SAndroid Build Coastguard Worker if ((gFileSharingKey != NULL) && (gFileSharingChangedEvent))
1436*48a54d36SAndroid Build Coastguard Worker {
1437*48a54d36SAndroid Build Coastguard Worker err = RegNotifyChangeKeyValue(gFileSharingKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, gFileSharingChangedEvent, TRUE);
1438*48a54d36SAndroid Build Coastguard Worker check_noerr( err );
1439*48a54d36SAndroid Build Coastguard Worker }
1440*48a54d36SAndroid Build Coastguard Worker }
1441*48a54d36SAndroid Build Coastguard Worker else if ( result == kWaitListFirewallEvent )
1442*48a54d36SAndroid Build Coastguard Worker {
1443*48a54d36SAndroid Build Coastguard Worker // Firewall configuration changed
1444*48a54d36SAndroid Build Coastguard Worker
1445*48a54d36SAndroid Build Coastguard Worker FirewallDidChange( &gMDNSRecord );
1446*48a54d36SAndroid Build Coastguard Worker
1447*48a54d36SAndroid Build Coastguard Worker // and reset the event handler
1448*48a54d36SAndroid Build Coastguard Worker
1449*48a54d36SAndroid Build Coastguard Worker if ((gFirewallKey != NULL) && (gFirewallChangedEvent))
1450*48a54d36SAndroid Build Coastguard Worker {
1451*48a54d36SAndroid Build Coastguard Worker err = RegNotifyChangeKeyValue(gFirewallKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, gFirewallChangedEvent, TRUE);
1452*48a54d36SAndroid Build Coastguard Worker check_noerr( err );
1453*48a54d36SAndroid Build Coastguard Worker }
1454*48a54d36SAndroid Build Coastguard Worker }
1455*48a54d36SAndroid Build Coastguard Worker else if ( result == kWaitListAdvertisedServicesEvent )
1456*48a54d36SAndroid Build Coastguard Worker {
1457*48a54d36SAndroid Build Coastguard Worker // Ultimately we'll want to manage multiple services, but right now the only service
1458*48a54d36SAndroid Build Coastguard Worker // we'll be managing is SMB.
1459*48a54d36SAndroid Build Coastguard Worker
1460*48a54d36SAndroid Build Coastguard Worker FileSharingDidChange( &gMDNSRecord );
1461*48a54d36SAndroid Build Coastguard Worker
1462*48a54d36SAndroid Build Coastguard Worker // and reset the event handler
1463*48a54d36SAndroid Build Coastguard Worker
1464*48a54d36SAndroid Build Coastguard Worker if ( ( gAdvertisedServicesKey != NULL ) && ( gAdvertisedServicesChangedEvent ) )
1465*48a54d36SAndroid Build Coastguard Worker {
1466*48a54d36SAndroid Build Coastguard Worker err = RegNotifyChangeKeyValue(gAdvertisedServicesKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, gAdvertisedServicesChangedEvent, TRUE);
1467*48a54d36SAndroid Build Coastguard Worker check_noerr( err );
1468*48a54d36SAndroid Build Coastguard Worker }
1469*48a54d36SAndroid Build Coastguard Worker }
1470*48a54d36SAndroid Build Coastguard Worker else if ( result == kWaitListSPSWakeupEvent )
1471*48a54d36SAndroid Build Coastguard Worker {
1472*48a54d36SAndroid Build Coastguard Worker LARGE_INTEGER timeout;
1473*48a54d36SAndroid Build Coastguard Worker
1474*48a54d36SAndroid Build Coastguard Worker ReportStatus( EVENTLOG_INFORMATION_TYPE, "Maintenance wake" );
1475*48a54d36SAndroid Build Coastguard Worker
1476*48a54d36SAndroid Build Coastguard Worker timeout.QuadPart = kSPSMaintenanceWakePeriod;
1477*48a54d36SAndroid Build Coastguard Worker timeout.QuadPart *= kSecondsTo100NSUnits;
1478*48a54d36SAndroid Build Coastguard Worker
1479*48a54d36SAndroid Build Coastguard Worker SetWaitableTimer( gSPSSleepEvent, &timeout, 0, NULL, NULL, TRUE );
1480*48a54d36SAndroid Build Coastguard Worker }
1481*48a54d36SAndroid Build Coastguard Worker else if ( result == kWaitListSPSSleepEvent )
1482*48a54d36SAndroid Build Coastguard Worker {
1483*48a54d36SAndroid Build Coastguard Worker ReportStatus( EVENTLOG_INFORMATION_TYPE, "Returning to sleep after maintenance wake" );
1484*48a54d36SAndroid Build Coastguard Worker
1485*48a54d36SAndroid Build Coastguard Worker // Calling SetSuspendState() doesn't invoke our sleep handlers, so we'll
1486*48a54d36SAndroid Build Coastguard Worker // call HandlePowerSuspend() explicity. This will reset the
1487*48a54d36SAndroid Build Coastguard Worker // maintenance wake timers.
1488*48a54d36SAndroid Build Coastguard Worker
1489*48a54d36SAndroid Build Coastguard Worker HandlePowerSuspend( NULL );
1490*48a54d36SAndroid Build Coastguard Worker SetSuspendState( FALSE, FALSE, FALSE );
1491*48a54d36SAndroid Build Coastguard Worker }
1492*48a54d36SAndroid Build Coastguard Worker else
1493*48a54d36SAndroid Build Coastguard Worker {
1494*48a54d36SAndroid Build Coastguard Worker int waitItemIndex;
1495*48a54d36SAndroid Build Coastguard Worker
1496*48a54d36SAndroid Build Coastguard Worker waitItemIndex = (int)( ( (int) result ) - WAIT_OBJECT_0 );
1497*48a54d36SAndroid Build Coastguard Worker dlog( kDebugLevelChatty, DEBUG_NAME "waitable event on %d\n", waitItemIndex );
1498*48a54d36SAndroid Build Coastguard Worker check( ( waitItemIndex >= 0 ) && ( waitItemIndex < waitListCount ) );
1499*48a54d36SAndroid Build Coastguard Worker
1500*48a54d36SAndroid Build Coastguard Worker if ( ( waitItemIndex >= 0 ) && ( waitItemIndex < waitListCount ) )
1501*48a54d36SAndroid Build Coastguard Worker {
1502*48a54d36SAndroid Build Coastguard Worker HANDLE signaledEvent;
1503*48a54d36SAndroid Build Coastguard Worker int n = 0;
1504*48a54d36SAndroid Build Coastguard Worker
1505*48a54d36SAndroid Build Coastguard Worker signaledEvent = waitList[ waitItemIndex ];
1506*48a54d36SAndroid Build Coastguard Worker
1507*48a54d36SAndroid Build Coastguard Worker // If gCurrentSource is not NULL, then this routine has been called
1508*48a54d36SAndroid Build Coastguard Worker // re-entrantly which should never happen.
1509*48a54d36SAndroid Build Coastguard Worker
1510*48a54d36SAndroid Build Coastguard Worker check( !gCurrentSource );
1511*48a54d36SAndroid Build Coastguard Worker
1512*48a54d36SAndroid Build Coastguard Worker for ( gCurrentSource = gEventSourceList; gCurrentSource; )
1513*48a54d36SAndroid Build Coastguard Worker {
1514*48a54d36SAndroid Build Coastguard Worker EventSource * current = gCurrentSource;
1515*48a54d36SAndroid Build Coastguard Worker
1516*48a54d36SAndroid Build Coastguard Worker if ( gCurrentSource->event == signaledEvent )
1517*48a54d36SAndroid Build Coastguard Worker {
1518*48a54d36SAndroid Build Coastguard Worker gCurrentSource->handler( &gMDNSRecord, gCurrentSource->event, gCurrentSource->context );
1519*48a54d36SAndroid Build Coastguard Worker ++n;
1520*48a54d36SAndroid Build Coastguard Worker break;
1521*48a54d36SAndroid Build Coastguard Worker }
1522*48a54d36SAndroid Build Coastguard Worker
1523*48a54d36SAndroid Build Coastguard Worker // If the current node was removed as a result of calling
1524*48a54d36SAndroid Build Coastguard Worker // the handler, then gCurrentSource was already incremented to
1525*48a54d36SAndroid Build Coastguard Worker // the next node. If it wasn't removed, then increment it
1526*48a54d36SAndroid Build Coastguard Worker // ourselves
1527*48a54d36SAndroid Build Coastguard Worker
1528*48a54d36SAndroid Build Coastguard Worker if ( gCurrentSource == current )
1529*48a54d36SAndroid Build Coastguard Worker {
1530*48a54d36SAndroid Build Coastguard Worker gCurrentSource = gCurrentSource->next;
1531*48a54d36SAndroid Build Coastguard Worker }
1532*48a54d36SAndroid Build Coastguard Worker }
1533*48a54d36SAndroid Build Coastguard Worker
1534*48a54d36SAndroid Build Coastguard Worker gCurrentSource = NULL;
1535*48a54d36SAndroid Build Coastguard Worker
1536*48a54d36SAndroid Build Coastguard Worker check( n > 0 );
1537*48a54d36SAndroid Build Coastguard Worker }
1538*48a54d36SAndroid Build Coastguard Worker else
1539*48a54d36SAndroid Build Coastguard Worker {
1540*48a54d36SAndroid Build Coastguard Worker dlog( kDebugLevelWarning, DEBUG_NAME "%s: unexpected wait result (result=0x%08X)\n", __ROUTINE__, result );
1541*48a54d36SAndroid Build Coastguard Worker }
1542*48a54d36SAndroid Build Coastguard Worker }
1543*48a54d36SAndroid Build Coastguard Worker }
1544*48a54d36SAndroid Build Coastguard Worker else
1545*48a54d36SAndroid Build Coastguard Worker {
1546*48a54d36SAndroid Build Coastguard Worker Sleep( 3 * 1000 );
1547*48a54d36SAndroid Build Coastguard Worker
1548*48a54d36SAndroid Build Coastguard Worker err = SetupInterfaceList( &gMDNSRecord );
1549*48a54d36SAndroid Build Coastguard Worker check( !err );
1550*48a54d36SAndroid Build Coastguard Worker
1551*48a54d36SAndroid Build Coastguard Worker err = uDNS_SetupDNSConfig( &gMDNSRecord );
1552*48a54d36SAndroid Build Coastguard Worker check( !err );
1553*48a54d36SAndroid Build Coastguard Worker
1554*48a54d36SAndroid Build Coastguard Worker break;
1555*48a54d36SAndroid Build Coastguard Worker }
1556*48a54d36SAndroid Build Coastguard Worker }
1557*48a54d36SAndroid Build Coastguard Worker
1558*48a54d36SAndroid Build Coastguard Worker if ( waitList )
1559*48a54d36SAndroid Build Coastguard Worker {
1560*48a54d36SAndroid Build Coastguard Worker free( waitList );
1561*48a54d36SAndroid Build Coastguard Worker waitList = NULL;
1562*48a54d36SAndroid Build Coastguard Worker waitListCount = 0;
1563*48a54d36SAndroid Build Coastguard Worker }
1564*48a54d36SAndroid Build Coastguard Worker }
1565*48a54d36SAndroid Build Coastguard Worker
1566*48a54d36SAndroid Build Coastguard Worker exit:
1567*48a54d36SAndroid Build Coastguard Worker
1568*48a54d36SAndroid Build Coastguard Worker return( 0 );
1569*48a54d36SAndroid Build Coastguard Worker }
1570*48a54d36SAndroid Build Coastguard Worker
1571*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1572*48a54d36SAndroid Build Coastguard Worker // ServiceSpecificStop
1573*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1574*48a54d36SAndroid Build Coastguard Worker
ServiceSpecificStop(void)1575*48a54d36SAndroid Build Coastguard Worker static OSStatus ServiceSpecificStop( void )
1576*48a54d36SAndroid Build Coastguard Worker {
1577*48a54d36SAndroid Build Coastguard Worker OSStatus err;
1578*48a54d36SAndroid Build Coastguard Worker BOOL ok;
1579*48a54d36SAndroid Build Coastguard Worker
1580*48a54d36SAndroid Build Coastguard Worker ok = SetEvent(gStopEvent);
1581*48a54d36SAndroid Build Coastguard Worker err = translate_errno( ok, (OSStatus) GetLastError(), kUnknownErr );
1582*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
1583*48a54d36SAndroid Build Coastguard Worker exit:
1584*48a54d36SAndroid Build Coastguard Worker return( err );
1585*48a54d36SAndroid Build Coastguard Worker }
1586*48a54d36SAndroid Build Coastguard Worker
1587*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1588*48a54d36SAndroid Build Coastguard Worker // ServiceSpecificFinalize
1589*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1590*48a54d36SAndroid Build Coastguard Worker
ServiceSpecificFinalize(int argc,LPTSTR argv[])1591*48a54d36SAndroid Build Coastguard Worker static void ServiceSpecificFinalize( int argc, LPTSTR argv[] )
1592*48a54d36SAndroid Build Coastguard Worker {
1593*48a54d36SAndroid Build Coastguard Worker DEBUG_UNUSED( argc );
1594*48a54d36SAndroid Build Coastguard Worker DEBUG_UNUSED( argv );
1595*48a54d36SAndroid Build Coastguard Worker
1596*48a54d36SAndroid Build Coastguard Worker //
1597*48a54d36SAndroid Build Coastguard Worker // clean up any open sessions
1598*48a54d36SAndroid Build Coastguard Worker //
1599*48a54d36SAndroid Build Coastguard Worker while ( gEventSourceList )
1600*48a54d36SAndroid Build Coastguard Worker {
1601*48a54d36SAndroid Build Coastguard Worker UnregisterWaitableEvent( &gMDNSRecord, gEventSourceList->event );
1602*48a54d36SAndroid Build Coastguard Worker }
1603*48a54d36SAndroid Build Coastguard Worker
1604*48a54d36SAndroid Build Coastguard Worker //
1605*48a54d36SAndroid Build Coastguard Worker // clean up the notifications
1606*48a54d36SAndroid Build Coastguard Worker //
1607*48a54d36SAndroid Build Coastguard Worker TearDownNotifications();
1608*48a54d36SAndroid Build Coastguard Worker
1609*48a54d36SAndroid Build Coastguard Worker //
1610*48a54d36SAndroid Build Coastguard Worker // clean up loaded library
1611*48a54d36SAndroid Build Coastguard Worker //
1612*48a54d36SAndroid Build Coastguard Worker
1613*48a54d36SAndroid Build Coastguard Worker if( gIPHelperLibraryInstance )
1614*48a54d36SAndroid Build Coastguard Worker {
1615*48a54d36SAndroid Build Coastguard Worker gGetIpInterfaceEntryFunctionPtr = NULL;
1616*48a54d36SAndroid Build Coastguard Worker
1617*48a54d36SAndroid Build Coastguard Worker FreeLibrary( gIPHelperLibraryInstance );
1618*48a54d36SAndroid Build Coastguard Worker gIPHelperLibraryInstance = NULL;
1619*48a54d36SAndroid Build Coastguard Worker }
1620*48a54d36SAndroid Build Coastguard Worker }
1621*48a54d36SAndroid Build Coastguard Worker
1622*48a54d36SAndroid Build Coastguard Worker
1623*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1624*48a54d36SAndroid Build Coastguard Worker // SetupNotifications
1625*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1626*48a54d36SAndroid Build Coastguard Worker
SetupNotifications()1627*48a54d36SAndroid Build Coastguard Worker mDNSlocal mStatus SetupNotifications()
1628*48a54d36SAndroid Build Coastguard Worker {
1629*48a54d36SAndroid Build Coastguard Worker mStatus err;
1630*48a54d36SAndroid Build Coastguard Worker SocketRef sock;
1631*48a54d36SAndroid Build Coastguard Worker unsigned long param;
1632*48a54d36SAndroid Build Coastguard Worker int inBuffer;
1633*48a54d36SAndroid Build Coastguard Worker int outBuffer;
1634*48a54d36SAndroid Build Coastguard Worker DWORD outSize;
1635*48a54d36SAndroid Build Coastguard Worker
1636*48a54d36SAndroid Build Coastguard Worker gStopEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
1637*48a54d36SAndroid Build Coastguard Worker err = translate_errno( gStopEvent, errno_compat(), kNoResourcesErr );
1638*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
1639*48a54d36SAndroid Build Coastguard Worker
1640*48a54d36SAndroid Build Coastguard Worker // Register to listen for address list changes.
1641*48a54d36SAndroid Build Coastguard Worker
1642*48a54d36SAndroid Build Coastguard Worker gInterfaceListChangedEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
1643*48a54d36SAndroid Build Coastguard Worker err = translate_errno( gInterfaceListChangedEvent, (mStatus) GetLastError(), kUnknownErr );
1644*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
1645*48a54d36SAndroid Build Coastguard Worker
1646*48a54d36SAndroid Build Coastguard Worker sock = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
1647*48a54d36SAndroid Build Coastguard Worker err = translate_errno( IsValidSocket( sock ), errno_compat(), kUnknownErr );
1648*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
1649*48a54d36SAndroid Build Coastguard Worker gInterfaceListChangedSocket = sock;
1650*48a54d36SAndroid Build Coastguard Worker
1651*48a54d36SAndroid Build Coastguard Worker // Make the socket non-blocking so the WSAIoctl returns immediately with WSAEWOULDBLOCK. It will set the event
1652*48a54d36SAndroid Build Coastguard Worker // when a change to the interface list is detected.
1653*48a54d36SAndroid Build Coastguard Worker
1654*48a54d36SAndroid Build Coastguard Worker param = 1;
1655*48a54d36SAndroid Build Coastguard Worker err = ioctlsocket( sock, FIONBIO, ¶m );
1656*48a54d36SAndroid Build Coastguard Worker err = translate_errno( err == 0, errno_compat(), kUnknownErr );
1657*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
1658*48a54d36SAndroid Build Coastguard Worker
1659*48a54d36SAndroid Build Coastguard Worker inBuffer = 0;
1660*48a54d36SAndroid Build Coastguard Worker outBuffer = 0;
1661*48a54d36SAndroid Build Coastguard Worker err = WSAIoctl( sock, SIO_ADDRESS_LIST_CHANGE, &inBuffer, 0, &outBuffer, 0, &outSize, NULL, NULL );
1662*48a54d36SAndroid Build Coastguard Worker if( err < 0 )
1663*48a54d36SAndroid Build Coastguard Worker {
1664*48a54d36SAndroid Build Coastguard Worker check( errno_compat() == WSAEWOULDBLOCK );
1665*48a54d36SAndroid Build Coastguard Worker }
1666*48a54d36SAndroid Build Coastguard Worker
1667*48a54d36SAndroid Build Coastguard Worker err = WSAEventSelect( sock, gInterfaceListChangedEvent, FD_ADDRESS_LIST_CHANGE );
1668*48a54d36SAndroid Build Coastguard Worker err = translate_errno( err == 0, errno_compat(), kUnknownErr );
1669*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
1670*48a54d36SAndroid Build Coastguard Worker
1671*48a54d36SAndroid Build Coastguard Worker gDescChangedEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
1672*48a54d36SAndroid Build Coastguard Worker err = translate_errno( gDescChangedEvent, (mStatus) GetLastError(), kUnknownErr );
1673*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
1674*48a54d36SAndroid Build Coastguard Worker
1675*48a54d36SAndroid Build Coastguard Worker err = RegOpenKeyEx( HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\lanmanserver\\parameters"), 0, KEY_READ, &gDescKey);
1676*48a54d36SAndroid Build Coastguard Worker check_translated_errno( err == 0, errno_compat(), kNameErr );
1677*48a54d36SAndroid Build Coastguard Worker
1678*48a54d36SAndroid Build Coastguard Worker if ( gDescKey != NULL )
1679*48a54d36SAndroid Build Coastguard Worker {
1680*48a54d36SAndroid Build Coastguard Worker err = RegNotifyChangeKeyValue( gDescKey, TRUE, REG_NOTIFY_CHANGE_LAST_SET, gDescChangedEvent, TRUE);
1681*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
1682*48a54d36SAndroid Build Coastguard Worker }
1683*48a54d36SAndroid Build Coastguard Worker
1684*48a54d36SAndroid Build Coastguard Worker // This will catch all changes to tcp/ip networking, including changes to the domain search list
1685*48a54d36SAndroid Build Coastguard Worker
1686*48a54d36SAndroid Build Coastguard Worker gTcpipChangedEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
1687*48a54d36SAndroid Build Coastguard Worker err = translate_errno( gTcpipChangedEvent, (mStatus) GetLastError(), kUnknownErr );
1688*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
1689*48a54d36SAndroid Build Coastguard Worker
1690*48a54d36SAndroid Build Coastguard Worker err = RegCreateKey( HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"), &gTcpipKey );
1691*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
1692*48a54d36SAndroid Build Coastguard Worker
1693*48a54d36SAndroid Build Coastguard Worker err = RegNotifyChangeKeyValue( gTcpipKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, gTcpipChangedEvent, TRUE);
1694*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
1695*48a54d36SAndroid Build Coastguard Worker
1696*48a54d36SAndroid Build Coastguard Worker // This will catch all changes to ddns configuration
1697*48a54d36SAndroid Build Coastguard Worker
1698*48a54d36SAndroid Build Coastguard Worker gDdnsChangedEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
1699*48a54d36SAndroid Build Coastguard Worker err = translate_errno( gDdnsChangedEvent, (mStatus) GetLastError(), kUnknownErr );
1700*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
1701*48a54d36SAndroid Build Coastguard Worker
1702*48a54d36SAndroid Build Coastguard Worker err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode TEXT("\\DynDNS\\Setup"), &gDdnsKey );
1703*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
1704*48a54d36SAndroid Build Coastguard Worker
1705*48a54d36SAndroid Build Coastguard Worker err = RegNotifyChangeKeyValue( gDdnsKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, gDdnsChangedEvent, TRUE);
1706*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
1707*48a54d36SAndroid Build Coastguard Worker
1708*48a54d36SAndroid Build Coastguard Worker // This will catch all changes to file sharing
1709*48a54d36SAndroid Build Coastguard Worker
1710*48a54d36SAndroid Build Coastguard Worker gFileSharingChangedEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
1711*48a54d36SAndroid Build Coastguard Worker err = translate_errno( gFileSharingChangedEvent, (mStatus) GetLastError(), kUnknownErr );
1712*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
1713*48a54d36SAndroid Build Coastguard Worker
1714*48a54d36SAndroid Build Coastguard Worker err = RegCreateKey( HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\lanmanserver\\Shares"), &gFileSharingKey );
1715*48a54d36SAndroid Build Coastguard Worker
1716*48a54d36SAndroid Build Coastguard Worker // Just to make sure that initialization doesn't fail on some old OS
1717*48a54d36SAndroid Build Coastguard Worker // that doesn't have this key, we'll only add the notification if
1718*48a54d36SAndroid Build Coastguard Worker // the key exists.
1719*48a54d36SAndroid Build Coastguard Worker
1720*48a54d36SAndroid Build Coastguard Worker if ( !err )
1721*48a54d36SAndroid Build Coastguard Worker {
1722*48a54d36SAndroid Build Coastguard Worker err = RegNotifyChangeKeyValue( gFileSharingKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, gFileSharingChangedEvent, TRUE);
1723*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
1724*48a54d36SAndroid Build Coastguard Worker }
1725*48a54d36SAndroid Build Coastguard Worker else
1726*48a54d36SAndroid Build Coastguard Worker {
1727*48a54d36SAndroid Build Coastguard Worker err = mStatus_NoError;
1728*48a54d36SAndroid Build Coastguard Worker }
1729*48a54d36SAndroid Build Coastguard Worker
1730*48a54d36SAndroid Build Coastguard Worker // This will catch changes to the Windows firewall
1731*48a54d36SAndroid Build Coastguard Worker
1732*48a54d36SAndroid Build Coastguard Worker gFirewallChangedEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
1733*48a54d36SAndroid Build Coastguard Worker err = translate_errno( gFirewallChangedEvent, (mStatus) GetLastError(), kUnknownErr );
1734*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
1735*48a54d36SAndroid Build Coastguard Worker
1736*48a54d36SAndroid Build Coastguard Worker // Just to make sure that initialization doesn't fail on some old OS
1737*48a54d36SAndroid Build Coastguard Worker // that doesn't have this key, we'll only add the notification if
1738*48a54d36SAndroid Build Coastguard Worker // the key exists.
1739*48a54d36SAndroid Build Coastguard Worker
1740*48a54d36SAndroid Build Coastguard Worker err = RegCreateKey( HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\SharedAccess\\Parameters\\FirewallPolicy\\FirewallRules"), &gFirewallKey );
1741*48a54d36SAndroid Build Coastguard Worker
1742*48a54d36SAndroid Build Coastguard Worker if ( !err )
1743*48a54d36SAndroid Build Coastguard Worker {
1744*48a54d36SAndroid Build Coastguard Worker err = RegNotifyChangeKeyValue( gFirewallKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, gFirewallChangedEvent, TRUE);
1745*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
1746*48a54d36SAndroid Build Coastguard Worker }
1747*48a54d36SAndroid Build Coastguard Worker else
1748*48a54d36SAndroid Build Coastguard Worker {
1749*48a54d36SAndroid Build Coastguard Worker err = mStatus_NoError;
1750*48a54d36SAndroid Build Coastguard Worker }
1751*48a54d36SAndroid Build Coastguard Worker
1752*48a54d36SAndroid Build Coastguard Worker // This will catch all changes to advertised services configuration
1753*48a54d36SAndroid Build Coastguard Worker
1754*48a54d36SAndroid Build Coastguard Worker gAdvertisedServicesChangedEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
1755*48a54d36SAndroid Build Coastguard Worker err = translate_errno( gAdvertisedServicesChangedEvent, (mStatus) GetLastError(), kUnknownErr );
1756*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
1757*48a54d36SAndroid Build Coastguard Worker
1758*48a54d36SAndroid Build Coastguard Worker err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode TEXT("\\Services"), &gAdvertisedServicesKey );
1759*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
1760*48a54d36SAndroid Build Coastguard Worker
1761*48a54d36SAndroid Build Coastguard Worker err = RegNotifyChangeKeyValue( gAdvertisedServicesKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, gAdvertisedServicesChangedEvent, TRUE);
1762*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
1763*48a54d36SAndroid Build Coastguard Worker
1764*48a54d36SAndroid Build Coastguard Worker gSPSWakeupEvent = CreateWaitableTimer( NULL, FALSE, NULL );
1765*48a54d36SAndroid Build Coastguard Worker err = translate_errno( gSPSWakeupEvent, (mStatus) GetLastError(), kUnknownErr );
1766*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
1767*48a54d36SAndroid Build Coastguard Worker
1768*48a54d36SAndroid Build Coastguard Worker gSPSSleepEvent = CreateWaitableTimer( NULL, FALSE, NULL );
1769*48a54d36SAndroid Build Coastguard Worker err = translate_errno( gSPSSleepEvent, (mStatus) GetLastError(), kUnknownErr );
1770*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
1771*48a54d36SAndroid Build Coastguard Worker
1772*48a54d36SAndroid Build Coastguard Worker gUDSEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
1773*48a54d36SAndroid Build Coastguard Worker err = translate_errno( gUDSEvent, ( mStatus ) GetLastError(), kUnknownErr );
1774*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
1775*48a54d36SAndroid Build Coastguard Worker
1776*48a54d36SAndroid Build Coastguard Worker exit:
1777*48a54d36SAndroid Build Coastguard Worker if( err )
1778*48a54d36SAndroid Build Coastguard Worker {
1779*48a54d36SAndroid Build Coastguard Worker TearDownNotifications();
1780*48a54d36SAndroid Build Coastguard Worker }
1781*48a54d36SAndroid Build Coastguard Worker return( err );
1782*48a54d36SAndroid Build Coastguard Worker }
1783*48a54d36SAndroid Build Coastguard Worker
1784*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1785*48a54d36SAndroid Build Coastguard Worker // TearDownNotifications
1786*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1787*48a54d36SAndroid Build Coastguard Worker
TearDownNotifications()1788*48a54d36SAndroid Build Coastguard Worker mDNSlocal mStatus TearDownNotifications()
1789*48a54d36SAndroid Build Coastguard Worker {
1790*48a54d36SAndroid Build Coastguard Worker if ( gStopEvent )
1791*48a54d36SAndroid Build Coastguard Worker {
1792*48a54d36SAndroid Build Coastguard Worker CloseHandle( gStopEvent );
1793*48a54d36SAndroid Build Coastguard Worker gStopEvent = NULL;
1794*48a54d36SAndroid Build Coastguard Worker }
1795*48a54d36SAndroid Build Coastguard Worker
1796*48a54d36SAndroid Build Coastguard Worker if( IsValidSocket( gInterfaceListChangedSocket ) )
1797*48a54d36SAndroid Build Coastguard Worker {
1798*48a54d36SAndroid Build Coastguard Worker close_compat( gInterfaceListChangedSocket );
1799*48a54d36SAndroid Build Coastguard Worker gInterfaceListChangedSocket = kInvalidSocketRef;
1800*48a54d36SAndroid Build Coastguard Worker }
1801*48a54d36SAndroid Build Coastguard Worker
1802*48a54d36SAndroid Build Coastguard Worker if( gInterfaceListChangedEvent )
1803*48a54d36SAndroid Build Coastguard Worker {
1804*48a54d36SAndroid Build Coastguard Worker CloseHandle( gInterfaceListChangedEvent );
1805*48a54d36SAndroid Build Coastguard Worker gInterfaceListChangedEvent = 0;
1806*48a54d36SAndroid Build Coastguard Worker }
1807*48a54d36SAndroid Build Coastguard Worker
1808*48a54d36SAndroid Build Coastguard Worker if ( gDescChangedEvent != NULL )
1809*48a54d36SAndroid Build Coastguard Worker {
1810*48a54d36SAndroid Build Coastguard Worker CloseHandle( gDescChangedEvent );
1811*48a54d36SAndroid Build Coastguard Worker gDescChangedEvent = NULL;
1812*48a54d36SAndroid Build Coastguard Worker }
1813*48a54d36SAndroid Build Coastguard Worker
1814*48a54d36SAndroid Build Coastguard Worker if ( gDescKey != NULL )
1815*48a54d36SAndroid Build Coastguard Worker {
1816*48a54d36SAndroid Build Coastguard Worker RegCloseKey( gDescKey );
1817*48a54d36SAndroid Build Coastguard Worker gDescKey = NULL;
1818*48a54d36SAndroid Build Coastguard Worker }
1819*48a54d36SAndroid Build Coastguard Worker
1820*48a54d36SAndroid Build Coastguard Worker if ( gTcpipChangedEvent != NULL )
1821*48a54d36SAndroid Build Coastguard Worker {
1822*48a54d36SAndroid Build Coastguard Worker CloseHandle( gTcpipChangedEvent );
1823*48a54d36SAndroid Build Coastguard Worker gTcpipChangedEvent = NULL;
1824*48a54d36SAndroid Build Coastguard Worker }
1825*48a54d36SAndroid Build Coastguard Worker
1826*48a54d36SAndroid Build Coastguard Worker if ( gDdnsChangedEvent != NULL )
1827*48a54d36SAndroid Build Coastguard Worker {
1828*48a54d36SAndroid Build Coastguard Worker CloseHandle( gDdnsChangedEvent );
1829*48a54d36SAndroid Build Coastguard Worker gDdnsChangedEvent = NULL;
1830*48a54d36SAndroid Build Coastguard Worker }
1831*48a54d36SAndroid Build Coastguard Worker
1832*48a54d36SAndroid Build Coastguard Worker if ( gDdnsKey != NULL )
1833*48a54d36SAndroid Build Coastguard Worker {
1834*48a54d36SAndroid Build Coastguard Worker RegCloseKey( gDdnsKey );
1835*48a54d36SAndroid Build Coastguard Worker gDdnsKey = NULL;
1836*48a54d36SAndroid Build Coastguard Worker }
1837*48a54d36SAndroid Build Coastguard Worker
1838*48a54d36SAndroid Build Coastguard Worker if ( gFileSharingChangedEvent != NULL )
1839*48a54d36SAndroid Build Coastguard Worker {
1840*48a54d36SAndroid Build Coastguard Worker CloseHandle( gFileSharingChangedEvent );
1841*48a54d36SAndroid Build Coastguard Worker gFileSharingChangedEvent = NULL;
1842*48a54d36SAndroid Build Coastguard Worker }
1843*48a54d36SAndroid Build Coastguard Worker
1844*48a54d36SAndroid Build Coastguard Worker if ( gFileSharingKey != NULL )
1845*48a54d36SAndroid Build Coastguard Worker {
1846*48a54d36SAndroid Build Coastguard Worker RegCloseKey( gFileSharingKey );
1847*48a54d36SAndroid Build Coastguard Worker gFileSharingKey = NULL;
1848*48a54d36SAndroid Build Coastguard Worker }
1849*48a54d36SAndroid Build Coastguard Worker
1850*48a54d36SAndroid Build Coastguard Worker if ( gFirewallChangedEvent != NULL )
1851*48a54d36SAndroid Build Coastguard Worker {
1852*48a54d36SAndroid Build Coastguard Worker CloseHandle( gFirewallChangedEvent );
1853*48a54d36SAndroid Build Coastguard Worker gFirewallChangedEvent = NULL;
1854*48a54d36SAndroid Build Coastguard Worker }
1855*48a54d36SAndroid Build Coastguard Worker
1856*48a54d36SAndroid Build Coastguard Worker if ( gFirewallKey != NULL )
1857*48a54d36SAndroid Build Coastguard Worker {
1858*48a54d36SAndroid Build Coastguard Worker RegCloseKey( gFirewallKey );
1859*48a54d36SAndroid Build Coastguard Worker gFirewallKey = NULL;
1860*48a54d36SAndroid Build Coastguard Worker }
1861*48a54d36SAndroid Build Coastguard Worker
1862*48a54d36SAndroid Build Coastguard Worker if ( gAdvertisedServicesChangedEvent != NULL )
1863*48a54d36SAndroid Build Coastguard Worker {
1864*48a54d36SAndroid Build Coastguard Worker CloseHandle( gAdvertisedServicesChangedEvent );
1865*48a54d36SAndroid Build Coastguard Worker gAdvertisedServicesChangedEvent = NULL;
1866*48a54d36SAndroid Build Coastguard Worker }
1867*48a54d36SAndroid Build Coastguard Worker
1868*48a54d36SAndroid Build Coastguard Worker if ( gAdvertisedServicesKey != NULL )
1869*48a54d36SAndroid Build Coastguard Worker {
1870*48a54d36SAndroid Build Coastguard Worker RegCloseKey( gAdvertisedServicesKey );
1871*48a54d36SAndroid Build Coastguard Worker gAdvertisedServicesKey = NULL;
1872*48a54d36SAndroid Build Coastguard Worker }
1873*48a54d36SAndroid Build Coastguard Worker
1874*48a54d36SAndroid Build Coastguard Worker if ( gSPSWakeupEvent )
1875*48a54d36SAndroid Build Coastguard Worker {
1876*48a54d36SAndroid Build Coastguard Worker CloseHandle( gSPSWakeupEvent );
1877*48a54d36SAndroid Build Coastguard Worker gSPSWakeupEvent = NULL;
1878*48a54d36SAndroid Build Coastguard Worker }
1879*48a54d36SAndroid Build Coastguard Worker
1880*48a54d36SAndroid Build Coastguard Worker if ( gSPSSleepEvent )
1881*48a54d36SAndroid Build Coastguard Worker {
1882*48a54d36SAndroid Build Coastguard Worker CloseHandle( gSPSSleepEvent );
1883*48a54d36SAndroid Build Coastguard Worker gSPSSleepEvent = NULL;
1884*48a54d36SAndroid Build Coastguard Worker }
1885*48a54d36SAndroid Build Coastguard Worker
1886*48a54d36SAndroid Build Coastguard Worker return( mStatus_NoError );
1887*48a54d36SAndroid Build Coastguard Worker }
1888*48a54d36SAndroid Build Coastguard Worker
1889*48a54d36SAndroid Build Coastguard Worker
1890*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1891*48a54d36SAndroid Build Coastguard Worker // RegisterWaitableEvent
1892*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1893*48a54d36SAndroid Build Coastguard Worker
RegisterWaitableEvent(mDNS * const inMDNS,HANDLE event,void * context,RegisterWaitableEventHandler handler)1894*48a54d36SAndroid Build Coastguard Worker static mStatus RegisterWaitableEvent( mDNS * const inMDNS, HANDLE event, void * context, RegisterWaitableEventHandler handler )
1895*48a54d36SAndroid Build Coastguard Worker {
1896*48a54d36SAndroid Build Coastguard Worker EventSource * source;
1897*48a54d36SAndroid Build Coastguard Worker mStatus err = mStatus_NoError;
1898*48a54d36SAndroid Build Coastguard Worker
1899*48a54d36SAndroid Build Coastguard Worker ( void ) inMDNS;
1900*48a54d36SAndroid Build Coastguard Worker check( event );
1901*48a54d36SAndroid Build Coastguard Worker check( handler );
1902*48a54d36SAndroid Build Coastguard Worker
1903*48a54d36SAndroid Build Coastguard Worker source = ( EventSource* ) malloc( sizeof( EventSource ) );
1904*48a54d36SAndroid Build Coastguard Worker require_action( source, exit, err = mStatus_NoMemoryErr );
1905*48a54d36SAndroid Build Coastguard Worker mDNSPlatformMemZero( source, sizeof( EventSource ) );
1906*48a54d36SAndroid Build Coastguard Worker source->event = event;
1907*48a54d36SAndroid Build Coastguard Worker source->context = context;
1908*48a54d36SAndroid Build Coastguard Worker source->handler = handler;
1909*48a54d36SAndroid Build Coastguard Worker
1910*48a54d36SAndroid Build Coastguard Worker source->next = gEventSourceList;
1911*48a54d36SAndroid Build Coastguard Worker gEventSourceList = source;
1912*48a54d36SAndroid Build Coastguard Worker gEventSourceListChanged = TRUE;
1913*48a54d36SAndroid Build Coastguard Worker gEventSources++;
1914*48a54d36SAndroid Build Coastguard Worker
1915*48a54d36SAndroid Build Coastguard Worker exit:
1916*48a54d36SAndroid Build Coastguard Worker
1917*48a54d36SAndroid Build Coastguard Worker return err;
1918*48a54d36SAndroid Build Coastguard Worker }
1919*48a54d36SAndroid Build Coastguard Worker
1920*48a54d36SAndroid Build Coastguard Worker
1921*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1922*48a54d36SAndroid Build Coastguard Worker // UnregisterWaitableEvent
1923*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1924*48a54d36SAndroid Build Coastguard Worker
UnregisterWaitableEvent(mDNS * const inMDNS,HANDLE event)1925*48a54d36SAndroid Build Coastguard Worker static void UnregisterWaitableEvent( mDNS * const inMDNS, HANDLE event )
1926*48a54d36SAndroid Build Coastguard Worker {
1927*48a54d36SAndroid Build Coastguard Worker EventSource * current = gEventSourceList;
1928*48a54d36SAndroid Build Coastguard Worker EventSource * last = NULL;
1929*48a54d36SAndroid Build Coastguard Worker
1930*48a54d36SAndroid Build Coastguard Worker ( void ) inMDNS;
1931*48a54d36SAndroid Build Coastguard Worker check( event );
1932*48a54d36SAndroid Build Coastguard Worker
1933*48a54d36SAndroid Build Coastguard Worker while ( current )
1934*48a54d36SAndroid Build Coastguard Worker {
1935*48a54d36SAndroid Build Coastguard Worker if ( current->event == event )
1936*48a54d36SAndroid Build Coastguard Worker {
1937*48a54d36SAndroid Build Coastguard Worker if ( last == NULL )
1938*48a54d36SAndroid Build Coastguard Worker {
1939*48a54d36SAndroid Build Coastguard Worker gEventSourceList = current->next;
1940*48a54d36SAndroid Build Coastguard Worker }
1941*48a54d36SAndroid Build Coastguard Worker else
1942*48a54d36SAndroid Build Coastguard Worker {
1943*48a54d36SAndroid Build Coastguard Worker last->next = current->next;
1944*48a54d36SAndroid Build Coastguard Worker }
1945*48a54d36SAndroid Build Coastguard Worker
1946*48a54d36SAndroid Build Coastguard Worker gEventSourceListChanged = TRUE;
1947*48a54d36SAndroid Build Coastguard Worker
1948*48a54d36SAndroid Build Coastguard Worker // Protect against removing the node that we happen
1949*48a54d36SAndroid Build Coastguard Worker // to be looking at as we iterate through the event
1950*48a54d36SAndroid Build Coastguard Worker // source list in ServiceSpecificRun()
1951*48a54d36SAndroid Build Coastguard Worker
1952*48a54d36SAndroid Build Coastguard Worker if ( current == gCurrentSource )
1953*48a54d36SAndroid Build Coastguard Worker {
1954*48a54d36SAndroid Build Coastguard Worker gCurrentSource = current->next;
1955*48a54d36SAndroid Build Coastguard Worker }
1956*48a54d36SAndroid Build Coastguard Worker
1957*48a54d36SAndroid Build Coastguard Worker gEventSources--;
1958*48a54d36SAndroid Build Coastguard Worker free( current );
1959*48a54d36SAndroid Build Coastguard Worker
1960*48a54d36SAndroid Build Coastguard Worker break;
1961*48a54d36SAndroid Build Coastguard Worker }
1962*48a54d36SAndroid Build Coastguard Worker
1963*48a54d36SAndroid Build Coastguard Worker last = current;
1964*48a54d36SAndroid Build Coastguard Worker current = current->next;
1965*48a54d36SAndroid Build Coastguard Worker }
1966*48a54d36SAndroid Build Coastguard Worker }
1967*48a54d36SAndroid Build Coastguard Worker
1968*48a54d36SAndroid Build Coastguard Worker
1969*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1970*48a54d36SAndroid Build Coastguard Worker // SetupWaitList
1971*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
1972*48a54d36SAndroid Build Coastguard Worker
SetupWaitList(mDNS * const inMDNS,HANDLE ** outWaitList,int * outWaitListCount)1973*48a54d36SAndroid Build Coastguard Worker mDNSlocal mStatus SetupWaitList( mDNS * const inMDNS, HANDLE **outWaitList, int *outWaitListCount )
1974*48a54d36SAndroid Build Coastguard Worker {
1975*48a54d36SAndroid Build Coastguard Worker int waitListCount;
1976*48a54d36SAndroid Build Coastguard Worker HANDLE * waitList;
1977*48a54d36SAndroid Build Coastguard Worker HANDLE * waitItemPtr;
1978*48a54d36SAndroid Build Coastguard Worker EventSource * source;
1979*48a54d36SAndroid Build Coastguard Worker mStatus err;
1980*48a54d36SAndroid Build Coastguard Worker
1981*48a54d36SAndroid Build Coastguard Worker dlog( kDebugLevelTrace, DEBUG_NAME "setting up wait list\n" );
1982*48a54d36SAndroid Build Coastguard Worker
1983*48a54d36SAndroid Build Coastguard Worker ( void ) inMDNS;
1984*48a54d36SAndroid Build Coastguard Worker check( inMDNS->p );
1985*48a54d36SAndroid Build Coastguard Worker check( outWaitList );
1986*48a54d36SAndroid Build Coastguard Worker check( outWaitListCount );
1987*48a54d36SAndroid Build Coastguard Worker
1988*48a54d36SAndroid Build Coastguard Worker // Allocate an array to hold all the objects to wait on.
1989*48a54d36SAndroid Build Coastguard Worker
1990*48a54d36SAndroid Build Coastguard Worker waitListCount = kWaitListFixedItemCount + gEventSources;
1991*48a54d36SAndroid Build Coastguard Worker waitList = ( HANDLE* ) malloc( waitListCount * sizeof( *waitList ) );
1992*48a54d36SAndroid Build Coastguard Worker require_action( waitList, exit, err = mStatus_NoMemoryErr );
1993*48a54d36SAndroid Build Coastguard Worker waitItemPtr = waitList;
1994*48a54d36SAndroid Build Coastguard Worker
1995*48a54d36SAndroid Build Coastguard Worker // Add the fixed wait items to the beginning of the list.
1996*48a54d36SAndroid Build Coastguard Worker
1997*48a54d36SAndroid Build Coastguard Worker *waitItemPtr++ = gStopEvent;
1998*48a54d36SAndroid Build Coastguard Worker *waitItemPtr++ = gInterfaceListChangedEvent;
1999*48a54d36SAndroid Build Coastguard Worker *waitItemPtr++ = gDescChangedEvent;
2000*48a54d36SAndroid Build Coastguard Worker *waitItemPtr++ = gTcpipChangedEvent;
2001*48a54d36SAndroid Build Coastguard Worker *waitItemPtr++ = gDdnsChangedEvent;
2002*48a54d36SAndroid Build Coastguard Worker *waitItemPtr++ = gFileSharingChangedEvent;
2003*48a54d36SAndroid Build Coastguard Worker *waitItemPtr++ = gFirewallChangedEvent;
2004*48a54d36SAndroid Build Coastguard Worker *waitItemPtr++ = gAdvertisedServicesChangedEvent;
2005*48a54d36SAndroid Build Coastguard Worker *waitItemPtr++ = gSPSWakeupEvent;
2006*48a54d36SAndroid Build Coastguard Worker *waitItemPtr++ = gSPSSleepEvent;
2007*48a54d36SAndroid Build Coastguard Worker
2008*48a54d36SAndroid Build Coastguard Worker for ( source = gEventSourceList; source; source = source->next )
2009*48a54d36SAndroid Build Coastguard Worker {
2010*48a54d36SAndroid Build Coastguard Worker *waitItemPtr++ = source->event;
2011*48a54d36SAndroid Build Coastguard Worker }
2012*48a54d36SAndroid Build Coastguard Worker
2013*48a54d36SAndroid Build Coastguard Worker check( ( int )( waitItemPtr - waitList ) == waitListCount );
2014*48a54d36SAndroid Build Coastguard Worker
2015*48a54d36SAndroid Build Coastguard Worker *outWaitList = waitList;
2016*48a54d36SAndroid Build Coastguard Worker *outWaitListCount = waitListCount;
2017*48a54d36SAndroid Build Coastguard Worker waitList = NULL;
2018*48a54d36SAndroid Build Coastguard Worker err = mStatus_NoError;
2019*48a54d36SAndroid Build Coastguard Worker
2020*48a54d36SAndroid Build Coastguard Worker exit:
2021*48a54d36SAndroid Build Coastguard Worker
2022*48a54d36SAndroid Build Coastguard Worker if( waitList )
2023*48a54d36SAndroid Build Coastguard Worker {
2024*48a54d36SAndroid Build Coastguard Worker free( waitList );
2025*48a54d36SAndroid Build Coastguard Worker }
2026*48a54d36SAndroid Build Coastguard Worker
2027*48a54d36SAndroid Build Coastguard Worker dlog( kDebugLevelTrace, DEBUG_NAME "setting up wait list done (err=%d %m)\n", err, err );
2028*48a54d36SAndroid Build Coastguard Worker return( err );
2029*48a54d36SAndroid Build Coastguard Worker }
2030*48a54d36SAndroid Build Coastguard Worker
2031*48a54d36SAndroid Build Coastguard Worker
2032*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2033*48a54d36SAndroid Build Coastguard Worker // CoreCallback
2034*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2035*48a54d36SAndroid Build Coastguard Worker
2036*48a54d36SAndroid Build Coastguard Worker static void
CoreCallback(mDNS * const inMDNS,mStatus status)2037*48a54d36SAndroid Build Coastguard Worker CoreCallback(mDNS * const inMDNS, mStatus status)
2038*48a54d36SAndroid Build Coastguard Worker {
2039*48a54d36SAndroid Build Coastguard Worker if (status == mStatus_ConfigChanged)
2040*48a54d36SAndroid Build Coastguard Worker {
2041*48a54d36SAndroid Build Coastguard Worker SetLLRoute( inMDNS );
2042*48a54d36SAndroid Build Coastguard Worker }
2043*48a54d36SAndroid Build Coastguard Worker }
2044*48a54d36SAndroid Build Coastguard Worker
2045*48a54d36SAndroid Build Coastguard Worker
2046*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2047*48a54d36SAndroid Build Coastguard Worker // UDSCanAccept
2048*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2049*48a54d36SAndroid Build Coastguard Worker
UDSCanAccept(mDNS * const inMDNS,HANDLE event,void * context)2050*48a54d36SAndroid Build Coastguard Worker mDNSlocal void UDSCanAccept( mDNS * const inMDNS, HANDLE event, void * context )
2051*48a54d36SAndroid Build Coastguard Worker {
2052*48a54d36SAndroid Build Coastguard Worker ( void ) inMDNS;
2053*48a54d36SAndroid Build Coastguard Worker ( void ) event;
2054*48a54d36SAndroid Build Coastguard Worker
2055*48a54d36SAndroid Build Coastguard Worker if ( gUDSCallback )
2056*48a54d36SAndroid Build Coastguard Worker {
2057*48a54d36SAndroid Build Coastguard Worker gUDSCallback( ( int ) gUDSSocket, 0, context );
2058*48a54d36SAndroid Build Coastguard Worker }
2059*48a54d36SAndroid Build Coastguard Worker }
2060*48a54d36SAndroid Build Coastguard Worker
2061*48a54d36SAndroid Build Coastguard Worker
2062*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2063*48a54d36SAndroid Build Coastguard Worker // UDSCanRead
2064*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2065*48a54d36SAndroid Build Coastguard Worker
UDSCanRead(TCPSocket * sock)2066*48a54d36SAndroid Build Coastguard Worker mDNSlocal void UDSCanRead( TCPSocket * sock )
2067*48a54d36SAndroid Build Coastguard Worker {
2068*48a54d36SAndroid Build Coastguard Worker udsEventCallback callback = ( udsEventCallback ) sock->userCallback;
2069*48a54d36SAndroid Build Coastguard Worker
2070*48a54d36SAndroid Build Coastguard Worker if ( callback )
2071*48a54d36SAndroid Build Coastguard Worker {
2072*48a54d36SAndroid Build Coastguard Worker callback( (int) sock->fd, 0, sock->userContext );
2073*48a54d36SAndroid Build Coastguard Worker }
2074*48a54d36SAndroid Build Coastguard Worker }
2075*48a54d36SAndroid Build Coastguard Worker
2076*48a54d36SAndroid Build Coastguard Worker
2077*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2078*48a54d36SAndroid Build Coastguard Worker // udsSupportAddFDToEventLoop
2079*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2080*48a54d36SAndroid Build Coastguard Worker
2081*48a54d36SAndroid Build Coastguard Worker
2082*48a54d36SAndroid Build Coastguard Worker mStatus
udsSupportAddFDToEventLoop(SocketRef fd,udsEventCallback callback,void * context,void ** platform_data)2083*48a54d36SAndroid Build Coastguard Worker udsSupportAddFDToEventLoop( SocketRef fd, udsEventCallback callback, void *context, void **platform_data)
2084*48a54d36SAndroid Build Coastguard Worker {
2085*48a54d36SAndroid Build Coastguard Worker mStatus err = mStatus_NoError;
2086*48a54d36SAndroid Build Coastguard Worker
2087*48a54d36SAndroid Build Coastguard Worker // We are using some knowledge of what is being passed to us here. If the fd is a listen socket,
2088*48a54d36SAndroid Build Coastguard Worker // then the "callback" parameter is NULL. If it is an actual read/write socket, then the "callback"
2089*48a54d36SAndroid Build Coastguard Worker // parameter is not null. This is important because we use waitable events for the listen socket
2090*48a54d36SAndroid Build Coastguard Worker // and alertable I/O for the read/write sockets.
2091*48a54d36SAndroid Build Coastguard Worker
2092*48a54d36SAndroid Build Coastguard Worker if ( context )
2093*48a54d36SAndroid Build Coastguard Worker {
2094*48a54d36SAndroid Build Coastguard Worker TCPSocket * sock;
2095*48a54d36SAndroid Build Coastguard Worker
2096*48a54d36SAndroid Build Coastguard Worker sock = malloc( sizeof( TCPSocket ) );
2097*48a54d36SAndroid Build Coastguard Worker require_action( sock, exit, err = mStatus_NoMemoryErr );
2098*48a54d36SAndroid Build Coastguard Worker mDNSPlatformMemZero( sock, sizeof( TCPSocket ) );
2099*48a54d36SAndroid Build Coastguard Worker
2100*48a54d36SAndroid Build Coastguard Worker sock->fd = (SOCKET) fd;
2101*48a54d36SAndroid Build Coastguard Worker sock->readEventHandler = UDSCanRead;
2102*48a54d36SAndroid Build Coastguard Worker sock->userCallback = callback;
2103*48a54d36SAndroid Build Coastguard Worker sock->userContext = context;
2104*48a54d36SAndroid Build Coastguard Worker sock->m = &gMDNSRecord;
2105*48a54d36SAndroid Build Coastguard Worker
2106*48a54d36SAndroid Build Coastguard Worker err = TCPAddSocket( sock->m, sock );
2107*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
2108*48a54d36SAndroid Build Coastguard Worker
2109*48a54d36SAndroid Build Coastguard Worker *platform_data = sock;
2110*48a54d36SAndroid Build Coastguard Worker }
2111*48a54d36SAndroid Build Coastguard Worker else
2112*48a54d36SAndroid Build Coastguard Worker {
2113*48a54d36SAndroid Build Coastguard Worker gUDSSocket = fd;
2114*48a54d36SAndroid Build Coastguard Worker gUDSCallback = callback;
2115*48a54d36SAndroid Build Coastguard Worker gUDSEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
2116*48a54d36SAndroid Build Coastguard Worker err = translate_errno( gUDSEvent, (mStatus) GetLastError(), kUnknownErr );
2117*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
2118*48a54d36SAndroid Build Coastguard Worker err = WSAEventSelect( fd, gUDSEvent, FD_ACCEPT | FD_CLOSE );
2119*48a54d36SAndroid Build Coastguard Worker err = translate_errno( err == 0, WSAGetLastError(), kNoResourcesErr );
2120*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
2121*48a54d36SAndroid Build Coastguard Worker err = RegisterWaitableEvent( &gMDNSRecord, gUDSEvent, context, UDSCanAccept );
2122*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
2123*48a54d36SAndroid Build Coastguard Worker }
2124*48a54d36SAndroid Build Coastguard Worker
2125*48a54d36SAndroid Build Coastguard Worker exit:
2126*48a54d36SAndroid Build Coastguard Worker
2127*48a54d36SAndroid Build Coastguard Worker return err;
2128*48a54d36SAndroid Build Coastguard Worker }
2129*48a54d36SAndroid Build Coastguard Worker
2130*48a54d36SAndroid Build Coastguard Worker
2131*48a54d36SAndroid Build Coastguard Worker int
udsSupportReadFD(SocketRef fd,char * buf,int len,int flags,void * platform_data)2132*48a54d36SAndroid Build Coastguard Worker udsSupportReadFD( SocketRef fd, char *buf, int len, int flags, void *platform_data )
2133*48a54d36SAndroid Build Coastguard Worker {
2134*48a54d36SAndroid Build Coastguard Worker TCPSocket * sock;
2135*48a54d36SAndroid Build Coastguard Worker mDNSBool closed;
2136*48a54d36SAndroid Build Coastguard Worker int ret;
2137*48a54d36SAndroid Build Coastguard Worker
2138*48a54d36SAndroid Build Coastguard Worker ( void ) flags;
2139*48a54d36SAndroid Build Coastguard Worker
2140*48a54d36SAndroid Build Coastguard Worker sock = ( TCPSocket* ) platform_data;
2141*48a54d36SAndroid Build Coastguard Worker require_action( sock, exit, ret = -1 );
2142*48a54d36SAndroid Build Coastguard Worker require_action( sock->fd == fd, exit, ret = -1 );
2143*48a54d36SAndroid Build Coastguard Worker
2144*48a54d36SAndroid Build Coastguard Worker ret = mDNSPlatformReadTCP( sock, buf, len, &closed );
2145*48a54d36SAndroid Build Coastguard Worker
2146*48a54d36SAndroid Build Coastguard Worker if ( closed )
2147*48a54d36SAndroid Build Coastguard Worker {
2148*48a54d36SAndroid Build Coastguard Worker ret = 0;
2149*48a54d36SAndroid Build Coastguard Worker }
2150*48a54d36SAndroid Build Coastguard Worker
2151*48a54d36SAndroid Build Coastguard Worker exit:
2152*48a54d36SAndroid Build Coastguard Worker
2153*48a54d36SAndroid Build Coastguard Worker return ret;
2154*48a54d36SAndroid Build Coastguard Worker }
2155*48a54d36SAndroid Build Coastguard Worker
2156*48a54d36SAndroid Build Coastguard Worker
2157*48a54d36SAndroid Build Coastguard Worker mStatus
udsSupportRemoveFDFromEventLoop(SocketRef fd,void * platform_data)2158*48a54d36SAndroid Build Coastguard Worker udsSupportRemoveFDFromEventLoop( SocketRef fd, void *platform_data) // Note: This also CLOSES the socket
2159*48a54d36SAndroid Build Coastguard Worker {
2160*48a54d36SAndroid Build Coastguard Worker mStatus err = kNoErr;
2161*48a54d36SAndroid Build Coastguard Worker
2162*48a54d36SAndroid Build Coastguard Worker if ( platform_data != NULL )
2163*48a54d36SAndroid Build Coastguard Worker {
2164*48a54d36SAndroid Build Coastguard Worker TCPSocket * sock;
2165*48a54d36SAndroid Build Coastguard Worker
2166*48a54d36SAndroid Build Coastguard Worker dlog( kDebugLevelInfo, DEBUG_NAME "session closed\n" );
2167*48a54d36SAndroid Build Coastguard Worker sock = ( TCPSocket* ) platform_data;
2168*48a54d36SAndroid Build Coastguard Worker check( sock->fd == fd );
2169*48a54d36SAndroid Build Coastguard Worker mDNSPlatformTCPCloseConnection( sock );
2170*48a54d36SAndroid Build Coastguard Worker }
2171*48a54d36SAndroid Build Coastguard Worker else if ( gUDSEvent != NULL )
2172*48a54d36SAndroid Build Coastguard Worker {
2173*48a54d36SAndroid Build Coastguard Worker UnregisterWaitableEvent( &gMDNSRecord, gUDSEvent );
2174*48a54d36SAndroid Build Coastguard Worker WSAEventSelect( fd, gUDSEvent, 0 );
2175*48a54d36SAndroid Build Coastguard Worker CloseHandle( gUDSEvent );
2176*48a54d36SAndroid Build Coastguard Worker gUDSEvent = NULL;
2177*48a54d36SAndroid Build Coastguard Worker }
2178*48a54d36SAndroid Build Coastguard Worker
2179*48a54d36SAndroid Build Coastguard Worker return err;
2180*48a54d36SAndroid Build Coastguard Worker }
2181*48a54d36SAndroid Build Coastguard Worker
2182*48a54d36SAndroid Build Coastguard Worker
RecordUpdatedNiceLabel(mDNS * const m,mDNSs32 delay)2183*48a54d36SAndroid Build Coastguard Worker mDNSexport void RecordUpdatedNiceLabel(mDNS *const m, mDNSs32 delay)
2184*48a54d36SAndroid Build Coastguard Worker {
2185*48a54d36SAndroid Build Coastguard Worker (void)m;
2186*48a54d36SAndroid Build Coastguard Worker (void)delay;
2187*48a54d36SAndroid Build Coastguard Worker // No-op, for now
2188*48a54d36SAndroid Build Coastguard Worker }
2189*48a54d36SAndroid Build Coastguard Worker
2190*48a54d36SAndroid Build Coastguard Worker
2191*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2192*48a54d36SAndroid Build Coastguard Worker // SystemWakeForNetworkAccess
2193*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2194*48a54d36SAndroid Build Coastguard Worker
2195*48a54d36SAndroid Build Coastguard Worker mDNSu8
SystemWakeForNetworkAccess(LARGE_INTEGER * timeout)2196*48a54d36SAndroid Build Coastguard Worker SystemWakeForNetworkAccess( LARGE_INTEGER * timeout )
2197*48a54d36SAndroid Build Coastguard Worker {
2198*48a54d36SAndroid Build Coastguard Worker HKEY key = NULL;
2199*48a54d36SAndroid Build Coastguard Worker DWORD dwSize;
2200*48a54d36SAndroid Build Coastguard Worker DWORD enabled;
2201*48a54d36SAndroid Build Coastguard Worker mDNSu8 ok;
2202*48a54d36SAndroid Build Coastguard Worker SYSTEM_POWER_STATUS powerStatus;
2203*48a54d36SAndroid Build Coastguard Worker time_t startTime;
2204*48a54d36SAndroid Build Coastguard Worker time_t nextWakeupTime;
2205*48a54d36SAndroid Build Coastguard Worker int delta;
2206*48a54d36SAndroid Build Coastguard Worker DWORD err;
2207*48a54d36SAndroid Build Coastguard Worker
2208*48a54d36SAndroid Build Coastguard Worker dlog( kDebugLevelInfo, DEBUG_NAME "SystemWakeForNetworkAccess\n" );
2209*48a54d36SAndroid Build Coastguard Worker
2210*48a54d36SAndroid Build Coastguard Worker // Make sure we have a timer
2211*48a54d36SAndroid Build Coastguard Worker
2212*48a54d36SAndroid Build Coastguard Worker require_action( gSPSWakeupEvent != NULL, exit, ok = FALSE );
2213*48a54d36SAndroid Build Coastguard Worker require_action( gSPSSleepEvent != NULL, exit, ok = FALSE );
2214*48a54d36SAndroid Build Coastguard Worker
2215*48a54d36SAndroid Build Coastguard Worker // Make sure the user enabled bonjour sleep proxy client
2216*48a54d36SAndroid Build Coastguard Worker
2217*48a54d36SAndroid Build Coastguard Worker err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode L"\\Power Management", &key );
2218*48a54d36SAndroid Build Coastguard Worker require_action( !err, exit, ok = FALSE );
2219*48a54d36SAndroid Build Coastguard Worker dwSize = sizeof( DWORD );
2220*48a54d36SAndroid Build Coastguard Worker err = RegQueryValueEx( key, L"Enabled", NULL, NULL, (LPBYTE) &enabled, &dwSize );
2221*48a54d36SAndroid Build Coastguard Worker require_action( !err, exit, ok = FALSE );
2222*48a54d36SAndroid Build Coastguard Worker require_action( enabled, exit, ok = FALSE );
2223*48a54d36SAndroid Build Coastguard Worker
2224*48a54d36SAndroid Build Coastguard Worker // Make sure machine is on AC power
2225*48a54d36SAndroid Build Coastguard Worker
2226*48a54d36SAndroid Build Coastguard Worker ok = ( mDNSu8 ) GetSystemPowerStatus( &powerStatus );
2227*48a54d36SAndroid Build Coastguard Worker require_action( ok, exit, ok = FALSE );
2228*48a54d36SAndroid Build Coastguard Worker require_action( powerStatus.ACLineStatus == AC_LINE_ONLINE, exit, ok = FALSE );
2229*48a54d36SAndroid Build Coastguard Worker
2230*48a54d36SAndroid Build Coastguard Worker // Now make sure we have a network interface that does wake-on-lan
2231*48a54d36SAndroid Build Coastguard Worker
2232*48a54d36SAndroid Build Coastguard Worker ok = ( mDNSu8 ) IsWOMPEnabled( &gMDNSRecord );
2233*48a54d36SAndroid Build Coastguard Worker require_action( ok, exit, ok = FALSE );
2234*48a54d36SAndroid Build Coastguard Worker
2235*48a54d36SAndroid Build Coastguard Worker // Now make sure we have advertised services. Doesn't make sense to
2236*48a54d36SAndroid Build Coastguard Worker // enable sleep proxy if we have no multicast services that could
2237*48a54d36SAndroid Build Coastguard Worker // potentially wake us up.
2238*48a54d36SAndroid Build Coastguard Worker
2239*48a54d36SAndroid Build Coastguard Worker ok = ( mDNSu8 ) mDNSCoreHaveAdvertisedMulticastServices( &gMDNSRecord );
2240*48a54d36SAndroid Build Coastguard Worker require_action( ok, exit, ok = FALSE );
2241*48a54d36SAndroid Build Coastguard Worker
2242*48a54d36SAndroid Build Coastguard Worker // Calculate next wake up time
2243*48a54d36SAndroid Build Coastguard Worker
2244*48a54d36SAndroid Build Coastguard Worker startTime = time( NULL ); // Seconds since midnight January 1, 1970
2245*48a54d36SAndroid Build Coastguard Worker nextWakeupTime = startTime + ( 120 * 60 ); // 2 hours later
2246*48a54d36SAndroid Build Coastguard Worker
2247*48a54d36SAndroid Build Coastguard Worker if ( gMDNSRecord.p->nextDHCPLeaseExpires < nextWakeupTime )
2248*48a54d36SAndroid Build Coastguard Worker {
2249*48a54d36SAndroid Build Coastguard Worker nextWakeupTime = gMDNSRecord.p->nextDHCPLeaseExpires;
2250*48a54d36SAndroid Build Coastguard Worker }
2251*48a54d36SAndroid Build Coastguard Worker
2252*48a54d36SAndroid Build Coastguard Worker // Finally calculate the next relative wakeup time
2253*48a54d36SAndroid Build Coastguard Worker
2254*48a54d36SAndroid Build Coastguard Worker delta = ( int )( ( ( double )( nextWakeupTime - startTime ) ) * 0.9 );
2255*48a54d36SAndroid Build Coastguard Worker ReportStatus( EVENTLOG_INFORMATION_TYPE, "enabling sleep proxy client with next maintenance wake in %d seconds", delta );
2256*48a54d36SAndroid Build Coastguard Worker
2257*48a54d36SAndroid Build Coastguard Worker // Convert seconds to 100 nanosecond units expected by SetWaitableTimer
2258*48a54d36SAndroid Build Coastguard Worker
2259*48a54d36SAndroid Build Coastguard Worker timeout->QuadPart = -delta;
2260*48a54d36SAndroid Build Coastguard Worker timeout->QuadPart *= kSecondsTo100NSUnits;
2261*48a54d36SAndroid Build Coastguard Worker
2262*48a54d36SAndroid Build Coastguard Worker ok = TRUE;
2263*48a54d36SAndroid Build Coastguard Worker
2264*48a54d36SAndroid Build Coastguard Worker exit:
2265*48a54d36SAndroid Build Coastguard Worker
2266*48a54d36SAndroid Build Coastguard Worker if ( key )
2267*48a54d36SAndroid Build Coastguard Worker {
2268*48a54d36SAndroid Build Coastguard Worker RegCloseKey( key );
2269*48a54d36SAndroid Build Coastguard Worker }
2270*48a54d36SAndroid Build Coastguard Worker
2271*48a54d36SAndroid Build Coastguard Worker return ok;
2272*48a54d36SAndroid Build Coastguard Worker }
2273*48a54d36SAndroid Build Coastguard Worker
2274*48a54d36SAndroid Build Coastguard Worker
2275*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2276*48a54d36SAndroid Build Coastguard Worker // HaveRoute
2277*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2278*48a54d36SAndroid Build Coastguard Worker
2279*48a54d36SAndroid Build Coastguard Worker static bool
HaveRoute(PMIB_IPFORWARDROW rowExtant,unsigned long addr,unsigned long metric)2280*48a54d36SAndroid Build Coastguard Worker HaveRoute( PMIB_IPFORWARDROW rowExtant, unsigned long addr, unsigned long metric )
2281*48a54d36SAndroid Build Coastguard Worker {
2282*48a54d36SAndroid Build Coastguard Worker PMIB_IPFORWARDTABLE pIpForwardTable = NULL;
2283*48a54d36SAndroid Build Coastguard Worker DWORD dwSize = 0;
2284*48a54d36SAndroid Build Coastguard Worker BOOL bOrder = FALSE;
2285*48a54d36SAndroid Build Coastguard Worker OSStatus err;
2286*48a54d36SAndroid Build Coastguard Worker bool found = false;
2287*48a54d36SAndroid Build Coastguard Worker unsigned long int i;
2288*48a54d36SAndroid Build Coastguard Worker
2289*48a54d36SAndroid Build Coastguard Worker //
2290*48a54d36SAndroid Build Coastguard Worker // Find out how big our buffer needs to be.
2291*48a54d36SAndroid Build Coastguard Worker //
2292*48a54d36SAndroid Build Coastguard Worker err = GetIpForwardTable(NULL, &dwSize, bOrder);
2293*48a54d36SAndroid Build Coastguard Worker require_action( err == ERROR_INSUFFICIENT_BUFFER, exit, err = kUnknownErr );
2294*48a54d36SAndroid Build Coastguard Worker
2295*48a54d36SAndroid Build Coastguard Worker //
2296*48a54d36SAndroid Build Coastguard Worker // Allocate the memory for the table
2297*48a54d36SAndroid Build Coastguard Worker //
2298*48a54d36SAndroid Build Coastguard Worker pIpForwardTable = (PMIB_IPFORWARDTABLE) malloc( dwSize );
2299*48a54d36SAndroid Build Coastguard Worker require_action( pIpForwardTable, exit, err = kNoMemoryErr );
2300*48a54d36SAndroid Build Coastguard Worker
2301*48a54d36SAndroid Build Coastguard Worker //
2302*48a54d36SAndroid Build Coastguard Worker // Now get the table.
2303*48a54d36SAndroid Build Coastguard Worker //
2304*48a54d36SAndroid Build Coastguard Worker err = GetIpForwardTable(pIpForwardTable, &dwSize, bOrder);
2305*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
2306*48a54d36SAndroid Build Coastguard Worker
2307*48a54d36SAndroid Build Coastguard Worker //
2308*48a54d36SAndroid Build Coastguard Worker // Search for the row in the table we want.
2309*48a54d36SAndroid Build Coastguard Worker //
2310*48a54d36SAndroid Build Coastguard Worker for ( i = 0; i < pIpForwardTable->dwNumEntries; i++)
2311*48a54d36SAndroid Build Coastguard Worker {
2312*48a54d36SAndroid Build Coastguard Worker if ( ( pIpForwardTable->table[i].dwForwardDest == addr ) && ( !metric || ( pIpForwardTable->table[i].dwForwardMetric1 == metric ) ) )
2313*48a54d36SAndroid Build Coastguard Worker {
2314*48a54d36SAndroid Build Coastguard Worker memcpy( rowExtant, &(pIpForwardTable->table[i]), sizeof(*rowExtant) );
2315*48a54d36SAndroid Build Coastguard Worker found = true;
2316*48a54d36SAndroid Build Coastguard Worker break;
2317*48a54d36SAndroid Build Coastguard Worker }
2318*48a54d36SAndroid Build Coastguard Worker }
2319*48a54d36SAndroid Build Coastguard Worker
2320*48a54d36SAndroid Build Coastguard Worker exit:
2321*48a54d36SAndroid Build Coastguard Worker
2322*48a54d36SAndroid Build Coastguard Worker if ( pIpForwardTable != NULL )
2323*48a54d36SAndroid Build Coastguard Worker {
2324*48a54d36SAndroid Build Coastguard Worker free(pIpForwardTable);
2325*48a54d36SAndroid Build Coastguard Worker }
2326*48a54d36SAndroid Build Coastguard Worker
2327*48a54d36SAndroid Build Coastguard Worker return found;
2328*48a54d36SAndroid Build Coastguard Worker }
2329*48a54d36SAndroid Build Coastguard Worker
2330*48a54d36SAndroid Build Coastguard Worker
2331*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2332*48a54d36SAndroid Build Coastguard Worker // IsValidAddress
2333*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2334*48a54d36SAndroid Build Coastguard Worker
2335*48a54d36SAndroid Build Coastguard Worker static bool
IsValidAddress(const char * addr)2336*48a54d36SAndroid Build Coastguard Worker IsValidAddress( const char * addr )
2337*48a54d36SAndroid Build Coastguard Worker {
2338*48a54d36SAndroid Build Coastguard Worker return ( addr && ( strcmp( addr, "0.0.0.0" ) != 0 ) ) ? true : false;
2339*48a54d36SAndroid Build Coastguard Worker }
2340*48a54d36SAndroid Build Coastguard Worker
2341*48a54d36SAndroid Build Coastguard Worker
2342*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2343*48a54d36SAndroid Build Coastguard Worker // GetAdditionalMetric
2344*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2345*48a54d36SAndroid Build Coastguard Worker
2346*48a54d36SAndroid Build Coastguard Worker static ULONG
GetAdditionalMetric(DWORD ifIndex)2347*48a54d36SAndroid Build Coastguard Worker GetAdditionalMetric( DWORD ifIndex )
2348*48a54d36SAndroid Build Coastguard Worker {
2349*48a54d36SAndroid Build Coastguard Worker ULONG metric = 0;
2350*48a54d36SAndroid Build Coastguard Worker
2351*48a54d36SAndroid Build Coastguard Worker if( !gIPHelperLibraryInstance )
2352*48a54d36SAndroid Build Coastguard Worker {
2353*48a54d36SAndroid Build Coastguard Worker gIPHelperLibraryInstance = LoadLibrary( TEXT( "Iphlpapi" ) );
2354*48a54d36SAndroid Build Coastguard Worker
2355*48a54d36SAndroid Build Coastguard Worker gGetIpInterfaceEntryFunctionPtr =
2356*48a54d36SAndroid Build Coastguard Worker (GetIpInterfaceEntryFunctionPtr) GetProcAddress( gIPHelperLibraryInstance, "GetIpInterfaceEntry" );
2357*48a54d36SAndroid Build Coastguard Worker
2358*48a54d36SAndroid Build Coastguard Worker if( !gGetIpInterfaceEntryFunctionPtr )
2359*48a54d36SAndroid Build Coastguard Worker {
2360*48a54d36SAndroid Build Coastguard Worker BOOL ok;
2361*48a54d36SAndroid Build Coastguard Worker
2362*48a54d36SAndroid Build Coastguard Worker ok = FreeLibrary( gIPHelperLibraryInstance );
2363*48a54d36SAndroid Build Coastguard Worker check_translated_errno( ok, GetLastError(), kUnknownErr );
2364*48a54d36SAndroid Build Coastguard Worker gIPHelperLibraryInstance = NULL;
2365*48a54d36SAndroid Build Coastguard Worker }
2366*48a54d36SAndroid Build Coastguard Worker }
2367*48a54d36SAndroid Build Coastguard Worker
2368*48a54d36SAndroid Build Coastguard Worker if ( gGetIpInterfaceEntryFunctionPtr )
2369*48a54d36SAndroid Build Coastguard Worker {
2370*48a54d36SAndroid Build Coastguard Worker MIB_IPINTERFACE_ROW row;
2371*48a54d36SAndroid Build Coastguard Worker DWORD err;
2372*48a54d36SAndroid Build Coastguard Worker
2373*48a54d36SAndroid Build Coastguard Worker ZeroMemory( &row, sizeof( MIB_IPINTERFACE_ROW ) );
2374*48a54d36SAndroid Build Coastguard Worker row.Family = AF_INET;
2375*48a54d36SAndroid Build Coastguard Worker row.InterfaceIndex = ifIndex;
2376*48a54d36SAndroid Build Coastguard Worker err = gGetIpInterfaceEntryFunctionPtr( &row );
2377*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
2378*48a54d36SAndroid Build Coastguard Worker metric = row.Metric + 256;
2379*48a54d36SAndroid Build Coastguard Worker }
2380*48a54d36SAndroid Build Coastguard Worker
2381*48a54d36SAndroid Build Coastguard Worker exit:
2382*48a54d36SAndroid Build Coastguard Worker
2383*48a54d36SAndroid Build Coastguard Worker return metric;
2384*48a54d36SAndroid Build Coastguard Worker }
2385*48a54d36SAndroid Build Coastguard Worker
2386*48a54d36SAndroid Build Coastguard Worker
2387*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2388*48a54d36SAndroid Build Coastguard Worker // SetLLRoute
2389*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2390*48a54d36SAndroid Build Coastguard Worker
2391*48a54d36SAndroid Build Coastguard Worker static OSStatus
SetLLRoute(mDNS * const inMDNS)2392*48a54d36SAndroid Build Coastguard Worker SetLLRoute( mDNS * const inMDNS )
2393*48a54d36SAndroid Build Coastguard Worker {
2394*48a54d36SAndroid Build Coastguard Worker OSStatus err = kNoErr;
2395*48a54d36SAndroid Build Coastguard Worker
2396*48a54d36SAndroid Build Coastguard Worker DEBUG_UNUSED( inMDNS );
2397*48a54d36SAndroid Build Coastguard Worker
2398*48a54d36SAndroid Build Coastguard Worker //
2399*48a54d36SAndroid Build Coastguard Worker // <rdar://problem/4096464> Don't call SetLLRoute on loopback
2400*48a54d36SAndroid Build Coastguard Worker // <rdar://problem/6885843> Default route on Windows 7 breaks network connectivity
2401*48a54d36SAndroid Build Coastguard Worker //
2402*48a54d36SAndroid Build Coastguard Worker // Don't mess w/ the routing table on Vista and later OSes, as
2403*48a54d36SAndroid Build Coastguard Worker // they have a permanent route to link-local addresses. Otherwise,
2404*48a54d36SAndroid Build Coastguard Worker // set a route to link local addresses (169.254.0.0)
2405*48a54d36SAndroid Build Coastguard Worker //
2406*48a54d36SAndroid Build Coastguard Worker if ( ( gOSMajorVersion < 6 ) && gServiceManageLLRouting && !gPlatformStorage.registeredLoopback4 )
2407*48a54d36SAndroid Build Coastguard Worker {
2408*48a54d36SAndroid Build Coastguard Worker DWORD ifIndex;
2409*48a54d36SAndroid Build Coastguard Worker MIB_IPFORWARDROW rowExtant;
2410*48a54d36SAndroid Build Coastguard Worker bool addRoute;
2411*48a54d36SAndroid Build Coastguard Worker MIB_IPFORWARDROW row;
2412*48a54d36SAndroid Build Coastguard Worker
2413*48a54d36SAndroid Build Coastguard Worker ZeroMemory(&row, sizeof(row));
2414*48a54d36SAndroid Build Coastguard Worker
2415*48a54d36SAndroid Build Coastguard Worker err = GetRouteDestination(&ifIndex, &row.dwForwardNextHop);
2416*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
2417*48a54d36SAndroid Build Coastguard Worker row.dwForwardDest = inet_addr(kLLNetworkAddr);
2418*48a54d36SAndroid Build Coastguard Worker row.dwForwardIfIndex = ifIndex;
2419*48a54d36SAndroid Build Coastguard Worker row.dwForwardMask = inet_addr(kLLNetworkAddrMask);
2420*48a54d36SAndroid Build Coastguard Worker row.dwForwardType = 3;
2421*48a54d36SAndroid Build Coastguard Worker row.dwForwardProto = MIB_IPPROTO_NETMGMT;
2422*48a54d36SAndroid Build Coastguard Worker row.dwForwardAge = 0;
2423*48a54d36SAndroid Build Coastguard Worker row.dwForwardPolicy = 0;
2424*48a54d36SAndroid Build Coastguard Worker row.dwForwardMetric1 = 20 + GetAdditionalMetric( ifIndex );
2425*48a54d36SAndroid Build Coastguard Worker row.dwForwardMetric2 = (DWORD) - 1;
2426*48a54d36SAndroid Build Coastguard Worker row.dwForwardMetric3 = (DWORD) - 1;
2427*48a54d36SAndroid Build Coastguard Worker row.dwForwardMetric4 = (DWORD) - 1;
2428*48a54d36SAndroid Build Coastguard Worker row.dwForwardMetric5 = (DWORD) - 1;
2429*48a54d36SAndroid Build Coastguard Worker
2430*48a54d36SAndroid Build Coastguard Worker addRoute = true;
2431*48a54d36SAndroid Build Coastguard Worker
2432*48a54d36SAndroid Build Coastguard Worker //
2433*48a54d36SAndroid Build Coastguard Worker // check to make sure we don't already have a route
2434*48a54d36SAndroid Build Coastguard Worker //
2435*48a54d36SAndroid Build Coastguard Worker if ( HaveRoute( &rowExtant, inet_addr( kLLNetworkAddr ), 0 ) )
2436*48a54d36SAndroid Build Coastguard Worker {
2437*48a54d36SAndroid Build Coastguard Worker //
2438*48a54d36SAndroid Build Coastguard Worker // set the age to 0 so that we can do a memcmp.
2439*48a54d36SAndroid Build Coastguard Worker //
2440*48a54d36SAndroid Build Coastguard Worker rowExtant.dwForwardAge = 0;
2441*48a54d36SAndroid Build Coastguard Worker
2442*48a54d36SAndroid Build Coastguard Worker //
2443*48a54d36SAndroid Build Coastguard Worker // check to see if this route is the same as our route
2444*48a54d36SAndroid Build Coastguard Worker //
2445*48a54d36SAndroid Build Coastguard Worker if (memcmp(&row, &rowExtant, sizeof(row)) != 0)
2446*48a54d36SAndroid Build Coastguard Worker {
2447*48a54d36SAndroid Build Coastguard Worker //
2448*48a54d36SAndroid Build Coastguard Worker // if it isn't then delete this entry
2449*48a54d36SAndroid Build Coastguard Worker //
2450*48a54d36SAndroid Build Coastguard Worker DeleteIpForwardEntry(&rowExtant);
2451*48a54d36SAndroid Build Coastguard Worker }
2452*48a54d36SAndroid Build Coastguard Worker else
2453*48a54d36SAndroid Build Coastguard Worker {
2454*48a54d36SAndroid Build Coastguard Worker //
2455*48a54d36SAndroid Build Coastguard Worker // else it is, so we don't want to create another route
2456*48a54d36SAndroid Build Coastguard Worker //
2457*48a54d36SAndroid Build Coastguard Worker addRoute = false;
2458*48a54d36SAndroid Build Coastguard Worker }
2459*48a54d36SAndroid Build Coastguard Worker }
2460*48a54d36SAndroid Build Coastguard Worker
2461*48a54d36SAndroid Build Coastguard Worker if (addRoute && row.dwForwardNextHop)
2462*48a54d36SAndroid Build Coastguard Worker {
2463*48a54d36SAndroid Build Coastguard Worker err = CreateIpForwardEntry(&row);
2464*48a54d36SAndroid Build Coastguard Worker check_noerr( err );
2465*48a54d36SAndroid Build Coastguard Worker }
2466*48a54d36SAndroid Build Coastguard Worker }
2467*48a54d36SAndroid Build Coastguard Worker
2468*48a54d36SAndroid Build Coastguard Worker exit:
2469*48a54d36SAndroid Build Coastguard Worker
2470*48a54d36SAndroid Build Coastguard Worker return ( err );
2471*48a54d36SAndroid Build Coastguard Worker }
2472*48a54d36SAndroid Build Coastguard Worker
2473*48a54d36SAndroid Build Coastguard Worker
2474*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2475*48a54d36SAndroid Build Coastguard Worker // GetRouteDestination
2476*48a54d36SAndroid Build Coastguard Worker //===========================================================================================================================
2477*48a54d36SAndroid Build Coastguard Worker
2478*48a54d36SAndroid Build Coastguard Worker static OSStatus
GetRouteDestination(DWORD * ifIndex,DWORD * address)2479*48a54d36SAndroid Build Coastguard Worker GetRouteDestination(DWORD * ifIndex, DWORD * address)
2480*48a54d36SAndroid Build Coastguard Worker {
2481*48a54d36SAndroid Build Coastguard Worker struct in_addr ia;
2482*48a54d36SAndroid Build Coastguard Worker IP_ADAPTER_INFO * pAdapterInfo = NULL;
2483*48a54d36SAndroid Build Coastguard Worker IP_ADAPTER_INFO * pAdapter = NULL;
2484*48a54d36SAndroid Build Coastguard Worker ULONG bufLen;
2485*48a54d36SAndroid Build Coastguard Worker mDNSBool done = mDNSfalse;
2486*48a54d36SAndroid Build Coastguard Worker OSStatus err;
2487*48a54d36SAndroid Build Coastguard Worker
2488*48a54d36SAndroid Build Coastguard Worker //
2489*48a54d36SAndroid Build Coastguard Worker // GetBestInterface will fail if there is no default gateway
2490*48a54d36SAndroid Build Coastguard Worker // configured. If that happens, we will just take the first
2491*48a54d36SAndroid Build Coastguard Worker // interface in the list. MSDN support says there is no surefire
2492*48a54d36SAndroid Build Coastguard Worker // way to manually determine what the best interface might
2493*48a54d36SAndroid Build Coastguard Worker // be for a particular network address.
2494*48a54d36SAndroid Build Coastguard Worker //
2495*48a54d36SAndroid Build Coastguard Worker ia.s_addr = inet_addr(kLLNetworkAddr);
2496*48a54d36SAndroid Build Coastguard Worker err = GetBestInterface(*(IPAddr*) &ia, ifIndex);
2497*48a54d36SAndroid Build Coastguard Worker
2498*48a54d36SAndroid Build Coastguard Worker if (err)
2499*48a54d36SAndroid Build Coastguard Worker {
2500*48a54d36SAndroid Build Coastguard Worker *ifIndex = 0;
2501*48a54d36SAndroid Build Coastguard Worker }
2502*48a54d36SAndroid Build Coastguard Worker
2503*48a54d36SAndroid Build Coastguard Worker //
2504*48a54d36SAndroid Build Coastguard Worker // Make an initial call to GetAdaptersInfo to get
2505*48a54d36SAndroid Build Coastguard Worker // the necessary size into the bufLen variable
2506*48a54d36SAndroid Build Coastguard Worker //
2507*48a54d36SAndroid Build Coastguard Worker err = GetAdaptersInfo( NULL, &bufLen);
2508*48a54d36SAndroid Build Coastguard Worker require_action( err == ERROR_BUFFER_OVERFLOW, exit, err = kUnknownErr );
2509*48a54d36SAndroid Build Coastguard Worker
2510*48a54d36SAndroid Build Coastguard Worker pAdapterInfo = (IP_ADAPTER_INFO*) malloc( bufLen );
2511*48a54d36SAndroid Build Coastguard Worker require_action( pAdapterInfo, exit, err = kNoMemoryErr );
2512*48a54d36SAndroid Build Coastguard Worker
2513*48a54d36SAndroid Build Coastguard Worker err = GetAdaptersInfo( pAdapterInfo, &bufLen);
2514*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
2515*48a54d36SAndroid Build Coastguard Worker
2516*48a54d36SAndroid Build Coastguard Worker pAdapter = pAdapterInfo;
2517*48a54d36SAndroid Build Coastguard Worker err = kUnknownErr;
2518*48a54d36SAndroid Build Coastguard Worker
2519*48a54d36SAndroid Build Coastguard Worker // <rdar://problem/3718122>
2520*48a54d36SAndroid Build Coastguard Worker // <rdar://problem/5652098>
2521*48a54d36SAndroid Build Coastguard Worker //
2522*48a54d36SAndroid Build Coastguard Worker // Look for the Nortel VPN virtual interface, along with Juniper virtual interface.
2523*48a54d36SAndroid Build Coastguard Worker //
2524*48a54d36SAndroid Build Coastguard Worker // If these interfaces are active (i.e., has a non-zero IP Address),
2525*48a54d36SAndroid Build Coastguard Worker // then we want to disable routing table modifications.
2526*48a54d36SAndroid Build Coastguard Worker
2527*48a54d36SAndroid Build Coastguard Worker while (pAdapter)
2528*48a54d36SAndroid Build Coastguard Worker {
2529*48a54d36SAndroid Build Coastguard Worker if ( ( IsNortelVPN( pAdapter ) || IsJuniperVPN( pAdapter ) || IsCiscoVPN( pAdapter ) ) &&
2530*48a54d36SAndroid Build Coastguard Worker ( inet_addr( pAdapter->IpAddressList.IpAddress.String ) != 0 ) )
2531*48a54d36SAndroid Build Coastguard Worker {
2532*48a54d36SAndroid Build Coastguard Worker dlog( kDebugLevelTrace, DEBUG_NAME "disabling routing table management due to VPN incompatibility" );
2533*48a54d36SAndroid Build Coastguard Worker goto exit;
2534*48a54d36SAndroid Build Coastguard Worker }
2535*48a54d36SAndroid Build Coastguard Worker
2536*48a54d36SAndroid Build Coastguard Worker pAdapter = pAdapter->Next;
2537*48a54d36SAndroid Build Coastguard Worker }
2538*48a54d36SAndroid Build Coastguard Worker
2539*48a54d36SAndroid Build Coastguard Worker while ( !done )
2540*48a54d36SAndroid Build Coastguard Worker {
2541*48a54d36SAndroid Build Coastguard Worker pAdapter = pAdapterInfo;
2542*48a54d36SAndroid Build Coastguard Worker err = kUnknownErr;
2543*48a54d36SAndroid Build Coastguard Worker
2544*48a54d36SAndroid Build Coastguard Worker while (pAdapter)
2545*48a54d36SAndroid Build Coastguard Worker {
2546*48a54d36SAndroid Build Coastguard Worker // If we don't have an interface selected, choose the first one that is of type ethernet and
2547*48a54d36SAndroid Build Coastguard Worker // has a valid IP Address
2548*48a54d36SAndroid Build Coastguard Worker
2549*48a54d36SAndroid Build Coastguard Worker if ((pAdapter->Type == MIB_IF_TYPE_ETHERNET) && ( IsValidAddress( pAdapter->IpAddressList.IpAddress.String ) ) && (!(*ifIndex) || (pAdapter->Index == (*ifIndex))))
2550*48a54d36SAndroid Build Coastguard Worker {
2551*48a54d36SAndroid Build Coastguard Worker *address = inet_addr( pAdapter->IpAddressList.IpAddress.String );
2552*48a54d36SAndroid Build Coastguard Worker *ifIndex = pAdapter->Index;
2553*48a54d36SAndroid Build Coastguard Worker err = kNoErr;
2554*48a54d36SAndroid Build Coastguard Worker break;
2555*48a54d36SAndroid Build Coastguard Worker }
2556*48a54d36SAndroid Build Coastguard Worker
2557*48a54d36SAndroid Build Coastguard Worker pAdapter = pAdapter->Next;
2558*48a54d36SAndroid Build Coastguard Worker }
2559*48a54d36SAndroid Build Coastguard Worker
2560*48a54d36SAndroid Build Coastguard Worker // If we found the right interface, or we weren't trying to find a specific interface then we're done
2561*48a54d36SAndroid Build Coastguard Worker
2562*48a54d36SAndroid Build Coastguard Worker if ( !err || !( *ifIndex) )
2563*48a54d36SAndroid Build Coastguard Worker {
2564*48a54d36SAndroid Build Coastguard Worker done = mDNStrue;
2565*48a54d36SAndroid Build Coastguard Worker }
2566*48a54d36SAndroid Build Coastguard Worker
2567*48a54d36SAndroid Build Coastguard Worker // Otherwise, try again by wildcarding the interface
2568*48a54d36SAndroid Build Coastguard Worker
2569*48a54d36SAndroid Build Coastguard Worker else
2570*48a54d36SAndroid Build Coastguard Worker {
2571*48a54d36SAndroid Build Coastguard Worker *ifIndex = 0;
2572*48a54d36SAndroid Build Coastguard Worker }
2573*48a54d36SAndroid Build Coastguard Worker }
2574*48a54d36SAndroid Build Coastguard Worker
2575*48a54d36SAndroid Build Coastguard Worker exit:
2576*48a54d36SAndroid Build Coastguard Worker
2577*48a54d36SAndroid Build Coastguard Worker if ( pAdapterInfo != NULL )
2578*48a54d36SAndroid Build Coastguard Worker {
2579*48a54d36SAndroid Build Coastguard Worker free( pAdapterInfo );
2580*48a54d36SAndroid Build Coastguard Worker }
2581*48a54d36SAndroid Build Coastguard Worker
2582*48a54d36SAndroid Build Coastguard Worker return( err );
2583*48a54d36SAndroid Build Coastguard Worker }
2584*48a54d36SAndroid Build Coastguard Worker
2585*48a54d36SAndroid Build Coastguard Worker
2586*48a54d36SAndroid Build Coastguard Worker static bool
IsNortelVPN(IP_ADAPTER_INFO * pAdapter)2587*48a54d36SAndroid Build Coastguard Worker IsNortelVPN( IP_ADAPTER_INFO * pAdapter )
2588*48a54d36SAndroid Build Coastguard Worker {
2589*48a54d36SAndroid Build Coastguard Worker return ((pAdapter->Type == MIB_IF_TYPE_ETHERNET) &&
2590*48a54d36SAndroid Build Coastguard Worker (pAdapter->AddressLength == 6) &&
2591*48a54d36SAndroid Build Coastguard Worker (pAdapter->Address[0] == 0x44) &&
2592*48a54d36SAndroid Build Coastguard Worker (pAdapter->Address[1] == 0x45) &&
2593*48a54d36SAndroid Build Coastguard Worker (pAdapter->Address[2] == 0x53) &&
2594*48a54d36SAndroid Build Coastguard Worker (pAdapter->Address[3] == 0x54) &&
2595*48a54d36SAndroid Build Coastguard Worker (pAdapter->Address[4] == 0x42) &&
2596*48a54d36SAndroid Build Coastguard Worker (pAdapter->Address[5] == 0x00)) ? true : false;
2597*48a54d36SAndroid Build Coastguard Worker }
2598*48a54d36SAndroid Build Coastguard Worker
2599*48a54d36SAndroid Build Coastguard Worker
2600*48a54d36SAndroid Build Coastguard Worker static bool
IsJuniperVPN(IP_ADAPTER_INFO * pAdapter)2601*48a54d36SAndroid Build Coastguard Worker IsJuniperVPN( IP_ADAPTER_INFO * pAdapter )
2602*48a54d36SAndroid Build Coastguard Worker {
2603*48a54d36SAndroid Build Coastguard Worker return ( strnistr( pAdapter->Description, "Juniper", sizeof( pAdapter->Description ) ) != NULL ) ? true : false;
2604*48a54d36SAndroid Build Coastguard Worker }
2605*48a54d36SAndroid Build Coastguard Worker
2606*48a54d36SAndroid Build Coastguard Worker
2607*48a54d36SAndroid Build Coastguard Worker static bool
IsCiscoVPN(IP_ADAPTER_INFO * pAdapter)2608*48a54d36SAndroid Build Coastguard Worker IsCiscoVPN( IP_ADAPTER_INFO * pAdapter )
2609*48a54d36SAndroid Build Coastguard Worker {
2610*48a54d36SAndroid Build Coastguard Worker return ((pAdapter->Type == MIB_IF_TYPE_ETHERNET) &&
2611*48a54d36SAndroid Build Coastguard Worker (pAdapter->AddressLength == 6) &&
2612*48a54d36SAndroid Build Coastguard Worker (pAdapter->Address[0] == 0x00) &&
2613*48a54d36SAndroid Build Coastguard Worker (pAdapter->Address[1] == 0x05) &&
2614*48a54d36SAndroid Build Coastguard Worker (pAdapter->Address[2] == 0x9a) &&
2615*48a54d36SAndroid Build Coastguard Worker (pAdapter->Address[3] == 0x3c) &&
2616*48a54d36SAndroid Build Coastguard Worker (pAdapter->Address[4] == 0x7a) &&
2617*48a54d36SAndroid Build Coastguard Worker (pAdapter->Address[5] == 0x00)) ? true : false;
2618*48a54d36SAndroid Build Coastguard Worker }
2619*48a54d36SAndroid Build Coastguard Worker
2620*48a54d36SAndroid Build Coastguard Worker
2621*48a54d36SAndroid Build Coastguard Worker static const char *
strnistr(const char * string,const char * subString,size_t max)2622*48a54d36SAndroid Build Coastguard Worker strnistr( const char * string, const char * subString, size_t max )
2623*48a54d36SAndroid Build Coastguard Worker {
2624*48a54d36SAndroid Build Coastguard Worker size_t subStringLen;
2625*48a54d36SAndroid Build Coastguard Worker size_t offset;
2626*48a54d36SAndroid Build Coastguard Worker size_t maxOffset;
2627*48a54d36SAndroid Build Coastguard Worker size_t stringLen;
2628*48a54d36SAndroid Build Coastguard Worker const char * pPos;
2629*48a54d36SAndroid Build Coastguard Worker
2630*48a54d36SAndroid Build Coastguard Worker if ( ( string == NULL ) || ( subString == NULL ) )
2631*48a54d36SAndroid Build Coastguard Worker {
2632*48a54d36SAndroid Build Coastguard Worker return string;
2633*48a54d36SAndroid Build Coastguard Worker }
2634*48a54d36SAndroid Build Coastguard Worker
2635*48a54d36SAndroid Build Coastguard Worker stringLen = ( max > strlen( string ) ) ? strlen( string ) : max;
2636*48a54d36SAndroid Build Coastguard Worker
2637*48a54d36SAndroid Build Coastguard Worker if ( stringLen == 0 )
2638*48a54d36SAndroid Build Coastguard Worker {
2639*48a54d36SAndroid Build Coastguard Worker return NULL;
2640*48a54d36SAndroid Build Coastguard Worker }
2641*48a54d36SAndroid Build Coastguard Worker
2642*48a54d36SAndroid Build Coastguard Worker subStringLen = strlen( subString );
2643*48a54d36SAndroid Build Coastguard Worker
2644*48a54d36SAndroid Build Coastguard Worker if ( subStringLen == 0 )
2645*48a54d36SAndroid Build Coastguard Worker {
2646*48a54d36SAndroid Build Coastguard Worker return string;
2647*48a54d36SAndroid Build Coastguard Worker }
2648*48a54d36SAndroid Build Coastguard Worker
2649*48a54d36SAndroid Build Coastguard Worker if ( subStringLen > stringLen )
2650*48a54d36SAndroid Build Coastguard Worker {
2651*48a54d36SAndroid Build Coastguard Worker return NULL;
2652*48a54d36SAndroid Build Coastguard Worker }
2653*48a54d36SAndroid Build Coastguard Worker
2654*48a54d36SAndroid Build Coastguard Worker maxOffset = stringLen - subStringLen;
2655*48a54d36SAndroid Build Coastguard Worker pPos = string;
2656*48a54d36SAndroid Build Coastguard Worker
2657*48a54d36SAndroid Build Coastguard Worker for ( offset = 0; offset <= maxOffset; offset++ )
2658*48a54d36SAndroid Build Coastguard Worker {
2659*48a54d36SAndroid Build Coastguard Worker if ( _strnicmp( pPos, subString, subStringLen ) == 0 )
2660*48a54d36SAndroid Build Coastguard Worker {
2661*48a54d36SAndroid Build Coastguard Worker return pPos;
2662*48a54d36SAndroid Build Coastguard Worker }
2663*48a54d36SAndroid Build Coastguard Worker
2664*48a54d36SAndroid Build Coastguard Worker pPos++;
2665*48a54d36SAndroid Build Coastguard Worker }
2666*48a54d36SAndroid Build Coastguard Worker
2667*48a54d36SAndroid Build Coastguard Worker return NULL;
2668*48a54d36SAndroid Build Coastguard Worker }
2669*48a54d36SAndroid Build Coastguard Worker
2670