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 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 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. 15 */ 16 17/* ==================================================================== 18 * ApacheMonitor.c Simple program to manage and monitor Apache services. 19 * 20 * Contributed by Mladen Turk <mturk mappingsoft.com> 21 * 22 * 05 Aug 2001 23 * ==================================================================== 24 */ 25 26#define _WIN32_WINNT 0x0500 27#ifndef STRICT 28#define STRICT 29#endif 30#ifndef OEMRESOURCE 31#define OEMRESOURCE 32#endif 33 34#if defined(_MSC_VER) && _MSC_VER >= 1400 35#define _CRT_SECURE_NO_DEPRECATE 36#endif 37 38#include <windows.h> 39#include <windowsx.h> 40#include <commctrl.h> 41#include <objbase.h> 42#include <shlobj.h> 43#include <stdlib.h> 44#include <stdio.h> 45#include <WtsApi32.h> 46#include <tchar.h> 47#include "ApacheMonitor.h" 48 49#ifndef AM_STRINGIFY 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 54#endif 55 56#define OS_VERSION_WINNT 2 57#define OS_VERSION_WIN2K 3 58 59/* Should be enough */ 60#define MAX_APACHE_SERVICES 128 61#define MAX_APACHE_COMPUTERS 32 62 63#define WM_TRAYMESSAGE (WM_APP+1) 64#define WM_UPDATEMESSAGE (WM_USER+1) 65#define WM_MANAGEMESSAGE (WM_USER+2) 66#define WM_TIMER_REFRESH 10 67#define WM_TIMER_RESCAN 11 68#define SERVICE_APACHE_RESTART 128 69#define XBITMAP 16 70#define YBITMAP 16 71#define MAX_LOADSTRING 100 72#define REFRESH_TIME 2000 /* service refresh time (ms) */ 73#define RESCAN_TIME 20000 /* registry rescan time (ms) */ 74 75typedef struct _st_APACHE_SERVICE 76{ 77 LPTSTR szServiceName; 78 LPTSTR szDisplayName; 79 LPTSTR szDescription; 80 LPTSTR szImagePath; 81 LPTSTR szComputerName; 82 DWORD dwPid; 83} ST_APACHE_SERVICE; 84 85typedef struct _st_MONITORED_COMPUTERS 86{ 87 LPTSTR szComputerName; 88 HKEY hRegistry; 89} ST_MONITORED_COMP; 90 91/* Global variables */ 92HINSTANCE g_hInstance = NULL; 93TCHAR *g_szTitle; /* The title bar text */ 94TCHAR *g_szWindowClass; /* Window Class Name */ 95HICON g_icoStop; 96HICON g_icoRun; 97UINT g_bUiTaskbarCreated; 98DWORD g_dwOSVersion; 99BOOL g_bDlgServiceOn = FALSE; 100BOOL g_bConsoleRun = FALSE; 101ST_APACHE_SERVICE g_stServices[MAX_APACHE_SERVICES]; 102ST_MONITORED_COMP g_stComputers[MAX_APACHE_COMPUTERS]; 103 104HBITMAP g_hBmpStart, g_hBmpStop; 105HBITMAP g_hBmpPicture, g_hBmpOld; 106BOOL g_bRescanServices; 107HWND g_hwndServiceDlg; 108HWND g_hwndMain; 109HWND g_hwndStdoutList; 110HWND g_hwndConnectDlg; 111HCURSOR g_hCursorHourglass; 112HCURSOR g_hCursorArrow; 113 114LANGID g_LangID; 115CRITICAL_SECTION g_stcSection; 116LPTSTR g_szLocalHost; 117 118/* locale language support */ 119static TCHAR *g_lpMsg[IDS_MSG_LAST - IDS_MSG_FIRST + 1]; 120 121 122void am_ClearServicesSt() 123{ 124 int i; 125 for (i = 0; i < MAX_APACHE_SERVICES; i++) 126 { 127 if (g_stServices[i].szServiceName) { 128 free(g_stServices[i].szServiceName); 129 } 130 if (g_stServices[i].szDisplayName) { 131 free(g_stServices[i].szDisplayName); 132 } 133 if (g_stServices[i].szDescription) { 134 free(g_stServices[i].szDescription); 135 } 136 if (g_stServices[i].szImagePath) { 137 free(g_stServices[i].szImagePath); 138 } 139 if (g_stServices[i].szComputerName) { 140 free(g_stServices[i].szComputerName); 141 } 142 143 } 144 memset(g_stServices, 0, sizeof(ST_APACHE_SERVICE) * MAX_APACHE_SERVICES); 145 146} 147 148 149void am_ClearComputersSt() 150{ 151 int i; 152 for (i = 0; i < MAX_APACHE_COMPUTERS; i++) { 153 if (g_stComputers[i].szComputerName) { 154 free(g_stComputers[i].szComputerName); 155 RegCloseKey(g_stComputers[i].hRegistry); 156 } 157 } 158 memset(g_stComputers, 0, sizeof(ST_MONITORED_COMP) * MAX_APACHE_COMPUTERS); 159 160} 161 162 163BOOL am_IsComputerConnected(LPTSTR szComputerName) 164{ 165 int i = 0; 166 while (g_stComputers[i].szComputerName != NULL) { 167 if (_tcscmp(g_stComputers[i].szComputerName, szComputerName) == 0) { 168 return TRUE; 169 } 170 ++i; 171 } 172 return FALSE; 173} 174 175 176void am_DisconnectComputer(LPTSTR szComputerName) 177{ 178 int i = 0, j; 179 while (g_stComputers[i].szComputerName != NULL) { 180 if (_tcscmp(g_stComputers[i].szComputerName, szComputerName) == 0) { 181 break; 182 } 183 ++i; 184 } 185 if (g_stComputers[i].szComputerName != NULL) { 186 free(g_stComputers[i].szComputerName); 187 RegCloseKey(g_stComputers[i].hRegistry); 188 for (j = i; j < MAX_APACHE_COMPUTERS - 1; j++) { 189 g_stComputers[j].szComputerName= g_stComputers[j+1].szComputerName; 190 g_stComputers[j].hRegistry = g_stComputers[j+1].hRegistry; 191 } 192 g_stComputers[j].szComputerName = NULL; 193 g_stComputers[j].hRegistry = NULL; 194 } 195} 196 197 198void ErrorMessage(LPCTSTR szError, BOOL bFatal) 199{ 200 LPVOID lpMsgBuf = NULL; 201 if (szError) { 202 MessageBox(NULL, szError, g_lpMsg[IDS_MSG_ERROR - IDS_MSG_FIRST], 203 MB_OK | (bFatal ? MB_ICONERROR : MB_ICONEXCLAMATION)); 204 } 205 else { 206 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 207 FORMAT_MESSAGE_FROM_SYSTEM | 208 FORMAT_MESSAGE_IGNORE_INSERTS, 209 NULL, GetLastError(), g_LangID, 210 (LPTSTR) &lpMsgBuf, 0, NULL); 211 MessageBox(NULL, (LPCTSTR)lpMsgBuf, 212 g_lpMsg[IDS_MSG_ERROR - IDS_MSG_FIRST], 213 MB_OK | (bFatal ? MB_ICONERROR : MB_ICONEXCLAMATION)); 214 LocalFree(lpMsgBuf); 215 } 216 if (bFatal) { 217 PostQuitMessage(0); 218 } 219} 220 221 222int am_RespawnAsUserAdmin(HWND hwnd, DWORD op, LPCTSTR szService, 223 LPCTSTR szComputerName) 224{ 225 TCHAR args[MAX_PATH + MAX_COMPUTERNAME_LENGTH + 12]; 226 227 if (g_dwOSVersion < OS_VERSION_WIN2K) { 228 ErrorMessage(g_lpMsg[IDS_MSG_SRVFAILED - IDS_MSG_FIRST], FALSE); 229 return 0; 230 } 231 232 _sntprintf(args, sizeof(args) / sizeof(TCHAR), 233 _T("%d \"%s\" \"%s\""), op, szService, 234 szComputerName ? szComputerName : _T("")); 235 if (!ShellExecute(hwnd, _T("runas"), __targv[0], args, NULL, SW_NORMAL)) { 236 ErrorMessage(g_lpMsg[IDS_MSG_SRVFAILED - IDS_MSG_FIRST], 237 FALSE); 238 return 0; 239 } 240 241 return 1; 242} 243 244 245BOOL am_ConnectComputer(LPTSTR szComputerName) 246{ 247 int i = 0; 248 HKEY hKeyRemote; 249 TCHAR szTmp[MAX_PATH]; 250 251 while (g_stComputers[i].szComputerName != NULL) { 252 if (_tcscmp(g_stComputers[i].szComputerName, szComputerName) == 0) { 253 return FALSE; 254 } 255 ++i; 256 } 257 if (i > MAX_APACHE_COMPUTERS - 1) { 258 return FALSE; 259 } 260 if (RegConnectRegistry(szComputerName, HKEY_LOCAL_MACHINE, &hKeyRemote) 261 != ERROR_SUCCESS) { 262 _sntprintf(szTmp, sizeof(szTmp) / sizeof(TCHAR), 263 g_lpMsg[IDS_MSG_ECONNECT - IDS_MSG_FIRST], 264 szComputerName); 265 ErrorMessage(szTmp, FALSE); 266 return FALSE; 267 } 268 else { 269 g_stComputers[i].szComputerName = _tcsdup(szComputerName); 270 g_stComputers[i].hRegistry = hKeyRemote; 271 return TRUE; 272 } 273} 274 275 276LPTSTR GetStringRes(int id) 277{ 278 static TCHAR buffer[MAX_PATH]; 279 280 buffer[0] = 0; 281 LoadString(GetModuleHandle(NULL), id, buffer, MAX_PATH); 282 return buffer; 283} 284 285 286BOOL GetSystemOSVersion(LPDWORD dwVersion) 287{ 288 OSVERSIONINFO osvi; 289 /* 290 Try calling GetVersionEx using the OSVERSIONINFOEX structure. 291 If that fails, try using the OSVERSIONINFO structure. 292 */ 293 memset(&osvi, 0, sizeof(OSVERSIONINFO)); 294 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); 295 296 if (!GetVersionEx(&osvi)) { 297 return FALSE; 298 } 299 300 switch (osvi.dwPlatformId) 301 { 302 case VER_PLATFORM_WIN32_NT: 303 if (osvi.dwMajorVersion >= 5) 304 *dwVersion = OS_VERSION_WIN2K; 305 else 306 *dwVersion = OS_VERSION_WINNT; 307 break; 308 309 case VER_PLATFORM_WIN32_WINDOWS: 310 case VER_PLATFORM_WIN32s: 311 default: 312 *dwVersion = 0; 313 return FALSE; 314 } 315 return TRUE; 316} 317 318 319static VOID ShowNotifyIcon(HWND hWnd, DWORD dwMessage) 320{ 321 NOTIFYICONDATA nid; 322 int i = 0, n = 0; 323 324 memset(&nid, 0, sizeof(nid)); 325 nid.cbSize = sizeof(NOTIFYICONDATA); 326 nid.hWnd = hWnd; 327 nid.uID = 0xFF; 328 nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; 329 nid.uCallbackMessage = WM_TRAYMESSAGE; 330 331 while (g_stServices[i].szServiceName != NULL) 332 { 333 if (g_stServices[i].dwPid != 0) { 334 ++n; 335 } 336 ++i; 337 } 338 if (dwMessage != NIM_DELETE) 339 { 340 if (n) { 341 nid.hIcon = g_icoRun; 342 } 343 else { 344 nid.hIcon = g_icoStop; 345 } 346 } 347 else { 348 nid.hIcon = NULL; 349 } 350 if (n == i && n > 0) { 351 _tcscpy(nid.szTip, g_lpMsg[IDS_MSG_RUNNINGALL - IDS_MSG_FIRST]); 352 } 353 else if (n) { 354 _sntprintf(nid.szTip, sizeof(nid.szTip) / sizeof(TCHAR), 355 g_lpMsg[IDS_MSG_RUNNING - IDS_MSG_FIRST], n, i); 356 } 357 else if (i) { 358 _sntprintf(nid.szTip, sizeof(nid.szTip) / sizeof(TCHAR), 359 g_lpMsg[IDS_MSG_RUNNINGNONE - IDS_MSG_FIRST], i); 360 } 361 else { 362 _tcscpy(nid.szTip, g_lpMsg[IDS_MSG_NOSERVICES - IDS_MSG_FIRST]); 363 } 364 Shell_NotifyIcon(dwMessage, &nid); 365} 366 367 368void appendMenuItem(HMENU hMenu, UINT uMenuId, LPTSTR szName, 369 BOOL fDefault, BOOL fEnabled) 370{ 371 MENUITEMINFO mii; 372 373 memset(&mii, 0, sizeof(MENUITEMINFO)); 374 mii.cbSize = sizeof(MENUITEMINFO); 375 mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE; 376 if (_tcslen(szName)) 377 { 378 mii.fType = MFT_STRING; 379 mii.wID = uMenuId; 380 if (fDefault) { 381 mii.fState = MFS_DEFAULT; 382 } 383 if (!fEnabled) { 384 mii.fState |= MFS_DISABLED; 385 } 386 mii.dwTypeData = szName; 387 } 388 else { 389 mii.fType = MFT_SEPARATOR; 390 } 391 InsertMenuItem(hMenu, uMenuId, FALSE, &mii); 392} 393 394 395void appendServiceMenu(HMENU hMenu, UINT uMenuId, 396 LPTSTR szServiceName, BOOL fRunning) 397{ 398 MENUITEMINFO mii; 399 HMENU smh; 400 401 smh = CreatePopupMenu(); 402 403 appendMenuItem(smh, IDM_SM_START + uMenuId, 404 g_lpMsg[IDS_MSG_SSTART - IDS_MSG_FIRST], FALSE, !fRunning); 405 appendMenuItem(smh, IDM_SM_STOP + uMenuId, 406 g_lpMsg[IDS_MSG_SSTOP - IDS_MSG_FIRST], FALSE, fRunning); 407 appendMenuItem(smh, IDM_SM_RESTART + uMenuId, 408 g_lpMsg[IDS_MSG_SRESTART - IDS_MSG_FIRST], FALSE, fRunning); 409 410 memset(&mii, 0, sizeof(MENUITEMINFO)); 411 mii.cbSize = sizeof(MENUITEMINFO); 412 mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE | MIIM_SUBMENU 413 | MIIM_CHECKMARKS; 414 mii.fType = MFT_STRING; 415 mii.wID = uMenuId; 416 mii.hbmpChecked = g_hBmpStart; 417 mii.hbmpUnchecked = g_hBmpStop; 418 mii.dwTypeData = szServiceName; 419 mii.hSubMenu = smh; 420 mii.fState = fRunning ? MFS_CHECKED : MFS_UNCHECKED; 421 InsertMenuItem(hMenu, IDM_SM_SERVICE + uMenuId, FALSE, &mii); 422} 423 424 425void ShowTryPopupMenu(HWND hWnd) 426{ 427 /* create popup menu */ 428 HMENU hMenu = CreatePopupMenu(); 429 POINT pt; 430 431 if (hMenu) 432 { 433 appendMenuItem(hMenu, IDM_RESTORE, 434 g_lpMsg[IDS_MSG_MNUSHOW - IDS_MSG_FIRST], 435 TRUE, TRUE); 436 appendMenuItem(hMenu, IDC_SMANAGER, 437 g_lpMsg[IDS_MSG_MNUSERVICES - IDS_MSG_FIRST], 438 FALSE, TRUE); 439 appendMenuItem(hMenu, 0, _T(""), FALSE, TRUE); 440 appendMenuItem(hMenu, IDM_EXIT, 441 g_lpMsg[IDS_MSG_MNUEXIT - IDS_MSG_FIRST], 442 FALSE, TRUE); 443 444 if (!SetForegroundWindow(hWnd)) { 445 SetForegroundWindow(NULL); 446 } 447 GetCursorPos(&pt); 448 TrackPopupMenu(hMenu, TPM_LEFTALIGN|TPM_RIGHTBUTTON, 449 pt.x, pt.y, 0, hWnd, NULL); 450 DestroyMenu(hMenu); 451 } 452} 453 454 455void ShowTryServicesMenu(HWND hWnd) 456{ 457 /* create services list popup menu and submenus */ 458 HMENU hMenu = CreatePopupMenu(); 459 POINT pt; 460 int i = 0; 461 462 if (hMenu) 463 { 464 while (g_stServices[i].szServiceName != NULL) 465 { 466 appendServiceMenu(hMenu, i, g_stServices[i].szDisplayName, 467 g_stServices[i].dwPid != 0); 468 ++i; 469 } 470 if (i) 471 { 472 if (!SetForegroundWindow(hWnd)) { 473 SetForegroundWindow(NULL); 474 } 475 GetCursorPos(&pt); 476 TrackPopupMenu(hMenu, TPM_LEFTALIGN|TPM_RIGHTBUTTON, 477 pt.x, pt.y, 0, hWnd, NULL); 478 DestroyMenu(hMenu); 479 } 480 } 481} 482 483 484BOOL CenterWindow(HWND hwndChild) 485{ 486 RECT rChild, rWorkArea; 487 int wChild, hChild; 488 int xNew, yNew; 489 BOOL bResult; 490 491 /* Get the Height and Width of the child window */ 492 GetWindowRect(hwndChild, &rChild); 493 wChild = rChild.right - rChild.left; 494 hChild = rChild.bottom - rChild.top; 495 496 /* Get the limits of the 'workarea' */ 497 bResult = SystemParametersInfo(SPI_GETWORKAREA, sizeof(RECT), 498 &rWorkArea, 0); 499 if (!bResult) { 500 rWorkArea.left = rWorkArea.top = 0; 501 rWorkArea.right = GetSystemMetrics(SM_CXSCREEN); 502 rWorkArea.bottom = GetSystemMetrics(SM_CYSCREEN); 503 } 504 505 /* Calculate new X and Y position*/ 506 xNew = (rWorkArea.right - wChild) / 2; 507 yNew = (rWorkArea.bottom - hChild) / 2; 508 return SetWindowPos(hwndChild, HWND_TOP, xNew, yNew, 0, 0, 509 SWP_NOSIZE | SWP_SHOWWINDOW); 510} 511 512 513static void addListBoxItem(HWND hDlg, LPTSTR lpStr, HBITMAP hBmp) 514{ 515 LRESULT nItem; 516 517 nItem = SendMessage(hDlg, LB_ADDSTRING, 0, (LPARAM)lpStr); 518 SendMessage(hDlg, LB_SETITEMDATA, nItem, (LPARAM)hBmp); 519} 520 521 522static void addListBoxString(HWND hListBox, LPTSTR lpStr) 523{ 524 static int nItems = 0; 525 if (!g_bDlgServiceOn) { 526 return; 527 } 528 ++nItems; 529 if (nItems > MAX_LOADSTRING) 530 { 531 SendMessage(hListBox, LB_RESETCONTENT, 0, 0); 532 nItems = 1; 533 } 534 ListBox_SetCurSel(hListBox, 535 ListBox_AddString(hListBox, lpStr)); 536 537} 538 539 540BOOL ApacheManageService(LPCTSTR szServiceName, LPCTSTR szImagePath, 541 LPTSTR szComputerName, DWORD dwCommand) 542{ 543 TCHAR szMsg[MAX_PATH]; 544 BOOL retValue; 545 SC_HANDLE schService; 546 SC_HANDLE schSCManager; 547 SERVICE_STATUS schSStatus; 548 int ticks; 549 550 schSCManager = OpenSCManager(szComputerName, NULL, 551 SC_MANAGER_CONNECT); 552 if (!schSCManager) { 553 ErrorMessage(g_lpMsg[IDS_MSG_SRVFAILED - IDS_MSG_FIRST], 554 FALSE); 555 return FALSE; 556 } 557 558 schService = OpenService(schSCManager, szServiceName, 559 SERVICE_QUERY_STATUS | SERVICE_START | 560 SERVICE_STOP | SERVICE_USER_DEFINED_CONTROL); 561 if (schService == NULL) 562 { 563 /* Avoid recursion of ImagePath NULL (from this Respawn) */ 564 if (szImagePath) { 565 am_RespawnAsUserAdmin(g_hwndMain, dwCommand, 566 szServiceName, szComputerName); 567 } 568 else { 569 ErrorMessage(g_lpMsg[IDS_MSG_SRVFAILED - IDS_MSG_FIRST], 570 FALSE); 571 } 572 CloseServiceHandle(schSCManager); 573 return FALSE; 574 } 575 else 576 { 577 retValue = FALSE; 578 g_bConsoleRun = TRUE; 579 SetCursor(g_hCursorHourglass); 580 switch (dwCommand) 581 { 582 case SERVICE_CONTROL_STOP: 583 _sntprintf(szMsg, sizeof(szMsg) / sizeof(TCHAR), 584 g_lpMsg[IDS_MSG_SRVSTOP - IDS_MSG_FIRST], 585 szServiceName); 586 addListBoxString(g_hwndStdoutList, szMsg); 587 if (ControlService(schService, SERVICE_CONTROL_STOP, 588 &schSStatus)) { 589 Sleep(1000); 590 while (QueryServiceStatus(schService, &schSStatus)) 591 { 592 if (schSStatus.dwCurrentState == SERVICE_STOP_PENDING) 593 { 594 Sleep(1000); 595 } 596 else { 597 break; 598 } 599 } 600 } 601 if (QueryServiceStatus(schService, &schSStatus)) 602 { 603 if (schSStatus.dwCurrentState == SERVICE_STOPPED) 604 { 605 retValue = TRUE; 606 _sntprintf(szMsg, sizeof(szMsg) / sizeof(TCHAR), 607 g_lpMsg[IDS_MSG_SRVSTOPPED - IDS_MSG_FIRST], 608 szServiceName); 609 addListBoxString(g_hwndStdoutList, szMsg); 610 } 611 } 612 break; 613 614 case SERVICE_CONTROL_CONTINUE: 615 _sntprintf(szMsg, sizeof(szMsg) / sizeof(TCHAR), 616 g_lpMsg[IDS_MSG_SRVSTART - IDS_MSG_FIRST], 617 szServiceName); 618 addListBoxString(g_hwndStdoutList, szMsg); 619 620 if (StartService(schService, 0, NULL)) 621 { 622 Sleep(1000); 623 while (QueryServiceStatus(schService, &schSStatus)) 624 { 625 if (schSStatus.dwCurrentState == SERVICE_START_PENDING) 626 { 627 Sleep(1000); 628 } 629 else { 630 break; 631 } 632 } 633 } 634 if (QueryServiceStatus(schService, &schSStatus)) 635 { 636 if (schSStatus.dwCurrentState == SERVICE_RUNNING) 637 { 638 retValue = TRUE; 639 _sntprintf(szMsg, sizeof(szMsg) / sizeof(TCHAR), 640 g_lpMsg[IDS_MSG_SRVSTARTED - IDS_MSG_FIRST], 641 szServiceName); 642 addListBoxString(g_hwndStdoutList, szMsg); 643 } 644 } 645 break; 646 647 case SERVICE_APACHE_RESTART: 648 _sntprintf(szMsg, sizeof(szMsg) / sizeof(TCHAR), 649 g_lpMsg[IDS_MSG_SRVRESTART - IDS_MSG_FIRST], 650 szServiceName); 651 addListBoxString(g_hwndStdoutList, szMsg); 652 if (ControlService(schService, SERVICE_APACHE_RESTART, 653 &schSStatus)) 654 { 655 ticks = 60; 656 while (schSStatus.dwCurrentState == SERVICE_START_PENDING) 657 { 658 Sleep(1000); 659 if (!QueryServiceStatus(schService, &schSStatus)) 660 { 661 CloseServiceHandle(schService); 662 CloseServiceHandle(schSCManager); 663 g_bConsoleRun = FALSE; 664 SetCursor(g_hCursorArrow); 665 return FALSE; 666 } 667 if (!--ticks) { 668 break; 669 } 670 } 671 } 672 if (schSStatus.dwCurrentState == SERVICE_RUNNING) 673 { 674 retValue = TRUE; 675 _sntprintf(szMsg, sizeof(szMsg) / sizeof(TCHAR), 676 g_lpMsg[IDS_MSG_SRVRESTARTED - IDS_MSG_FIRST], 677 szServiceName); 678 addListBoxString(g_hwndStdoutList, szMsg); 679 } 680 break; 681 } 682 CloseServiceHandle(schService); 683 CloseServiceHandle(schSCManager); 684 if (!retValue) { 685 ErrorMessage(g_lpMsg[IDS_MSG_SRVFAILED - IDS_MSG_FIRST], 686 FALSE); 687 } 688 g_bConsoleRun = FALSE; 689 SetCursor(g_hCursorArrow); 690 return retValue; 691 } 692 return FALSE; 693} 694 695 696BOOL IsServiceRunning(LPCTSTR szServiceName, LPCTSTR szComputerName, 697 LPDWORD lpdwPid) 698{ 699 DWORD dwPid; 700 SC_HANDLE schService; 701 SC_HANDLE schSCManager; 702 SERVICE_STATUS schSStatus; 703 704 dwPid = 0; 705 schSCManager = OpenSCManager(szComputerName, NULL, 706 SC_MANAGER_CONNECT); 707 if (!schSCManager) { 708 return FALSE; 709 } 710 711 schService = OpenService(schSCManager, szServiceName, 712 SERVICE_QUERY_STATUS); 713 if (schService != NULL) 714 { 715 if (QueryServiceStatus(schService, &schSStatus)) 716 { 717 dwPid = schSStatus.dwCurrentState; 718 if (lpdwPid) { 719 *lpdwPid = 1; 720 } 721 } 722 CloseServiceHandle(schService); 723 CloseServiceHandle(schSCManager); 724 return dwPid == SERVICE_RUNNING ? TRUE : FALSE; 725 } 726 else { 727 g_bRescanServices = TRUE; 728 } 729 CloseServiceHandle(schSCManager); 730 return FALSE; 731} 732 733 734BOOL FindRunningServices(void) 735{ 736 int i = 0; 737 DWORD dwPid; 738 BOOL rv = FALSE; 739 while (g_stServices[i].szServiceName != NULL) 740 { 741 if (!IsServiceRunning(g_stServices[i].szServiceName, 742 g_stServices[i].szComputerName, &dwPid)) { 743 dwPid = 0; 744 } 745 if (g_stServices[i].dwPid != dwPid) { 746 rv = TRUE; 747 } 748 g_stServices[i].dwPid = dwPid; 749 ++i; 750 } 751 return rv; 752} 753 754 755BOOL GetApacheServicesStatus() 756{ 757 TCHAR szKey[MAX_PATH]; 758 TCHAR achKey[MAX_PATH]; 759 TCHAR szImagePath[MAX_PATH]; 760 TCHAR szBuf[MAX_PATH]; 761 TCHAR szTmp[MAX_PATH]; 762 HKEY hKey, hSubKey, hKeyRemote; 763 DWORD retCode, rv, dwKeyType; 764 DWORD dwBufLen = MAX_PATH; 765 int i, stPos = 0; 766 int computers = 0; 767 768 g_bRescanServices = FALSE; 769 770 am_ClearServicesSt(); 771 while (g_stComputers[computers].szComputerName != NULL) { 772 hKeyRemote = g_stComputers[computers].hRegistry; 773 retCode = RegOpenKeyEx(hKeyRemote, 774 _T("System\\CurrentControlSet\\Services\\"), 775 0, KEY_READ, &hKey); 776 if (retCode != ERROR_SUCCESS) 777 { 778 ErrorMessage(NULL, FALSE); 779 return FALSE; 780 } 781 for (i = 0, retCode = ERROR_SUCCESS; retCode == ERROR_SUCCESS; i++) 782 { 783 retCode = RegEnumKey(hKey, i, achKey, MAX_PATH); 784 if (retCode == ERROR_SUCCESS) 785 { 786 _tcscpy(szKey, _T("System\\CurrentControlSet\\Services\\")); 787 _tcscat(szKey, achKey); 788 789 if (RegOpenKeyEx(hKeyRemote, szKey, 0, 790 KEY_QUERY_VALUE, &hSubKey) == ERROR_SUCCESS) 791 { 792 dwBufLen = MAX_PATH; 793 rv = RegQueryValueEx(hSubKey, _T("ImagePath"), NULL, 794 &dwKeyType, (LPBYTE)szImagePath, &dwBufLen); 795 796 if (rv == ERROR_SUCCESS 797 && (dwKeyType == REG_SZ 798 || dwKeyType == REG_EXPAND_SZ) 799 && dwBufLen) 800 { 801 _tcscpy(szBuf, szImagePath); 802 CharLower(szBuf); 803 /* the service name could be httpd*.exe or Apache*.exe */ 804 if (((_tcsstr(szBuf, _T("\\apache")) != NULL) 805 || (_tcsstr(szBuf, _T("\\httpd")) != NULL)) 806 && _tcsstr(szBuf, _T(".exe")) 807 && (_tcsstr(szBuf, _T("--ntservice")) != NULL 808 || _tcsstr(szBuf, _T("-k ")) != NULL)) 809 { 810 g_stServices[stPos].szServiceName = _tcsdup(achKey); 811 g_stServices[stPos].szImagePath = _tcsdup(szImagePath); 812 g_stServices[stPos].szComputerName = 813 _tcsdup(g_stComputers[computers].szComputerName); 814 dwBufLen = MAX_PATH; 815 if (RegQueryValueEx(hSubKey, _T("Description"), NULL, 816 &dwKeyType, (LPBYTE)szBuf, &dwBufLen) 817 == ERROR_SUCCESS) { 818 g_stServices[stPos].szDescription = _tcsdup(szBuf); 819 } 820 dwBufLen = MAX_PATH; 821 if (RegQueryValueEx(hSubKey, _T("DisplayName"), NULL, 822 &dwKeyType, (LPBYTE)szBuf, &dwBufLen) 823 == ERROR_SUCCESS) 824 { 825 if (_tcscmp(g_stComputers[computers] 826 .szComputerName, g_szLocalHost) != 0) 827 { 828 _tcscpy(szTmp, g_stComputers[computers] 829 .szComputerName + 2); 830 _tcscat(szTmp, _T("@")); 831 _tcscat(szTmp, szBuf); 832 } 833 else { 834 _tcscpy(szTmp, szBuf); 835 } 836 g_stServices[stPos].szDisplayName = _tcsdup(szTmp); 837 838 } 839 ++stPos; 840 if (stPos >= MAX_APACHE_SERVICES) { 841 retCode = !ERROR_SUCCESS; 842 } 843 } 844 } 845 RegCloseKey(hSubKey); 846 } 847 } 848 } 849 ++computers; 850 RegCloseKey(hKey); 851 } 852 FindRunningServices(); 853 return TRUE; 854} 855 856 857LRESULT CALLBACK ConnectDlgProc(HWND hDlg, UINT message, 858 WPARAM wParam, LPARAM lParam) 859{ 860 TCHAR szCmp[MAX_COMPUTERNAME_LENGTH+4]; 861 switch (message) 862 { 863 case WM_INITDIALOG: 864 ShowWindow(hDlg, SW_HIDE); 865 g_hwndConnectDlg = hDlg; 866 CenterWindow(hDlg); 867 ShowWindow(hDlg, SW_SHOW); 868 SetFocus(GetDlgItem(hDlg, IDC_COMPUTER)); 869 return TRUE; 870 871 case WM_COMMAND: 872 switch (LOWORD(wParam)) 873 { 874 case IDOK: 875 memset(szCmp, 0, sizeof(szCmp)); 876 _tcscpy(szCmp, _T("\\\\")); 877 SendMessage(GetDlgItem(hDlg, IDC_COMPUTER), WM_GETTEXT, 878 (WPARAM) MAX_COMPUTERNAME_LENGTH, 879 (LPARAM) szCmp+2); 880 881 _tcsupr(szCmp); 882 if (_tcslen(szCmp) < 3) { 883 EndDialog(hDlg, TRUE); 884 return TRUE; 885 } 886 am_ConnectComputer(szCmp); 887 SendMessage(g_hwndMain, WM_TIMER, WM_TIMER_RESCAN, 0); 888 889 case IDCANCEL: 890 EndDialog(hDlg, TRUE); 891 return TRUE; 892 893 case IDC_LBROWSE: 894 { 895 BROWSEINFO bi; 896 ITEMIDLIST *il; 897 LPMALLOC pMalloc; 898 memset(&bi, 0, sizeof(BROWSEINFO)); 899 SHGetSpecialFolderLocation(hDlg, CSIDL_NETWORK, &il); 900 901 bi.lpszTitle = _T("ApacheMonitor :\nSelect Network Computer!"); 902 bi.pszDisplayName = szCmp; 903 bi.hwndOwner = hDlg; 904 bi.ulFlags = BIF_BROWSEFORCOMPUTER; 905 bi.lpfn = NULL; 906 bi.lParam = 0; 907 bi.iImage = 0; 908 bi.pidlRoot = il; 909 910 if (SHBrowseForFolder(&bi) != NULL) { 911 SendMessage(GetDlgItem(hDlg, IDC_COMPUTER), 912 WM_SETTEXT, 913 (WPARAM) NULL, (LPARAM) szCmp); 914 } 915 if (SHGetMalloc(&pMalloc)) { 916 pMalloc->lpVtbl->Free(pMalloc, il); 917 pMalloc->lpVtbl->Release(pMalloc); 918 } 919 return TRUE; 920 } 921 } 922 break; 923 924 case WM_QUIT: 925 case WM_CLOSE: 926 EndDialog(hDlg, TRUE); 927 return TRUE; 928 929 default: 930 return FALSE; 931 } 932 return FALSE; 933 934} 935 936 937LRESULT CALLBACK ServiceDlgProc(HWND hDlg, UINT message, 938 WPARAM wParam, LPARAM lParam) 939{ 940 TCHAR szBuf[MAX_PATH]; 941 HWND hListBox; 942 static HWND hStatusBar; 943 TEXTMETRIC tm; 944 int i, y; 945 HDC hdcMem; 946 RECT rcBitmap; 947 LRESULT nItem; 948 LPMEASUREITEMSTRUCT lpmis; 949 LPDRAWITEMSTRUCT lpdis; 950 951 memset(szBuf, 0, sizeof(szBuf)); 952 switch (message) 953 { 954 case WM_INITDIALOG: 955 ShowWindow(hDlg, SW_HIDE); 956 g_hwndServiceDlg = hDlg; 957 SetWindowText(hDlg, g_szTitle); 958 Button_Enable(GetDlgItem(hDlg, IDC_SSTART), FALSE); 959 Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), FALSE); 960 Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), FALSE); 961 Button_Enable(GetDlgItem(hDlg, IDC_SDISCONN), FALSE); 962 SetWindowText(GetDlgItem(hDlg, IDC_SSTART), 963 g_lpMsg[IDS_MSG_SSTART - IDS_MSG_FIRST]); 964 SetWindowText(GetDlgItem(hDlg, IDC_SSTOP), 965 g_lpMsg[IDS_MSG_SSTOP - IDS_MSG_FIRST]); 966 SetWindowText(GetDlgItem(hDlg, IDC_SRESTART), 967 g_lpMsg[IDS_MSG_SRESTART - IDS_MSG_FIRST]); 968 SetWindowText(GetDlgItem(hDlg, IDC_SMANAGER), 969 g_lpMsg[IDS_MSG_SERVICES - IDS_MSG_FIRST]); 970 SetWindowText(GetDlgItem(hDlg, IDC_SCONNECT), 971 g_lpMsg[IDS_MSG_CONNECT - IDS_MSG_FIRST]); 972 SetWindowText(GetDlgItem(hDlg, IDCANCEL), 973 g_lpMsg[IDS_MSG_OK - IDS_MSG_FIRST]); 974 hListBox = GetDlgItem(hDlg, IDL_SERVICES); 975 g_hwndStdoutList = GetDlgItem(hDlg, IDL_STDOUT); 976 hStatusBar = CreateStatusWindow(0x0800 /* SBT_TOOLTIPS */ 977 | WS_CHILD | WS_VISIBLE, 978 _T(""), hDlg, IDC_STATBAR); 979 if (GetApacheServicesStatus()) 980 { 981 i = 0; 982 while (g_stServices[i].szServiceName != NULL) 983 { 984 addListBoxItem(hListBox, g_stServices[i].szDisplayName, 985 g_stServices[i].dwPid == 0 ? g_hBmpStop 986 : g_hBmpStart); 987 ++i; 988 } 989 } 990 CenterWindow(hDlg); 991 ShowWindow(hDlg, SW_SHOW); 992 SetFocus(hListBox); 993 SendMessage(hListBox, LB_SETCURSEL, 0, 0); 994 return TRUE; 995 break; 996 997 case WM_MANAGEMESSAGE: 998 ApacheManageService(g_stServices[LOWORD(wParam)].szServiceName, 999 g_stServices[LOWORD(wParam)].szImagePath, 1000 g_stServices[LOWORD(wParam)].szComputerName, 1001 LOWORD(lParam)); 1002 1003 return TRUE; 1004 break; 1005 1006 case WM_UPDATEMESSAGE: 1007 hListBox = GetDlgItem(hDlg, IDL_SERVICES); 1008 SendMessage(hListBox, LB_RESETCONTENT, 0, 0); 1009 SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)_T("")); 1010 Button_Enable(GetDlgItem(hDlg, IDC_SSTART), FALSE); 1011 Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), FALSE); 1012 Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), FALSE); 1013 Button_Enable(GetDlgItem(hDlg, IDC_SDISCONN), FALSE); 1014 i = 0; 1015 while (g_stServices[i].szServiceName != NULL) 1016 { 1017 addListBoxItem(hListBox, g_stServices[i].szDisplayName, 1018 g_stServices[i].dwPid == 0 ? g_hBmpStop : g_hBmpStart); 1019 ++i; 1020 } 1021 SendMessage(hListBox, LB_SETCURSEL, 0, 0); 1022 /* Dirty hack to bring the window to the foreground */ 1023 SetWindowPos(hDlg, HWND_TOPMOST, 0, 0, 0, 0, 1024 SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW); 1025 SetWindowPos(hDlg, HWND_NOTOPMOST, 0, 0, 0, 0, 1026 SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW); 1027 SetFocus(hListBox); 1028 return TRUE; 1029 break; 1030 1031 case WM_MEASUREITEM: 1032 lpmis = (LPMEASUREITEMSTRUCT) lParam; 1033 lpmis->itemHeight = YBITMAP; 1034 return TRUE; 1035 1036 case WM_SETCURSOR: 1037 if (g_bConsoleRun) { 1038 SetCursor(g_hCursorHourglass); 1039 } 1040 else { 1041 SetCursor(g_hCursorArrow); 1042 } 1043 return TRUE; 1044 1045 case WM_DRAWITEM: 1046 lpdis = (LPDRAWITEMSTRUCT) lParam; 1047 if (lpdis->itemID == -1) { 1048 break; 1049 } 1050 switch (lpdis->itemAction) 1051 { 1052 case ODA_FOCUS: 1053 case ODA_SELECT: 1054 case ODA_DRAWENTIRE: 1055 g_hBmpPicture = (HBITMAP)SendMessage(lpdis->hwndItem, 1056 LB_GETITEMDATA, 1057 lpdis->itemID, (LPARAM) 0); 1058 1059 hdcMem = CreateCompatibleDC(lpdis->hDC); 1060 g_hBmpOld = SelectObject(hdcMem, g_hBmpPicture); 1061 1062 BitBlt(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, 1063 lpdis->rcItem.right - lpdis->rcItem.left, 1064 lpdis->rcItem.bottom - lpdis->rcItem.top, 1065 hdcMem, 0, 0, SRCCOPY); 1066 SendMessage(lpdis->hwndItem, LB_GETTEXT, 1067 lpdis->itemID, (LPARAM) szBuf); 1068 1069 GetTextMetrics(lpdis->hDC, &tm); 1070 y = (lpdis->rcItem.bottom + lpdis->rcItem.top - tm.tmHeight) / 2; 1071 1072 SelectObject(hdcMem, g_hBmpOld); 1073 DeleteDC(hdcMem); 1074 1075 rcBitmap.left = lpdis->rcItem.left + XBITMAP + 2; 1076 rcBitmap.top = lpdis->rcItem.top; 1077 rcBitmap.right = lpdis->rcItem.right; 1078 rcBitmap.bottom = lpdis->rcItem.top + YBITMAP; 1079 1080 if (lpdis->itemState & ODS_SELECTED) 1081 { 1082 if (g_hBmpPicture == g_hBmpStop) 1083 { 1084 Button_Enable(GetDlgItem(hDlg, IDC_SSTART), TRUE); 1085 Button_SetStyle(GetDlgItem(hDlg, IDC_SSTART), BS_DEFPUSHBUTTON, TRUE); 1086 Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), FALSE); 1087 Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), FALSE); 1088 } 1089 else if (g_hBmpPicture == g_hBmpStart) 1090 { 1091 Button_Enable(GetDlgItem(hDlg, IDC_SSTART), FALSE); 1092 Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), TRUE); 1093 Button_SetStyle(GetDlgItem(hDlg, IDC_SSTOP), BS_DEFPUSHBUTTON, TRUE); 1094 Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), TRUE); 1095 } 1096 else { 1097 Button_Enable(GetDlgItem(hDlg, IDC_SSTART), FALSE); 1098 Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), FALSE); 1099 Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), FALSE); 1100 } 1101 if (_tcscmp(g_stServices[lpdis->itemID].szComputerName, 1102 g_szLocalHost) == 0) { 1103 Button_Enable(GetDlgItem(hDlg, IDC_SDISCONN), FALSE); 1104 } 1105 else { 1106 Button_Enable(GetDlgItem(hDlg, IDC_SDISCONN), TRUE); 1107 } 1108 1109 if (g_stServices[lpdis->itemID].szDescription) { 1110 SendMessage(hStatusBar, SB_SETTEXT, 0, 1111 (LPARAM)g_stServices[lpdis->itemID].szDescription); 1112 } 1113 else { 1114 SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)_T("")); 1115 } 1116 if (lpdis->itemState & ODS_FOCUS) { 1117 SetTextColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); 1118 SetBkColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHT)); 1119 FillRect(lpdis->hDC, &rcBitmap, (HBRUSH)(COLOR_HIGHLIGHT+1)); 1120 } 1121 else { 1122 SetTextColor(lpdis->hDC, GetSysColor(COLOR_INACTIVECAPTIONTEXT)); 1123 SetBkColor(lpdis->hDC, GetSysColor(COLOR_INACTIVECAPTION)); 1124 FillRect(lpdis->hDC, &rcBitmap, (HBRUSH)(COLOR_INACTIVECAPTION+1)); 1125 } 1126 } 1127 else 1128 { 1129 SetTextColor(lpdis->hDC, GetSysColor(COLOR_MENUTEXT)); 1130 SetBkColor(lpdis->hDC, GetSysColor(COLOR_WINDOW)); 1131 FillRect(lpdis->hDC, &rcBitmap, (HBRUSH)(COLOR_WINDOW+1)); 1132 } 1133 TextOut(lpdis->hDC, XBITMAP + 6, y, szBuf, (int)_tcslen(szBuf)); 1134 break; 1135 } 1136 return TRUE; 1137 case WM_COMMAND: 1138 switch (LOWORD(wParam)) 1139 { 1140 case IDL_SERVICES: 1141 switch (HIWORD(wParam)) 1142 { 1143 case LBN_DBLCLK: 1144 /* if started then stop, if stopped then start */ 1145 hListBox = GetDlgItem(hDlg, IDL_SERVICES); 1146 nItem = SendMessage(hListBox, LB_GETCURSEL, 0, 0); 1147 if (nItem != LB_ERR) 1148 { 1149 g_hBmpPicture = (HBITMAP)SendMessage(hListBox, 1150 LB_GETITEMDATA, 1151 nItem, (LPARAM) 0); 1152 if (g_hBmpPicture == g_hBmpStop) { 1153 SendMessage(hDlg, WM_MANAGEMESSAGE, nItem, 1154 SERVICE_CONTROL_CONTINUE); 1155 } 1156 else { 1157 SendMessage(hDlg, WM_MANAGEMESSAGE, nItem, 1158 SERVICE_CONTROL_STOP); 1159 } 1160 1161 } 1162 return TRUE; 1163 } 1164 break; 1165 1166 case IDCANCEL: 1167 EndDialog(hDlg, TRUE); 1168 return TRUE; 1169 1170 case IDC_SSTART: 1171 Button_Enable(GetDlgItem(hDlg, IDC_SSTART), FALSE); 1172 hListBox = GetDlgItem(hDlg, IDL_SERVICES); 1173 nItem = SendMessage(hListBox, LB_GETCURSEL, 0, 0); 1174 if (nItem != LB_ERR) { 1175 SendMessage(hDlg, WM_MANAGEMESSAGE, nItem, 1176 SERVICE_CONTROL_CONTINUE); 1177 } 1178 Button_Enable(GetDlgItem(hDlg, IDC_SSTART), TRUE); 1179 return TRUE; 1180 1181 case IDC_SSTOP: 1182 Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), FALSE); 1183 hListBox = GetDlgItem(hDlg, IDL_SERVICES); 1184 nItem = SendMessage(hListBox, LB_GETCURSEL, 0, 0); 1185 if (nItem != LB_ERR) { 1186 SendMessage(hDlg, WM_MANAGEMESSAGE, nItem, 1187 SERVICE_CONTROL_STOP); 1188 } 1189 Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), TRUE); 1190 return TRUE; 1191 1192 case IDC_SRESTART: 1193 Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), FALSE); 1194 hListBox = GetDlgItem(hDlg, IDL_SERVICES); 1195 nItem = SendMessage(hListBox, LB_GETCURSEL, 0, 0); 1196 if (nItem != LB_ERR) { 1197 SendMessage(hDlg, WM_MANAGEMESSAGE, nItem, 1198 SERVICE_APACHE_RESTART); 1199 } 1200 Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), TRUE); 1201 return TRUE; 1202 1203 case IDC_SMANAGER: 1204 if (g_dwOSVersion >= OS_VERSION_WIN2K) { 1205 ShellExecute(hDlg, _T("open"), _T("services.msc"), _T("/s"), 1206 NULL, SW_NORMAL); 1207 } 1208 else { 1209 WinExec("Control.exe SrvMgr.cpl Services", SW_NORMAL); 1210 } 1211 return TRUE; 1212 1213 case IDC_SCONNECT: 1214 DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_DLGCONNECT), 1215 hDlg, (DLGPROC)ConnectDlgProc); 1216 return TRUE; 1217 1218 case IDC_SDISCONN: 1219 hListBox = GetDlgItem(hDlg, IDL_SERVICES); 1220 nItem = SendMessage(hListBox, LB_GETCURSEL, 0, 0); 1221 if (nItem != LB_ERR) { 1222 am_DisconnectComputer(g_stServices[nItem].szComputerName); 1223 SendMessage(g_hwndMain, WM_TIMER, WM_TIMER_RESCAN, 0); 1224 } 1225 return TRUE; 1226 } 1227 break; 1228 1229 case WM_SIZE: 1230 switch (LOWORD(wParam)) 1231 { 1232 case SIZE_MINIMIZED: 1233 EndDialog(hDlg, TRUE); 1234 return TRUE; 1235 break; 1236 } 1237 break; 1238 1239 case WM_QUIT: 1240 case WM_CLOSE: 1241 EndDialog(hDlg, TRUE); 1242 return TRUE; 1243 1244 default: 1245 return FALSE; 1246 } 1247 return FALSE; 1248} 1249 1250 1251LRESULT CALLBACK WndProc(HWND hWnd, UINT message, 1252 WPARAM wParam, LPARAM lParam) 1253{ 1254 if (message == g_bUiTaskbarCreated) 1255 { 1256 /* restore the tray icon on shell restart */ 1257 ShowNotifyIcon(hWnd, NIM_ADD); 1258 return DefWindowProc(hWnd, message, wParam, lParam); 1259 } 1260 switch (message) 1261 { 1262 case WM_CREATE: 1263 GetApacheServicesStatus(); 1264 ShowNotifyIcon(hWnd, NIM_ADD); 1265 SetTimer(hWnd, WM_TIMER_REFRESH, REFRESH_TIME, NULL); 1266 SetTimer(hWnd, WM_TIMER_RESCAN, RESCAN_TIME, NULL); 1267 break; 1268 1269 case WM_TIMER: 1270 switch (wParam) 1271 { 1272 case WM_TIMER_RESCAN: 1273 { 1274 int nPrev = 0, nNew = 0; 1275 EnterCriticalSection(&g_stcSection); 1276 if (FindRunningServices() || g_bRescanServices) 1277 { 1278 ShowNotifyIcon(hWnd, NIM_MODIFY); 1279 if (g_hwndServiceDlg) 1280 PostMessage(g_hwndServiceDlg, WM_UPDATEMESSAGE, 0, 0); 1281 } 1282 /* check if services list changed */ 1283 while (g_stServices[nPrev].szServiceName != NULL) 1284 ++nPrev; 1285 GetApacheServicesStatus(); 1286 while (g_stServices[nNew].szServiceName != NULL) 1287 ++nNew; 1288 if (nPrev != nNew) 1289 { 1290 ShowNotifyIcon(hWnd, NIM_MODIFY); 1291 if (g_hwndServiceDlg) { 1292 PostMessage(g_hwndServiceDlg, WM_UPDATEMESSAGE, 0, 0); 1293 } 1294 } 1295 LeaveCriticalSection(&g_stcSection); 1296 break; 1297 } 1298 1299 case WM_TIMER_REFRESH: 1300 { 1301 EnterCriticalSection(&g_stcSection); 1302 if (g_bRescanServices) 1303 { 1304 GetApacheServicesStatus(); 1305 ShowNotifyIcon(hWnd, NIM_MODIFY); 1306 if (g_hwndServiceDlg) { 1307 PostMessage(g_hwndServiceDlg, WM_UPDATEMESSAGE, 0, 0); 1308 } 1309 } 1310 else if (FindRunningServices()) 1311 { 1312 ShowNotifyIcon(hWnd, NIM_MODIFY); 1313 if (g_hwndServiceDlg) { 1314 PostMessage(g_hwndServiceDlg, WM_UPDATEMESSAGE, 0, 0); 1315 } 1316 } 1317 LeaveCriticalSection(&g_stcSection); 1318 break; 1319 } 1320 } 1321 break; 1322 1323 case WM_QUIT: 1324 ShowNotifyIcon(hWnd, NIM_DELETE); 1325 break; 1326 1327 case WM_TRAYMESSAGE: 1328 switch (lParam) 1329 { 1330 case WM_LBUTTONDBLCLK: 1331 if (!g_bDlgServiceOn) 1332 { 1333 g_bDlgServiceOn = TRUE; 1334 DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_DLGSERVICES), 1335 hWnd, (DLGPROC)ServiceDlgProc); 1336 g_bDlgServiceOn = FALSE; 1337 g_hwndServiceDlg = NULL; 1338 } 1339 else if (IsWindow(g_hwndServiceDlg)) 1340 { 1341 /* Dirty hack to bring the window to the foreground */ 1342 SetWindowPos(g_hwndServiceDlg, HWND_TOPMOST, 0, 0, 0, 0, 1343 SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW); 1344 SetWindowPos(g_hwndServiceDlg, HWND_NOTOPMOST, 0, 0, 0, 0, 1345 SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW); 1346 SetFocus(g_hwndServiceDlg); 1347 } 1348 break; 1349 1350 case WM_LBUTTONUP: 1351 ShowTryServicesMenu(hWnd); 1352 break; 1353 1354 case WM_RBUTTONUP: 1355 ShowTryPopupMenu(hWnd); 1356 break; 1357 } 1358 break; 1359 1360 case WM_COMMAND: 1361 if ((LOWORD(wParam) & IDM_SM_START) == IDM_SM_START) 1362 { 1363 ApacheManageService(g_stServices[LOWORD(wParam) 1364 - IDM_SM_START].szServiceName, 1365 g_stServices[LOWORD(wParam) 1366 - IDM_SM_START].szImagePath, 1367 g_stServices[LOWORD(wParam) 1368 - IDM_SM_START].szComputerName, 1369 SERVICE_CONTROL_CONTINUE); 1370 return TRUE; 1371 } 1372 else if ((LOWORD(wParam) & IDM_SM_STOP) == IDM_SM_STOP) 1373 { 1374 ApacheManageService(g_stServices[LOWORD(wParam) 1375 - IDM_SM_STOP].szServiceName, 1376 g_stServices[LOWORD(wParam) 1377 - IDM_SM_STOP].szImagePath, 1378 g_stServices[LOWORD(wParam) 1379 - IDM_SM_STOP].szComputerName, 1380 SERVICE_CONTROL_STOP); 1381 return TRUE; 1382 } 1383 else if ((LOWORD(wParam) & IDM_SM_RESTART) == IDM_SM_RESTART) 1384 { 1385 ApacheManageService(g_stServices[LOWORD(wParam) 1386 - IDM_SM_RESTART].szServiceName, 1387 g_stServices[LOWORD(wParam) 1388 - IDM_SM_RESTART].szImagePath, 1389 g_stServices[LOWORD(wParam) 1390 - IDM_SM_RESTART].szComputerName, 1391 SERVICE_APACHE_RESTART); 1392 return TRUE; 1393 } 1394 switch (LOWORD(wParam)) 1395 { 1396 case IDM_RESTORE: 1397 if (!g_bDlgServiceOn) 1398 { 1399 g_bDlgServiceOn = TRUE; 1400 DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_DLGSERVICES), 1401 hWnd, (DLGPROC)ServiceDlgProc); 1402 g_bDlgServiceOn = FALSE; 1403 g_hwndServiceDlg = NULL; 1404 } 1405 else if (IsWindow(g_hwndServiceDlg)) { 1406 SetFocus(g_hwndServiceDlg); 1407 } 1408 break; 1409 1410 case IDC_SMANAGER: 1411 if (g_dwOSVersion >= OS_VERSION_WIN2K) { 1412 ShellExecute(NULL, _T("open"), _T("services.msc"), _T("/s"), 1413 NULL, SW_NORMAL); 1414 } 1415 else { 1416 WinExec("Control.exe SrvMgr.cpl Services", SW_NORMAL); 1417 } 1418 return TRUE; 1419 1420 case IDM_EXIT: 1421 ShowNotifyIcon(hWnd, NIM_DELETE); 1422 PostQuitMessage(0); 1423 return TRUE; 1424 } 1425 1426 default: 1427 return DefWindowProc(hWnd, message, wParam, lParam); 1428 } 1429 1430 return FALSE; 1431} 1432 1433 1434static int KillAWindow(HWND appwindow) 1435{ 1436 HANDLE appproc; 1437 DWORD procid; 1438 BOOL postres; 1439 1440 SetLastError(0); 1441 GetWindowThreadProcessId(appwindow, &procid); 1442 if (GetLastError()) 1443 return(2); 1444 1445 appproc = OpenProcess(SYNCHRONIZE, 0, procid); 1446 postres = PostMessage(appwindow, WM_COMMAND, IDM_EXIT, 0); 1447 if (appproc && postres) { 1448 if (WaitForSingleObject(appproc, 10 /* seconds */ * 1000) 1449 == WAIT_OBJECT_0) { 1450 CloseHandle(appproc); 1451 return (0); 1452 } 1453 } 1454 if (appproc) 1455 CloseHandle(appproc); 1456 1457 if ((appproc = OpenProcess(PROCESS_TERMINATE, 0, procid)) != NULL) { 1458 if (TerminateProcess(appproc, 0)) { 1459 CloseHandle(appproc); 1460 return (0); 1461 } 1462 CloseHandle(appproc); 1463 } 1464 1465 /* Perhaps we were short of permissions? */ 1466 return (2); 1467} 1468 1469 1470static int KillAllMonitors(void) 1471{ 1472 HWND appwindow; 1473 int exitcode = 0; 1474 PWTS_PROCESS_INFO tsProcs; 1475 DWORD tsProcCount, i; 1476 DWORD thisProcId; 1477 1478 /* This is graceful, close our own Window, clearing the icon */ 1479 if ((appwindow = FindWindow(g_szWindowClass, g_szTitle)) != NULL) 1480 exitcode = KillAWindow(appwindow); 1481 1482 if (g_dwOSVersion < OS_VERSION_WIN2K) 1483 return exitcode; 1484 1485 thisProcId = GetCurrentProcessId(); 1486 1487 if (!WTSEnumerateProcesses(WTS_CURRENT_SERVER_HANDLE, 0, 1, 1488 &tsProcs, &tsProcCount)) 1489 return exitcode; 1490 1491 /* This is ungraceful; close other Windows, with a lingering icon. 1492 * Since on terminal server it's not possible to post the message 1493 * to exit across sessions, we have to suffer this side effect 1494 * of a taskbar 'icon' which will evaporate the next time that 1495 * the user hovers over it or when the taskbar area is updated. 1496 */ 1497 for (i = 0; i < tsProcCount; ++i) { 1498 if (_tcscmp(tsProcs[i].pProcessName, _T(AM_STRINGIFY(BIN_NAME))) == 0 1499 && tsProcs[i].ProcessId != thisProcId) 1500 WTSTerminateProcess(WTS_CURRENT_SERVER_HANDLE, 1501 tsProcs[i].ProcessId, 1); 1502 } 1503 WTSFreeMemory(tsProcs); 1504 return exitcode; 1505} 1506 1507 1508/* Create main invisible window */ 1509HWND CreateMainWindow(HINSTANCE hInstance) 1510{ 1511 HWND hWnd = NULL; 1512 WNDCLASSEX wcex; 1513 1514 wcex.cbSize = sizeof(WNDCLASSEX); 1515 1516 wcex.style = CS_HREDRAW | CS_VREDRAW; 1517 wcex.lpfnWndProc = (WNDPROC)WndProc; 1518 wcex.cbClsExtra = 0; 1519 wcex.cbWndExtra = 0; 1520 wcex.hInstance = hInstance; 1521 wcex.hIcon = (HICON)LoadImage(hInstance, MAKEINTRESOURCE(IDI_APSRVMON), 1522 IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR); 1523 wcex.hCursor = g_hCursorArrow; 1524 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); 1525 wcex.lpszMenuName = 0; 1526 wcex.lpszClassName = g_szWindowClass; 1527 wcex.hIconSm = (HICON)LoadImage(hInstance, MAKEINTRESOURCE(IDI_APSRVMON), 1528 IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); 1529 1530 if (RegisterClassEx(&wcex)) { 1531 hWnd = CreateWindow(g_szWindowClass, g_szTitle, 1532 0, 0, 0, 0, 0, 1533 NULL, NULL, hInstance, NULL); 1534 } 1535 return hWnd; 1536} 1537 1538 1539#ifndef UNICODE 1540/* Borrowed from CRT internal.h for _MBCS argc/argv parsing in this GUI app */ 1541int __cdecl _setargv(void); 1542#endif 1543 1544int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 1545 LPSTR lpCmdLine, int nCmdShow) 1546{ 1547 TCHAR szTmp[MAX_LOADSTRING]; 1548 TCHAR szCmp[MAX_COMPUTERNAME_LENGTH+4]; 1549 MSG msg; 1550 /* existing window */ 1551 HWND appwindow; 1552 DWORD dwControl; 1553 int i; 1554 DWORD d; 1555 1556 if (!GetSystemOSVersion(&g_dwOSVersion)) 1557 { 1558 ErrorMessage(NULL, TRUE); 1559 return 1; 1560 } 1561 1562 g_LangID = GetUserDefaultLangID(); 1563 if ((g_LangID & 0xFF) != LANG_ENGLISH) { 1564 g_LangID = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL); 1565 } 1566 for (i = IDS_MSG_FIRST; i <= IDS_MSG_LAST; ++i) { 1567 LoadString(hInstance, i, szTmp, MAX_LOADSTRING); 1568 g_lpMsg[i - IDS_MSG_FIRST] = _tcsdup(szTmp); 1569 } 1570 LoadString(hInstance, IDS_APMONITORTITLE, szTmp, MAX_LOADSTRING); 1571 d = MAX_COMPUTERNAME_LENGTH+1; 1572 _tcscpy(szCmp, _T("\\\\")); 1573 GetComputerName(szCmp + 2, &d); 1574 _tcsupr(szCmp); 1575 g_szLocalHost = _tcsdup(szCmp); 1576 1577 memset(g_stComputers, 0, sizeof(ST_MONITORED_COMP) * MAX_APACHE_COMPUTERS); 1578 g_stComputers[0].szComputerName = _tcsdup(szCmp); 1579 g_stComputers[0].hRegistry = HKEY_LOCAL_MACHINE; 1580 g_szTitle = _tcsdup(szTmp); 1581 LoadString(hInstance, IDS_APMONITORCLASS, szTmp, MAX_LOADSTRING); 1582 g_szWindowClass = _tcsdup(szTmp); 1583 1584 appwindow = FindWindow(g_szWindowClass, g_szTitle); 1585 1586#ifdef UNICODE 1587 __wargv = CommandLineToArgvW(GetCommandLineW(), &__argc); 1588#else 1589 _setargv(); 1590#endif 1591 1592 if ((__argc == 2) && (_tcscmp(__targv[1], _T("--kill")) == 0)) 1593 { 1594 /* Off to chase and close up every ApacheMonitor taskbar window */ 1595 return KillAllMonitors(); 1596 } 1597 else if ((__argc == 4) && (g_dwOSVersion >= OS_VERSION_WIN2K)) 1598 { 1599 dwControl = _ttoi(__targv[1]); 1600 if ((dwControl != SERVICE_CONTROL_CONTINUE) && 1601 (dwControl != SERVICE_APACHE_RESTART) && 1602 (dwControl != SERVICE_CONTROL_STOP)) 1603 { 1604 return 1; 1605 } 1606 1607 /* Chase down and close up our session's previous window */ 1608 if ((appwindow) != NULL) 1609 KillAWindow(appwindow); 1610 } 1611 else if (__argc != 1) { 1612 return 1; 1613 } 1614 else if (appwindow) 1615 { 1616 ErrorMessage(g_lpMsg[IDS_MSG_APPRUNNING - IDS_MSG_FIRST], FALSE); 1617 return 0; 1618 } 1619 1620 g_icoStop = LoadImage(hInstance, MAKEINTRESOURCE(IDI_ICOSTOP), 1621 IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); 1622 g_icoRun = LoadImage(hInstance, MAKEINTRESOURCE(IDI_ICORUN), 1623 IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); 1624 g_hCursorHourglass = LoadImage(NULL, MAKEINTRESOURCE(OCR_WAIT), 1625 IMAGE_CURSOR, LR_DEFAULTSIZE, 1626 LR_DEFAULTSIZE, LR_SHARED); 1627 g_hCursorArrow = LoadImage(NULL, MAKEINTRESOURCE(OCR_NORMAL), 1628 IMAGE_CURSOR, LR_DEFAULTSIZE, 1629 LR_DEFAULTSIZE, LR_SHARED); 1630 g_hBmpStart = LoadImage(hInstance, MAKEINTRESOURCE(IDB_BMPRUN), 1631 IMAGE_BITMAP, XBITMAP, YBITMAP, 1632 LR_DEFAULTCOLOR); 1633 g_hBmpStop = LoadImage(hInstance, MAKEINTRESOURCE(IDB_BMPSTOP), 1634 IMAGE_BITMAP, XBITMAP, YBITMAP, 1635 LR_DEFAULTCOLOR); 1636 1637 memset(g_stServices, 0, sizeof(ST_APACHE_SERVICE) * MAX_APACHE_SERVICES); 1638 CoInitialize(NULL); 1639 InitCommonControls(); 1640 g_hInstance = hInstance; 1641 g_hwndMain = CreateMainWindow(hInstance); 1642 g_bUiTaskbarCreated = RegisterWindowMessage(_T("TaskbarCreated")); 1643 InitializeCriticalSection(&g_stcSection); 1644 g_hwndServiceDlg = NULL; 1645 if (g_hwndMain != NULL) 1646 { 1647 /* To avoid recursion, pass ImagePath NULL (a noop on NT and later) */ 1648 if ((__argc == 4) && (g_dwOSVersion >= OS_VERSION_WIN2K)) 1649 ApacheManageService(__targv[2], NULL, __targv[3], dwControl); 1650 1651 while (GetMessage(&msg, NULL, 0, 0) == TRUE) 1652 { 1653 TranslateMessage(&msg); 1654 DispatchMessage(&msg); 1655 } 1656 am_ClearServicesSt(); 1657 } 1658 am_ClearComputersSt(); 1659 DeleteCriticalSection(&g_stcSection); 1660 DestroyIcon(g_icoStop); 1661 DestroyIcon(g_icoRun); 1662 DestroyCursor(g_hCursorHourglass); 1663 DestroyCursor(g_hCursorArrow); 1664 DeleteObject(g_hBmpStart); 1665 DeleteObject(g_hBmpStop); 1666 CoUninitialize(); 1667 return 0; 1668} 1669 1670