win-xp-sp2-20040325
[openafs.git] / src / WINNT / afsd / afsd_service.c
index 6ee75a5..99f7c1a 100644 (file)
@@ -32,7 +32,7 @@
 // The following is defined if you want to receive Power notifications,
 // including Hibernation, and also subsequent flushing of AFS volumes
 //
-// #define REGISTER_POWER_NOTIFICATIONS
+#define REGISTER_POWER_NOTIFICATIONS
 //
 // Check
 */
 
 extern void afsi_log(char *pattern, ...);
 
+HANDLE hAFSDMainThread = NULL;
+
 HANDLE WaitToTerminate;
 
 int GlobalStatus;
 
+#ifdef JUMP
 unsigned int MainThreadId;
 jmp_buf notifier_jmp;
+#endif /* JUMP */
 
 extern int traceOnPanic;
 extern HANDLE afsi_file;
@@ -89,9 +93,11 @@ static void afsd_notifier(char *msgp, char *filep, long line)
 
        SetEvent(WaitToTerminate);
 
+#ifdef JUMP
        if (GetCurrentThreadId() == MainThreadId)
                longjmp(notifier_jmp, 1);
        else
+#endif /* JUMP */
                ExitThread(1);
 }
 
@@ -185,7 +191,7 @@ afsd_ServiceControlHandlerEx(
         ServiceStatus.dwWin32ExitCode = NO_ERROR;
         ServiceStatus.dwCheckPoint = 1;
         ServiceStatus.dwWaitHint = 10000;
-        ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_POWEREVENT;
+        ServiceStatus.dwControlsAccepted = 0;
         SetServiceStatus(StatusHandle, &ServiceStatus);
         SetEvent(WaitToTerminate);
         dwRet = NO_ERROR;
@@ -313,7 +319,9 @@ void afsd_Main(DWORD argc, LPTSTR *argv)
 {
        long code;
        char *reason;
+#ifdef JUMP
        int jmpret;
+#endif /* JUMP */
     HANDLE hInitHookDll;
     AfsdInitHook initHook;
 
@@ -327,7 +335,11 @@ void afsd_Main(DWORD argc, LPTSTR *argv)
 
        GlobalStatus = 0;
 
-       WaitToTerminate = CreateEvent(NULL, TRUE, FALSE, NULL);
+       afsi_start();
+
+       WaitToTerminate = CreateEvent(NULL, TRUE, FALSE, TEXT("afsd_service_WaitToTerminate"));
+    if ( GetLastError() == ERROR_ALREADY_EXISTS )
+        afsi_log("Event Object Already Exists: %s", TEXT("afsd_service_WaitToTerminate"));
 
 #ifndef NOTSERVICE
        StatusHandle = RegisterServiceCtrlHandlerEx(AFS_DAEMON_SERVICE_NAME,
@@ -359,8 +371,6 @@ void afsd_Main(DWORD argc, LPTSTR *argv)
     PowerNotificationThreadCreate();
 #endif
 
-       afsi_start();
-
     /* allow an exit to be called prior to any initialization */
     hInitHookDll = LoadLibrary(AFSD_HOOK_DLL);
     if (hInitHookDll)
@@ -379,7 +389,7 @@ void afsd_Main(DWORD argc, LPTSTR *argv)
             ServiceStatus.dwWin32ExitCode = NO_ERROR;
             ServiceStatus.dwCheckPoint = 0;
             ServiceStatus.dwWaitHint = 0;
-            ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
+            ServiceStatus.dwControlsAccepted = 0;
             SetServiceStatus(StatusHandle, &ServiceStatus);
                        
             /* exit if initialization failed */
@@ -393,16 +403,20 @@ void afsd_Main(DWORD argc, LPTSTR *argv)
             ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
             ServiceStatus.dwWin32ExitCode = NO_ERROR;
             ServiceStatus.dwCheckPoint = 2;
-            ServiceStatus.dwWaitHint = 15000;
-            ServiceStatus.dwControlsAccepted = 0;
+            ServiceStatus.dwWaitHint = 20000;
+            /* accept Power Events */
+            ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_POWEREVENT;
             SetServiceStatus(StatusHandle, &ServiceStatus);
         }
     }
 
+#ifdef JUMP
     MainThreadId = GetCurrentThreadId();
        jmpret = setjmp(notifier_jmp);
 
-       if (jmpret == 0) {
+       if (jmpret == 0) 
+#endif /* JUMP */
+    {
                code = afsd_InitCM(&reason);
                if (code != 0)
                        osi_panic(reason, __FILE__, __LINE__);
@@ -448,7 +462,7 @@ void afsd_Main(DWORD argc, LPTSTR *argv)
     CheckMountDrive();
 
        WaitForSingleObject(WaitToTerminate, INFINITE);
-       
+
     {   
     HANDLE h; char *ptbuf[1];
        h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
@@ -458,49 +472,56 @@ void afsd_Main(DWORD argc, LPTSTR *argv)
     DeregisterEventSource(h);
     }
 
-       ServiceStatus.dwCurrentState = SERVICE_STOPPED;
-       ServiceStatus.dwWin32ExitCode = GlobalStatus ? ERROR_EXCEPTION_IN_SERVICE : NO_ERROR;
-       ServiceStatus.dwCheckPoint = 0;
-       ServiceStatus.dwWaitHint = 0;
-       ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
-    /* also now accept Power events - shutdown maybe? */
-       ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
-
 #ifdef REGISTER_POWER_NOTIFICATIONS
        /* terminate thread used to flush cache */
        PowerNotificationThreadExit();
 #endif
 
+    /* Remove the ExceptionFilter */
+    SetUnhandledExceptionFilter(NULL);
+
+    if ( hInitHookDll )
+        FreeLibrary(hInitHookDll);
+
+    ServiceStatus.dwCurrentState = SERVICE_STOPPED;
+       ServiceStatus.dwWin32ExitCode = GlobalStatus ? ERROR_EXCEPTION_IN_SERVICE : NO_ERROR;
+       ServiceStatus.dwCheckPoint = 0;
+       ServiceStatus.dwWaitHint = 0;
+       ServiceStatus.dwControlsAccepted = 0;
        SetServiceStatus(StatusHandle, &ServiceStatus);
 }
 
 DWORD __stdcall afsdMain_thread(void* notUsed)
 {
        afsd_Main(0, (LPTSTR*)NULL);
-    return(0);
+    exit(0);
 }
 
-void main()
+int
+main(void)
 {
-       SERVICE_TABLE_ENTRY dispatchTable[] = {
+       static SERVICE_TABLE_ENTRY dispatchTable[] = {
                {AFS_DAEMON_SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION) afsd_Main},
                {NULL, NULL}
        };
 
-    afsd_SetUnhandledExceptionFilter();
-
        if (!StartServiceCtrlDispatcher(dispatchTable))
     {
         LONG status = GetLastError();
            if (status == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT)
         {
             DWORD tid;
-            CreateThread(NULL, 0, afsdMain_thread, 0, 0, &tid);
+            hAFSDMainThread = CreateThread(NULL, 0, afsdMain_thread, 0, 0, &tid);
                
             printf("Hit <Enter> to terminate OpenAFS Client Service\n");
             getchar();              
             SetEvent(WaitToTerminate);
         }
     }
+
+    if ( hAFSDMainThread ) {
+        WaitForSingleObject( hAFSDMainThread, INFINITE );
+        CloseHandle( hAFSDMainThread );
+    }
+    return(0);
 }