2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afs/param.h>
17 #include "afsd_init.h"
31 extern void afsi_log(char *pattern, ...);
33 extern char AFSConfigKeyName[];
35 HANDLE WaitToTerminate;
39 unsigned int MainThreadId;
42 extern int traceOnPanic;
45 * Notifier function for use by osi_panic
47 static void afsd_notifier(char *msgp, char *filep, long line)
54 sprintf(tbuffer, "Error at file %s, line %d: %s",
57 sprintf(tbuffer, "Error at unknown location: %s", msgp);
59 h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
61 ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, line, NULL, 1, 0, ptbuf, NULL);
62 DeregisterEventSource(h);
66 osi_LogEnable(afsd_logp);
68 afsd_ForceTrace(TRUE);
74 SetEvent(WaitToTerminate);
76 if (GetCurrentThreadId() == MainThreadId)
77 longjmp(notifier_jmp, 1);
83 * For use miscellaneously in smb.c; need to do better
85 static int DummyMessageBox(HWND h, LPCTSTR l1, LPCTSTR l2, UINT ui)
90 static SERVICE_STATUS ServiceStatus;
91 static SERVICE_STATUS_HANDLE StatusHandle;
93 void afsd_ServiceControlHandler(DWORD ctrlCode)
96 DWORD dummyLen, doTrace;
100 case SERVICE_CONTROL_STOP:
102 RpcMgmtStopServerListening(NULL);
104 /* Force trace if requested */
105 code = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
107 0, KEY_QUERY_VALUE, &parmKey);
108 if (code != ERROR_SUCCESS)
111 dummyLen = sizeof(doTrace);
112 code = RegQueryValueEx(parmKey, "TraceOnShutdown",
114 (BYTE *) &doTrace, &dummyLen);
115 RegCloseKey (parmKey);
116 if (code != ERROR_SUCCESS)
119 afsd_ForceTrace(FALSE);
122 ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
123 ServiceStatus.dwWin32ExitCode = NO_ERROR;
124 ServiceStatus.dwCheckPoint = 1;
125 ServiceStatus.dwWaitHint = 10000;
126 ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
127 SetServiceStatus(StatusHandle, &ServiceStatus);
128 SetEvent(WaitToTerminate);
130 case SERVICE_CONTROL_INTERROGATE:
131 ServiceStatus.dwCurrentState = SERVICE_RUNNING;
132 ServiceStatus.dwWin32ExitCode = NO_ERROR;
133 ServiceStatus.dwCheckPoint = 0;
134 ServiceStatus.dwWaitHint = 0;
135 ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
136 SetServiceStatus(StatusHandle, &ServiceStatus);
138 /* XXX handle system shutdown */
139 /* XXX handle pause & continue */
144 /* This code was moved to Drivemap.cpp*/
145 /* Mount a drive into AFS if the user wants us to */
146 /* DEE Could check first if we are run as SYSTEM */
147 void CheckMountDrive()
149 char szAfsPath[_MAX_PATH];
150 char szDriveToMapTo[5];
156 DWORD dwSubMountSize;
157 char szSubMount[256];
160 sprintf(szKeyName, "%s\\GlobalAutoMapper", AFSConfigKeyName);
162 dwResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE, &hKey);
163 if (dwResult != ERROR_SUCCESS)
167 dwDriveSize = sizeof(szDriveToMapTo);
168 dwSubMountSize = sizeof(szSubMount);
169 dwResult = RegEnumValue(hKey, dwIndex++, szDriveToMapTo, &dwDriveSize, 0, &dwType, szSubMount, &dwSubMountSize);
170 if (dwResult != ERROR_MORE_DATA) {
171 if (dwResult != ERROR_SUCCESS) {
172 if (dwResult != ERROR_NO_MORE_ITEMS)
173 afsi_log("Failed to read GlobalAutoMapper values: %d\n", dwResult);
179 sprintf(szAfsPath, "\\Device\\LanmanRedirector\\%s\\%s-AFS\\%s", szDriveToMapTo, cm_HostName, szSubMount);
181 dwResult = DefineDosDevice(DDD_RAW_TARGET_PATH, szDriveToMapTo, szAfsPath);
185 memset (&nr, 0x00, sizeof(NETRESOURCE));
187 sprintf(szAfsPath,"\\\\%s-AFS\\%s",cm_HostName,szSubMount);
189 nr.dwScope = RESOURCE_GLOBALNET;
190 nr.dwType=RESOURCETYPE_DISK;
191 nr.lpLocalName=szDriveToMapTo;
192 nr.lpRemoteName=szAfsPath;
193 nr.dwDisplayType = RESOURCEDISPLAYTYPE_SHARE;
194 nr.dwUsage = RESOURCEUSAGE_CONNECTABLE;
196 dwResult = WNetAddConnection2(&nr,NULL,NULL,FALSE);
199 afsi_log("GlobalAutoMap of %s to %s %s", szDriveToMapTo, szSubMount, dwResult ? "succeeded" : "failed");
206 typedef BOOL ( APIENTRY * AfsdInitHook )(void);
207 #define AFSD_INIT_HOOK "AfsdInitHook"
208 #define AFSD_HOOK_DLL "afsdhook.dll"
216 AfsdInitHook initHook;
219 _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF /*| _CRTDBG_CHECK_ALWAYS_DF*/ |
220 _CRTDBG_CHECK_CRT_DF /* | _CRTDBG_DELAY_FREE_MEM_DF */ );
223 osi_InitPanic(afsd_notifier);
224 osi_InitTraceOption();
228 WaitToTerminate = CreateEvent(NULL, TRUE, FALSE, NULL);
231 StatusHandle = RegisterServiceCtrlHandler(AFS_DAEMON_SERVICE_NAME,
232 (LPHANDLER_FUNCTION) afsd_ServiceControlHandler);
234 ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
235 ServiceStatus.dwServiceSpecificExitCode = 0;
236 ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
237 ServiceStatus.dwWin32ExitCode = NO_ERROR;
238 ServiceStatus.dwCheckPoint = 1;
239 ServiceStatus.dwWaitHint = 15000;
240 ServiceStatus.dwControlsAccepted = 0;
241 SetServiceStatus(StatusHandle, &ServiceStatus);
244 HANDLE h; char *ptbuf[1];
245 h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
246 ptbuf[0] = "AFS start pending";
247 ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, ptbuf, NULL);
248 DeregisterEventSource(h);
253 /* allow an exit to be called prior to any initialization */
254 hInitHookDll = LoadLibrary(AFSD_HOOK_DLL);
258 initHook = ( AfsdInitHook ) GetProcAddress(hInitHookDll, AFSD_INIT_HOOK);
263 FreeLibrary(hInitHookDll);
267 ServiceStatus.dwCurrentState = SERVICE_STOPPED;
268 ServiceStatus.dwWin32ExitCode = NO_ERROR;
269 ServiceStatus.dwCheckPoint = 0;
270 ServiceStatus.dwWaitHint = 0;
271 ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
272 SetServiceStatus(StatusHandle, &ServiceStatus);
274 /* exit if initialization failed */
279 /* allow another 15 seconds to start */
280 ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
281 ServiceStatus.dwServiceSpecificExitCode = 0;
282 ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
283 ServiceStatus.dwWin32ExitCode = NO_ERROR;
284 ServiceStatus.dwCheckPoint = 2;
285 ServiceStatus.dwWaitHint = 15000;
286 ServiceStatus.dwControlsAccepted = 0;
287 SetServiceStatus(StatusHandle, &ServiceStatus);
291 MainThreadId = GetCurrentThreadId();
292 jmpret = setjmp(notifier_jmp);
295 code = afsd_InitCM(&reason);
297 osi_panic(reason, __FILE__, __LINE__);
299 code = afsd_InitDaemons(&reason);
301 osi_panic(reason, __FILE__, __LINE__);
303 code = afsd_InitSMB(&reason, DummyMessageBox);
305 osi_panic(reason, __FILE__, __LINE__);
308 ServiceStatus.dwCurrentState = SERVICE_RUNNING;
309 ServiceStatus.dwWin32ExitCode = NO_ERROR;
310 ServiceStatus.dwCheckPoint = 0;
311 ServiceStatus.dwWaitHint = 0;
312 ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
313 SetServiceStatus(StatusHandle, &ServiceStatus);
316 HANDLE h; char *ptbuf[1];
317 h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
318 ptbuf[0] = "AFS running";
319 ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, ptbuf, NULL);
320 DeregisterEventSource(h);
324 /* Check if we should mount a drive into AFS */
327 WaitForSingleObject(WaitToTerminate, INFINITE);
330 HANDLE h; char *ptbuf[1];
331 h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
332 ptbuf[0] = "AFS quitting";
333 ReportEvent(h, GlobalStatus ? EVENTLOG_ERROR_TYPE : EVENTLOG_INFORMATION_TYPE,
334 0, 0, NULL, 1, 0, ptbuf, NULL);
335 DeregisterEventSource(h);
338 ServiceStatus.dwCurrentState = SERVICE_STOPPED;
339 ServiceStatus.dwWin32ExitCode = NO_ERROR;
340 ServiceStatus.dwCheckPoint = 0;
341 ServiceStatus.dwWaitHint = 0;
342 ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
343 SetServiceStatus(StatusHandle, &ServiceStatus);
346 DWORD __stdcall afsdMain_thread(void* notUsed)
354 SERVICE_TABLE_ENTRY dispatchTable[] = {
355 {AFS_DAEMON_SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION) afsd_Main},
359 afsd_SetUnhandledExceptionFilter();
361 if (!StartServiceCtrlDispatcher(dispatchTable))
363 LONG status = GetLastError();
364 if (status == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT)
367 CreateThread(NULL, 0, afsdMain_thread, 0, 0, &tid);
369 printf("Hit <Enter> to terminate OpenAFS Client Service\n");
371 SetEvent(WaitToTerminate);