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);
330 SetForegroundWindow(NULL);
331 TrackPopupMenu(hMenu, TPM_LEFTALIGN|TPM_RIGHTBUTTON, pt.x, pt.y, 0, hWnd, NULL);
336 void ShowTryServicesMenu(HWND hWnd)
338 /* create services list popup menu and submenus */
339 HMENU hMenu = CreatePopupMenu();
345 while (g_stServices[i].szServiceName != NULL)
347 appendServiceMenu(hMenu, i, g_stServices[i].szDisplayName,
348 g_stServices[i].dwPid != 0);
354 SetForegroundWindow(NULL);
355 TrackPopupMenu(hMenu, TPM_LEFTALIGN|TPM_RIGHTBUTTON, pt.x, pt.y, 0, hWnd, NULL);
361 BOOL CenterWindow(HWND hwndChild)
363 RECT rChild, rWorkArea;
368 /* Get the Height and Width of the child window */
369 GetWindowRect(hwndChild, &rChild);
370 wChild = rChild.right - rChild.left;
371 hChild = rChild.bottom - rChild.top;
373 /* Get the limits of the 'workarea' */
374 bResult = SystemParametersInfo(
380 rWorkArea.left = rWorkArea.top = 0;
381 rWorkArea.right = GetSystemMetrics(SM_CXSCREEN);
382 rWorkArea.bottom = GetSystemMetrics(SM_CYSCREEN);
385 /* Calculate new X and Y position*/
386 xNew = (rWorkArea.right - wChild)/2;
387 yNew = (rWorkArea.bottom - hChild)/2;
388 return SetWindowPos (hwndChild, HWND_TOP, xNew, yNew, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW);
391 static void addListBoxItem(HWND hDlg, LPSTR lpStr, HBITMAP hBmp)
395 nItem = SendMessage(hDlg, LB_ADDSTRING, 0, (LPARAM)lpStr);
396 SendMessage(hDlg, LB_SETITEMDATA, nItem, (LPARAM)hBmp);
399 static void addListBoxString(HWND hListBox, LPSTR lpStr)
401 static int nItems = 0;
402 if (!g_bDlgServiceOn)
406 if ( nItems > MAX_LOADSTRING)
408 SendMessage(hListBox, LB_RESETCONTENT, 0, 0);
411 ListBox_SetCurSel(hListBox,
412 ListBox_AddString(hListBox, lpStr));
415 static DWORD WINAPI ConsoleOutputThread(LPVOID lpThreadParameter)
417 static BYTE lpBuffer[MAX_PATH+1];
422 while (ReadFile(g_hpipeOutRead, &ch, 1, &dwReaded, NULL) == TRUE)
426 if (ch == '\n' || nPtr >= MAX_PATH)
428 lpBuffer[nPtr] = '\0';
429 addListBoxString(g_hwndStdoutList, lpBuffer);
432 else if (ch == '\t' && nPtr < (MAX_PATH - 4))
435 for (i = 0; i < 4; ++i)
436 lpBuffer[nPtr++] = ' ';
439 lpBuffer[nPtr++] = ch;
442 CloseHandle(g_hpipeInWrite);
443 CloseHandle(g_hpipeOutRead);
444 CloseHandle(g_hpipeStdError);
449 DWORD WINAPI ConsoleWaitingThread(LPVOID lpThreadParameter)
451 WaitForSingleObject(g_lpRedirectProc.hThread, INFINITE);
452 CloseHandle(g_lpRedirectProc.hThread);
454 g_bConsoleRun = FALSE;
455 SetCursor(g_hCursorArrow);
460 BOOL RunRedirectedConsole(LPSTR szCmdLine)
467 ZeroMemory(&stInfo, sizeof(stInfo));
468 stInfo.cb = sizeof(stInfo);
469 stInfo.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
470 stInfo.wShowWindow = SW_HIDE;
472 hProc = GetCurrentProcess();
474 if (!CreatePipe(&g_hpipeInRead, &g_hpipeInWrite, NULL, MAX_PATH))
475 ErrorMessage(NULL, TRUE);
476 if (!CreatePipe(&g_hpipeOutRead, &g_hpipeOutWrite, NULL, MAX_PATH*8))
477 ErrorMessage(NULL, TRUE);
479 DuplicateHandle(hProc, g_hpipeInRead, hProc, &g_hpipeInRead, 0, TRUE,
480 DUPLICATE_CLOSE_SOURCE|DUPLICATE_SAME_ACCESS);
481 DuplicateHandle(hProc, g_hpipeOutWrite, hProc, &g_hpipeOutWrite, 0, TRUE,
482 DUPLICATE_CLOSE_SOURCE|DUPLICATE_SAME_ACCESS);
483 DuplicateHandle(hProc, g_hpipeOutWrite, hProc, &g_hpipeStdError, 0, TRUE,
484 DUPLICATE_SAME_ACCESS);
485 if (!g_hpipeInRead && !g_hpipeOutWrite && !g_hpipeStdError)
486 ErrorMessage(NULL, TRUE);
488 stInfo.hStdInput = g_hpipeInRead;
489 stInfo.hStdOutput = g_hpipeOutWrite;
490 stInfo.hStdError = g_hpipeStdError;
492 bResult = CreateProcess(NULL,
504 CloseHandle(g_hpipeInRead);
505 CloseHandle(g_hpipeOutWrite);
506 CloseHandle(g_hpipeStdError);
510 CloseHandle(g_hpipeInWrite);
511 CloseHandle(g_hpipeOutRead);
512 CloseHandle(g_hpipeStdError);
516 CloseHandle(CreateThread(NULL, 0, ConsoleOutputThread, 0, 0, &dwThreadId));
517 ResumeThread(g_lpRedirectProc.hThread);
518 CloseHandle(CreateThread(NULL, 0, ConsoleWaitingThread, 0, 0, &dwThreadId));
523 BOOL RunAndForgetConsole(LPSTR szCmdLine,
524 BOOL bRedirectConsole)
528 PROCESS_INFORMATION prInfo;
531 if (bRedirectConsole)
532 return RunRedirectedConsole(szCmdLine);
535 ZeroMemory(&stInfo, sizeof(stInfo));
536 stInfo.cb = sizeof(stInfo);
537 stInfo.dwFlags = STARTF_USESHOWWINDOW;
538 stInfo.wShowWindow = SW_HIDE;
540 bResult = CreateProcess(NULL,
555 if (g_dwOSVersion == OS_VERSION_WIN9X) /* give some time to rescan the status */
557 CloseHandle(prInfo.hThread);
558 CloseHandle(prInfo.hProcess);
562 BOOL ApacheManageService(LPCSTR szServiceName, LPCSTR szImagePath, DWORD dwCommand)
565 CHAR szBuf[MAX_PATH];
566 CHAR szMsg[MAX_PATH];
569 BOOL serviceFlag = TRUE;
570 SC_HANDLE schService;
571 SC_HANDLE schSCManager;
572 SERVICE_STATUS schSStatus;
576 if (g_dwOSVersion == OS_VERSION_WIN9X)
578 sPos = strstr(szImagePath, "-k start");
581 lstrcpyn(szBuf, szImagePath, sPos - szImagePath);
584 case SERVICE_CONTROL_STOP:
585 lstrcat(szBuf, " -k stop -n ");
587 case SERVICE_CONTROL_CONTINUE:
588 sprintf(szMsg, g_lpMsg[IDS_MSG_SRVSTART-IDS_MSG_FIRST], szServiceName);
589 addListBoxString(g_hwndStdoutList, szMsg);
590 lstrcat(szBuf, " -k start -n ");
593 case SERVICE_APACHE_RESTART:
594 lstrcat(szBuf, " -k restart -n ");
599 lstrcat(szBuf, szServiceName);
603 g_bConsoleRun = TRUE;
604 SetCursor(g_hCursorHourglass);
605 if (!RunAndForgetConsole(szBuf, serviceFlag))
607 ErrorMessage(NULL, FALSE);
608 g_bConsoleRun = FALSE;
609 SetCursor(g_hCursorArrow);
612 else if (!serviceFlag)
614 sprintf(szMsg, g_lpMsg[IDS_MSG_SRVSTARTED-IDS_MSG_FIRST], szServiceName);
615 addListBoxString(g_hwndStdoutList, szMsg);
616 g_bConsoleRun = FALSE;
617 SetCursor(g_hCursorArrow);
623 /* Apache 2.0 uses '-k runservice' as cmdline parameter */
624 sPos = strstr(szImagePath, "--ntservice");
627 sPos = strstr(szImagePath, "-k runservice");
631 lstrcpyn(szBuf, szImagePath, sPos - szImagePath);
634 schSCManager = OpenSCManager(
637 SC_MANAGER_ALL_ACCESS
642 schService = OpenService(schSCManager, szServiceName, SERVICE_ALL_ACCESS);
643 if (schService != NULL)
646 g_bConsoleRun = TRUE;
647 SetCursor(g_hCursorHourglass);
650 case SERVICE_CONTROL_STOP:
651 sprintf(szMsg, g_lpMsg[IDS_MSG_SRVSTOP-IDS_MSG_FIRST], szServiceName);
652 addListBoxString(g_hwndStdoutList, szMsg);
653 if(ControlService(schService, SERVICE_CONTROL_STOP, &schSStatus))
656 while (QueryServiceStatus(schService, &schSStatus))
658 if (schSStatus.dwCurrentState == SERVICE_STOP_PENDING)
664 if (QueryServiceStatus(schService, &schSStatus))
666 if(schSStatus.dwCurrentState == SERVICE_STOPPED)
669 sprintf(szMsg, g_lpMsg[IDS_MSG_SRVSTOPPED-IDS_MSG_FIRST], szServiceName);
670 addListBoxString(g_hwndStdoutList, szMsg);
674 case SERVICE_CONTROL_CONTINUE:
675 sprintf(szMsg, g_lpMsg[IDS_MSG_SRVSTART-IDS_MSG_FIRST], szServiceName);
676 addListBoxString(g_hwndStdoutList, szMsg);
677 args = (char **)malloc(3 * sizeof(char*));
680 args[1] = "--ntservice";
684 args[2] = "runservice";
686 if(StartService(schService, serviceFlag ? 2 : 3, args))
689 while (QueryServiceStatus(schService, &schSStatus))
691 if (schSStatus.dwCurrentState == SERVICE_START_PENDING)
697 if (QueryServiceStatus(schService, &schSStatus))
699 if(schSStatus.dwCurrentState == SERVICE_RUNNING)
702 sprintf(szMsg, g_lpMsg[IDS_MSG_SRVSTARTED-IDS_MSG_FIRST], szServiceName);
703 addListBoxString(g_hwndStdoutList, szMsg);
706 /* is this OK to do? */
709 case SERVICE_APACHE_RESTART:
710 sprintf(szMsg, g_lpMsg[IDS_MSG_SRVRESTART-IDS_MSG_FIRST], szServiceName);
711 addListBoxString(g_hwndStdoutList, szMsg);
712 if(ControlService(schService, SERVICE_APACHE_RESTART, &schSStatus))
715 while(schSStatus.dwCurrentState == SERVICE_START_PENDING)
718 if(!QueryServiceStatus(schService, &schSStatus))
720 CloseServiceHandle(schService);
721 CloseServiceHandle(schSCManager);
722 g_bConsoleRun = FALSE;
723 SetCursor(g_hCursorArrow);
730 if(schSStatus.dwCurrentState == SERVICE_RUNNING)
733 sprintf(szMsg, g_lpMsg[IDS_MSG_SRVRESTARTED-IDS_MSG_FIRST], szServiceName);
734 addListBoxString(g_hwndStdoutList, szMsg);
738 CloseServiceHandle(schService);
739 CloseServiceHandle(schSCManager);
741 ErrorMessage(g_lpMsg[IDS_MSG_SRVFAILED-IDS_MSG_FIRST], FALSE);
742 g_bConsoleRun = FALSE;
743 SetCursor(g_hCursorArrow);
748 g_bRescanServices = TRUE;
750 CloseServiceHandle(schSCManager);
757 BOOL IsServiceRunning(LPCSTR szServiceName, LPDWORD lpdwPid)
762 SC_HANDLE schService;
763 SC_HANDLE schSCManager;
764 SERVICE_STATUS schSStatus;
766 if (g_dwOSVersion == OS_VERSION_WIN9X)
768 hWnd = FindWindow("ApacheWin95ServiceMonitor", szServiceName);
769 if (hWnd && GetWindowThreadProcessId(hWnd, &dwPid))
781 schSCManager = OpenSCManager(
784 SC_MANAGER_ALL_ACCESS
789 schService = OpenService(schSCManager, szServiceName, SERVICE_QUERY_STATUS);
790 if (schService != NULL)
792 if (QueryServiceStatus(schService, &schSStatus))
795 dwPid = schSStatus.dwCurrentState;
799 CloseServiceHandle(schService);
800 CloseServiceHandle(schSCManager);
801 return dwPid == SERVICE_RUNNING ? TRUE : FALSE;
804 g_bRescanServices = TRUE;
806 CloseServiceHandle(schSCManager);
814 BOOL FindRunningServices()
819 while (g_stServices[i].szServiceName != NULL)
821 if (!IsServiceRunning(g_stServices[i].szServiceName, &dwPid))
823 if (g_stServices[i].dwPid != dwPid)
825 g_stServices[i].dwPid = dwPid;
831 BOOL GetApacheServicesStatus()
834 CHAR szKey[MAX_PATH];
835 CHAR achKey[MAX_PATH];
836 CHAR szImagePath[MAX_PATH];
837 CHAR szBuf[MAX_PATH];
840 DWORD retCode, rv, dwKeyType;
841 DWORD dwBufLen = MAX_PATH;
844 g_bRescanServices = FALSE;
846 retCode = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
847 "System\\CurrentControlSet\\Services\\",
849 if (retCode != ERROR_SUCCESS)
851 ErrorMessage(NULL, FALSE);
854 am_ClearServicesSt();
855 for (i = 0, retCode = ERROR_SUCCESS; retCode == ERROR_SUCCESS; i++)
858 retCode = RegEnumKey(hKey, i, achKey, MAX_PATH);
859 if (retCode == ERROR_SUCCESS)
861 lstrcpy(szKey, "System\\CurrentControlSet\\Services\\");
862 lstrcat(szKey, achKey);
864 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKey, 0,
865 KEY_QUERY_VALUE, &hSubKey) == ERROR_SUCCESS)
868 rv = RegQueryValueEx(hSubKey, "ImagePath", NULL,
869 &dwKeyType, szImagePath, &dwBufLen);
871 if (rv == ERROR_SUCCESS && (dwKeyType == REG_SZ || dwKeyType == REG_EXPAND_SZ) && dwBufLen)
873 lstrcpy(szBuf, szImagePath);
875 /* the service name could be Apache*.exe */
876 if (strstr(szBuf, "\\apache") != NULL && strstr(szBuf, ".exe") &&
877 (strstr(szBuf, "--ntservice") != NULL || strstr(szBuf, "-k ") !=NULL))
879 g_stServices[stPos].szServiceName = strdup(achKey);
880 g_stServices[stPos].szImagePath = strdup(szImagePath);
882 if (RegQueryValueEx(hSubKey, "Description", NULL,
883 &dwKeyType, szBuf, &dwBufLen) == ERROR_SUCCESS)
884 g_stServices[stPos].szDescription = strdup(szBuf);
887 if (RegQueryValueEx(hSubKey, "DisplayName", NULL,
888 &dwKeyType, szBuf, &dwBufLen) == ERROR_SUCCESS)
889 g_stServices[stPos].szDisplayName= strdup(szBuf);
891 if (stPos >= MAX_APACHE_SERVICES)
892 retCode = !ERROR_SUCCESS;
895 RegCloseKey(hSubKey);
900 FindRunningServices();
905 LRESULT CALLBACK ServiceDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
908 CHAR szBuf[MAX_PATH];
910 static HWND hStatusBar;
916 LPMEASUREITEMSTRUCT lpmis;
917 LPDRAWITEMSTRUCT lpdis;
919 ZeroMemory(szBuf, MAX_PATH);
924 ShowWindow(hDlg, SW_HIDE);
925 g_hwndServiceDlg = hDlg;
926 g_hBmpStart = LoadImage(g_hInstance, MAKEINTRESOURCE(IDB_BMPRUN),
927 IMAGE_BITMAP, XBITMAP, YBITMAP, LR_DEFAULTCOLOR);
928 g_hBmpStop = LoadImage(g_hInstance, MAKEINTRESOURCE(IDB_BMPSTOP),
929 IMAGE_BITMAP, XBITMAP, YBITMAP, LR_DEFAULTCOLOR);
931 Button_Enable(GetDlgItem(hDlg, IDC_SSTART), FALSE);
932 Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), FALSE);
933 Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), FALSE);
935 if (g_dwOSVersion < OS_VERSION_WINNT)
936 ShowWindow(GetDlgItem(hDlg, IDC_SMANAGER), SW_HIDE);
938 hListBox = GetDlgItem(hDlg, IDL_SERVICES);
939 g_hwndStdoutList = GetDlgItem(hDlg, IDL_STDOUT);
940 hStatusBar = CreateStatusWindow(SBT_TOOLTIPS | WS_CHILD | WS_VISIBLE,
941 "", hDlg, IDC_STATBAR);
942 if (GetApacheServicesStatus())
945 while (g_stServices[i].szServiceName != NULL)
947 addListBoxItem(hListBox, g_stServices[i].szDisplayName,
948 g_stServices[i].dwPid == 0 ? g_hBmpStop : g_hBmpStart);
953 ShowWindow(hDlg, SW_SHOW);
955 SendMessage(hListBox, LB_SETCURSEL, 0, 0);
958 case WM_UPDATEMESSAGE:
959 hListBox = GetDlgItem(hDlg, IDL_SERVICES);
960 SendMessage(hListBox, LB_RESETCONTENT, 0, 0);
961 SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)"");
962 Button_Enable(GetDlgItem(hDlg, IDC_SSTART), FALSE);
963 Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), FALSE);
964 Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), FALSE);
966 while (g_stServices[i].szServiceName != NULL)
968 addListBoxItem(hListBox, g_stServices[i].szDisplayName,
969 g_stServices[i].dwPid == 0 ? g_hBmpStop : g_hBmpStart);
972 SendMessage(hListBox, LB_SETCURSEL, 0, 0);
973 /* Dirty hack to bring the window to the foreground */
974 SetWindowPos(hDlg, HWND_TOPMOST, 0, 0, 0, 0,
975 SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
976 SetWindowPos(hDlg, HWND_NOTOPMOST, 0, 0, 0, 0,
977 SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
983 lpmis = (LPMEASUREITEMSTRUCT) lParam;
984 lpmis->itemHeight = YBITMAP;
988 SetCursor(g_hCursorHourglass);
990 SetCursor(g_hCursorArrow);
993 lpdis = (LPDRAWITEMSTRUCT) lParam;
994 if (lpdis->itemID == -1)
998 switch (lpdis->itemAction)
1001 case ODA_DRAWENTIRE:
1002 g_hBmpPicture = (HBITMAP)SendMessage(lpdis->hwndItem,
1003 LB_GETITEMDATA, lpdis->itemID, (LPARAM) 0);
1005 hdcMem = CreateCompatibleDC(lpdis->hDC);
1006 g_hBmpOld = SelectObject(hdcMem, g_hBmpPicture);
1009 lpdis->rcItem.left, lpdis->rcItem.top,
1010 lpdis->rcItem.right - lpdis->rcItem.left,
1011 lpdis->rcItem.bottom - lpdis->rcItem.top,
1012 hdcMem, 0, 0, SRCCOPY);
1013 SendMessage(lpdis->hwndItem, LB_GETTEXT,
1014 lpdis->itemID, (LPARAM) szBuf);
1016 GetTextMetrics(lpdis->hDC, &tm);
1017 y = (lpdis->rcItem.bottom + lpdis->rcItem.top -
1020 SelectObject(hdcMem, g_hBmpOld);
1023 rcBitmap.left = lpdis->rcItem.left + XBITMAP + 2;
1024 rcBitmap.top = lpdis->rcItem.top;
1025 rcBitmap.right = lpdis->rcItem.right;
1026 rcBitmap.bottom = lpdis->rcItem.top + YBITMAP;
1028 if (lpdis->itemState & ODS_SELECTED)
1030 if (g_hBmpPicture == g_hBmpStop)
1032 Button_Enable(GetDlgItem(hDlg, IDC_SSTART), TRUE);
1033 Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), FALSE);
1034 Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), FALSE);
1036 else if (g_hBmpPicture == g_hBmpStart)
1038 Button_Enable(GetDlgItem(hDlg, IDC_SSTART), FALSE);
1039 Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), TRUE);
1040 Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), TRUE);
1042 if (g_stServices[lpdis->itemID].szDescription)
1043 SendMessage(hStatusBar, SB_SETTEXT, 0,
1044 (LPARAM)g_stServices[lpdis->itemID].szDescription);
1046 SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)"");
1048 SetTextColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
1049 SetBkColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHT));
1050 FillRect(lpdis->hDC, &rcBitmap, (HBRUSH)(COLOR_HIGHLIGHTTEXT));
1054 SetTextColor(lpdis->hDC, GetSysColor(COLOR_MENUTEXT));
1055 SetBkColor(lpdis->hDC, GetSysColor(COLOR_WINDOW));
1056 FillRect(lpdis->hDC, &rcBitmap, (HBRUSH)(COLOR_WINDOW+1));
1070 switch (LOWORD(wParam))
1073 switch (HIWORD(wParam))
1076 /* if started then stop, if stopped then start the service */
1077 hListBox = GetDlgItem(hDlg, IDL_SERVICES);
1078 nItem = SendMessage(hListBox, LB_GETCURSEL, 0, 0);
1079 if (nItem != LB_ERR)
1081 g_hBmpPicture = (HBITMAP)SendMessage(hListBox, LB_GETITEMDATA,
1083 if (g_hBmpPicture == g_hBmpStop)
1085 ApacheManageService(g_stServices[nItem].szServiceName,
1086 g_stServices[nItem].szImagePath,
1087 SERVICE_CONTROL_CONTINUE);
1090 ApacheManageService(g_stServices[nItem].szServiceName,
1091 g_stServices[nItem].szImagePath,
1092 SERVICE_CONTROL_STOP);
1100 EndDialog(hDlg, TRUE);
1103 Button_Enable(GetDlgItem(hDlg, IDC_SSTART), FALSE);
1104 hListBox = GetDlgItem(hDlg, IDL_SERVICES);
1105 nItem = SendMessage(hListBox, LB_GETCURSEL, 0, 0);
1106 if (nItem != LB_ERR)
1108 ApacheManageService(g_stServices[nItem].szServiceName,
1109 g_stServices[nItem].szImagePath,
1110 SERVICE_CONTROL_CONTINUE);
1112 Button_Enable(GetDlgItem(hDlg, IDC_SSTART), TRUE);
1115 Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), FALSE);
1116 hListBox = GetDlgItem(hDlg, IDL_SERVICES);
1117 nItem = SendMessage(hListBox, LB_GETCURSEL, 0, 0);
1118 if (nItem != LB_ERR)
1120 ApacheManageService(g_stServices[nItem].szServiceName,
1121 g_stServices[nItem].szImagePath,
1122 SERVICE_CONTROL_STOP);
1124 Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), TRUE);
1127 Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), FALSE);
1128 hListBox = GetDlgItem(hDlg, IDL_SERVICES);
1129 nItem = SendMessage(hListBox, LB_GETCURSEL, 0, 0);
1130 if (nItem != LB_ERR)
1132 ApacheManageService(g_stServices[nItem].szServiceName,
1133 g_stServices[nItem].szImagePath,
1134 SERVICE_APACHE_RESTART);
1136 Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), TRUE);
1139 if (g_dwOSVersion >= OS_VERSION_WIN2K)
1140 ShellExecute(hDlg, "open", "services.msc", "/s", NULL, SW_NORMAL);
1142 WinExec("Control.exe SrvMgr.cpl Services", SW_NORMAL);
1145 EndDialog( hDlg, TRUE);
1146 SendMessage( g_hwndMain, WM_COMMAND, (WPARAM)IDM_EXIT, 0);
1151 switch (LOWORD(wParam))
1153 case SIZE_MINIMIZED:
1154 EndDialog(hDlg, TRUE);
1161 EndDialog(hDlg, TRUE);
1164 DeleteObject(g_hBmpStart);
1165 DeleteObject(g_hBmpStop);
1174 LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
1175 WPARAM wParam, LPARAM lParam)
1177 if (message == g_bUiTaskbarCreated)
1179 /* restore the tray icon on shell restart */
1180 ShowNotifyIcon(hWnd, NIM_ADD);
1181 return DefWindowProc(hWnd, message, wParam, lParam);
1186 GetApacheServicesStatus();
1187 ShowNotifyIcon(hWnd, NIM_ADD);
1188 SetTimer(hWnd, WM_TIMER_REFRESH, REFRESH_TIME, NULL);
1189 SetTimer(hWnd, WM_TIMER_RESCAN, RESCAN_TIME, NULL);
1190 g_hwndServiceDlg = NULL;
1195 case WM_TIMER_RESCAN:
1197 int nPrev = 0, nNew = 0;
1198 EnterCriticalSection(&g_stcSection);
1199 if (FindRunningServices() || g_bRescanServices)
1201 ShowNotifyIcon(hWnd, NIM_MODIFY);
1202 if (g_hwndServiceDlg)
1203 PostMessage(g_hwndServiceDlg, WM_UPDATEMESSAGE, 0, 0);
1205 /* check if services list changed */
1206 while (g_stServices[nPrev].szServiceName != NULL)
1208 GetApacheServicesStatus();
1209 while (g_stServices[nNew].szServiceName != NULL)
1213 ShowNotifyIcon(hWnd, NIM_MODIFY);
1214 if (g_hwndServiceDlg)
1215 PostMessage(g_hwndServiceDlg, WM_UPDATEMESSAGE, 0, 0);
1217 LeaveCriticalSection(&g_stcSection);
1220 case WM_TIMER_REFRESH:
1222 int nPrev = 0, nNew = 0;
1223 EnterCriticalSection(&g_stcSection);
1224 if (g_bRescanServices)
1226 GetApacheServicesStatus();
1227 ShowNotifyIcon(hWnd, NIM_MODIFY);
1228 if (g_hwndServiceDlg)
1229 PostMessage(g_hwndServiceDlg, WM_UPDATEMESSAGE, 0, 0);
1231 else if (FindRunningServices())
1233 ShowNotifyIcon(hWnd, NIM_MODIFY);
1234 if (g_hwndServiceDlg)
1235 PostMessage(g_hwndServiceDlg, WM_UPDATEMESSAGE, 0, 0);
1237 LeaveCriticalSection(&g_stcSection);
1243 ShowNotifyIcon(hWnd, NIM_DELETE);
1245 case WM_TRAYMESSAGE:
1248 case WM_LBUTTONDBLCLK:
1249 if (!g_bDlgServiceOn)
1251 g_bDlgServiceOn = TRUE;
1252 DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_DLGSERVICES),
1253 hWnd, (DLGPROC)ServiceDlgProc);
1254 g_bDlgServiceOn = FALSE;
1255 g_hwndServiceDlg = NULL;
1257 else if (g_hwndServiceDlg)
1259 /* Dirty hack to bring the window to the foreground */
1260 SetWindowPos(g_hwndServiceDlg, HWND_TOPMOST, 0, 0, 0, 0,
1261 SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
1262 SetWindowPos(g_hwndServiceDlg, HWND_NOTOPMOST, 0, 0, 0, 0,
1263 SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
1264 SetFocus(g_hwndServiceDlg);
1268 ShowTryServicesMenu(hWnd);
1271 ShowTryPopupMenu(hWnd);
1276 if ((LOWORD(wParam) & IDM_SM_START) == IDM_SM_START)
1278 ApacheManageService(g_stServices[LOWORD(wParam) - IDM_SM_START].szServiceName,
1279 g_stServices[LOWORD(wParam) - IDM_SM_START].szImagePath,
1280 SERVICE_CONTROL_CONTINUE);
1283 else if ((LOWORD(wParam) & IDM_SM_STOP) == IDM_SM_STOP)
1285 ApacheManageService(g_stServices[LOWORD(wParam) - IDM_SM_STOP].szServiceName,
1286 g_stServices[LOWORD(wParam) - IDM_SM_STOP].szImagePath,
1287 SERVICE_CONTROL_STOP);
1290 else if ((LOWORD(wParam) & IDM_SM_RESTART) == IDM_SM_RESTART)
1292 ApacheManageService(g_stServices[LOWORD(wParam) - IDM_SM_RESTART].szServiceName,
1293 g_stServices[LOWORD(wParam) - IDM_SM_RESTART].szImagePath,
1294 SERVICE_APACHE_RESTART);
1297 switch (LOWORD(wParam))
1300 if (!g_bDlgServiceOn)
1302 g_bDlgServiceOn = TRUE;
1303 DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_DLGSERVICES),
1304 hWnd, (DLGPROC)ServiceDlgProc);
1305 g_bDlgServiceOn = FALSE;
1306 g_hwndServiceDlg = NULL;
1308 else if (g_hwndServiceDlg)
1309 SetFocus(g_hwndServiceDlg);
1312 if (g_dwOSVersion >= OS_VERSION_WIN2K)
1313 ShellExecute(NULL, "open", "services.msc", "/s", NULL, SW_NORMAL);
1315 WinExec("Control.exe SrvMgr.cpl Services", SW_NORMAL);
1318 ShowNotifyIcon(hWnd, NIM_DELETE);
1323 return DefWindowProc(hWnd, message, wParam, lParam);
1329 /* Create main invisible window */
1330 HWND CreateMainWindow(HINSTANCE hInstance)
1335 if (!GetSystemOSVersion(&g_dwOSVersion))
1337 ErrorMessage(NULL, TRUE);
1341 wcex.cbSize = sizeof(WNDCLASSEX);
1343 wcex.style = CS_HREDRAW | CS_VREDRAW;
1344 wcex.lpfnWndProc = (WNDPROC)WndProc;
1345 wcex.cbClsExtra = 0;
1346 wcex.cbWndExtra = 0;
1347 wcex.hInstance = hInstance;
1348 wcex.hIcon = (HICON)LoadImage(hInstance, MAKEINTRESOURCE(IDI_APSRVMON),
1349 IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
1350 wcex.hCursor = g_hCursorArrow;
1351 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
1352 wcex.lpszMenuName = 0;
1353 wcex.lpszClassName = g_szWindowClass;
1354 wcex.hIconSm = (HICON)LoadImage(hInstance, MAKEINTRESOURCE(IDI_APSRVMON),
1355 IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
1357 if (RegisterClassEx(&wcex))
1358 hWnd = CreateWindow(g_szWindowClass, g_szTitle,
1360 NULL, NULL, hInstance, NULL);
1367 int WINAPI WinMain(HINSTANCE hInstance,
1368 HINSTANCE hPrevInstance,
1372 TCHAR szTmp[MAX_LOADSTRING];
1374 /* single instance mutex */
1378 g_LangID = GetUserDefaultLangID();
1379 if ((g_LangID & 0xFF) != LANG_ENGLISH)
1380 g_LangID = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
1382 for (i = IDS_MSG_FIRST; i <= IDS_MSG_LAST; ++i) {
1383 LoadString(hInstance, i, szTmp, MAX_LOADSTRING);
1384 g_lpMsg[i - IDS_MSG_FIRST] = strdup(szTmp);
1386 LoadString(hInstance, IDS_APMONITORTITLE, szTmp, MAX_LOADSTRING);
1387 g_szTitle = strdup(szTmp);
1388 LoadString(hInstance, IDS_APMONITORCLASS, szTmp, MAX_LOADSTRING);
1389 g_szWindowClass = strdup(szTmp);
1391 g_icoStop = LoadImage(hInstance, MAKEINTRESOURCE(IDI_ICOSTOP),
1392 IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
1393 g_icoRun = LoadImage(hInstance, MAKEINTRESOURCE(IDI_ICORUN),
1394 IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
1395 g_hCursorHourglass = LoadImage(NULL, MAKEINTRESOURCE(OCR_WAIT), IMAGE_CURSOR,
1396 LR_DEFAULTSIZE, LR_DEFAULTSIZE, LR_SHARED);
1397 g_hCursorArrow = LoadImage(NULL, MAKEINTRESOURCE(OCR_NORMAL), IMAGE_CURSOR,
1398 LR_DEFAULTSIZE, LR_DEFAULTSIZE, LR_SHARED);
1400 hMutex = CreateMutex(NULL, FALSE, "APSRVMON_MUTEX");
1401 if((hMutex == NULL) || (GetLastError() == ERROR_ALREADY_EXISTS))
1403 ErrorMessage(g_lpMsg[IDS_MSG_APPRUNNING-IDS_MSG_FIRST], FALSE);
1405 CloseHandle(hMutex);
1410 ZeroMemory(g_stServices, sizeof(ST_APACHE_SERVICE) * MAX_APACHE_SERVICES);
1411 InitCommonControls();
1412 g_hInstance = hInstance;
1413 g_hwndMain = CreateMainWindow(hInstance);
1414 g_bUiTaskbarCreated = RegisterWindowMessage("TaskbarCreated");
1415 InitializeCriticalSection(&g_stcSection);
1416 if (g_hwndMain != NULL)
1418 while (GetMessage(&msg, NULL, 0, 0) == TRUE)
1420 TranslateMessage(&msg);
1421 DispatchMessage(&msg);
1423 am_ClearServicesSt();
1425 DeleteCriticalSection(&g_stcSection);
1426 CloseHandle(hMutex);
1427 DestroyIcon(g_icoStop);
1428 DestroyIcon(g_icoRun);
1429 DestroyCursor(g_hCursorHourglass);
1430 DestroyCursor(g_hCursorArrow);