]> granicus.if.org Git - apache/blobdiff - support/win32/ApacheMonitor.c
cppCheck: unreadVariable - 'serviceFlag' is not used in the function, so remove it
[apache] / support / win32 / ApacheMonitor.c
index 4f4d3d97840da49d035f22eefcec24b4a8539ffc..c6021f3b19b0b728599aaf045356e9b63722abbc 100644 (file)
@@ -33,7 +33,6 @@
 
 #if defined(_MSC_VER) && _MSC_VER >= 1400
 #define _CRT_SECURE_NO_DEPRECATE
-#pragma warning(disable: 4996)
 #endif
 
 #include <windows.h>
@@ -54,7 +53,6 @@
 #define AM_STRINGIFY_HELPER(n) #n
 #endif
 
-#define OS_VERSION_WIN9X    1
 #define OS_VERSION_WINNT    2
 #define OS_VERSION_WIN2K    3
 
@@ -113,13 +111,7 @@ HWND              g_hwndConnectDlg;
 HCURSOR           g_hCursorHourglass;
 HCURSOR           g_hCursorArrow;
 
-HANDLE            g_hpipeOutRead;
-HANDLE            g_hpipeOutWrite;
-HANDLE            g_hpipeInRead;
-HANDLE            g_hpipeInWrite;
-HANDLE            g_hpipeStdError;
 LANGID            g_LangID;
-PROCESS_INFORMATION g_lpRedirectProc;
 CRITICAL_SECTION  g_stcSection;
 LPTSTR            g_szLocalHost;
 
@@ -227,6 +219,29 @@ void ErrorMessage(LPCTSTR szError, BOOL bFatal)
 }
 
 
+int am_RespawnAsUserAdmin(HWND hwnd, DWORD op, LPCTSTR szService,
+                          LPCTSTR szComputerName)
+{
+    TCHAR args[MAX_PATH + MAX_COMPUTERNAME_LENGTH + 12];
+
+    if (g_dwOSVersion < OS_VERSION_WIN2K) {
+        ErrorMessage(g_lpMsg[IDS_MSG_SRVFAILED - IDS_MSG_FIRST], FALSE);
+        return 0;
+    }
+
+    _sntprintf(args, sizeof(args) / sizeof(TCHAR),
+               _T("%d \"%s\" \"%s\""), op, szService,
+               szComputerName ? szComputerName : _T(""));
+    if (!ShellExecute(hwnd, _T("runas"), __targv[0], args, NULL, SW_NORMAL)) {
+        ErrorMessage(g_lpMsg[IDS_MSG_SRVFAILED - IDS_MSG_FIRST],
+                     FALSE);
+        return 0;
+    }
+
+    return 1;
+}
+
+
 BOOL am_ConnectComputer(LPTSTR szComputerName)
 {
     int i = 0;
@@ -244,7 +259,7 @@ BOOL am_ConnectComputer(LPTSTR szComputerName)
     }
     if (RegConnectRegistry(szComputerName, HKEY_LOCAL_MACHINE, &hKeyRemote)
             != ERROR_SUCCESS) {
-        _sntprintf(szTmp, sizeof(szTmp) / sizeof(TCHAR), 
+        _sntprintf(szTmp, sizeof(szTmp) / sizeof(TCHAR),
                    g_lpMsg[IDS_MSG_ECONNECT - IDS_MSG_FIRST],
                    szComputerName);
         ErrorMessage(szTmp, FALSE);
@@ -288,13 +303,10 @@ BOOL GetSystemOSVersion(LPDWORD dwVersion)
         if (osvi.dwMajorVersion >= 5)
             *dwVersion = OS_VERSION_WIN2K;
         else
-            *dwVersion = OS_VERSION_WINNT;            
+            *dwVersion = OS_VERSION_WINNT;
         break;
 
     case VER_PLATFORM_WIN32_WINDOWS:
-        *dwVersion = OS_VERSION_WIN9X;
-        break;
-
     case VER_PLATFORM_WIN32s:
     default:
         *dwVersion = 0;
@@ -339,11 +351,11 @@ static VOID ShowNotifyIcon(HWND hWnd, DWORD dwMessage)
         _tcscpy(nid.szTip, g_lpMsg[IDS_MSG_RUNNINGALL - IDS_MSG_FIRST]);
     }
     else if (n) {
-        _sntprintf(nid.szTip, sizeof(nid.szTip) / sizeof(TCHAR), 
+        _sntprintf(nid.szTip, sizeof(nid.szTip) / sizeof(TCHAR),
                   g_lpMsg[IDS_MSG_RUNNING - IDS_MSG_FIRST], n, i);
     }
     else if (i) {
-        _sntprintf(nid.szTip, sizeof(nid.szTip) / sizeof(TCHAR), 
+        _sntprintf(nid.szTip, sizeof(nid.szTip) / sizeof(TCHAR),
                   g_lpMsg[IDS_MSG_RUNNINGNONE - IDS_MSG_FIRST], i);
     }
     else {
@@ -421,11 +433,9 @@ void ShowTryPopupMenu(HWND hWnd)
         appendMenuItem(hMenu, IDM_RESTORE,
                        g_lpMsg[IDS_MSG_MNUSHOW - IDS_MSG_FIRST],
                        TRUE, TRUE);
-        if (g_dwOSVersion >= OS_VERSION_WINNT) {
-            appendMenuItem(hMenu, IDC_SMANAGER,
-                           g_lpMsg[IDS_MSG_MNUSERVICES - IDS_MSG_FIRST],
-                           FALSE, TRUE);
-        }
+        appendMenuItem(hMenu, IDC_SMANAGER,
+                       g_lpMsg[IDS_MSG_MNUSERVICES - IDS_MSG_FIRST],
+                       FALSE, TRUE);
         appendMenuItem(hMenu, 0, _T(""), FALSE, TRUE);
         appendMenuItem(hMenu, IDM_EXIT,
                        g_lpMsg[IDS_MSG_MNUEXIT - IDS_MSG_FIRST],
@@ -527,386 +537,158 @@ static void addListBoxString(HWND hListBox, LPTSTR lpStr)
 }
 
 
-#ifndef UNICODE
-#define addListBoxStringA addListBoxString
-#else
-static void addListBoxStringA(HWND hListBox, LPSTR lpStr)
-{
-    static int nItems = 0;
-    TCHAR WStr[16384];
-
-    if (!g_bDlgServiceOn) {
-        return;
-    }
-    if (!MultiByteToWideChar(CP_ACP, 0, lpStr, (int)strlen(lpStr) + 1,
-                             WStr, (int) (sizeof(WStr) / sizeof(TCHAR))))
-        return;
-    ++nItems;
-    if (nItems > MAX_LOADSTRING)
-    {
-        SendMessage(hListBox, LB_RESETCONTENT, 0, 0);
-        nItems = 1;
-    }
-    ListBox_SetCurSel(hListBox,
-                      ListBox_AddString(hListBox, WStr));
-}
-#endif
-
-
-static DWORD WINAPI ConsoleOutputThread(LPVOID lpThreadParameter)
-{
-    static BYTE lpBuffer[MAX_PATH+1];
-    int nPtr = 0;
-    BYTE ch;
-    DWORD dwReaded;
-
-    while (ReadFile(g_hpipeOutRead, &ch, 1, &dwReaded, NULL) == TRUE)
-    {
-        if (dwReaded > 0)
-        {
-            if (ch == '\n' || nPtr >= MAX_PATH)
-            {
-                lpBuffer[nPtr] = '\0';
-                addListBoxStringA(g_hwndStdoutList, lpBuffer);
-                nPtr = 0;
-            }
-            else if (ch == '\t' && nPtr < (MAX_PATH - 4))
-            {
-                int i;
-                for (i = 0; i < 4; ++i) {
-                    lpBuffer[nPtr++] = ' ';
-                }
-            }
-            else if (ch != '\r') {
-                lpBuffer[nPtr++] = ch;
-            }
-        }
-    }
-    CloseHandle(g_hpipeInWrite);
-    CloseHandle(g_hpipeOutRead);
-    CloseHandle(g_hpipeStdError);
-    return 0;
-}
-
-
-DWORD WINAPI ConsoleWaitingThread(LPVOID lpThreadParameter)
-{
-    WaitForSingleObject(g_lpRedirectProc.hThread, INFINITE);
-    CloseHandle(g_lpRedirectProc.hThread);
-    MessageBeep(100);
-    g_bConsoleRun = FALSE;
-    SetCursor(g_hCursorArrow);
-    return 0;
-}
-
-
-BOOL RunRedirectedConsole(LPTSTR szCmdLine)
-{
-    DWORD dwThreadId;
-    HANDLE hProc;
-    STARTUPINFO stInfo;
-    BOOL bResult;
-
-    memset(&stInfo, 0, sizeof(stInfo));
-    stInfo.cb = sizeof(stInfo);
-    stInfo.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
-    stInfo.wShowWindow = SW_HIDE;
-
-    hProc = GetCurrentProcess();
-
-    if (!CreatePipe(&g_hpipeInRead, &g_hpipeInWrite, NULL, MAX_PATH)) {
-        ErrorMessage(NULL, TRUE);
-    }
-    if (!CreatePipe(&g_hpipeOutRead, &g_hpipeOutWrite, NULL, MAX_PATH*8)) {
-        ErrorMessage(NULL, TRUE);
-    }
-    DuplicateHandle(hProc, g_hpipeInRead, hProc, &g_hpipeInRead, 0, TRUE,
-                    DUPLICATE_CLOSE_SOURCE|DUPLICATE_SAME_ACCESS);
-    DuplicateHandle(hProc, g_hpipeOutWrite, hProc, &g_hpipeOutWrite, 0, TRUE,
-                    DUPLICATE_CLOSE_SOURCE|DUPLICATE_SAME_ACCESS);
-    DuplicateHandle(hProc, g_hpipeOutWrite, hProc, &g_hpipeStdError, 0, TRUE,
-                    DUPLICATE_SAME_ACCESS);
-    if (!g_hpipeInRead && !g_hpipeOutWrite && !g_hpipeStdError) {
-        ErrorMessage(NULL, TRUE);
-    }
-    stInfo.hStdInput  = g_hpipeInRead;
-    stInfo.hStdOutput = g_hpipeOutWrite;
-    stInfo.hStdError  = g_hpipeStdError;
-
-    bResult = CreateProcess(NULL,
-        szCmdLine,
-        NULL,
-        NULL,
-        TRUE,
-        CREATE_SUSPENDED,
-        NULL,
-        NULL,
-        &stInfo,
-        &g_lpRedirectProc);
-
-
-    CloseHandle(g_hpipeInRead);
-    CloseHandle(g_hpipeOutWrite);
-    CloseHandle(g_hpipeStdError);
-
-    if (!bResult)
-    {
-        CloseHandle(g_hpipeInWrite);
-        CloseHandle(g_hpipeOutRead);
-        CloseHandle(g_hpipeStdError);
-        return FALSE;
-    }
-
-    CloseHandle(CreateThread(NULL, 0, ConsoleOutputThread,
-                             0, 0, &dwThreadId));
-    ResumeThread(g_lpRedirectProc.hThread);
-    CloseHandle(CreateThread(NULL, 0, ConsoleWaitingThread,
-                             0, 0, &dwThreadId));
-
-    return TRUE;
-}
-
-
-BOOL RunAndForgetConsole(LPTSTR szCmdLine, BOOL bRedirectConsole)
-{
-    STARTUPINFO stInfo;
-    PROCESS_INFORMATION prInfo;
-    BOOL bResult;
-
-    if (bRedirectConsole) {
-        return RunRedirectedConsole(szCmdLine);
-    }
-
-    memset(&stInfo, 0, sizeof(stInfo));
-    stInfo.cb = sizeof(stInfo);
-    stInfo.dwFlags = STARTF_USESHOWWINDOW;
-    stInfo.wShowWindow = SW_HIDE;
-
-    bResult = CreateProcess(NULL,
-                            szCmdLine,
-                            NULL,
-                            NULL,
-                            TRUE,
-                            CREATE_NEW_CONSOLE,
-                            NULL,
-                            NULL,
-                            &stInfo,
-                            &prInfo);
-
-    if (!bResult) {
-        return FALSE;
-    }
-    if (g_dwOSVersion == OS_VERSION_WIN9X) {
-        /* give some time to rescan the status */
-        Sleep(2000);
-    }
-    CloseHandle(prInfo.hThread);
-    CloseHandle(prInfo.hProcess);
-    return TRUE;
-}
-
-
 BOOL ApacheManageService(LPCTSTR szServiceName, LPCTSTR szImagePath,
                          LPTSTR szComputerName, DWORD dwCommand)
 {
-    TCHAR szBuf[MAX_PATH];
     TCHAR szMsg[MAX_PATH];
-    LPTSTR sPos;
     BOOL retValue;
-    BOOL serviceFlag = TRUE;
     SC_HANDLE schService;
     SC_HANDLE schSCManager;
     SERVICE_STATUS schSStatus;
     int ticks;
 
-    if (g_dwOSVersion == OS_VERSION_WIN9X)
-    {
-        sPos = _tcsstr(szImagePath, _T("-k start"));
-        if (sPos)
-        {
-            _tcsncpy(szBuf, szImagePath, (int)(sPos - szImagePath));
-            switch (dwCommand)
-            {
-            case SERVICE_CONTROL_STOP:
-                _tcscat(szBuf, _T(" -k shutdown -n "));
-                break;
-
-            case SERVICE_CONTROL_CONTINUE:
-                _sntprintf(szMsg, sizeof(szMsg) / sizeof(TCHAR),
-                          g_lpMsg[IDS_MSG_SRVSTART - IDS_MSG_FIRST],
-                          szServiceName);
-                addListBoxString(g_hwndStdoutList, szMsg);
-                _tcscat(szBuf, _T(" -k start -n "));
-                serviceFlag = FALSE;
-                break;
-
-            case SERVICE_APACHE_RESTART:
-                _tcscat(szBuf, _T(" -k restart -n "));
-                break;
+    schSCManager = OpenSCManager(szComputerName, NULL,
+                                 SC_MANAGER_CONNECT);
+    if (!schSCManager) {
+        ErrorMessage(g_lpMsg[IDS_MSG_SRVFAILED - IDS_MSG_FIRST],
+                     FALSE);
+        return FALSE;
+    }
 
-            default:
-                return FALSE;
-            }
-            _tcscat(szBuf, szServiceName);
+    schService = OpenService(schSCManager, szServiceName,
+                             SERVICE_QUERY_STATUS | SERVICE_START |
+                             SERVICE_STOP | SERVICE_USER_DEFINED_CONTROL);
+    if (schService == NULL)
+    {
+        /* Avoid recursion of ImagePath NULL (from this Respawn) */
+        if (szImagePath) {
+            am_RespawnAsUserAdmin(g_hwndMain, dwCommand,
+                                  szServiceName, szComputerName);
         }
         else {
-            return FALSE;
-        }
-        g_bConsoleRun = TRUE;
-        SetCursor(g_hCursorHourglass);
-        if (!RunAndForgetConsole(szBuf, serviceFlag))
-        {
-            ErrorMessage(NULL, FALSE);
-            g_bConsoleRun = FALSE;
-            SetCursor(g_hCursorArrow);
-            return FALSE;
-        }
-        else if (!serviceFlag)
-        {
-            _sntprintf(szMsg, sizeof(szMsg) / sizeof(TCHAR), 
-                      g_lpMsg[IDS_MSG_SRVSTARTED - IDS_MSG_FIRST],
-                      szServiceName);
-            addListBoxString(g_hwndStdoutList, szMsg);
-            g_bConsoleRun = FALSE;
-            SetCursor(g_hCursorArrow);
-            return TRUE;
+            ErrorMessage(g_lpMsg[IDS_MSG_SRVFAILED - IDS_MSG_FIRST],
+                         FALSE);
         }
+        CloseServiceHandle(schSCManager);
+        return FALSE;
     }
     else
     {
-        schSCManager = OpenSCManager(szComputerName, NULL,
-                                     SC_MANAGER_CONNECT);
-        if (!schSCManager) {
-            return FALSE;
-        }
-
-        schService = OpenService(schSCManager, szServiceName,
-                                 SERVICE_QUERY_STATUS | SERVICE_START |
-                                 SERVICE_STOP | SERVICE_USER_DEFINED_CONTROL);
-        if (schService != NULL)
+        retValue = FALSE;
+        g_bConsoleRun = TRUE;
+        SetCursor(g_hCursorHourglass);
+        switch (dwCommand)
         {
-            retValue = FALSE;
-            g_bConsoleRun = TRUE;
-            SetCursor(g_hCursorHourglass);
-            switch (dwCommand)
-            {
-            case SERVICE_CONTROL_STOP:
-                _sntprintf(szMsg, sizeof(szMsg) / sizeof(TCHAR), 
-                          g_lpMsg[IDS_MSG_SRVSTOP - IDS_MSG_FIRST],
-                          szServiceName);
-                addListBoxString(g_hwndStdoutList, szMsg);
-                if (ControlService(schService, SERVICE_CONTROL_STOP,
-                                   &schSStatus)) {
-                    Sleep(1000);
-                    while (QueryServiceStatus(schService, &schSStatus))
-                    {
-                        if (schSStatus.dwCurrentState == SERVICE_STOP_PENDING)
-                        {
-                            Sleep(1000);
-                        }
-                        else {
-                            break;
-                        }
-                    }
-                }
-                if (QueryServiceStatus(schService, &schSStatus))
+          case SERVICE_CONTROL_STOP:
+            _sntprintf(szMsg, sizeof(szMsg) / sizeof(TCHAR),
+                       g_lpMsg[IDS_MSG_SRVSTOP - IDS_MSG_FIRST],
+                       szServiceName);
+            addListBoxString(g_hwndStdoutList, szMsg);
+            if (ControlService(schService, SERVICE_CONTROL_STOP,
+                               &schSStatus)) {
+                Sleep(1000);
+                while (QueryServiceStatus(schService, &schSStatus))
                 {
-                    if (schSStatus.dwCurrentState == SERVICE_STOPPED)
+                    if (schSStatus.dwCurrentState == SERVICE_STOP_PENDING)
                     {
-                        retValue = TRUE;
-                        _sntprintf(szMsg, sizeof(szMsg) / sizeof(TCHAR), 
-                                  g_lpMsg[IDS_MSG_SRVSTOPPED - IDS_MSG_FIRST],
-                                  szServiceName);
-                        addListBoxString(g_hwndStdoutList, szMsg);
+                        Sleep(1000);
                     }
-                }
-                break;
-
-            case SERVICE_CONTROL_CONTINUE:
-                _sntprintf(szMsg, sizeof(szMsg) / sizeof(TCHAR),
-                          g_lpMsg[IDS_MSG_SRVSTART - IDS_MSG_FIRST],
-                          szServiceName);
-                addListBoxString(g_hwndStdoutList, szMsg);
-
-                if (StartService(schService, 0, NULL))
-                {
-                    Sleep(1000);
-                    while (QueryServiceStatus(schService, &schSStatus))
-                    {
-                        if (schSStatus.dwCurrentState == SERVICE_START_PENDING)
-                        {
-                            Sleep(1000);
-                        }
-                        else {
-                            break;
-                        }
+                    else {
+                        break;
                     }
                 }
-                if (QueryServiceStatus(schService, &schSStatus))
+            }
+            if (QueryServiceStatus(schService, &schSStatus))
+            {
+                if (schSStatus.dwCurrentState == SERVICE_STOPPED)
                 {
-                    if (schSStatus.dwCurrentState == SERVICE_RUNNING)
-                    {
-                        retValue = TRUE;
-                        _sntprintf(szMsg, sizeof(szMsg) / sizeof(TCHAR), 
-                                  g_lpMsg[IDS_MSG_SRVSTARTED - IDS_MSG_FIRST],
-                                  szServiceName);
-                        addListBoxString(g_hwndStdoutList, szMsg);
-                    }
+                    retValue = TRUE;
+                    _sntprintf(szMsg, sizeof(szMsg) / sizeof(TCHAR),
+                               g_lpMsg[IDS_MSG_SRVSTOPPED - IDS_MSG_FIRST],
+                               szServiceName);
+                    addListBoxString(g_hwndStdoutList, szMsg);
                 }
-                break;
+            }
+            break;
 
-            case SERVICE_APACHE_RESTART:
-                _sntprintf(szMsg, sizeof(szMsg) / sizeof(TCHAR), 
-                          g_lpMsg[IDS_MSG_SRVRESTART - IDS_MSG_FIRST],
-                          szServiceName);
-                addListBoxString(g_hwndStdoutList, szMsg);
-                if (ControlService(schService, SERVICE_APACHE_RESTART,
-                                   &schSStatus))
+          case SERVICE_CONTROL_CONTINUE:
+            _sntprintf(szMsg, sizeof(szMsg) / sizeof(TCHAR),
+                       g_lpMsg[IDS_MSG_SRVSTART - IDS_MSG_FIRST],
+                       szServiceName);
+            addListBoxString(g_hwndStdoutList, szMsg);
+
+            if (StartService(schService, 0, NULL))
+            {
+                Sleep(1000);
+                while (QueryServiceStatus(schService, &schSStatus))
                 {
-                    ticks = 60;
-                    while (schSStatus.dwCurrentState == SERVICE_START_PENDING)
+                    if (schSStatus.dwCurrentState == SERVICE_START_PENDING)
                     {
                         Sleep(1000);
-                        if (!QueryServiceStatus(schService, &schSStatus))
-                        {
-                            CloseServiceHandle(schService);
-                            CloseServiceHandle(schSCManager);
-                            g_bConsoleRun = FALSE;
-                            SetCursor(g_hCursorArrow);
-                            return FALSE;
-                        }
-                        if (!--ticks) {
-                            break;
-                        }
+                    }
+                    else {
+                        break;
                     }
                 }
+            }
+            if (QueryServiceStatus(schService, &schSStatus))
+            {
                 if (schSStatus.dwCurrentState == SERVICE_RUNNING)
                 {
                     retValue = TRUE;
-                    _sntprintf(szMsg, sizeof(szMsg) / sizeof(TCHAR), 
-                              g_lpMsg[IDS_MSG_SRVRESTARTED - IDS_MSG_FIRST],
-                              szServiceName);
+                    _sntprintf(szMsg, sizeof(szMsg) / sizeof(TCHAR),
+                               g_lpMsg[IDS_MSG_SRVSTARTED - IDS_MSG_FIRST],
+                               szServiceName);
                     addListBoxString(g_hwndStdoutList, szMsg);
                 }
-                break;
             }
-            CloseServiceHandle(schService);
-            CloseServiceHandle(schSCManager);
-            if (!retValue) {
-                ErrorMessage(g_lpMsg[IDS_MSG_SRVFAILED - IDS_MSG_FIRST],
-                             FALSE);
+            break;
+
+          case SERVICE_APACHE_RESTART:
+            _sntprintf(szMsg, sizeof(szMsg) / sizeof(TCHAR),
+                       g_lpMsg[IDS_MSG_SRVRESTART - IDS_MSG_FIRST],
+                       szServiceName);
+            addListBoxString(g_hwndStdoutList, szMsg);
+            if (ControlService(schService, SERVICE_APACHE_RESTART,
+                               &schSStatus))
+            {
+                ticks = 60;
+                while (schSStatus.dwCurrentState == SERVICE_START_PENDING)
+                {
+                    Sleep(1000);
+                    if (!QueryServiceStatus(schService, &schSStatus))
+                    {
+                        CloseServiceHandle(schService);
+                        CloseServiceHandle(schSCManager);
+                        g_bConsoleRun = FALSE;
+                        SetCursor(g_hCursorArrow);
+                        return FALSE;
+                    }
+                    if (!--ticks) {
+                        break;
+                    }
+                }
+            }
+            if (schSStatus.dwCurrentState == SERVICE_RUNNING)
+            {
+                retValue = TRUE;
+                _sntprintf(szMsg, sizeof(szMsg) / sizeof(TCHAR),
+                           g_lpMsg[IDS_MSG_SRVRESTARTED - IDS_MSG_FIRST],
+                           szServiceName);
+                addListBoxString(g_hwndStdoutList, szMsg);
             }
-            g_bConsoleRun = FALSE;
-            SetCursor(g_hCursorArrow);
-            return retValue;
-        }
-        else {
-            g_bRescanServices = TRUE;
+            break;
         }
+        CloseServiceHandle(schService);
         CloseServiceHandle(schSCManager);
-        return FALSE;
+        if (!retValue) {
+            ErrorMessage(g_lpMsg[IDS_MSG_SRVFAILED - IDS_MSG_FIRST],
+                         FALSE);
+        }
+        g_bConsoleRun = FALSE;
+        SetCursor(g_hCursorArrow);
+        return retValue;
     }
-
     return FALSE;
 }
 
@@ -915,55 +697,36 @@ BOOL IsServiceRunning(LPCTSTR szServiceName, LPCTSTR szComputerName,
                       LPDWORD lpdwPid)
 {
     DWORD dwPid;
-    HWND hWnd;
     SC_HANDLE schService;
     SC_HANDLE schSCManager;
     SERVICE_STATUS schSStatus;
 
-    if (g_dwOSVersion == OS_VERSION_WIN9X)
-    {
-        hWnd = FindWindow(_T("ApacheWin95ServiceMonitor"), szServiceName);
-        if (hWnd && GetWindowThreadProcessId(hWnd, &dwPid))
-        {
-            *lpdwPid = 1;
-            return TRUE;
-        }
-        else {
-            return FALSE;
-        }
+    dwPid = 0;
+    schSCManager = OpenSCManager(szComputerName, NULL,
+                                SC_MANAGER_CONNECT);
+    if (!schSCManager) {
+        return FALSE;
     }
-    else
-    {
-        dwPid = 0;
-        schSCManager = OpenSCManager(szComputerName, NULL,
-                                     SC_MANAGER_CONNECT);
-        if (!schSCManager) {
-            return FALSE;
-        }
 
-        schService = OpenService(schSCManager, szServiceName,
-                                 SERVICE_QUERY_STATUS);
-        if (schService != NULL)
+    schService = OpenService(schSCManager, szServiceName,
+                             SERVICE_QUERY_STATUS);
+    if (schService != NULL)
+    {
+        if (QueryServiceStatus(schService, &schSStatus))
         {
-            if (QueryServiceStatus(schService, &schSStatus))
-            {
-                dwPid = schSStatus.dwCurrentState;
-                if (lpdwPid) {
-                    *lpdwPid = 1;
-                }
+            dwPid = schSStatus.dwCurrentState;
+            if (lpdwPid) {
+                *lpdwPid = 1;
             }
-            CloseServiceHandle(schService);
-            CloseServiceHandle(schSCManager);
-            return dwPid == SERVICE_RUNNING ? TRUE : FALSE;
-        }
-        else {
-            g_bRescanServices = TRUE;
         }
+        CloseServiceHandle(schService);
         CloseServiceHandle(schSCManager);
-        return FALSE;
-
+        return dwPid == SERVICE_RUNNING ? TRUE : FALSE;
     }
-
+    else {
+        g_bRescanServices = TRUE;
+    }
+    CloseServiceHandle(schSCManager);
     return FALSE;
 }
 
@@ -1206,14 +969,8 @@ LRESULT CALLBACK ServiceDlgProc(HWND hDlg, UINT message,
                       g_lpMsg[IDS_MSG_SERVICES - IDS_MSG_FIRST]);
         SetWindowText(GetDlgItem(hDlg, IDC_SCONNECT),
                       g_lpMsg[IDS_MSG_CONNECT - IDS_MSG_FIRST]);
-        SetWindowText(GetDlgItem(hDlg, IDC_SEXIT),
-                      g_lpMsg[IDS_MSG_MNUEXIT - IDS_MSG_FIRST]);
-        if (g_dwOSVersion < OS_VERSION_WINNT)
-        {
-            ShowWindow(GetDlgItem(hDlg, IDC_SMANAGER), SW_HIDE);
-            ShowWindow(GetDlgItem(hDlg, IDC_SCONNECT), SW_HIDE);
-            ShowWindow(GetDlgItem(hDlg, IDC_SDISCONN), SW_HIDE);
-        }
+        SetWindowText(GetDlgItem(hDlg, IDCANCEL),
+                      g_lpMsg[IDS_MSG_OK - IDS_MSG_FIRST]);
         hListBox = GetDlgItem(hDlg, IDL_SERVICES);
         g_hwndStdoutList = GetDlgItem(hDlg, IDL_STDOUT);
         hStatusBar = CreateStatusWindow(0x0800 /* SBT_TOOLTIPS */
@@ -1292,6 +1049,7 @@ LRESULT CALLBACK ServiceDlgProc(HWND hDlg, UINT message,
         }
         switch (lpdis->itemAction)
         {
+        case ODA_FOCUS:
         case ODA_SELECT:
         case ODA_DRAWENTIRE:
             g_hBmpPicture = (HBITMAP)SendMessage(lpdis->hwndItem,
@@ -1324,6 +1082,7 @@ LRESULT CALLBACK ServiceDlgProc(HWND hDlg, UINT message,
                 if (g_hBmpPicture == g_hBmpStop)
                 {
                     Button_Enable(GetDlgItem(hDlg, IDC_SSTART), TRUE);
+                    Button_SetStyle(GetDlgItem(hDlg, IDC_SSTART), BS_DEFPUSHBUTTON, TRUE);
                     Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), FALSE);
                     Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), FALSE);
                 }
@@ -1331,6 +1090,7 @@ LRESULT CALLBACK ServiceDlgProc(HWND hDlg, UINT message,
                 {
                     Button_Enable(GetDlgItem(hDlg, IDC_SSTART), FALSE);
                     Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), TRUE);
+                    Button_SetStyle(GetDlgItem(hDlg, IDC_SSTOP), BS_DEFPUSHBUTTON, TRUE);
                     Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), TRUE);
                 }
                 else {
@@ -1353,9 +1113,16 @@ LRESULT CALLBACK ServiceDlgProc(HWND hDlg, UINT message,
                 else {
                     SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)_T(""));
                 }
-                SetTextColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
-                SetBkColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHT));
-                FillRect(lpdis->hDC, &rcBitmap, (HBRUSH)(COLOR_HIGHLIGHTTEXT));
+                if (lpdis->itemState & ODS_FOCUS) {
+                    SetTextColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
+                    SetBkColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHT));
+                    FillRect(lpdis->hDC, &rcBitmap, (HBRUSH)(COLOR_HIGHLIGHT+1));
+                }
+                else {
+                    SetTextColor(lpdis->hDC, GetSysColor(COLOR_INACTIVECAPTIONTEXT));
+                    SetBkColor(lpdis->hDC, GetSysColor(COLOR_INACTIVECAPTION));
+                    FillRect(lpdis->hDC, &rcBitmap, (HBRUSH)(COLOR_INACTIVECAPTION+1));
+                }
             }
             else
             {
@@ -1365,9 +1132,6 @@ LRESULT CALLBACK ServiceDlgProc(HWND hDlg, UINT message,
             }
             TextOut(lpdis->hDC, XBITMAP + 6, y, szBuf, (int)_tcslen(szBuf));
             break;
-
-        case ODA_FOCUS:
-            break;
         }
         return TRUE;
     case WM_COMMAND:
@@ -1399,7 +1163,7 @@ LRESULT CALLBACK ServiceDlgProc(HWND hDlg, UINT message,
             }
             break;
 
-        case IDOK:
+        case IDCANCEL:
             EndDialog(hDlg, TRUE);
             return TRUE;
 
@@ -1438,7 +1202,7 @@ LRESULT CALLBACK ServiceDlgProc(HWND hDlg, UINT message,
 
         case IDC_SMANAGER:
             if (g_dwOSVersion >= OS_VERSION_WIN2K) {
-                ShellExecute(NULL, _T("open"), _T("services.msc"), _T("/s"),
+                ShellExecute(hDlg, _T("open"), _T("services.msc"), _T("/s"),
                              NULL, SW_NORMAL);
             }
             else {
@@ -1446,11 +1210,6 @@ LRESULT CALLBACK ServiceDlgProc(HWND hDlg, UINT message,
             }
             return TRUE;
 
-        case IDC_SEXIT:
-            EndDialog(hDlg, TRUE);
-            SendMessage(g_hwndMain, WM_COMMAND, (WPARAM)IDM_EXIT, 0);
-            return TRUE;
-
         case IDC_SCONNECT:
             DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_DLGCONNECT),
                       hDlg, (DLGPROC)ConnectDlgProc);
@@ -1539,7 +1298,6 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
 
         case WM_TIMER_REFRESH:
         {
-            int nPrev = 0, nNew = 0;
             EnterCriticalSection(&g_stcSection);
             if (g_bRescanServices)
             {
@@ -1715,7 +1473,7 @@ static int KillAllMonitors(void)
     int exitcode = 0;
     PWTS_PROCESS_INFO tsProcs;
     DWORD tsProcCount, i;
-    DWORD thisProcId; 
+    DWORD thisProcId;
 
     /* This is graceful, close our own Window, clearing the icon */
     if ((appwindow = FindWindow(g_szWindowClass, g_szTitle)) != NULL)
@@ -1739,7 +1497,7 @@ static int KillAllMonitors(void)
     for (i = 0; i < tsProcCount; ++i) {
         if (_tcscmp(tsProcs[i].pProcessName, _T(AM_STRINGIFY(BIN_NAME))) == 0
                 && tsProcs[i].ProcessId != thisProcId)
-            WTSTerminateProcess(WTS_CURRENT_SERVER_HANDLE, 
+            WTSTerminateProcess(WTS_CURRENT_SERVER_HANDLE,
                                 tsProcs[i].ProcessId, 1);
     }
     WTSFreeMemory(tsProcs);
@@ -1777,19 +1535,21 @@ HWND CreateMainWindow(HINSTANCE hInstance)
     return hWnd;
 }
 
-#ifdef UNICODE
-int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
-                    LPWSTR lpCmdLine, int nCmdShow)
-#else
+
+#ifndef UNICODE
+/* Borrowed from CRT internal.h for _MBCS argc/argv parsing in this GUI app */
+int  __cdecl _setargv(void);
+#endif
+
 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    LPSTR lpCmdLine, int nCmdShow)
-#endif
 {
     TCHAR szTmp[MAX_LOADSTRING];
     TCHAR szCmp[MAX_COMPUTERNAME_LENGTH+4];
     MSG msg;
-    /* single instance mutex */
-    HANDLE hMutex;
+    /* existing window */
+    HWND appwindow;
+    DWORD dwControl;
     int i;
     DWORD d;
 
@@ -1821,18 +1581,39 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
     LoadString(hInstance, IDS_APMONITORCLASS, szTmp, MAX_LOADSTRING);
     g_szWindowClass = _tcsdup(szTmp);
 
-    if (_tcsstr(lpCmdLine, _T("--kill")) != NULL) {
+    appwindow = FindWindow(g_szWindowClass, g_szTitle);
+
+#ifdef UNICODE
+    __wargv = CommandLineToArgvW(GetCommandLineW(), &__argc);
+#else
+    _setargv();
+#endif
+
+    if ((__argc == 2) && (_tcscmp(__targv[1], _T("--kill")) == 0))
+    {
         /* Off to chase and close up every ApacheMonitor taskbar window */
         return KillAllMonitors();
     }
+    else if ((__argc == 4) && (g_dwOSVersion >= OS_VERSION_WIN2K))
+    {
+        dwControl = _ttoi(__targv[1]);
+        if ((dwControl != SERVICE_CONTROL_CONTINUE) &&
+            (dwControl != SERVICE_APACHE_RESTART) &&
+            (dwControl != SERVICE_CONTROL_STOP))
+        {
+            return 1;
+        }
 
-    hMutex = CreateMutex(NULL, FALSE, _T("APSRVMON_MUTEX"));
-    if ((hMutex == NULL) || (GetLastError() == ERROR_ALREADY_EXISTS))
+        /* Chase down and close up our session's previous window */
+        if ((appwindow) != NULL)
+            KillAWindow(appwindow);
+    }
+    else if (__argc != 1) {
+        return 1;
+    }
+    else if (appwindow)
     {
         ErrorMessage(g_lpMsg[IDS_MSG_APPRUNNING - IDS_MSG_FIRST], FALSE);
-        if (hMutex) {
-            CloseHandle(hMutex);
-        }
         return 0;
     }
 
@@ -1863,6 +1644,10 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
     g_hwndServiceDlg = NULL;
     if (g_hwndMain != NULL)
     {
+        /* To avoid recursion, pass ImagePath NULL (a noop on NT and later) */
+        if ((__argc == 4) && (g_dwOSVersion >= OS_VERSION_WIN2K))
+            ApacheManageService(__targv[2], NULL, __targv[3], dwControl);
+
         while (GetMessage(&msg, NULL, 0, 0) == TRUE)
         {
             TranslateMessage(&msg);
@@ -1872,7 +1657,6 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
     }
     am_ClearComputersSt();
     DeleteCriticalSection(&g_stcSection);
-    CloseHandle(hMutex);
     DestroyIcon(g_icoStop);
     DestroyIcon(g_icoRun);
     DestroyCursor(g_hCursorHourglass);