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"
24 extern void afsi_log(char *pattern, ...);
26 extern char AFSConfigKeyName[];
28 HANDLE WaitToTerminate;
32 unsigned int MainThreadId;
35 extern int traceOnPanic;
38 * Notifier function for use by osi_panic
40 static void afsd_notifier(char *msgp, char *filep, long line)
47 sprintf(tbuffer, "Error at file %s, line %d: %s",
50 sprintf(tbuffer, "Error at unknown location: %s", msgp);
52 h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
54 ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, line, NULL, 1, 0, ptbuf, NULL);
55 DeregisterEventSource(h);
59 osi_LogEnable(afsd_logp);
61 afsd_ForceTrace(TRUE);
67 SetEvent(WaitToTerminate);
69 if (GetCurrentThreadId() == MainThreadId)
70 longjmp(notifier_jmp, 1);
76 * For use miscellaneously in smb.c; need to do better
78 static int DummyMessageBox(HWND h, LPCTSTR l1, LPCTSTR l2, UINT ui)
83 static SERVICE_STATUS ServiceStatus;
84 static SERVICE_STATUS_HANDLE StatusHandle;
86 void afsd_ServiceControlHandler(DWORD ctrlCode)
89 DWORD dummyLen, doTrace;
93 case SERVICE_CONTROL_STOP:
95 RpcMgmtStopServerListening(NULL);
97 /* Force trace if requested */
98 code = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
100 0, KEY_QUERY_VALUE, &parmKey);
101 if (code != ERROR_SUCCESS)
104 dummyLen = sizeof(doTrace);
105 code = RegQueryValueEx(parmKey, "TraceOnShutdown",
107 (BYTE *) &doTrace, &dummyLen);
108 RegCloseKey (parmKey);
109 if (code != ERROR_SUCCESS)
112 afsd_ForceTrace(FALSE);
115 ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
116 ServiceStatus.dwWin32ExitCode = NO_ERROR;
117 ServiceStatus.dwCheckPoint = 1;
118 ServiceStatus.dwWaitHint = 10000;
119 ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
120 SetServiceStatus(StatusHandle, &ServiceStatus);
121 SetEvent(WaitToTerminate);
123 case SERVICE_CONTROL_INTERROGATE:
124 ServiceStatus.dwCurrentState = SERVICE_RUNNING;
125 ServiceStatus.dwWin32ExitCode = NO_ERROR;
126 ServiceStatus.dwCheckPoint = 0;
127 ServiceStatus.dwWaitHint = 0;
128 ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
129 SetServiceStatus(StatusHandle, &ServiceStatus);
131 /* XXX handle system shutdown */
132 /* XXX handle pause & continue */
136 /* Mount a drive into AFS if the user wants us to */
137 void CheckMountDrive()
139 char szAfsPath[_MAX_PATH];
140 char szDriveToMapTo[5];
146 DWORD dwSubMountSize;
147 char szSubMount[256];
150 sprintf(szKeyName, "%s\\GlobalAutoMapper", AFSConfigKeyName);
152 dwResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE, &hKey);
153 if (dwResult != ERROR_SUCCESS)
157 dwDriveSize = sizeof(szDriveToMapTo);
158 dwSubMountSize = sizeof(szSubMount);
159 dwResult = RegEnumValue(hKey, dwIndex++, szDriveToMapTo, &dwDriveSize, 0, &dwType, szSubMount, &dwSubMountSize);
160 if (dwResult != ERROR_MORE_DATA) {
161 if (dwResult != ERROR_SUCCESS) {
162 if (dwResult != ERROR_NO_MORE_ITEMS)
163 afsi_log("Failed to read GlobalAutoMapper values: %d\n", dwResult);
168 sprintf(szAfsPath, "\\Device\\LanmanRedirector\\%s\\%s-AFS\\%s", szDriveToMapTo, cm_HostName, szSubMount);
170 dwResult = DefineDosDevice(DDD_RAW_TARGET_PATH, szDriveToMapTo, szAfsPath);
171 afsi_log("GlobalAutoMap of %s to %s %s", szDriveToMapTo, szSubMount, dwResult ? "succeeded" : "failed");
183 osi_InitPanic(afsd_notifier);
187 WaitToTerminate = CreateEvent(NULL, TRUE, FALSE, NULL);
189 StatusHandle = RegisterServiceCtrlHandler(AFS_DAEMON_SERVICE_NAME,
190 (LPHANDLER_FUNCTION) afsd_ServiceControlHandler);
192 ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
193 ServiceStatus.dwServiceSpecificExitCode = 0;
194 ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
195 ServiceStatus.dwWin32ExitCode = NO_ERROR;
196 ServiceStatus.dwCheckPoint = 1;
197 ServiceStatus.dwWaitHint = 15000;
198 ServiceStatus.dwControlsAccepted = 0;
199 SetServiceStatus(StatusHandle, &ServiceStatus);
201 HANDLE h; char *ptbuf[1];
202 h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
203 ptbuf[0] = "AFS start pending";
204 ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, ptbuf, NULL);
205 DeregisterEventSource(h);
210 MainThreadId = GetCurrentThreadId();
211 jmpret = setjmp(notifier_jmp);
214 code = afsd_InitCM(&reason);
216 osi_panic(reason, __FILE__, __LINE__);
218 code = afsd_InitDaemons(&reason);
220 osi_panic(reason, __FILE__, __LINE__);
222 code = afsd_InitSMB(&reason, DummyMessageBox);
224 osi_panic(reason, __FILE__, __LINE__);
226 ServiceStatus.dwCurrentState = SERVICE_RUNNING;
227 ServiceStatus.dwWin32ExitCode = NO_ERROR;
228 ServiceStatus.dwCheckPoint = 0;
229 ServiceStatus.dwWaitHint = 0;
230 ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
231 SetServiceStatus(StatusHandle, &ServiceStatus);
233 HANDLE h; char *ptbuf[1];
234 h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
235 ptbuf[0] = "AFS running";
236 ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, ptbuf, NULL);
237 DeregisterEventSource(h);
241 /* Check if we should mount a drive into AFS */
244 WaitForSingleObject(WaitToTerminate, INFINITE);
247 HANDLE h; char *ptbuf[1];
248 h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
249 ptbuf[0] = "AFS quitting";
251 GlobalStatus ? EVENTLOG_ERROR_TYPE : EVENTLOG_INFORMATION_TYPE,
252 0, 0, NULL, 1, 0, ptbuf, NULL);
253 DeregisterEventSource(h);
256 ServiceStatus.dwCurrentState = SERVICE_STOPPED;
257 ServiceStatus.dwWin32ExitCode = NO_ERROR;
258 ServiceStatus.dwCheckPoint = 0;
259 ServiceStatus.dwWaitHint = 0;
260 ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
261 SetServiceStatus(StatusHandle, &ServiceStatus);
266 LONG status = ERROR_SUCCESS;
267 SERVICE_TABLE_ENTRY dispatchTable[] = {
268 {AFS_DAEMON_SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION) afsd_Main},
272 if (!StartServiceCtrlDispatcher(dispatchTable))
273 status = GetLastError();