1 /* ====================================================================
2 * The Apache Software License, Version 1.1
4 * Copyright (c) 2000 The Apache Software Foundation. All rights
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
19 * 3. The end-user documentation included with the redistribution,
20 * if any, must include the following acknowledgment:
21 * "This product includes software developed by the
22 * Apache Software Foundation (http://www.apache.org/)."
23 * Alternately, this acknowledgment may appear in the software itself,
24 * if and wherever such third-party acknowledgments normally appear.
26 * 4. The names "Apache" and "Apache Software Foundation" must
27 * not be used to endorse or promote products derived from this
28 * software without prior written permission. For written
29 * permission, please contact apache@apache.org.
31 * 5. Products derived from this software may not be called "Apache",
32 * nor may "Apache" appear in their name, without prior written
33 * permission of the Apache Software Foundation.
35 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
42 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 * ====================================================================
49 * This software consists of voluntary contributions made by many
50 * individuals on behalf of the Apache Software Foundation. For more
51 * information on the Apache Software Foundation, please see
52 * <http://www.apache.org/>.
54 * Portions of this software are based upon public domain software
55 * originally written at the National Center for Supercomputing Applications,
56 * University of Illinois, Urbana-Champaign.
59 /* ====================================================================
60 * ApacheMonitor.c Simple program to manage and monitor Apache services.
62 * Contributed by Mladen Turk <mturk@mappingsoft.com>
65 * ====================================================================
68 #define _WIN32_WINNT 0x0400
81 #include "ApacheMonitor.h"
84 #define OS_VERSION_WIN9X 1
85 #define OS_VERSION_WINNT 2
86 #define OS_VERSION_WIN2K 3
87 /* Should be enough */
88 #define MAX_APACHE_SERVICES 128
90 #define WM_TRAYMESSAGE (WM_APP+1)
91 #define WM_UPDATEMESSAGE (WM_USER+1)
92 #define WM_TIMER_REFRESH 10
93 #define WM_TIMER_RESCAN 11
94 #define SERVICE_APACHE_RESTART 128
97 #define MAX_LOADSTRING 100
98 #define REFRESH_TIME 2000 /* service refresh time (ms) */
99 #define RESCAN_TIME 20000 /* registry rescan time (ms) */
101 typedef struct _st_APACHE_SERVICE
110 /* Global variables */
111 HINSTANCE g_hInstance = NULL;
112 TCHAR *g_szTitle; /* The title bar text */
113 TCHAR *g_szWindowClass; /* Window Class Name */
116 UINT g_bUiTaskbarCreated;
118 BOOL g_bDlgServiceOn = FALSE;
119 BOOL g_bConsoleRun = FALSE;
120 ST_APACHE_SERVICE g_stServices[MAX_APACHE_SERVICES];
122 HBITMAP g_hBmpStart, g_hBmpStop;
123 HBITMAP g_hBmpPicture, g_hBmpOld;
124 BOOL g_bRescanServices;
125 HWND g_hwndServiceDlg;
127 HWND g_hwndStdoutList;
128 HCURSOR g_hCursorHourglass;
129 HCURSOR g_hCursorArrow;
131 HANDLE g_hpipeOutRead;
132 HANDLE g_hpipeOutWrite;
133 HANDLE g_hpipeInRead;
134 HANDLE g_hpipeInWrite;
135 HANDLE g_hpipeStdError;
137 PROCESS_INFORMATION g_lpRedirectProc;
138 CRITICAL_SECTION g_stcSection;
141 /* locale language support */
142 static CHAR *g_lpMsg[IDS_MSG_LAST - IDS_MSG_FIRST + 1];
144 void am_ClearServicesSt()
147 for (i = 0; i < MAX_APACHE_SERVICES; i++)
149 if (g_stServices[i].szServiceName)
150 free(g_stServices[i].szServiceName);
151 if (g_stServices[i].szDisplayName)
152 free(g_stServices[i].szDisplayName);
153 if (g_stServices[i].szDescription)
154 free(g_stServices[i].szDescription);
155 if (g_stServices[i].szImagePath)
156 free(g_stServices[i].szImagePath);
159 ZeroMemory(g_stServices, sizeof(ST_APACHE_SERVICE) * MAX_APACHE_SERVICES);
163 void ErrorMessage(LPCSTR szError, BOOL bFatal)
165 LPVOID lpMsgBuf = NULL;
167 MessageBox(NULL, szError, g_lpMsg[IDS_MSG_ERROR-IDS_MSG_FIRST],
168 MB_OK | (bFatal ? MB_ICONERROR : MB_ICONEXCLAMATION));
171 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
172 FORMAT_MESSAGE_FROM_SYSTEM |
173 FORMAT_MESSAGE_IGNORE_INSERTS,
177 (LPSTR) &lpMsgBuf, 0, NULL);
178 MessageBox(NULL, (LPCSTR)lpMsgBuf, g_lpMsg[IDS_MSG_ERROR-IDS_MSG_FIRST],
179 MB_OK | (bFatal ? MB_ICONERROR : MB_ICONEXCLAMATION));
186 LPSTR GetStringRes(int id)
188 static TCHAR buffer[MAX_PATH];
191 LoadString(GetModuleHandle (NULL), id, buffer, MAX_PATH);
195 BOOL GetSystemOSVersion(LPDWORD dwVersion)
199 Try calling GetVersionEx using the OSVERSIONINFOEX structure.
200 If that fails, try using the OSVERSIONINFO structure.
202 ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
203 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
205 if (!GetVersionEx(&osvi))
208 switch (osvi.dwPlatformId)
210 case VER_PLATFORM_WIN32_NT:
211 if (osvi.dwMajorVersion <= 4)
212 *dwVersion = OS_VERSION_WINNT;
213 else if (osvi.dwMajorVersion == 5)
214 *dwVersion = OS_VERSION_WIN2K;
219 case VER_PLATFORM_WIN32_WINDOWS:
220 *dwVersion = OS_VERSION_WIN9X;
223 case VER_PLATFORM_WIN32s:
233 static VOID ShowNotifyIcon(HWND hWnd, DWORD dwMessage)
239 ZeroMemory(&nid,sizeof(nid));
240 nid.cbSize = sizeof(NOTIFYICONDATA);
243 nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
244 nid.uCallbackMessage = WM_TRAYMESSAGE;
246 while (g_stServices[i].szServiceName != NULL)
248 if (g_stServices[i].dwPid != 0)
252 if (dwMessage != NIM_DELETE)
255 nid.hIcon = g_icoRun;
257 nid.hIcon = g_icoStop;
262 lstrcpy(nid.szTip, g_lpMsg[IDS_MSG_RUNNINGALL-IDS_MSG_FIRST]);
264 sprintf(nid.szTip, g_lpMsg[IDS_MSG_RUNNING-IDS_MSG_FIRST], n, i);
266 sprintf(nid.szTip, g_lpMsg[IDS_MSG_RUNNINGNONE-IDS_MSG_FIRST], i);
268 lstrcpy(nid.szTip, g_lpMsg[IDS_MSG_NOSERVICES-IDS_MSG_FIRST]);
269 Shell_NotifyIcon(dwMessage, &nid);
272 void appendMenuItem(HMENU hMenu, UINT uMenuId, LPSTR szName, BOOL fDefault, BOOL fEnabled)
276 ZeroMemory(&mii, sizeof(MENUITEMINFO));
277 mii.cbSize = sizeof(MENUITEMINFO);
278 mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
281 mii.fType = MFT_STRING;
284 mii.fState = MFS_DEFAULT;
286 mii.fState |= MFS_DISABLED;
287 mii.dwTypeData = szName;
290 mii.fType = MFT_SEPARATOR;
291 InsertMenuItem(hMenu, uMenuId, FALSE, &mii);
294 void appendServiceMenu(HMENU hMenu, UINT uMenuId, LPSTR szServiceName, BOOL fRunning)
299 smh = CreatePopupMenu();
301 appendMenuItem(smh, IDM_SM_START + uMenuId, g_lpMsg[IDS_MSG_SSTART-IDS_MSG_FIRST], FALSE, !fRunning);
302 appendMenuItem(smh, IDM_SM_STOP + uMenuId, g_lpMsg[IDS_MSG_SSTOP-IDS_MSG_FIRST], FALSE, fRunning);
303 appendMenuItem(smh, IDM_SM_RESTART + uMenuId, g_lpMsg[IDS_MSG_SRESTART-IDS_MSG_FIRST], FALSE, fRunning);
305 ZeroMemory(&mii, sizeof(MENUITEMINFO));
306 mii.cbSize = sizeof(MENUITEMINFO);
307 mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE | MIIM_SUBMENU;
308 mii.fType = MFT_STRING;
310 mii.dwTypeData = szServiceName;
312 InsertMenuItem(hMenu, IDM_SM_SERVICE + uMenuId, FALSE, &mii);
315 void ShowTryPopupMenu(HWND hWnd)
317 /* create popup menu */
318 HMENU hMenu = CreatePopupMenu();
323 appendMenuItem(hMenu, IDM_RESTORE, g_lpMsg[IDS_MSG_MNUSHOW-IDS_MSG_FIRST], TRUE, TRUE);
324 if (g_dwOSVersion >= OS_VERSION_WINNT)
325 appendMenuItem(hMenu, IDC_SMANAGER, g_lpMsg[IDS_MSG_MNUSERVICES-IDS_MSG_FIRST], FALSE, TRUE);
326 appendMenuItem(hMenu, 0, "", FALSE, TRUE);
327 appendMenuItem(hMenu, IDM_EXIT, g_lpMsg[IDS_MSG_MNUEXIT-IDS_MSG_FIRST], FALSE, TRUE);
329 if (!SetForegroundWindow(hWnd))
330 SetForegroundWindow(NULL);
332 TrackPopupMenu(hMenu, TPM_LEFTALIGN|TPM_RIGHTBUTTON,
333 pt.x, pt.y, 0, hWnd, NULL);
338 void ShowTryServicesMenu(HWND hWnd)
340 /* create services list popup menu and submenus */
341 HMENU hMenu = CreatePopupMenu();
347 while (g_stServices[i].szServiceName != NULL)
349 appendServiceMenu(hMenu, i, g_stServices[i].szDisplayName,
350 g_stServices[i].dwPid != 0);
355 if (!SetForegroundWindow(hWnd))
356 SetForegroundWindow(NULL);
358 TrackPopupMenu(hMenu, TPM_LEFTALIGN|TPM_RIGHTBUTTON,
359 pt.x, pt.y, 0, hWnd, NULL);
365 BOOL CenterWindow(HWND hwndChild)
367 RECT rChild, rWorkArea;
372 /* Get the Height and Width of the child window */
373 GetWindowRect(hwndChild, &rChild);
374 wChild = rChild.right - rChild.left;
375 hChild = rChild.bottom - rChild.top;
377 /* Get the limits of the 'workarea' */
378 bResult = SystemParametersInfo(
384 rWorkArea.left = rWorkArea.top = 0;
385 rWorkArea.right = GetSystemMetrics(SM_CXSCREEN);
386 rWorkArea.bottom = GetSystemMetrics(SM_CYSCREEN);
389 /* Calculate new X and Y position*/
390 xNew = (rWorkArea.right - wChild)/2;
391 yNew = (rWorkArea.bottom - hChild)/2;
392 return SetWindowPos (hwndChild, HWND_TOP, xNew, yNew, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW);
395 static void addListBoxItem(HWND hDlg, LPSTR lpStr, HBITMAP hBmp)
399 nItem = SendMessage(hDlg, LB_ADDSTRING, 0, (LPARAM)lpStr);
400 SendMessage(hDlg, LB_SETITEMDATA, nItem, (LPARAM)hBmp);
403 static void addListBoxString(HWND hListBox, LPSTR lpStr)
405 static int nItems = 0;
406 if (!g_bDlgServiceOn)
410 if ( nItems > MAX_LOADSTRING)
412 SendMessage(hListBox, LB_RESETCONTENT, 0, 0);
415 ListBox_SetCurSel(hListBox,
416 ListBox_AddString(hListBox, lpStr));
419 static DWORD WINAPI ConsoleOutputThread(LPVOID lpThreadParameter)
421 static BYTE lpBuffer[MAX_PATH+1];
426 while (ReadFile(g_hpipeOutRead, &ch, 1, &dwReaded, NULL) == TRUE)
430 if (ch == '\n' || nPtr >= MAX_PATH)
432 lpBuffer[nPtr] = '\0';
433 addListBoxString(g_hwndStdoutList, lpBuffer);
436 else if (ch == '\t' && nPtr < (MAX_PATH - 4))
439 for (i = 0; i < 4; ++i)
440 lpBuffer[nPtr++] = ' ';
443 lpBuffer[nPtr++] = ch;
446 CloseHandle(g_hpipeInWrite);
447 CloseHandle(g_hpipeOutRead);
448 CloseHandle(g_hpipeStdError);
453 DWORD WINAPI ConsoleWaitingThread(LPVOID lpThreadParameter)
455 WaitForSingleObject(g_lpRedirectProc.hThread, INFINITE);
456 CloseHandle(g_lpRedirectProc.hThread);
458 g_bConsoleRun = FALSE;
459 SetCursor(g_hCursorArrow);
464 BOOL RunRedirectedConsole(LPSTR szCmdLine)
471 ZeroMemory(&stInfo, sizeof(stInfo));
472 stInfo.cb = sizeof(stInfo);
473 stInfo.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
474 stInfo.wShowWindow = SW_HIDE;
476 hProc = GetCurrentProcess();
478 if (!CreatePipe(&g_hpipeInRead, &g_hpipeInWrite, NULL, MAX_PATH))
479 ErrorMessage(NULL, TRUE);
480 if (!CreatePipe(&g_hpipeOutRead, &g_hpipeOutWrite, NULL, MAX_PATH*8))
481 ErrorMessage(NULL, TRUE);
483 DuplicateHandle(hProc, g_hpipeInRead, hProc, &g_hpipeInRead, 0, TRUE,
484 DUPLICATE_CLOSE_SOURCE|DUPLICATE_SAME_ACCESS);
485 DuplicateHandle(hProc, g_hpipeOutWrite, hProc, &g_hpipeOutWrite, 0, TRUE,
486 DUPLICATE_CLOSE_SOURCE|DUPLICATE_SAME_ACCESS);
487 DuplicateHandle(hProc, g_hpipeOutWrite, hProc, &g_hpipeStdError, 0, TRUE,
488 DUPLICATE_SAME_ACCESS);
489 if (!g_hpipeInRead && !g_hpipeOutWrite && !g_hpipeStdError)
490 ErrorMessage(NULL, TRUE);
492 stInfo.hStdInput = g_hpipeInRead;
493 stInfo.hStdOutput = g_hpipeOutWrite;
494 stInfo.hStdError = g_hpipeStdError;
496 bResult = CreateProcess(NULL,
508 CloseHandle(g_hpipeInRead);
509 CloseHandle(g_hpipeOutWrite);
510 CloseHandle(g_hpipeStdError);
514 CloseHandle(g_hpipeInWrite);
515 CloseHandle(g_hpipeOutRead);
516 CloseHandle(g_hpipeStdError);
520 CloseHandle(CreateThread(NULL, 0, ConsoleOutputThread, 0, 0, &dwThreadId));
521 ResumeThread(g_lpRedirectProc.hThread);
522 CloseHandle(CreateThread(NULL, 0, ConsoleWaitingThread, 0, 0, &dwThreadId));
527 BOOL RunAndForgetConsole(LPSTR szCmdLine,
528 BOOL bRedirectConsole)
532 PROCESS_INFORMATION prInfo;
535 if (bRedirectConsole)
536 return RunRedirectedConsole(szCmdLine);
539 ZeroMemory(&stInfo, sizeof(stInfo));
540 stInfo.cb = sizeof(stInfo);
541 stInfo.dwFlags = STARTF_USESHOWWINDOW;
542 stInfo.wShowWindow = SW_HIDE;
544 bResult = CreateProcess(NULL,
559 if (g_dwOSVersion == OS_VERSION_WIN9X) /* give some time to rescan the status */
561 CloseHandle(prInfo.hThread);
562 CloseHandle(prInfo.hProcess);
566 BOOL ApacheManageService(LPCSTR szServiceName, LPCSTR szImagePath, DWORD dwCommand)
569 CHAR szBuf[MAX_PATH];
570 CHAR szMsg[MAX_PATH];
573 BOOL serviceFlag = TRUE;
574 SC_HANDLE schService;
575 SC_HANDLE schSCManager;
576 SERVICE_STATUS schSStatus;
580 if (g_dwOSVersion == OS_VERSION_WIN9X)
582 sPos = strstr(szImagePath, "-k start");
585 lstrcpyn(szBuf, szImagePath, sPos - szImagePath);
588 case SERVICE_CONTROL_STOP:
589 lstrcat(szBuf, " -k stop -n ");
591 case SERVICE_CONTROL_CONTINUE:
592 sprintf(szMsg, g_lpMsg[IDS_MSG_SRVSTART-IDS_MSG_FIRST], szServiceName);
593 addListBoxString(g_hwndStdoutList, szMsg);
594 lstrcat(szBuf, " -k start -n ");
597 case SERVICE_APACHE_RESTART:
598 lstrcat(szBuf, " -k restart -n ");
603 lstrcat(szBuf, szServiceName);
607 g_bConsoleRun = TRUE;
608 SetCursor(g_hCursorHourglass);
609 if (!RunAndForgetConsole(szBuf, serviceFlag))
611 ErrorMessage(NULL, FALSE);
612 g_bConsoleRun = FALSE;
613 SetCursor(g_hCursorArrow);
616 else if (!serviceFlag)
618 sprintf(szMsg, g_lpMsg[IDS_MSG_SRVSTARTED-IDS_MSG_FIRST], szServiceName);
619 addListBoxString(g_hwndStdoutList, szMsg);
620 g_bConsoleRun = FALSE;
621 SetCursor(g_hCursorArrow);
627 /* Apache 2.0 uses '-k runservice' as cmdline parameter */
628 sPos = strstr(szImagePath, "--ntservice");
631 sPos = strstr(szImagePath, "-k runservice");
635 lstrcpyn(szBuf, szImagePath, sPos - szImagePath);
638 schSCManager = OpenSCManager(
641 SC_MANAGER_ALL_ACCESS
646 schService = OpenService(schSCManager, szServiceName, SERVICE_ALL_ACCESS);
647 if (schService != NULL)
650 g_bConsoleRun = TRUE;
651 SetCursor(g_hCursorHourglass);
654 case SERVICE_CONTROL_STOP:
655 sprintf(szMsg, g_lpMsg[IDS_MSG_SRVSTOP-IDS_MSG_FIRST], szServiceName);
656 addListBoxString(g_hwndStdoutList, szMsg);
657 if(ControlService(schService, SERVICE_CONTROL_STOP, &schSStatus))
660 while (QueryServiceStatus(schService, &schSStatus))
662 if (schSStatus.dwCurrentState == SERVICE_STOP_PENDING)
668 if (QueryServiceStatus(schService, &schSStatus))
670 if(schSStatus.dwCurrentState == SERVICE_STOPPED)
673 sprintf(szMsg, g_lpMsg[IDS_MSG_SRVSTOPPED-IDS_MSG_FIRST], szServiceName);
674 addListBoxString(g_hwndStdoutList, szMsg);
678 case SERVICE_CONTROL_CONTINUE:
679 sprintf(szMsg, g_lpMsg[IDS_MSG_SRVSTART-IDS_MSG_FIRST], szServiceName);
680 addListBoxString(g_hwndStdoutList, szMsg);
681 args = (char **)malloc(3 * sizeof(char*));
684 args[1] = "--ntservice";
688 args[2] = "runservice";
690 if(StartService(schService, serviceFlag ? 2 : 3, args))
693 while (QueryServiceStatus(schService, &schSStatus))
695 if (schSStatus.dwCurrentState == SERVICE_START_PENDING)
701 if (QueryServiceStatus(schService, &schSStatus))
703 if(schSStatus.dwCurrentState == SERVICE_RUNNING)
706 sprintf(szMsg, g_lpMsg[IDS_MSG_SRVSTARTED-IDS_MSG_FIRST], szServiceName);
707 addListBoxString(g_hwndStdoutList, szMsg);
710 /* is this OK to do? */
713 case SERVICE_APACHE_RESTART:
714 sprintf(szMsg, g_lpMsg[IDS_MSG_SRVRESTART-IDS_MSG_FIRST], szServiceName);
715 addListBoxString(g_hwndStdoutList, szMsg);
716 if(ControlService(schService, SERVICE_APACHE_RESTART, &schSStatus))
719 while(schSStatus.dwCurrentState == SERVICE_START_PENDING)
722 if(!QueryServiceStatus(schService, &schSStatus))
724 CloseServiceHandle(schService);
725 CloseServiceHandle(schSCManager);
726 g_bConsoleRun = FALSE;
727 SetCursor(g_hCursorArrow);
734 if(schSStatus.dwCurrentState == SERVICE_RUNNING)
737 sprintf(szMsg, g_lpMsg[IDS_MSG_SRVRESTARTED-IDS_MSG_FIRST], szServiceName);
738 addListBoxString(g_hwndStdoutList, szMsg);
742 CloseServiceHandle(schService);
743 CloseServiceHandle(schSCManager);
745 ErrorMessage(g_lpMsg[IDS_MSG_SRVFAILED-IDS_MSG_FIRST], FALSE);
746 g_bConsoleRun = FALSE;
747 SetCursor(g_hCursorArrow);
752 g_bRescanServices = TRUE;
754 CloseServiceHandle(schSCManager);
761 BOOL IsServiceRunning(LPCSTR szServiceName, LPDWORD lpdwPid)
766 SC_HANDLE schService;
767 SC_HANDLE schSCManager;
768 SERVICE_STATUS schSStatus;
770 if (g_dwOSVersion == OS_VERSION_WIN9X)
772 hWnd = FindWindow("ApacheWin95ServiceMonitor", szServiceName);
773 if (hWnd && GetWindowThreadProcessId(hWnd, &dwPid))
785 schSCManager = OpenSCManager(
788 SC_MANAGER_ALL_ACCESS
793 schService = OpenService(schSCManager, szServiceName, SERVICE_QUERY_STATUS);
794 if (schService != NULL)
796 if (QueryServiceStatus(schService, &schSStatus))
799 dwPid = schSStatus.dwCurrentState;
803 CloseServiceHandle(schService);
804 CloseServiceHandle(schSCManager);
805 return dwPid == SERVICE_RUNNING ? TRUE : FALSE;
808 g_bRescanServices = TRUE;
810 CloseServiceHandle(schSCManager);
818 BOOL FindRunningServices()
823 while (g_stServices[i].szServiceName != NULL)
825 if (!IsServiceRunning(g_stServices[i].szServiceName, &dwPid))
827 if (g_stServices[i].dwPid != dwPid)
829 g_stServices[i].dwPid = dwPid;
835 BOOL GetApacheServicesStatus()
838 CHAR szKey[MAX_PATH];
839 CHAR achKey[MAX_PATH];
840 CHAR szImagePath[MAX_PATH];
841 CHAR szBuf[MAX_PATH];
844 DWORD retCode, rv, dwKeyType;
845 DWORD dwBufLen = MAX_PATH;
848 g_bRescanServices = FALSE;
850 retCode = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
851 "System\\CurrentControlSet\\Services\\",
853 if (retCode != ERROR_SUCCESS)
855 ErrorMessage(NULL, FALSE);
858 am_ClearServicesSt();
859 for (i = 0, retCode = ERROR_SUCCESS; retCode == ERROR_SUCCESS; i++)
862 retCode = RegEnumKey(hKey, i, achKey, MAX_PATH);
863 if (retCode == ERROR_SUCCESS)
865 lstrcpy(szKey, "System\\CurrentControlSet\\Services\\");
866 lstrcat(szKey, achKey);
868 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKey, 0,
869 KEY_QUERY_VALUE, &hSubKey) == ERROR_SUCCESS)
872 rv = RegQueryValueEx(hSubKey, "ImagePath", NULL,
873 &dwKeyType, szImagePath, &dwBufLen);
875 if (rv == ERROR_SUCCESS && (dwKeyType == REG_SZ || dwKeyType == REG_EXPAND_SZ) && dwBufLen)
877 lstrcpy(szBuf, szImagePath);
879 /* the service name could be Apache*.exe */
880 if (strstr(szBuf, "\\apache") != NULL && strstr(szBuf, ".exe") &&
881 (strstr(szBuf, "--ntservice") != NULL || strstr(szBuf, "-k ") !=NULL))
883 g_stServices[stPos].szServiceName = strdup(achKey);
884 g_stServices[stPos].szImagePath = strdup(szImagePath);
886 if (RegQueryValueEx(hSubKey, "Description", NULL,
887 &dwKeyType, szBuf, &dwBufLen) == ERROR_SUCCESS)
888 g_stServices[stPos].szDescription = strdup(szBuf);
891 if (RegQueryValueEx(hSubKey, "DisplayName", NULL,
892 &dwKeyType, szBuf, &dwBufLen) == ERROR_SUCCESS)
893 g_stServices[stPos].szDisplayName= strdup(szBuf);
895 if (stPos >= MAX_APACHE_SERVICES)
896 retCode = !ERROR_SUCCESS;
899 RegCloseKey(hSubKey);
904 FindRunningServices();
909 LRESULT CALLBACK ServiceDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
912 CHAR szBuf[MAX_PATH];
914 static HWND hStatusBar;
920 LPMEASUREITEMSTRUCT lpmis;
921 LPDRAWITEMSTRUCT lpdis;
923 ZeroMemory(szBuf, MAX_PATH);
928 ShowWindow(hDlg, SW_HIDE);
929 g_hwndServiceDlg = hDlg;
930 g_hBmpStart = LoadImage(g_hInstance, MAKEINTRESOURCE(IDB_BMPRUN),
931 IMAGE_BITMAP, XBITMAP, YBITMAP, LR_DEFAULTCOLOR);
932 g_hBmpStop = LoadImage(g_hInstance, MAKEINTRESOURCE(IDB_BMPSTOP),
933 IMAGE_BITMAP, XBITMAP, YBITMAP, LR_DEFAULTCOLOR);
935 Button_Enable(GetDlgItem(hDlg, IDC_SSTART), FALSE);
936 Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), FALSE);
937 Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), FALSE);
939 if (g_dwOSVersion < OS_VERSION_WINNT)
940 ShowWindow(GetDlgItem(hDlg, IDC_SMANAGER), SW_HIDE);
942 hListBox = GetDlgItem(hDlg, IDL_SERVICES);
943 g_hwndStdoutList = GetDlgItem(hDlg, IDL_STDOUT);
944 hStatusBar = CreateStatusWindow(SBT_TOOLTIPS | WS_CHILD | WS_VISIBLE,
945 "", hDlg, IDC_STATBAR);
946 if (GetApacheServicesStatus())
949 while (g_stServices[i].szServiceName != NULL)
951 addListBoxItem(hListBox, g_stServices[i].szDisplayName,
952 g_stServices[i].dwPid == 0 ? g_hBmpStop : g_hBmpStart);
957 ShowWindow(hDlg, SW_SHOW);
959 SendMessage(hListBox, LB_SETCURSEL, 0, 0);
962 case WM_UPDATEMESSAGE:
963 hListBox = GetDlgItem(hDlg, IDL_SERVICES);
964 SendMessage(hListBox, LB_RESETCONTENT, 0, 0);
965 SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)"");
966 Button_Enable(GetDlgItem(hDlg, IDC_SSTART), FALSE);
967 Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), FALSE);
968 Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), FALSE);
970 while (g_stServices[i].szServiceName != NULL)
972 addListBoxItem(hListBox, g_stServices[i].szDisplayName,
973 g_stServices[i].dwPid == 0 ? g_hBmpStop : g_hBmpStart);
976 SendMessage(hListBox, LB_SETCURSEL, 0, 0);
977 /* Dirty hack to bring the window to the foreground */
978 SetWindowPos(hDlg, HWND_TOPMOST, 0, 0, 0, 0,
979 SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
980 SetWindowPos(hDlg, HWND_NOTOPMOST, 0, 0, 0, 0,
981 SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
987 lpmis = (LPMEASUREITEMSTRUCT) lParam;
988 lpmis->itemHeight = YBITMAP;
992 SetCursor(g_hCursorHourglass);
994 SetCursor(g_hCursorArrow);
997 lpdis = (LPDRAWITEMSTRUCT) lParam;
998 if (lpdis->itemID == -1)
1002 switch (lpdis->itemAction)
1005 case ODA_DRAWENTIRE:
1006 g_hBmpPicture = (HBITMAP)SendMessage(lpdis->hwndItem,
1007 LB_GETITEMDATA, lpdis->itemID, (LPARAM) 0);
1009 hdcMem = CreateCompatibleDC(lpdis->hDC);
1010 g_hBmpOld = SelectObject(hdcMem, g_hBmpPicture);
1013 lpdis->rcItem.left, lpdis->rcItem.top,
1014 lpdis->rcItem.right - lpdis->rcItem.left,
1015 lpdis->rcItem.bottom - lpdis->rcItem.top,
1016 hdcMem, 0, 0, SRCCOPY);
1017 SendMessage(lpdis->hwndItem, LB_GETTEXT,
1018 lpdis->itemID, (LPARAM) szBuf);
1020 GetTextMetrics(lpdis->hDC, &tm);
1021 y = (lpdis->rcItem.bottom + lpdis->rcItem.top -
1024 SelectObject(hdcMem, g_hBmpOld);
1027 rcBitmap.left = lpdis->rcItem.left + XBITMAP + 2;
1028 rcBitmap.top = lpdis->rcItem.top;
1029 rcBitmap.right = lpdis->rcItem.right;
1030 rcBitmap.bottom = lpdis->rcItem.top + YBITMAP;
1032 if (lpdis->itemState & ODS_SELECTED)
1034 if (g_hBmpPicture == g_hBmpStop)
1036 Button_Enable(GetDlgItem(hDlg, IDC_SSTART), TRUE);
1037 Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), FALSE);
1038 Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), FALSE);
1040 else if (g_hBmpPicture == g_hBmpStart)
1042 Button_Enable(GetDlgItem(hDlg, IDC_SSTART), FALSE);
1043 Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), TRUE);
1044 Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), TRUE);
1046 if (g_stServices[lpdis->itemID].szDescription)
1047 SendMessage(hStatusBar, SB_SETTEXT, 0,
1048 (LPARAM)g_stServices[lpdis->itemID].szDescription);
1050 SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)"");
1052 SetTextColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
1053 SetBkColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHT));
1054 FillRect(lpdis->hDC, &rcBitmap, (HBRUSH)(COLOR_HIGHLIGHTTEXT));
1058 SetTextColor(lpdis->hDC, GetSysColor(COLOR_MENUTEXT));
1059 SetBkColor(lpdis->hDC, GetSysColor(COLOR_WINDOW));
1060 FillRect(lpdis->hDC, &rcBitmap, (HBRUSH)(COLOR_WINDOW+1));
1074 switch (LOWORD(wParam))
1077 switch (HIWORD(wParam))
1080 /* if started then stop, if stopped then start the service */
1081 hListBox = GetDlgItem(hDlg, IDL_SERVICES);
1082 nItem = SendMessage(hListBox, LB_GETCURSEL, 0, 0);
1083 if (nItem != LB_ERR)
1085 g_hBmpPicture = (HBITMAP)SendMessage(hListBox, LB_GETITEMDATA,
1087 if (g_hBmpPicture == g_hBmpStop)
1089 ApacheManageService(g_stServices[nItem].szServiceName,
1090 g_stServices[nItem].szImagePath,
1091 SERVICE_CONTROL_CONTINUE);
1094 ApacheManageService(g_stServices[nItem].szServiceName,
1095 g_stServices[nItem].szImagePath,
1096 SERVICE_CONTROL_STOP);
1104 EndDialog(hDlg, TRUE);
1107 Button_Enable(GetDlgItem(hDlg, IDC_SSTART), FALSE);
1108 hListBox = GetDlgItem(hDlg, IDL_SERVICES);
1109 nItem = SendMessage(hListBox, LB_GETCURSEL, 0, 0);
1110 if (nItem != LB_ERR)
1112 ApacheManageService(g_stServices[nItem].szServiceName,
1113 g_stServices[nItem].szImagePath,
1114 SERVICE_CONTROL_CONTINUE);
1116 Button_Enable(GetDlgItem(hDlg, IDC_SSTART), TRUE);
1119 Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), FALSE);
1120 hListBox = GetDlgItem(hDlg, IDL_SERVICES);
1121 nItem = SendMessage(hListBox, LB_GETCURSEL, 0, 0);
1122 if (nItem != LB_ERR)
1124 ApacheManageService(g_stServices[nItem].szServiceName,
1125 g_stServices[nItem].szImagePath,
1126 SERVICE_CONTROL_STOP);
1128 Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), TRUE);
1131 Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), FALSE);
1132 hListBox = GetDlgItem(hDlg, IDL_SERVICES);
1133 nItem = SendMessage(hListBox, LB_GETCURSEL, 0, 0);
1134 if (nItem != LB_ERR)
1136 ApacheManageService(g_stServices[nItem].szServiceName,
1137 g_stServices[nItem].szImagePath,
1138 SERVICE_APACHE_RESTART);
1140 Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), TRUE);
1143 if (g_dwOSVersion >= OS_VERSION_WIN2K)
1144 ShellExecute(hDlg, "open", "services.msc", "/s", NULL, SW_NORMAL);
1146 WinExec("Control.exe SrvMgr.cpl Services", SW_NORMAL);
1149 EndDialog( hDlg, TRUE);
1150 SendMessage( g_hwndMain, WM_COMMAND, (WPARAM)IDM_EXIT, 0);
1155 switch (LOWORD(wParam))
1157 case SIZE_MINIMIZED:
1158 EndDialog(hDlg, TRUE);
1165 EndDialog(hDlg, TRUE);
1168 DeleteObject(g_hBmpStart);
1169 DeleteObject(g_hBmpStop);
1178 LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
1179 WPARAM wParam, LPARAM lParam)
1181 if (message == g_bUiTaskbarCreated)
1183 /* restore the tray icon on shell restart */
1184 ShowNotifyIcon(hWnd, NIM_ADD);
1185 return DefWindowProc(hWnd, message, wParam, lParam);
1190 GetApacheServicesStatus();
1191 ShowNotifyIcon(hWnd, NIM_ADD);
1192 SetTimer(hWnd, WM_TIMER_REFRESH, REFRESH_TIME, NULL);
1193 SetTimer(hWnd, WM_TIMER_RESCAN, RESCAN_TIME, NULL);
1194 g_hwndServiceDlg = NULL;
1199 case WM_TIMER_RESCAN:
1201 int nPrev = 0, nNew = 0;
1202 EnterCriticalSection(&g_stcSection);
1203 if (FindRunningServices() || g_bRescanServices)
1205 ShowNotifyIcon(hWnd, NIM_MODIFY);
1206 if (g_hwndServiceDlg)
1207 PostMessage(g_hwndServiceDlg, WM_UPDATEMESSAGE, 0, 0);
1209 /* check if services list changed */
1210 while (g_stServices[nPrev].szServiceName != NULL)
1212 GetApacheServicesStatus();
1213 while (g_stServices[nNew].szServiceName != NULL)
1217 ShowNotifyIcon(hWnd, NIM_MODIFY);
1218 if (g_hwndServiceDlg)
1219 PostMessage(g_hwndServiceDlg, WM_UPDATEMESSAGE, 0, 0);
1221 LeaveCriticalSection(&g_stcSection);
1224 case WM_TIMER_REFRESH:
1226 int nPrev = 0, nNew = 0;
1227 EnterCriticalSection(&g_stcSection);
1228 if (g_bRescanServices)
1230 GetApacheServicesStatus();
1231 ShowNotifyIcon(hWnd, NIM_MODIFY);
1232 if (g_hwndServiceDlg)
1233 PostMessage(g_hwndServiceDlg, WM_UPDATEMESSAGE, 0, 0);
1235 else if (FindRunningServices())
1237 ShowNotifyIcon(hWnd, NIM_MODIFY);
1238 if (g_hwndServiceDlg)
1239 PostMessage(g_hwndServiceDlg, WM_UPDATEMESSAGE, 0, 0);
1241 LeaveCriticalSection(&g_stcSection);
1247 ShowNotifyIcon(hWnd, NIM_DELETE);
1249 case WM_TRAYMESSAGE:
1252 case WM_LBUTTONDBLCLK:
1253 if (!g_bDlgServiceOn)
1255 g_bDlgServiceOn = TRUE;
1256 DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_DLGSERVICES),
1257 hWnd, (DLGPROC)ServiceDlgProc);
1258 g_bDlgServiceOn = FALSE;
1259 g_hwndServiceDlg = NULL;
1261 else if (g_hwndServiceDlg)
1263 /* Dirty hack to bring the window to the foreground */
1264 SetWindowPos(g_hwndServiceDlg, HWND_TOPMOST, 0, 0, 0, 0,
1265 SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
1266 SetWindowPos(g_hwndServiceDlg, HWND_NOTOPMOST, 0, 0, 0, 0,
1267 SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
1268 SetFocus(g_hwndServiceDlg);
1272 ShowTryServicesMenu(hWnd);
1275 ShowTryPopupMenu(hWnd);
1280 if ((LOWORD(wParam) & IDM_SM_START) == IDM_SM_START)
1282 ApacheManageService(g_stServices[LOWORD(wParam) - IDM_SM_START].szServiceName,
1283 g_stServices[LOWORD(wParam) - IDM_SM_START].szImagePath,
1284 SERVICE_CONTROL_CONTINUE);
1287 else if ((LOWORD(wParam) & IDM_SM_STOP) == IDM_SM_STOP)
1289 ApacheManageService(g_stServices[LOWORD(wParam) - IDM_SM_STOP].szServiceName,
1290 g_stServices[LOWORD(wParam) - IDM_SM_STOP].szImagePath,
1291 SERVICE_CONTROL_STOP);
1294 else if ((LOWORD(wParam) & IDM_SM_RESTART) == IDM_SM_RESTART)
1296 ApacheManageService(g_stServices[LOWORD(wParam) - IDM_SM_RESTART].szServiceName,
1297 g_stServices[LOWORD(wParam) - IDM_SM_RESTART].szImagePath,
1298 SERVICE_APACHE_RESTART);
1301 switch (LOWORD(wParam))
1304 if (!g_bDlgServiceOn)
1306 g_bDlgServiceOn = TRUE;
1307 DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_DLGSERVICES),
1308 hWnd, (DLGPROC)ServiceDlgProc);
1309 g_bDlgServiceOn = FALSE;
1310 g_hwndServiceDlg = NULL;
1312 else if (g_hwndServiceDlg)
1313 SetFocus(g_hwndServiceDlg);
1316 if (g_dwOSVersion >= OS_VERSION_WIN2K)
1317 ShellExecute(NULL, "open", "services.msc", "/s", NULL, SW_NORMAL);
1319 WinExec("Control.exe SrvMgr.cpl Services", SW_NORMAL);
1322 ShowNotifyIcon(hWnd, NIM_DELETE);
1327 return DefWindowProc(hWnd, message, wParam, lParam);
1333 /* Create main invisible window */
1334 HWND CreateMainWindow(HINSTANCE hInstance)
1339 if (!GetSystemOSVersion(&g_dwOSVersion))
1341 ErrorMessage(NULL, TRUE);
1345 wcex.cbSize = sizeof(WNDCLASSEX);
1347 wcex.style = CS_HREDRAW | CS_VREDRAW;
1348 wcex.lpfnWndProc = (WNDPROC)WndProc;
1349 wcex.cbClsExtra = 0;
1350 wcex.cbWndExtra = 0;
1351 wcex.hInstance = hInstance;
1352 wcex.hIcon = (HICON)LoadImage(hInstance, MAKEINTRESOURCE(IDI_APSRVMON),
1353 IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
1354 wcex.hCursor = g_hCursorArrow;
1355 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
1356 wcex.lpszMenuName = 0;
1357 wcex.lpszClassName = g_szWindowClass;
1358 wcex.hIconSm = (HICON)LoadImage(hInstance, MAKEINTRESOURCE(IDI_APSRVMON),
1359 IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
1361 if (RegisterClassEx(&wcex))
1362 hWnd = CreateWindow(g_szWindowClass, g_szTitle,
1364 NULL, NULL, hInstance, NULL);
1371 int WINAPI WinMain(HINSTANCE hInstance,
1372 HINSTANCE hPrevInstance,
1376 TCHAR szTmp[MAX_LOADSTRING];
1378 /* single instance mutex */
1382 g_LangID = GetUserDefaultLangID();
1383 if ((g_LangID & 0xFF) != LANG_ENGLISH)
1384 g_LangID = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
1386 for (i = IDS_MSG_FIRST; i <= IDS_MSG_LAST; ++i) {
1387 LoadString(hInstance, i, szTmp, MAX_LOADSTRING);
1388 g_lpMsg[i - IDS_MSG_FIRST] = strdup(szTmp);
1390 LoadString(hInstance, IDS_APMONITORTITLE, szTmp, MAX_LOADSTRING);
1391 g_szTitle = strdup(szTmp);
1392 LoadString(hInstance, IDS_APMONITORCLASS, szTmp, MAX_LOADSTRING);
1393 g_szWindowClass = strdup(szTmp);
1395 g_icoStop = LoadImage(hInstance, MAKEINTRESOURCE(IDI_ICOSTOP),
1396 IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
1397 g_icoRun = LoadImage(hInstance, MAKEINTRESOURCE(IDI_ICORUN),
1398 IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
1399 g_hCursorHourglass = LoadImage(NULL, MAKEINTRESOURCE(OCR_WAIT), IMAGE_CURSOR,
1400 LR_DEFAULTSIZE, LR_DEFAULTSIZE, LR_SHARED);
1401 g_hCursorArrow = LoadImage(NULL, MAKEINTRESOURCE(OCR_NORMAL), IMAGE_CURSOR,
1402 LR_DEFAULTSIZE, LR_DEFAULTSIZE, LR_SHARED);
1404 hMutex = CreateMutex(NULL, FALSE, "APSRVMON_MUTEX");
1405 if((hMutex == NULL) || (GetLastError() == ERROR_ALREADY_EXISTS))
1407 ErrorMessage(g_lpMsg[IDS_MSG_APPRUNNING-IDS_MSG_FIRST], FALSE);
1409 CloseHandle(hMutex);
1414 ZeroMemory(g_stServices, sizeof(ST_APACHE_SERVICE) * MAX_APACHE_SERVICES);
1415 InitCommonControls();
1416 g_hInstance = hInstance;
1417 g_hwndMain = CreateMainWindow(hInstance);
1418 g_bUiTaskbarCreated = RegisterWindowMessage("TaskbarCreated");
1419 InitializeCriticalSection(&g_stcSection);
1420 if (g_hwndMain != NULL)
1422 while (GetMessage(&msg, NULL, 0, 0) == TRUE)
1424 TranslateMessage(&msg);
1425 DispatchMessage(&msg);
1427 am_ClearServicesSt();
1429 DeleteCriticalSection(&g_stcSection);
1430 CloseHandle(hMutex);
1431 DestroyIcon(g_icoStop);
1432 DestroyIcon(g_icoRun);
1433 DestroyCursor(g_hCursorHourglass);
1434 DestroyCursor(g_hCursorArrow);