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 HANDLE WaitToTerminate;
37 unsigned int MainThreadId;
40 extern int traceOnPanic;
43 * Notifier function for use by osi_panic
45 static void afsd_notifier(char *msgp, char *filep, long line)
52 sprintf(tbuffer, "Error at file %s, line %d: %s",
55 sprintf(tbuffer, "Error at unknown location: %s", msgp);
57 h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
59 ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, line, NULL, 1, 0, ptbuf, NULL);
60 DeregisterEventSource(h);
64 osi_LogEnable(afsd_logp);
66 afsd_ForceTrace(TRUE);
72 SetEvent(WaitToTerminate);
74 if (GetCurrentThreadId() == MainThreadId)
75 longjmp(notifier_jmp, 1);
81 * For use miscellaneously in smb.c; need to do better
83 static int DummyMessageBox(HWND h, LPCTSTR l1, LPCTSTR l2, UINT ui)
88 static SERVICE_STATUS ServiceStatus;
89 static SERVICE_STATUS_HANDLE StatusHandle;
91 void afsd_ServiceControlHandler(DWORD ctrlCode)
94 DWORD dummyLen, doTrace;
98 case SERVICE_CONTROL_STOP:
100 RpcMgmtStopServerListening(NULL);
102 /* Force trace if requested */
103 code = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
105 0, KEY_QUERY_VALUE, &parmKey);
106 if (code != ERROR_SUCCESS)
109 dummyLen = sizeof(doTrace);
110 code = RegQueryValueEx(parmKey, "TraceOnShutdown",
112 (BYTE *) &doTrace, &dummyLen);
113 RegCloseKey (parmKey);
114 if (code != ERROR_SUCCESS)
117 afsd_ForceTrace(FALSE);
120 ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
121 ServiceStatus.dwWin32ExitCode = NO_ERROR;
122 ServiceStatus.dwCheckPoint = 1;
123 ServiceStatus.dwWaitHint = 10000;
124 ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
125 SetServiceStatus(StatusHandle, &ServiceStatus);
126 SetEvent(WaitToTerminate);
128 case SERVICE_CONTROL_INTERROGATE:
129 ServiceStatus.dwCurrentState = SERVICE_RUNNING;
130 ServiceStatus.dwWin32ExitCode = NO_ERROR;
131 ServiceStatus.dwCheckPoint = 0;
132 ServiceStatus.dwWaitHint = 0;
133 ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
134 SetServiceStatus(StatusHandle, &ServiceStatus);
136 /* XXX handle system shutdown */
137 /* XXX handle pause & continue */
142 /* This code was moved to Drivemap.cpp*/
143 /* Mount a drive into AFS if the user wants us to */
144 /* DEE Could check first if we are run as SYSTEM */
145 void CheckMountDrive()
147 char szAfsPath[_MAX_PATH];
148 char szDriveToMapTo[5];
154 DWORD dwSubMountSize;
155 char szSubMount[256];
158 sprintf(szKeyName, "%s\\GlobalAutoMapper", AFSConfigKeyName);
160 dwResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE, &hKey);
161 if (dwResult != ERROR_SUCCESS)
165 dwDriveSize = sizeof(szDriveToMapTo);
166 dwSubMountSize = sizeof(szSubMount);
167 dwResult = RegEnumValue(hKey, dwIndex++, szDriveToMapTo, &dwDriveSize, 0, &dwType, szSubMount, &dwSubMountSize);
168 if (dwResult != ERROR_MORE_DATA) {
169 if (dwResult != ERROR_SUCCESS) {
170 if (dwResult != ERROR_NO_MORE_ITEMS)
171 afsi_log("Failed to read GlobalAutoMapper values: %d\n", dwResult);
177 sprintf(szAfsPath, "\\Device\\LanmanRedirector\\%s\\%s-AFS\\%s", szDriveToMapTo, cm_HostName, szSubMount);
179 dwResult = DefineDosDevice(DDD_RAW_TARGET_PATH, szDriveToMapTo, szAfsPath);
183 memset (&nr, 0x00, sizeof(NETRESOURCE));
185 sprintf(szAfsPath,"\\\\%s-AFS\\%s",cm_HostName,szSubMount);
187 nr.dwScope = RESOURCE_GLOBALNET;
188 nr.dwType=RESOURCETYPE_DISK;
189 nr.lpLocalName=szDriveToMapTo;
190 nr.lpRemoteName=szAfsPath;
191 nr.dwDisplayType = RESOURCEDISPLAYTYPE_SHARE;
192 nr.dwUsage = RESOURCEUSAGE_CONNECTABLE;
194 dwResult = WNetAddConnection2(&nr,NULL,NULL,FALSE);
197 afsi_log("GlobalAutoMap of %s to %s %s", szDriveToMapTo, szSubMount, dwResult ? "succeeded" : "failed");
204 typedef BOOL ( APIENTRY * AfsdInitHook )(void);
205 #define AFSD_INIT_HOOK "AfsdInitHook"
206 #define AFSD_HOOK_DLL "afsdhook.dll"
214 AfsdInitHook initHook;
217 _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF /*| _CRTDBG_CHECK_ALWAYS_DF*/ |
218 _CRTDBG_CHECK_CRT_DF /* | _CRTDBG_DELAY_FREE_MEM_DF */ );
221 osi_InitPanic(afsd_notifier);
222 osi_InitTraceOption();
226 WaitToTerminate = CreateEvent(NULL, TRUE, FALSE, NULL);
229 StatusHandle = RegisterServiceCtrlHandler(AFS_DAEMON_SERVICE_NAME,
230 (LPHANDLER_FUNCTION) afsd_ServiceControlHandler);
232 ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
233 ServiceStatus.dwServiceSpecificExitCode = 0;
234 ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
235 ServiceStatus.dwWin32ExitCode = NO_ERROR;
236 ServiceStatus.dwCheckPoint = 1;
237 ServiceStatus.dwWaitHint = 15000;
238 ServiceStatus.dwControlsAccepted = 0;
239 SetServiceStatus(StatusHandle, &ServiceStatus);
242 HANDLE h; char *ptbuf[1];
243 h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
244 ptbuf[0] = "AFS start pending";
245 ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, ptbuf, NULL);
246 DeregisterEventSource(h);
251 /* allow an exit to be called prior to any initialization */
252 hInitHookDll = LoadLibrary(AFSD_HOOK_DLL);
256 initHook = ( AfsdInitHook ) GetProcAddress(hInitHookDll, AFSD_INIT_HOOK);
261 FreeLibrary(hInitHookDll);
265 ServiceStatus.dwCurrentState = SERVICE_STOPPED;
266 ServiceStatus.dwWin32ExitCode = NO_ERROR;
267 ServiceStatus.dwCheckPoint = 0;
268 ServiceStatus.dwWaitHint = 0;
269 ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
270 SetServiceStatus(StatusHandle, &ServiceStatus);
272 /* exit if initialization failed */
277 /* allow another 15 seconds to start */
278 ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
279 ServiceStatus.dwServiceSpecificExitCode = 0;
280 ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
281 ServiceStatus.dwWin32ExitCode = NO_ERROR;
282 ServiceStatus.dwCheckPoint = 2;
283 ServiceStatus.dwWaitHint = 15000;
284 ServiceStatus.dwControlsAccepted = 0;
285 SetServiceStatus(StatusHandle, &ServiceStatus);
289 MainThreadId = GetCurrentThreadId();
290 jmpret = setjmp(notifier_jmp);
293 code = afsd_InitCM(&reason);
295 osi_panic(reason, __FILE__, __LINE__);
297 code = afsd_InitDaemons(&reason);
299 osi_panic(reason, __FILE__, __LINE__);
301 code = afsd_InitSMB(&reason, DummyMessageBox);
303 osi_panic(reason, __FILE__, __LINE__);
306 ServiceStatus.dwCurrentState = SERVICE_RUNNING;
307 ServiceStatus.dwWin32ExitCode = NO_ERROR;
308 ServiceStatus.dwCheckPoint = 0;
309 ServiceStatus.dwWaitHint = 0;
310 ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
311 SetServiceStatus(StatusHandle, &ServiceStatus);
314 HANDLE h; char *ptbuf[1];
315 h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
316 ptbuf[0] = "AFS running";
317 ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, ptbuf, NULL);
318 DeregisterEventSource(h);
322 /* Check if we should mount a drive into AFS */
325 WaitForSingleObject(WaitToTerminate, INFINITE);
328 HANDLE h; char *ptbuf[1];
329 h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
330 ptbuf[0] = "AFS quitting";
331 ReportEvent(h, GlobalStatus ? EVENTLOG_ERROR_TYPE : EVENTLOG_INFORMATION_TYPE,
332 0, 0, NULL, 1, 0, ptbuf, NULL);
333 DeregisterEventSource(h);
336 ServiceStatus.dwCurrentState = SERVICE_STOPPED;
337 ServiceStatus.dwWin32ExitCode = GlobalStatus ? ERROR_EXCEPTION_IN_SERVICE : NO_ERROR;
338 ServiceStatus.dwCheckPoint = 0;
339 ServiceStatus.dwWaitHint = 0;
340 ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
341 SetServiceStatus(StatusHandle, &ServiceStatus);
344 DWORD __stdcall afsdMain_thread(void* notUsed)
352 SERVICE_TABLE_ENTRY dispatchTable[] = {
353 {AFS_DAEMON_SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION) afsd_Main},
357 afsd_SetUnhandledExceptionFilter();
359 if (!StartServiceCtrlDispatcher(dispatchTable))
361 LONG status = GetLastError();
362 if (status == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT)
365 CreateThread(NULL, 0, afsdMain_thread, 0, 0, &tid);
367 printf("Hit <Enter> to terminate OpenAFS Client Service\n");
369 SetEvent(WaitToTerminate);