1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 /* ====================================================================
18 * ApacheMonitor.c Simple program to manage and monitor Apache services.
20 * Contributed by Mladen Turk <mturk mappingsoft.com>
23 * ====================================================================
26 #define _WIN32_WINNT 0x0500
34 #if defined(_MSC_VER) && _MSC_VER >= 1400
35 #define _CRT_SECURE_NO_DEPRECATE
47 #include "ApacheMonitor.h"
50 /** Properly quote a value as a string in the C preprocessor */
51 #define AM_STRINGIFY(n) AM_STRINGIFY_HELPER(n)
52 /** Helper macro for AM_STRINGIFY */
53 #define AM_STRINGIFY_HELPER(n) #n
56 #define OS_VERSION_WIN9X 1
57 #define OS_VERSION_WINNT 2
58 #define OS_VERSION_WIN2K 3
60 /* Should be enough */
61 #define MAX_APACHE_SERVICES 128
62 #define MAX_APACHE_COMPUTERS 32
64 #define WM_TRAYMESSAGE (WM_APP+1)
65 #define WM_UPDATEMESSAGE (WM_USER+1)
66 #define WM_MANAGEMESSAGE (WM_USER+2)
67 #define WM_TIMER_REFRESH 10
68 #define WM_TIMER_RESCAN 11
69 #define SERVICE_APACHE_RESTART 128
72 #define MAX_LOADSTRING 100
73 #define REFRESH_TIME 2000 /* service refresh time (ms) */
74 #define RESCAN_TIME 20000 /* registry rescan time (ms) */
76 typedef struct _st_APACHE_SERVICE
82 LPTSTR szComputerName;
86 typedef struct _st_MONITORED_COMPUTERS
88 LPTSTR szComputerName;
92 /* Global variables */
93 HINSTANCE g_hInstance = NULL;
94 TCHAR *g_szTitle; /* The title bar text */
95 TCHAR *g_szWindowClass; /* Window Class Name */
98 UINT g_bUiTaskbarCreated;
100 BOOL g_bDlgServiceOn = FALSE;
101 BOOL g_bConsoleRun = FALSE;
102 ST_APACHE_SERVICE g_stServices[MAX_APACHE_SERVICES];
103 ST_MONITORED_COMP g_stComputers[MAX_APACHE_COMPUTERS];
105 HBITMAP g_hBmpStart, g_hBmpStop;
106 HBITMAP g_hBmpPicture, g_hBmpOld;
107 BOOL g_bRescanServices;
108 HWND g_hwndServiceDlg;
110 HWND g_hwndStdoutList;
111 HWND g_hwndConnectDlg;
112 HCURSOR g_hCursorHourglass;
113 HCURSOR g_hCursorArrow;
115 HANDLE g_hpipeOutRead;
116 HANDLE g_hpipeOutWrite;
117 HANDLE g_hpipeInRead;
118 HANDLE g_hpipeInWrite;
119 HANDLE g_hpipeStdError;
121 PROCESS_INFORMATION g_lpRedirectProc;
122 CRITICAL_SECTION g_stcSection;
123 LPTSTR g_szLocalHost;
125 /* locale language support */
126 static TCHAR *g_lpMsg[IDS_MSG_LAST - IDS_MSG_FIRST + 1];
129 void am_ClearServicesSt()
132 for (i = 0; i < MAX_APACHE_SERVICES; i++)
134 if (g_stServices[i].szServiceName) {
135 free(g_stServices[i].szServiceName);
137 if (g_stServices[i].szDisplayName) {
138 free(g_stServices[i].szDisplayName);
140 if (g_stServices[i].szDescription) {
141 free(g_stServices[i].szDescription);
143 if (g_stServices[i].szImagePath) {
144 free(g_stServices[i].szImagePath);
146 if (g_stServices[i].szComputerName) {
147 free(g_stServices[i].szComputerName);
151 memset(g_stServices, 0, sizeof(ST_APACHE_SERVICE) * MAX_APACHE_SERVICES);
156 void am_ClearComputersSt()
159 for (i = 0; i < MAX_APACHE_COMPUTERS; i++) {
160 if (g_stComputers[i].szComputerName) {
161 free(g_stComputers[i].szComputerName);
162 RegCloseKey(g_stComputers[i].hRegistry);
165 memset(g_stComputers, 0, sizeof(ST_MONITORED_COMP) * MAX_APACHE_COMPUTERS);
170 BOOL am_IsComputerConnected(LPTSTR szComputerName)
173 while (g_stComputers[i].szComputerName != NULL) {
174 if (_tcscmp(g_stComputers[i].szComputerName, szComputerName) == 0) {
183 void am_DisconnectComputer(LPTSTR szComputerName)
186 while (g_stComputers[i].szComputerName != NULL) {
187 if (_tcscmp(g_stComputers[i].szComputerName, szComputerName) == 0) {
192 if (g_stComputers[i].szComputerName != NULL) {
193 free(g_stComputers[i].szComputerName);
194 RegCloseKey(g_stComputers[i].hRegistry);
195 for (j = i; j < MAX_APACHE_COMPUTERS - 1; j++) {
196 g_stComputers[j].szComputerName= g_stComputers[j+1].szComputerName;
197 g_stComputers[j].hRegistry = g_stComputers[j+1].hRegistry;
199 g_stComputers[j].szComputerName = NULL;
200 g_stComputers[j].hRegistry = NULL;
205 void ErrorMessage(LPCTSTR szError, BOOL bFatal)
207 LPVOID lpMsgBuf = NULL;
209 MessageBox(NULL, szError, g_lpMsg[IDS_MSG_ERROR - IDS_MSG_FIRST],
210 MB_OK | (bFatal ? MB_ICONERROR : MB_ICONEXCLAMATION));
213 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
214 FORMAT_MESSAGE_FROM_SYSTEM |
215 FORMAT_MESSAGE_IGNORE_INSERTS,
216 NULL, GetLastError(), g_LangID,
217 (LPTSTR) &lpMsgBuf, 0, NULL);
218 MessageBox(NULL, (LPCTSTR)lpMsgBuf,
219 g_lpMsg[IDS_MSG_ERROR - IDS_MSG_FIRST],
220 MB_OK | (bFatal ? MB_ICONERROR : MB_ICONEXCLAMATION));
229 int am_RespawnAsUserAdmin(HWND hwnd, DWORD op, LPCTSTR szService,
230 LPCTSTR szComputerName)
232 TCHAR args[MAX_PATH + MAX_COMPUTERNAME_LENGTH + 12];
234 if (g_dwOSVersion < OS_VERSION_WIN2K) {
235 ErrorMessage(g_lpMsg[IDS_MSG_SRVFAILED - IDS_MSG_FIRST], FALSE);
239 _sntprintf(args, sizeof(args) / sizeof(TCHAR),
240 _T("%d \"%s\" \"%s\""), op, szService,
241 szComputerName ? szComputerName : _T(""));
242 if (!ShellExecute(hwnd, _T("runas"), __targv[0], args, NULL, SW_NORMAL)) {
243 ErrorMessage(g_lpMsg[IDS_MSG_SRVFAILED - IDS_MSG_FIRST],
252 BOOL am_ConnectComputer(LPTSTR szComputerName)
256 TCHAR szTmp[MAX_PATH];
258 while (g_stComputers[i].szComputerName != NULL) {
259 if (_tcscmp(g_stComputers[i].szComputerName, szComputerName) == 0) {
264 if (i > MAX_APACHE_COMPUTERS - 1) {
267 if (RegConnectRegistry(szComputerName, HKEY_LOCAL_MACHINE, &hKeyRemote)
269 _sntprintf(szTmp, sizeof(szTmp) / sizeof(TCHAR),
270 g_lpMsg[IDS_MSG_ECONNECT - IDS_MSG_FIRST],
272 ErrorMessage(szTmp, FALSE);
276 g_stComputers[i].szComputerName = _tcsdup(szComputerName);
277 g_stComputers[i].hRegistry = hKeyRemote;
283 LPTSTR GetStringRes(int id)
285 static TCHAR buffer[MAX_PATH];
288 LoadString(GetModuleHandle(NULL), id, buffer, MAX_PATH);
293 BOOL GetSystemOSVersion(LPDWORD dwVersion)
297 Try calling GetVersionEx using the OSVERSIONINFOEX structure.
298 If that fails, try using the OSVERSIONINFO structure.
300 memset(&osvi, 0, sizeof(OSVERSIONINFO));
301 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
303 if (!GetVersionEx(&osvi)) {
307 switch (osvi.dwPlatformId)
309 case VER_PLATFORM_WIN32_NT:
310 if (osvi.dwMajorVersion >= 5)
311 *dwVersion = OS_VERSION_WIN2K;
313 *dwVersion = OS_VERSION_WINNT;
316 case VER_PLATFORM_WIN32_WINDOWS:
317 *dwVersion = OS_VERSION_WIN9X;
320 case VER_PLATFORM_WIN32s:
329 static VOID ShowNotifyIcon(HWND hWnd, DWORD dwMessage)
334 memset(&nid, 0, sizeof(nid));
335 nid.cbSize = sizeof(NOTIFYICONDATA);
338 nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
339 nid.uCallbackMessage = WM_TRAYMESSAGE;
341 while (g_stServices[i].szServiceName != NULL)
343 if (g_stServices[i].dwPid != 0) {
348 if (dwMessage != NIM_DELETE)
351 nid.hIcon = g_icoRun;
354 nid.hIcon = g_icoStop;
360 if (n == i && n > 0) {
361 _tcscpy(nid.szTip, g_lpMsg[IDS_MSG_RUNNINGALL - IDS_MSG_FIRST]);
364 _sntprintf(nid.szTip, sizeof(nid.szTip) / sizeof(TCHAR),
365 g_lpMsg[IDS_MSG_RUNNING - IDS_MSG_FIRST], n, i);
368 _sntprintf(nid.szTip, sizeof(nid.szTip) / sizeof(TCHAR),
369 g_lpMsg[IDS_MSG_RUNNINGNONE - IDS_MSG_FIRST], i);
372 _tcscpy(nid.szTip, g_lpMsg[IDS_MSG_NOSERVICES - IDS_MSG_FIRST]);
374 Shell_NotifyIcon(dwMessage, &nid);
378 void appendMenuItem(HMENU hMenu, UINT uMenuId, LPTSTR szName,
379 BOOL fDefault, BOOL fEnabled)
383 memset(&mii, 0, sizeof(MENUITEMINFO));
384 mii.cbSize = sizeof(MENUITEMINFO);
385 mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
388 mii.fType = MFT_STRING;
391 mii.fState = MFS_DEFAULT;
394 mii.fState |= MFS_DISABLED;
396 mii.dwTypeData = szName;
399 mii.fType = MFT_SEPARATOR;
401 InsertMenuItem(hMenu, uMenuId, FALSE, &mii);
405 void appendServiceMenu(HMENU hMenu, UINT uMenuId,
406 LPTSTR szServiceName, BOOL fRunning)
411 smh = CreatePopupMenu();
413 appendMenuItem(smh, IDM_SM_START + uMenuId,
414 g_lpMsg[IDS_MSG_SSTART - IDS_MSG_FIRST], FALSE, !fRunning);
415 appendMenuItem(smh, IDM_SM_STOP + uMenuId,
416 g_lpMsg[IDS_MSG_SSTOP - IDS_MSG_FIRST], FALSE, fRunning);
417 appendMenuItem(smh, IDM_SM_RESTART + uMenuId,
418 g_lpMsg[IDS_MSG_SRESTART - IDS_MSG_FIRST], FALSE, fRunning);
420 memset(&mii, 0, sizeof(MENUITEMINFO));
421 mii.cbSize = sizeof(MENUITEMINFO);
422 mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE | MIIM_SUBMENU
424 mii.fType = MFT_STRING;
426 mii.hbmpChecked = g_hBmpStart;
427 mii.hbmpUnchecked = g_hBmpStop;
428 mii.dwTypeData = szServiceName;
430 mii.fState = fRunning ? MFS_CHECKED : MFS_UNCHECKED;
431 InsertMenuItem(hMenu, IDM_SM_SERVICE + uMenuId, FALSE, &mii);
435 void ShowTryPopupMenu(HWND hWnd)
437 /* create popup menu */
438 HMENU hMenu = CreatePopupMenu();
443 appendMenuItem(hMenu, IDM_RESTORE,
444 g_lpMsg[IDS_MSG_MNUSHOW - IDS_MSG_FIRST],
446 if (g_dwOSVersion >= OS_VERSION_WINNT) {
447 appendMenuItem(hMenu, IDC_SMANAGER,
448 g_lpMsg[IDS_MSG_MNUSERVICES - IDS_MSG_FIRST],
451 appendMenuItem(hMenu, 0, _T(""), FALSE, TRUE);
452 appendMenuItem(hMenu, IDM_EXIT,
453 g_lpMsg[IDS_MSG_MNUEXIT - IDS_MSG_FIRST],
456 if (!SetForegroundWindow(hWnd)) {
457 SetForegroundWindow(NULL);
460 TrackPopupMenu(hMenu, TPM_LEFTALIGN|TPM_RIGHTBUTTON,
461 pt.x, pt.y, 0, hWnd, NULL);
467 void ShowTryServicesMenu(HWND hWnd)
469 /* create services list popup menu and submenus */
470 HMENU hMenu = CreatePopupMenu();
476 while (g_stServices[i].szServiceName != NULL)
478 appendServiceMenu(hMenu, i, g_stServices[i].szDisplayName,
479 g_stServices[i].dwPid != 0);
484 if (!SetForegroundWindow(hWnd)) {
485 SetForegroundWindow(NULL);
488 TrackPopupMenu(hMenu, TPM_LEFTALIGN|TPM_RIGHTBUTTON,
489 pt.x, pt.y, 0, hWnd, NULL);
496 BOOL CenterWindow(HWND hwndChild)
498 RECT rChild, rWorkArea;
503 /* Get the Height and Width of the child window */
504 GetWindowRect(hwndChild, &rChild);
505 wChild = rChild.right - rChild.left;
506 hChild = rChild.bottom - rChild.top;
508 /* Get the limits of the 'workarea' */
509 bResult = SystemParametersInfo(SPI_GETWORKAREA, sizeof(RECT),
512 rWorkArea.left = rWorkArea.top = 0;
513 rWorkArea.right = GetSystemMetrics(SM_CXSCREEN);
514 rWorkArea.bottom = GetSystemMetrics(SM_CYSCREEN);
517 /* Calculate new X and Y position*/
518 xNew = (rWorkArea.right - wChild) / 2;
519 yNew = (rWorkArea.bottom - hChild) / 2;
520 return SetWindowPos(hwndChild, HWND_TOP, xNew, yNew, 0, 0,
521 SWP_NOSIZE | SWP_SHOWWINDOW);
525 static void addListBoxItem(HWND hDlg, LPTSTR lpStr, HBITMAP hBmp)
529 nItem = SendMessage(hDlg, LB_ADDSTRING, 0, (LPARAM)lpStr);
530 SendMessage(hDlg, LB_SETITEMDATA, nItem, (LPARAM)hBmp);
534 static void addListBoxString(HWND hListBox, LPTSTR lpStr)
536 static int nItems = 0;
537 if (!g_bDlgServiceOn) {
541 if (nItems > MAX_LOADSTRING)
543 SendMessage(hListBox, LB_RESETCONTENT, 0, 0);
546 ListBox_SetCurSel(hListBox,
547 ListBox_AddString(hListBox, lpStr));
553 #define addListBoxStringA addListBoxString
555 static void addListBoxStringA(HWND hListBox, LPSTR lpStr)
557 static int nItems = 0;
560 if (!g_bDlgServiceOn) {
563 if (!MultiByteToWideChar(CP_ACP, 0, lpStr, (int)strlen(lpStr) + 1,
564 WStr, (int) (sizeof(WStr) / sizeof(TCHAR))))
567 if (nItems > MAX_LOADSTRING)
569 SendMessage(hListBox, LB_RESETCONTENT, 0, 0);
572 ListBox_SetCurSel(hListBox,
573 ListBox_AddString(hListBox, WStr));
578 static DWORD WINAPI ConsoleOutputThread(LPVOID lpThreadParameter)
580 static BYTE lpBuffer[MAX_PATH+1];
585 while (ReadFile(g_hpipeOutRead, &ch, 1, &dwReaded, NULL) == TRUE)
589 if (ch == '\n' || nPtr >= MAX_PATH)
591 lpBuffer[nPtr] = '\0';
592 addListBoxStringA(g_hwndStdoutList, lpBuffer);
595 else if (ch == '\t' && nPtr < (MAX_PATH - 4))
598 for (i = 0; i < 4; ++i) {
599 lpBuffer[nPtr++] = ' ';
602 else if (ch != '\r') {
603 lpBuffer[nPtr++] = ch;
607 CloseHandle(g_hpipeInWrite);
608 CloseHandle(g_hpipeOutRead);
609 CloseHandle(g_hpipeStdError);
614 DWORD WINAPI ConsoleWaitingThread(LPVOID lpThreadParameter)
616 WaitForSingleObject(g_lpRedirectProc.hThread, INFINITE);
617 CloseHandle(g_lpRedirectProc.hThread);
619 g_bConsoleRun = FALSE;
620 SetCursor(g_hCursorArrow);
625 BOOL RunRedirectedConsole(LPTSTR szCmdLine)
632 memset(&stInfo, 0, sizeof(stInfo));
633 stInfo.cb = sizeof(stInfo);
634 stInfo.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
635 stInfo.wShowWindow = SW_HIDE;
637 hProc = GetCurrentProcess();
639 if (!CreatePipe(&g_hpipeInRead, &g_hpipeInWrite, NULL, MAX_PATH)) {
640 ErrorMessage(NULL, TRUE);
642 if (!CreatePipe(&g_hpipeOutRead, &g_hpipeOutWrite, NULL, MAX_PATH*8)) {
643 ErrorMessage(NULL, TRUE);
645 DuplicateHandle(hProc, g_hpipeInRead, hProc, &g_hpipeInRead, 0, TRUE,
646 DUPLICATE_CLOSE_SOURCE|DUPLICATE_SAME_ACCESS);
647 DuplicateHandle(hProc, g_hpipeOutWrite, hProc, &g_hpipeOutWrite, 0, TRUE,
648 DUPLICATE_CLOSE_SOURCE|DUPLICATE_SAME_ACCESS);
649 DuplicateHandle(hProc, g_hpipeOutWrite, hProc, &g_hpipeStdError, 0, TRUE,
650 DUPLICATE_SAME_ACCESS);
651 if (!g_hpipeInRead && !g_hpipeOutWrite && !g_hpipeStdError) {
652 ErrorMessage(NULL, TRUE);
654 stInfo.hStdInput = g_hpipeInRead;
655 stInfo.hStdOutput = g_hpipeOutWrite;
656 stInfo.hStdError = g_hpipeStdError;
658 bResult = CreateProcess(NULL,
670 CloseHandle(g_hpipeInRead);
671 CloseHandle(g_hpipeOutWrite);
672 CloseHandle(g_hpipeStdError);
676 CloseHandle(g_hpipeInWrite);
677 CloseHandle(g_hpipeOutRead);
678 CloseHandle(g_hpipeStdError);
682 CloseHandle(CreateThread(NULL, 0, ConsoleOutputThread,
684 ResumeThread(g_lpRedirectProc.hThread);
685 CloseHandle(CreateThread(NULL, 0, ConsoleWaitingThread,
692 BOOL RunAndForgetConsole(LPTSTR szCmdLine, BOOL bRedirectConsole)
695 PROCESS_INFORMATION prInfo;
698 if (bRedirectConsole) {
699 return RunRedirectedConsole(szCmdLine);
702 memset(&stInfo, 0, sizeof(stInfo));
703 stInfo.cb = sizeof(stInfo);
704 stInfo.dwFlags = STARTF_USESHOWWINDOW;
705 stInfo.wShowWindow = SW_HIDE;
707 bResult = CreateProcess(NULL,
721 if (g_dwOSVersion == OS_VERSION_WIN9X) {
722 /* give some time to rescan the status */
725 CloseHandle(prInfo.hThread);
726 CloseHandle(prInfo.hProcess);
731 BOOL ApacheManageService(LPCTSTR szServiceName, LPCTSTR szImagePath,
732 LPTSTR szComputerName, DWORD dwCommand)
734 TCHAR szBuf[MAX_PATH];
735 TCHAR szMsg[MAX_PATH];
738 BOOL serviceFlag = TRUE;
739 SC_HANDLE schService;
740 SC_HANDLE schSCManager;
741 SERVICE_STATUS schSStatus;
744 if (g_dwOSVersion == OS_VERSION_WIN9X)
746 sPos = _tcsstr(szImagePath, _T("-k start"));
749 _tcsncpy(szBuf, szImagePath, (int)(sPos - szImagePath));
752 case SERVICE_CONTROL_STOP:
753 _tcscat(szBuf, _T(" -k shutdown -n "));
756 case SERVICE_CONTROL_CONTINUE:
757 _sntprintf(szMsg, sizeof(szMsg) / sizeof(TCHAR),
758 g_lpMsg[IDS_MSG_SRVSTART - IDS_MSG_FIRST],
760 addListBoxString(g_hwndStdoutList, szMsg);
761 _tcscat(szBuf, _T(" -k start -n "));
765 case SERVICE_APACHE_RESTART:
766 _tcscat(szBuf, _T(" -k restart -n "));
772 _tcscat(szBuf, szServiceName);
777 g_bConsoleRun = TRUE;
778 SetCursor(g_hCursorHourglass);
779 if (!RunAndForgetConsole(szBuf, serviceFlag))
781 ErrorMessage(NULL, FALSE);
782 g_bConsoleRun = FALSE;
783 SetCursor(g_hCursorArrow);
786 else if (!serviceFlag)
788 _sntprintf(szMsg, sizeof(szMsg) / sizeof(TCHAR),
789 g_lpMsg[IDS_MSG_SRVSTARTED - IDS_MSG_FIRST],
791 addListBoxString(g_hwndStdoutList, szMsg);
792 g_bConsoleRun = FALSE;
793 SetCursor(g_hCursorArrow);
799 schSCManager = OpenSCManager(szComputerName, NULL,
802 ErrorMessage(g_lpMsg[IDS_MSG_SRVFAILED - IDS_MSG_FIRST],
807 schService = OpenService(schSCManager, szServiceName,
808 SERVICE_QUERY_STATUS | SERVICE_START |
809 SERVICE_STOP | SERVICE_USER_DEFINED_CONTROL);
810 if (schService == NULL)
812 /* Avoid recursion of ImagePath NULL (from this Respawn) */
814 am_RespawnAsUserAdmin(g_hwndMain, dwCommand,
815 szServiceName, szComputerName);
818 ErrorMessage(g_lpMsg[IDS_MSG_SRVFAILED - IDS_MSG_FIRST],
821 CloseServiceHandle(schSCManager);
827 g_bConsoleRun = TRUE;
828 SetCursor(g_hCursorHourglass);
831 case SERVICE_CONTROL_STOP:
832 _sntprintf(szMsg, sizeof(szMsg) / sizeof(TCHAR),
833 g_lpMsg[IDS_MSG_SRVSTOP - IDS_MSG_FIRST],
835 addListBoxString(g_hwndStdoutList, szMsg);
836 if (ControlService(schService, SERVICE_CONTROL_STOP,
839 while (QueryServiceStatus(schService, &schSStatus))
841 if (schSStatus.dwCurrentState == SERVICE_STOP_PENDING)
850 if (QueryServiceStatus(schService, &schSStatus))
852 if (schSStatus.dwCurrentState == SERVICE_STOPPED)
855 _sntprintf(szMsg, sizeof(szMsg) / sizeof(TCHAR),
856 g_lpMsg[IDS_MSG_SRVSTOPPED - IDS_MSG_FIRST],
858 addListBoxString(g_hwndStdoutList, szMsg);
863 case SERVICE_CONTROL_CONTINUE:
864 _sntprintf(szMsg, sizeof(szMsg) / sizeof(TCHAR),
865 g_lpMsg[IDS_MSG_SRVSTART - IDS_MSG_FIRST],
867 addListBoxString(g_hwndStdoutList, szMsg);
869 if (StartService(schService, 0, NULL))
872 while (QueryServiceStatus(schService, &schSStatus))
874 if (schSStatus.dwCurrentState == SERVICE_START_PENDING)
883 if (QueryServiceStatus(schService, &schSStatus))
885 if (schSStatus.dwCurrentState == SERVICE_RUNNING)
888 _sntprintf(szMsg, sizeof(szMsg) / sizeof(TCHAR),
889 g_lpMsg[IDS_MSG_SRVSTARTED - IDS_MSG_FIRST],
891 addListBoxString(g_hwndStdoutList, szMsg);
896 case SERVICE_APACHE_RESTART:
897 _sntprintf(szMsg, sizeof(szMsg) / sizeof(TCHAR),
898 g_lpMsg[IDS_MSG_SRVRESTART - IDS_MSG_FIRST],
900 addListBoxString(g_hwndStdoutList, szMsg);
901 if (ControlService(schService, SERVICE_APACHE_RESTART,
905 while (schSStatus.dwCurrentState == SERVICE_START_PENDING)
908 if (!QueryServiceStatus(schService, &schSStatus))
910 CloseServiceHandle(schService);
911 CloseServiceHandle(schSCManager);
912 g_bConsoleRun = FALSE;
913 SetCursor(g_hCursorArrow);
921 if (schSStatus.dwCurrentState == SERVICE_RUNNING)
924 _sntprintf(szMsg, sizeof(szMsg) / sizeof(TCHAR),
925 g_lpMsg[IDS_MSG_SRVRESTARTED - IDS_MSG_FIRST],
927 addListBoxString(g_hwndStdoutList, szMsg);
931 CloseServiceHandle(schService);
932 CloseServiceHandle(schSCManager);
934 ErrorMessage(g_lpMsg[IDS_MSG_SRVFAILED - IDS_MSG_FIRST],
937 g_bConsoleRun = FALSE;
938 SetCursor(g_hCursorArrow);
948 BOOL IsServiceRunning(LPCTSTR szServiceName, LPCTSTR szComputerName,
953 SC_HANDLE schService;
954 SC_HANDLE schSCManager;
955 SERVICE_STATUS schSStatus;
957 if (g_dwOSVersion == OS_VERSION_WIN9X)
959 hWnd = FindWindow(_T("ApacheWin95ServiceMonitor"), szServiceName);
960 if (hWnd && GetWindowThreadProcessId(hWnd, &dwPid))
972 schSCManager = OpenSCManager(szComputerName, NULL,
978 schService = OpenService(schSCManager, szServiceName,
979 SERVICE_QUERY_STATUS);
980 if (schService != NULL)
982 if (QueryServiceStatus(schService, &schSStatus))
984 dwPid = schSStatus.dwCurrentState;
989 CloseServiceHandle(schService);
990 CloseServiceHandle(schSCManager);
991 return dwPid == SERVICE_RUNNING ? TRUE : FALSE;
994 g_bRescanServices = TRUE;
996 CloseServiceHandle(schSCManager);
1005 BOOL FindRunningServices(void)
1010 while (g_stServices[i].szServiceName != NULL)
1012 if (!IsServiceRunning(g_stServices[i].szServiceName,
1013 g_stServices[i].szComputerName, &dwPid)) {
1016 if (g_stServices[i].dwPid != dwPid) {
1019 g_stServices[i].dwPid = dwPid;
1026 BOOL GetApacheServicesStatus()
1028 TCHAR szKey[MAX_PATH];
1029 TCHAR achKey[MAX_PATH];
1030 TCHAR szImagePath[MAX_PATH];
1031 TCHAR szBuf[MAX_PATH];
1032 TCHAR szTmp[MAX_PATH];
1033 HKEY hKey, hSubKey, hKeyRemote;
1034 DWORD retCode, rv, dwKeyType;
1035 DWORD dwBufLen = MAX_PATH;
1039 g_bRescanServices = FALSE;
1041 am_ClearServicesSt();
1042 while (g_stComputers[computers].szComputerName != NULL) {
1043 hKeyRemote = g_stComputers[computers].hRegistry;
1044 retCode = RegOpenKeyEx(hKeyRemote,
1045 _T("System\\CurrentControlSet\\Services\\"),
1046 0, KEY_READ, &hKey);
1047 if (retCode != ERROR_SUCCESS)
1049 ErrorMessage(NULL, FALSE);
1052 for (i = 0, retCode = ERROR_SUCCESS; retCode == ERROR_SUCCESS; i++)
1054 retCode = RegEnumKey(hKey, i, achKey, MAX_PATH);
1055 if (retCode == ERROR_SUCCESS)
1057 _tcscpy(szKey, _T("System\\CurrentControlSet\\Services\\"));
1058 _tcscat(szKey, achKey);
1060 if (RegOpenKeyEx(hKeyRemote, szKey, 0,
1061 KEY_QUERY_VALUE, &hSubKey) == ERROR_SUCCESS)
1063 dwBufLen = MAX_PATH;
1064 rv = RegQueryValueEx(hSubKey, _T("ImagePath"), NULL,
1065 &dwKeyType, (LPBYTE)szImagePath, &dwBufLen);
1067 if (rv == ERROR_SUCCESS
1068 && (dwKeyType == REG_SZ
1069 || dwKeyType == REG_EXPAND_SZ)
1072 _tcscpy(szBuf, szImagePath);
1074 /* the service name could be httpd*.exe or Apache*.exe */
1075 if (((_tcsstr(szBuf, _T("\\apache")) != NULL)
1076 || (_tcsstr(szBuf, _T("\\httpd")) != NULL))
1077 && _tcsstr(szBuf, _T(".exe"))
1078 && (_tcsstr(szBuf, _T("--ntservice")) != NULL
1079 || _tcsstr(szBuf, _T("-k ")) != NULL))
1081 g_stServices[stPos].szServiceName = _tcsdup(achKey);
1082 g_stServices[stPos].szImagePath = _tcsdup(szImagePath);
1083 g_stServices[stPos].szComputerName =
1084 _tcsdup(g_stComputers[computers].szComputerName);
1085 dwBufLen = MAX_PATH;
1086 if (RegQueryValueEx(hSubKey, _T("Description"), NULL,
1087 &dwKeyType, (LPBYTE)szBuf, &dwBufLen)
1089 g_stServices[stPos].szDescription = _tcsdup(szBuf);
1091 dwBufLen = MAX_PATH;
1092 if (RegQueryValueEx(hSubKey, _T("DisplayName"), NULL,
1093 &dwKeyType, (LPBYTE)szBuf, &dwBufLen)
1096 if (_tcscmp(g_stComputers[computers]
1097 .szComputerName, g_szLocalHost) != 0)
1099 _tcscpy(szTmp, g_stComputers[computers]
1100 .szComputerName + 2);
1101 _tcscat(szTmp, _T("@"));
1102 _tcscat(szTmp, szBuf);
1105 _tcscpy(szTmp, szBuf);
1107 g_stServices[stPos].szDisplayName = _tcsdup(szTmp);
1111 if (stPos >= MAX_APACHE_SERVICES) {
1112 retCode = !ERROR_SUCCESS;
1116 RegCloseKey(hSubKey);
1123 FindRunningServices();
1128 LRESULT CALLBACK ConnectDlgProc(HWND hDlg, UINT message,
1129 WPARAM wParam, LPARAM lParam)
1131 TCHAR szCmp[MAX_COMPUTERNAME_LENGTH+4];
1135 ShowWindow(hDlg, SW_HIDE);
1136 g_hwndConnectDlg = hDlg;
1138 ShowWindow(hDlg, SW_SHOW);
1139 SetFocus(GetDlgItem(hDlg, IDC_COMPUTER));
1143 switch (LOWORD(wParam))
1146 memset(szCmp, 0, sizeof(szCmp));
1147 _tcscpy(szCmp, _T("\\\\"));
1148 SendMessage(GetDlgItem(hDlg, IDC_COMPUTER), WM_GETTEXT,
1149 (WPARAM) MAX_COMPUTERNAME_LENGTH,
1153 if (_tcslen(szCmp) < 3) {
1154 EndDialog(hDlg, TRUE);
1157 am_ConnectComputer(szCmp);
1158 SendMessage(g_hwndMain, WM_TIMER, WM_TIMER_RESCAN, 0);
1161 EndDialog(hDlg, TRUE);
1169 memset(&bi, 0, sizeof(BROWSEINFO));
1170 SHGetSpecialFolderLocation(hDlg, CSIDL_NETWORK, &il);
1172 bi.lpszTitle = _T("ApacheMonitor :\nSelect Network Computer!");
1173 bi.pszDisplayName = szCmp;
1174 bi.hwndOwner = hDlg;
1175 bi.ulFlags = BIF_BROWSEFORCOMPUTER;
1181 if (SHBrowseForFolder(&bi) != NULL) {
1182 SendMessage(GetDlgItem(hDlg, IDC_COMPUTER),
1184 (WPARAM) NULL, (LPARAM) szCmp);
1186 if (SHGetMalloc(&pMalloc)) {
1187 pMalloc->lpVtbl->Free(pMalloc, il);
1188 pMalloc->lpVtbl->Release(pMalloc);
1197 EndDialog(hDlg, TRUE);
1208 LRESULT CALLBACK ServiceDlgProc(HWND hDlg, UINT message,
1209 WPARAM wParam, LPARAM lParam)
1211 TCHAR szBuf[MAX_PATH];
1213 static HWND hStatusBar;
1219 LPMEASUREITEMSTRUCT lpmis;
1220 LPDRAWITEMSTRUCT lpdis;
1222 memset(szBuf, 0, sizeof(szBuf));
1226 ShowWindow(hDlg, SW_HIDE);
1227 g_hwndServiceDlg = hDlg;
1228 SetWindowText(hDlg, g_szTitle);
1229 Button_Enable(GetDlgItem(hDlg, IDC_SSTART), FALSE);
1230 Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), FALSE);
1231 Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), FALSE);
1232 Button_Enable(GetDlgItem(hDlg, IDC_SDISCONN), FALSE);
1233 SetWindowText(GetDlgItem(hDlg, IDC_SSTART),
1234 g_lpMsg[IDS_MSG_SSTART - IDS_MSG_FIRST]);
1235 SetWindowText(GetDlgItem(hDlg, IDC_SSTOP),
1236 g_lpMsg[IDS_MSG_SSTOP - IDS_MSG_FIRST]);
1237 SetWindowText(GetDlgItem(hDlg, IDC_SRESTART),
1238 g_lpMsg[IDS_MSG_SRESTART - IDS_MSG_FIRST]);
1239 SetWindowText(GetDlgItem(hDlg, IDC_SMANAGER),
1240 g_lpMsg[IDS_MSG_SERVICES - IDS_MSG_FIRST]);
1241 SetWindowText(GetDlgItem(hDlg, IDC_SCONNECT),
1242 g_lpMsg[IDS_MSG_CONNECT - IDS_MSG_FIRST]);
1243 SetWindowText(GetDlgItem(hDlg, IDC_SEXIT),
1244 g_lpMsg[IDS_MSG_MNUEXIT - IDS_MSG_FIRST]);
1245 if (g_dwOSVersion < OS_VERSION_WINNT)
1247 ShowWindow(GetDlgItem(hDlg, IDC_SMANAGER), SW_HIDE);
1248 ShowWindow(GetDlgItem(hDlg, IDC_SCONNECT), SW_HIDE);
1249 ShowWindow(GetDlgItem(hDlg, IDC_SDISCONN), SW_HIDE);
1251 hListBox = GetDlgItem(hDlg, IDL_SERVICES);
1252 g_hwndStdoutList = GetDlgItem(hDlg, IDL_STDOUT);
1253 hStatusBar = CreateStatusWindow(0x0800 /* SBT_TOOLTIPS */
1254 | WS_CHILD | WS_VISIBLE,
1255 _T(""), hDlg, IDC_STATBAR);
1256 if (GetApacheServicesStatus())
1259 while (g_stServices[i].szServiceName != NULL)
1261 addListBoxItem(hListBox, g_stServices[i].szDisplayName,
1262 g_stServices[i].dwPid == 0 ? g_hBmpStop
1268 ShowWindow(hDlg, SW_SHOW);
1270 SendMessage(hListBox, LB_SETCURSEL, 0, 0);
1274 case WM_MANAGEMESSAGE:
1275 ApacheManageService(g_stServices[LOWORD(wParam)].szServiceName,
1276 g_stServices[LOWORD(wParam)].szImagePath,
1277 g_stServices[LOWORD(wParam)].szComputerName,
1283 case WM_UPDATEMESSAGE:
1284 hListBox = GetDlgItem(hDlg, IDL_SERVICES);
1285 SendMessage(hListBox, LB_RESETCONTENT, 0, 0);
1286 SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)_T(""));
1287 Button_Enable(GetDlgItem(hDlg, IDC_SSTART), FALSE);
1288 Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), FALSE);
1289 Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), FALSE);
1290 Button_Enable(GetDlgItem(hDlg, IDC_SDISCONN), FALSE);
1292 while (g_stServices[i].szServiceName != NULL)
1294 addListBoxItem(hListBox, g_stServices[i].szDisplayName,
1295 g_stServices[i].dwPid == 0 ? g_hBmpStop : g_hBmpStart);
1298 SendMessage(hListBox, LB_SETCURSEL, 0, 0);
1299 /* Dirty hack to bring the window to the foreground */
1300 SetWindowPos(hDlg, HWND_TOPMOST, 0, 0, 0, 0,
1301 SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
1302 SetWindowPos(hDlg, HWND_NOTOPMOST, 0, 0, 0, 0,
1303 SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
1308 case WM_MEASUREITEM:
1309 lpmis = (LPMEASUREITEMSTRUCT) lParam;
1310 lpmis->itemHeight = YBITMAP;
1314 if (g_bConsoleRun) {
1315 SetCursor(g_hCursorHourglass);
1318 SetCursor(g_hCursorArrow);
1323 lpdis = (LPDRAWITEMSTRUCT) lParam;
1324 if (lpdis->itemID == -1) {
1327 switch (lpdis->itemAction)
1330 case ODA_DRAWENTIRE:
1331 g_hBmpPicture = (HBITMAP)SendMessage(lpdis->hwndItem,
1333 lpdis->itemID, (LPARAM) 0);
1335 hdcMem = CreateCompatibleDC(lpdis->hDC);
1336 g_hBmpOld = SelectObject(hdcMem, g_hBmpPicture);
1338 BitBlt(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
1339 lpdis->rcItem.right - lpdis->rcItem.left,
1340 lpdis->rcItem.bottom - lpdis->rcItem.top,
1341 hdcMem, 0, 0, SRCCOPY);
1342 SendMessage(lpdis->hwndItem, LB_GETTEXT,
1343 lpdis->itemID, (LPARAM) szBuf);
1345 GetTextMetrics(lpdis->hDC, &tm);
1346 y = (lpdis->rcItem.bottom + lpdis->rcItem.top - tm.tmHeight) / 2;
1348 SelectObject(hdcMem, g_hBmpOld);
1351 rcBitmap.left = lpdis->rcItem.left + XBITMAP + 2;
1352 rcBitmap.top = lpdis->rcItem.top;
1353 rcBitmap.right = lpdis->rcItem.right;
1354 rcBitmap.bottom = lpdis->rcItem.top + YBITMAP;
1356 if (lpdis->itemState & ODS_SELECTED)
1358 if (g_hBmpPicture == g_hBmpStop)
1360 Button_Enable(GetDlgItem(hDlg, IDC_SSTART), TRUE);
1361 Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), FALSE);
1362 Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), FALSE);
1364 else if (g_hBmpPicture == g_hBmpStart)
1366 Button_Enable(GetDlgItem(hDlg, IDC_SSTART), FALSE);
1367 Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), TRUE);
1368 Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), TRUE);
1371 Button_Enable(GetDlgItem(hDlg, IDC_SSTART), FALSE);
1372 Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), FALSE);
1373 Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), FALSE);
1375 if (_tcscmp(g_stServices[lpdis->itemID].szComputerName,
1376 g_szLocalHost) == 0) {
1377 Button_Enable(GetDlgItem(hDlg, IDC_SDISCONN), FALSE);
1380 Button_Enable(GetDlgItem(hDlg, IDC_SDISCONN), TRUE);
1383 if (g_stServices[lpdis->itemID].szDescription) {
1384 SendMessage(hStatusBar, SB_SETTEXT, 0,
1385 (LPARAM)g_stServices[lpdis->itemID].szDescription);
1388 SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)_T(""));
1390 SetTextColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
1391 SetBkColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHT));
1392 FillRect(lpdis->hDC, &rcBitmap, (HBRUSH)(COLOR_HIGHLIGHTTEXT));
1396 SetTextColor(lpdis->hDC, GetSysColor(COLOR_MENUTEXT));
1397 SetBkColor(lpdis->hDC, GetSysColor(COLOR_WINDOW));
1398 FillRect(lpdis->hDC, &rcBitmap, (HBRUSH)(COLOR_WINDOW+1));
1400 TextOut(lpdis->hDC, XBITMAP + 6, y, szBuf, (int)_tcslen(szBuf));
1408 switch (LOWORD(wParam))
1411 switch (HIWORD(wParam))
1414 /* if started then stop, if stopped then start */
1415 hListBox = GetDlgItem(hDlg, IDL_SERVICES);
1416 nItem = SendMessage(hListBox, LB_GETCURSEL, 0, 0);
1417 if (nItem != LB_ERR)
1419 g_hBmpPicture = (HBITMAP)SendMessage(hListBox,
1422 if (g_hBmpPicture == g_hBmpStop) {
1423 SendMessage(hDlg, WM_MANAGEMESSAGE, nItem,
1424 SERVICE_CONTROL_CONTINUE);
1427 SendMessage(hDlg, WM_MANAGEMESSAGE, nItem,
1428 SERVICE_CONTROL_STOP);
1437 EndDialog(hDlg, TRUE);
1441 Button_Enable(GetDlgItem(hDlg, IDC_SSTART), FALSE);
1442 hListBox = GetDlgItem(hDlg, IDL_SERVICES);
1443 nItem = SendMessage(hListBox, LB_GETCURSEL, 0, 0);
1444 if (nItem != LB_ERR) {
1445 SendMessage(hDlg, WM_MANAGEMESSAGE, nItem,
1446 SERVICE_CONTROL_CONTINUE);
1448 Button_Enable(GetDlgItem(hDlg, IDC_SSTART), TRUE);
1452 Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), FALSE);
1453 hListBox = GetDlgItem(hDlg, IDL_SERVICES);
1454 nItem = SendMessage(hListBox, LB_GETCURSEL, 0, 0);
1455 if (nItem != LB_ERR) {
1456 SendMessage(hDlg, WM_MANAGEMESSAGE, nItem,
1457 SERVICE_CONTROL_STOP);
1459 Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), TRUE);
1463 Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), FALSE);
1464 hListBox = GetDlgItem(hDlg, IDL_SERVICES);
1465 nItem = SendMessage(hListBox, LB_GETCURSEL, 0, 0);
1466 if (nItem != LB_ERR) {
1467 SendMessage(hDlg, WM_MANAGEMESSAGE, nItem,
1468 SERVICE_APACHE_RESTART);
1470 Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), TRUE);
1474 if (g_dwOSVersion >= OS_VERSION_WIN2K) {
1475 ShellExecute(hDlg, _T("open"), _T("services.msc"), _T("/s"),
1479 WinExec("Control.exe SrvMgr.cpl Services", SW_NORMAL);
1484 EndDialog(hDlg, TRUE);
1485 SendMessage(g_hwndMain, WM_COMMAND, (WPARAM)IDM_EXIT, 0);
1489 DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_DLGCONNECT),
1490 hDlg, (DLGPROC)ConnectDlgProc);
1494 hListBox = GetDlgItem(hDlg, IDL_SERVICES);
1495 nItem = SendMessage(hListBox, LB_GETCURSEL, 0, 0);
1496 if (nItem != LB_ERR) {
1497 am_DisconnectComputer(g_stServices[nItem].szComputerName);
1498 SendMessage(g_hwndMain, WM_TIMER, WM_TIMER_RESCAN, 0);
1505 switch (LOWORD(wParam))
1507 case SIZE_MINIMIZED:
1508 EndDialog(hDlg, TRUE);
1516 EndDialog(hDlg, TRUE);
1526 LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
1527 WPARAM wParam, LPARAM lParam)
1529 if (message == g_bUiTaskbarCreated)
1531 /* restore the tray icon on shell restart */
1532 ShowNotifyIcon(hWnd, NIM_ADD);
1533 return DefWindowProc(hWnd, message, wParam, lParam);
1538 GetApacheServicesStatus();
1539 ShowNotifyIcon(hWnd, NIM_ADD);
1540 SetTimer(hWnd, WM_TIMER_REFRESH, REFRESH_TIME, NULL);
1541 SetTimer(hWnd, WM_TIMER_RESCAN, RESCAN_TIME, NULL);
1547 case WM_TIMER_RESCAN:
1549 int nPrev = 0, nNew = 0;
1550 EnterCriticalSection(&g_stcSection);
1551 if (FindRunningServices() || g_bRescanServices)
1553 ShowNotifyIcon(hWnd, NIM_MODIFY);
1554 if (g_hwndServiceDlg)
1555 PostMessage(g_hwndServiceDlg, WM_UPDATEMESSAGE, 0, 0);
1557 /* check if services list changed */
1558 while (g_stServices[nPrev].szServiceName != NULL)
1560 GetApacheServicesStatus();
1561 while (g_stServices[nNew].szServiceName != NULL)
1565 ShowNotifyIcon(hWnd, NIM_MODIFY);
1566 if (g_hwndServiceDlg) {
1567 PostMessage(g_hwndServiceDlg, WM_UPDATEMESSAGE, 0, 0);
1570 LeaveCriticalSection(&g_stcSection);
1574 case WM_TIMER_REFRESH:
1576 int nPrev = 0, nNew = 0;
1577 EnterCriticalSection(&g_stcSection);
1578 if (g_bRescanServices)
1580 GetApacheServicesStatus();
1581 ShowNotifyIcon(hWnd, NIM_MODIFY);
1582 if (g_hwndServiceDlg) {
1583 PostMessage(g_hwndServiceDlg, WM_UPDATEMESSAGE, 0, 0);
1586 else if (FindRunningServices())
1588 ShowNotifyIcon(hWnd, NIM_MODIFY);
1589 if (g_hwndServiceDlg) {
1590 PostMessage(g_hwndServiceDlg, WM_UPDATEMESSAGE, 0, 0);
1593 LeaveCriticalSection(&g_stcSection);
1600 ShowNotifyIcon(hWnd, NIM_DELETE);
1603 case WM_TRAYMESSAGE:
1606 case WM_LBUTTONDBLCLK:
1607 if (!g_bDlgServiceOn)
1609 g_bDlgServiceOn = TRUE;
1610 DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_DLGSERVICES),
1611 hWnd, (DLGPROC)ServiceDlgProc);
1612 g_bDlgServiceOn = FALSE;
1613 g_hwndServiceDlg = NULL;
1615 else if (IsWindow(g_hwndServiceDlg))
1617 /* Dirty hack to bring the window to the foreground */
1618 SetWindowPos(g_hwndServiceDlg, HWND_TOPMOST, 0, 0, 0, 0,
1619 SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
1620 SetWindowPos(g_hwndServiceDlg, HWND_NOTOPMOST, 0, 0, 0, 0,
1621 SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
1622 SetFocus(g_hwndServiceDlg);
1627 ShowTryServicesMenu(hWnd);
1631 ShowTryPopupMenu(hWnd);
1637 if ((LOWORD(wParam) & IDM_SM_START) == IDM_SM_START)
1639 ApacheManageService(g_stServices[LOWORD(wParam)
1640 - IDM_SM_START].szServiceName,
1641 g_stServices[LOWORD(wParam)
1642 - IDM_SM_START].szImagePath,
1643 g_stServices[LOWORD(wParam)
1644 - IDM_SM_START].szComputerName,
1645 SERVICE_CONTROL_CONTINUE);
1648 else if ((LOWORD(wParam) & IDM_SM_STOP) == IDM_SM_STOP)
1650 ApacheManageService(g_stServices[LOWORD(wParam)
1651 - IDM_SM_STOP].szServiceName,
1652 g_stServices[LOWORD(wParam)
1653 - IDM_SM_STOP].szImagePath,
1654 g_stServices[LOWORD(wParam)
1655 - IDM_SM_STOP].szComputerName,
1656 SERVICE_CONTROL_STOP);
1659 else if ((LOWORD(wParam) & IDM_SM_RESTART) == IDM_SM_RESTART)
1661 ApacheManageService(g_stServices[LOWORD(wParam)
1662 - IDM_SM_RESTART].szServiceName,
1663 g_stServices[LOWORD(wParam)
1664 - IDM_SM_RESTART].szImagePath,
1665 g_stServices[LOWORD(wParam)
1666 - IDM_SM_RESTART].szComputerName,
1667 SERVICE_APACHE_RESTART);
1670 switch (LOWORD(wParam))
1673 if (!g_bDlgServiceOn)
1675 g_bDlgServiceOn = TRUE;
1676 DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_DLGSERVICES),
1677 hWnd, (DLGPROC)ServiceDlgProc);
1678 g_bDlgServiceOn = FALSE;
1679 g_hwndServiceDlg = NULL;
1681 else if (IsWindow(g_hwndServiceDlg)) {
1682 SetFocus(g_hwndServiceDlg);
1687 if (g_dwOSVersion >= OS_VERSION_WIN2K) {
1688 ShellExecute(NULL, _T("open"), _T("services.msc"), _T("/s"),
1692 WinExec("Control.exe SrvMgr.cpl Services", SW_NORMAL);
1697 ShowNotifyIcon(hWnd, NIM_DELETE);
1703 return DefWindowProc(hWnd, message, wParam, lParam);
1710 static int KillAWindow(HWND appwindow)
1717 GetWindowThreadProcessId(appwindow, &procid);
1721 appproc = OpenProcess(SYNCHRONIZE, 0, procid);
1722 postres = PostMessage(appwindow, WM_COMMAND, IDM_EXIT, 0);
1723 if (appproc && postres) {
1724 if (WaitForSingleObject(appproc, 10 /* seconds */ * 1000)
1726 CloseHandle(appproc);
1731 CloseHandle(appproc);
1733 if ((appproc = OpenProcess(PROCESS_TERMINATE, 0, procid)) != NULL) {
1734 if (TerminateProcess(appproc, 0)) {
1735 CloseHandle(appproc);
1738 CloseHandle(appproc);
1741 /* Perhaps we were short of permissions? */
1746 static int KillAllMonitors(void)
1750 PWTS_PROCESS_INFO tsProcs;
1751 DWORD tsProcCount, i;
1754 /* This is graceful, close our own Window, clearing the icon */
1755 if ((appwindow = FindWindow(g_szWindowClass, g_szTitle)) != NULL)
1756 exitcode = KillAWindow(appwindow);
1758 if (g_dwOSVersion < OS_VERSION_WIN2K)
1761 thisProcId = GetCurrentProcessId();
1763 if (!WTSEnumerateProcesses(WTS_CURRENT_SERVER_HANDLE, 0, 1,
1764 &tsProcs, &tsProcCount))
1767 /* This is ungraceful; close other Windows, with a lingering icon.
1768 * Since on terminal server it's not possible to post the message
1769 * to exit across sessions, we have to suffer this side effect
1770 * of a taskbar 'icon' which will evaporate the next time that
1771 * the user hovers over it or when the taskbar area is updated.
1773 for (i = 0; i < tsProcCount; ++i) {
1774 if (_tcscmp(tsProcs[i].pProcessName, _T(AM_STRINGIFY(BIN_NAME))) == 0
1775 && tsProcs[i].ProcessId != thisProcId)
1776 WTSTerminateProcess(WTS_CURRENT_SERVER_HANDLE,
1777 tsProcs[i].ProcessId, 1);
1779 WTSFreeMemory(tsProcs);
1784 /* Create main invisible window */
1785 HWND CreateMainWindow(HINSTANCE hInstance)
1790 wcex.cbSize = sizeof(WNDCLASSEX);
1792 wcex.style = CS_HREDRAW | CS_VREDRAW;
1793 wcex.lpfnWndProc = (WNDPROC)WndProc;
1794 wcex.cbClsExtra = 0;
1795 wcex.cbWndExtra = 0;
1796 wcex.hInstance = hInstance;
1797 wcex.hIcon = (HICON)LoadImage(hInstance, MAKEINTRESOURCE(IDI_APSRVMON),
1798 IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
1799 wcex.hCursor = g_hCursorArrow;
1800 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
1801 wcex.lpszMenuName = 0;
1802 wcex.lpszClassName = g_szWindowClass;
1803 wcex.hIconSm = (HICON)LoadImage(hInstance, MAKEINTRESOURCE(IDI_APSRVMON),
1804 IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
1806 if (RegisterClassEx(&wcex)) {
1807 hWnd = CreateWindow(g_szWindowClass, g_szTitle,
1809 NULL, NULL, hInstance, NULL);
1816 /* Borrowed from CRT internal.h for _MBCS argc/argv parsing in this GUI app */
1817 int __cdecl _setargv(void);
1820 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
1821 LPSTR lpCmdLine, int nCmdShow)
1823 TCHAR szTmp[MAX_LOADSTRING];
1824 TCHAR szCmp[MAX_COMPUTERNAME_LENGTH+4];
1826 /* existing window */
1832 if (!GetSystemOSVersion(&g_dwOSVersion))
1834 ErrorMessage(NULL, TRUE);
1838 g_LangID = GetUserDefaultLangID();
1839 if ((g_LangID & 0xFF) != LANG_ENGLISH) {
1840 g_LangID = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
1842 for (i = IDS_MSG_FIRST; i <= IDS_MSG_LAST; ++i) {
1843 LoadString(hInstance, i, szTmp, MAX_LOADSTRING);
1844 g_lpMsg[i - IDS_MSG_FIRST] = _tcsdup(szTmp);
1846 LoadString(hInstance, IDS_APMONITORTITLE, szTmp, MAX_LOADSTRING);
1847 d = MAX_COMPUTERNAME_LENGTH+1;
1848 _tcscpy(szCmp, _T("\\\\"));
1849 GetComputerName(szCmp + 2, &d);
1851 g_szLocalHost = _tcsdup(szCmp);
1853 memset(g_stComputers, 0, sizeof(ST_MONITORED_COMP) * MAX_APACHE_COMPUTERS);
1854 g_stComputers[0].szComputerName = _tcsdup(szCmp);
1855 g_stComputers[0].hRegistry = HKEY_LOCAL_MACHINE;
1856 g_szTitle = _tcsdup(szTmp);
1857 LoadString(hInstance, IDS_APMONITORCLASS, szTmp, MAX_LOADSTRING);
1858 g_szWindowClass = _tcsdup(szTmp);
1860 appwindow = FindWindow(g_szWindowClass, g_szTitle);
1863 __wargv = CommandLineToArgvW(GetCommandLineW(), &__argc);
1868 if ((__argc == 2) && (_tcscmp(__targv[1], _T("--kill")) == 0))
1870 /* Off to chase and close up every ApacheMonitor taskbar window */
1871 return KillAllMonitors();
1873 else if ((__argc == 4) && (g_dwOSVersion >= OS_VERSION_WIN2K))
1875 dwControl = _ttoi(__targv[1]);
1876 if ((dwControl != SERVICE_CONTROL_CONTINUE) &&
1877 (dwControl != SERVICE_APACHE_RESTART) &&
1878 (dwControl != SERVICE_CONTROL_STOP))
1883 /* Chase down and close up our session's previous window */
1884 if ((appwindow) != NULL)
1885 KillAWindow(appwindow);
1887 else if (__argc != 1) {
1892 ErrorMessage(g_lpMsg[IDS_MSG_APPRUNNING - IDS_MSG_FIRST], FALSE);
1896 g_icoStop = LoadImage(hInstance, MAKEINTRESOURCE(IDI_ICOSTOP),
1897 IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
1898 g_icoRun = LoadImage(hInstance, MAKEINTRESOURCE(IDI_ICORUN),
1899 IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
1900 g_hCursorHourglass = LoadImage(NULL, MAKEINTRESOURCE(OCR_WAIT),
1901 IMAGE_CURSOR, LR_DEFAULTSIZE,
1902 LR_DEFAULTSIZE, LR_SHARED);
1903 g_hCursorArrow = LoadImage(NULL, MAKEINTRESOURCE(OCR_NORMAL),
1904 IMAGE_CURSOR, LR_DEFAULTSIZE,
1905 LR_DEFAULTSIZE, LR_SHARED);
1906 g_hBmpStart = LoadImage(hInstance, MAKEINTRESOURCE(IDB_BMPRUN),
1907 IMAGE_BITMAP, XBITMAP, YBITMAP,
1909 g_hBmpStop = LoadImage(hInstance, MAKEINTRESOURCE(IDB_BMPSTOP),
1910 IMAGE_BITMAP, XBITMAP, YBITMAP,
1913 memset(g_stServices, 0, sizeof(ST_APACHE_SERVICE) * MAX_APACHE_SERVICES);
1915 InitCommonControls();
1916 g_hInstance = hInstance;
1917 g_hwndMain = CreateMainWindow(hInstance);
1918 g_bUiTaskbarCreated = RegisterWindowMessage(_T("TaskbarCreated"));
1919 InitializeCriticalSection(&g_stcSection);
1920 g_hwndServiceDlg = NULL;
1921 if (g_hwndMain != NULL)
1923 /* To avoid recursion, pass ImagePath NULL (a noop on NT and later) */
1924 if ((__argc == 4) && (g_dwOSVersion >= OS_VERSION_WIN2K))
1925 ApacheManageService(__targv[2], NULL, __targv[3], dwControl);
1927 while (GetMessage(&msg, NULL, 0, 0) == TRUE)
1929 TranslateMessage(&msg);
1930 DispatchMessage(&msg);
1932 am_ClearServicesSt();
1934 am_ClearComputersSt();
1935 DeleteCriticalSection(&g_stcSection);
1936 DestroyIcon(g_icoStop);
1937 DestroyIcon(g_icoRun);
1938 DestroyCursor(g_hCursorHourglass);
1939 DestroyCursor(g_hCursorArrow);
1940 DeleteObject(g_hBmpStart);
1941 DeleteObject(g_hBmpStop);