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"
25 //#define NOTSERVICE
\r
28 extern void afsi_log(char *pattern, ...);
30 extern char AFSConfigKeyName[];
32 HANDLE WaitToTerminate;
36 unsigned int MainThreadId;
39 extern int traceOnPanic;
42 * Notifier function for use by osi_panic
44 static void afsd_notifier(char *msgp, char *filep, long line)
51 sprintf(tbuffer, "Error at file %s, line %d: %s",
54 sprintf(tbuffer, "Error at unknown location: %s", msgp);
56 h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
58 ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, line, NULL, 1, 0, ptbuf, NULL);
59 DeregisterEventSource(h);
63 osi_LogEnable(afsd_logp);
65 afsd_ForceTrace(TRUE);
71 SetEvent(WaitToTerminate);
73 if (GetCurrentThreadId() == MainThreadId)
74 longjmp(notifier_jmp, 1);
80 * For use miscellaneously in smb.c; need to do better
82 static int DummyMessageBox(HWND h, LPCTSTR l1, LPCTSTR l2, UINT ui)
87 static SERVICE_STATUS ServiceStatus;
88 static SERVICE_STATUS_HANDLE StatusHandle;
90 void afsd_ServiceControlHandler(DWORD ctrlCode)
93 DWORD dummyLen, doTrace;
97 case SERVICE_CONTROL_STOP:
99 RpcMgmtStopServerListening(NULL);
101 /* Force trace if requested */
102 code = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
104 0, KEY_QUERY_VALUE, &parmKey);
105 if (code != ERROR_SUCCESS)
108 dummyLen = sizeof(doTrace);
109 code = RegQueryValueEx(parmKey, "TraceOnShutdown",
111 (BYTE *) &doTrace, &dummyLen);
112 RegCloseKey (parmKey);
113 if (code != ERROR_SUCCESS)
116 afsd_ForceTrace(FALSE);
119 ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
120 ServiceStatus.dwWin32ExitCode = NO_ERROR;
121 ServiceStatus.dwCheckPoint = 1;
122 ServiceStatus.dwWaitHint = 10000;
123 ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
124 SetServiceStatus(StatusHandle, &ServiceStatus);
125 SetEvent(WaitToTerminate);
127 case SERVICE_CONTROL_INTERROGATE:
128 ServiceStatus.dwCurrentState = SERVICE_RUNNING;
129 ServiceStatus.dwWin32ExitCode = NO_ERROR;
130 ServiceStatus.dwCheckPoint = 0;
131 ServiceStatus.dwWaitHint = 0;
132 ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
133 SetServiceStatus(StatusHandle, &ServiceStatus);
135 /* XXX handle system shutdown */
136 /* XXX handle pause & continue */
140 /* Mount a drive into AFS if the user wants us to */
141 void CheckMountDrive()
143 char szAfsPath[_MAX_PATH];
144 char szDriveToMapTo[5];
150 DWORD dwSubMountSize;
151 char szSubMount[256];
154 sprintf(szKeyName, "%s\\GlobalAutoMapper", AFSConfigKeyName);
156 dwResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE, &hKey);
157 if (dwResult != ERROR_SUCCESS)
161 dwDriveSize = sizeof(szDriveToMapTo);
162 dwSubMountSize = sizeof(szSubMount);
163 dwResult = RegEnumValue(hKey, dwIndex++, szDriveToMapTo, &dwDriveSize, 0, &dwType, szSubMount, &dwSubMountSize);
164 if (dwResult != ERROR_MORE_DATA) {
165 if (dwResult != ERROR_SUCCESS) {
166 if (dwResult != ERROR_NO_MORE_ITEMS)
167 afsi_log("Failed to read GlobalAutoMapper values: %d\n", dwResult);
172 sprintf(szAfsPath, "\\Device\\LanmanRedirector\\%s\\%s-AFS\\%s", szDriveToMapTo, cm_HostName, szSubMount);
174 dwResult = DefineDosDevice(DDD_RAW_TARGET_PATH, szDriveToMapTo, szAfsPath);
175 afsi_log("GlobalAutoMap of %s to %s %s", szDriveToMapTo, szSubMount, dwResult ? "succeeded" : "failed");
187 osi_InitPanic(afsd_notifier);
191 WaitToTerminate = CreateEvent(NULL, TRUE, FALSE, NULL);
194 StatusHandle = RegisterServiceCtrlHandler(AFS_DAEMON_SERVICE_NAME,
195 (LPHANDLER_FUNCTION) afsd_ServiceControlHandler);
197 ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
198 ServiceStatus.dwServiceSpecificExitCode = 0;
199 ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
200 ServiceStatus.dwWin32ExitCode = NO_ERROR;
201 ServiceStatus.dwCheckPoint = 1;
202 ServiceStatus.dwWaitHint = 15000;
203 ServiceStatus.dwControlsAccepted = 0;
204 SetServiceStatus(StatusHandle, &ServiceStatus);
207 HANDLE h; char *ptbuf[1];
208 h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
209 ptbuf[0] = "AFS start pending";
210 ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, ptbuf, NULL);
211 DeregisterEventSource(h);
216 MainThreadId = GetCurrentThreadId();
217 jmpret = setjmp(notifier_jmp);
220 code = afsd_InitCM(&reason);
222 osi_panic(reason, __FILE__, __LINE__);
224 code = afsd_InitDaemons(&reason);
226 osi_panic(reason, __FILE__, __LINE__);
228 code = afsd_InitSMB(&reason, DummyMessageBox);
230 osi_panic(reason, __FILE__, __LINE__);
233 ServiceStatus.dwCurrentState = SERVICE_RUNNING;
234 ServiceStatus.dwWin32ExitCode = NO_ERROR;
235 ServiceStatus.dwCheckPoint = 0;
236 ServiceStatus.dwWaitHint = 0;
237 ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
238 SetServiceStatus(StatusHandle, &ServiceStatus);
241 HANDLE h; char *ptbuf[1];
242 h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
243 ptbuf[0] = "AFS running";
244 ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, ptbuf, NULL);
245 DeregisterEventSource(h);
249 /* Check if we should mount a drive into AFS */
252 WaitForSingleObject(WaitToTerminate, INFINITE);
255 HANDLE h; char *ptbuf[1];
256 h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
257 ptbuf[0] = "AFS quitting";
259 GlobalStatus ? EVENTLOG_ERROR_TYPE : EVENTLOG_INFORMATION_TYPE,
260 0, 0, NULL, 1, 0, ptbuf, NULL);
261 DeregisterEventSource(h);
264 ServiceStatus.dwCurrentState = SERVICE_STOPPED;
265 ServiceStatus.dwWin32ExitCode = NO_ERROR;
266 ServiceStatus.dwCheckPoint = 0;
267 ServiceStatus.dwWaitHint = 0;
268 ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
269 SetServiceStatus(StatusHandle, &ServiceStatus);
282 LONG status = ERROR_SUCCESS;
283 SERVICE_TABLE_ENTRY dispatchTable[] = {
284 {AFS_DAEMON_SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION) afsd_Main},
288 if (!StartServiceCtrlDispatcher(dispatchTable))
289 status = GetLastError();