Main Page | Modules | Namespace List | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages | Examples

ApacheMonitor.c

Go to the documentation of this file.
00001 /* Copyright 2001-2005 The Apache Software Foundation or its licensors, as
00002  * applicable.
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 /* ====================================================================
00018  * ApacheMonitor.c Simple program to manage and monitor Apache services.
00019  *
00020  * Contributed by Mladen Turk <mturk mappingsoft.com>
00021  *
00022  * 05 Aug 2001
00023  * ==================================================================== 
00024  */
00025 
00026 #define _WIN32_WINNT 0x0400
00027 #ifndef STRICT
00028 #define STRICT
00029 #endif
00030 #ifndef OEMRESOURCE
00031 #define OEMRESOURCE
00032 #endif
00033 
00034 #include <windows.h>
00035 #include <windowsx.h>
00036 #include <commctrl.h>
00037 #include <objbase.h>
00038 #include <shlobj.h>
00039 #include <stdlib.h>
00040 #include <stdio.h>
00041 #include "ApacheMonitor.h"
00042 
00043 
00044 #define OS_VERSION_WIN9X    1
00045 #define OS_VERSION_WINNT    2
00046 #define OS_VERSION_WIN2K    3
00047 /* Should be enough */
00048 #define MAX_APACHE_SERVICES 128
00049 #define MAX_APACHE_COMPUTERS 32
00050 
00051 #define WM_TRAYMESSAGE         (WM_APP+1)
00052 #define WM_UPDATEMESSAGE       (WM_USER+1)
00053 #define WM_MANAGEMESSAGE       (WM_USER+2)
00054 #define WM_TIMER_REFRESH       10
00055 #define WM_TIMER_RESCAN        11
00056 #define SERVICE_APACHE_RESTART 128
00057 #define XBITMAP                16
00058 #define YBITMAP                16
00059 #define MAX_LOADSTRING         100
00060 #define REFRESH_TIME           2000           /* service refresh time (ms) */
00061 #define RESCAN_TIME            20000          /* registry rescan time (ms) */
00062 
00063 typedef struct _st_APACHE_SERVICE
00064 {
00065     LPSTR    szServiceName;
00066     LPSTR    szDisplayName;
00067     LPSTR    szDescription;
00068     LPSTR    szImagePath;
00069     LPSTR    szComputerName;
00070     DWORD    dwPid;
00071 } ST_APACHE_SERVICE;
00072 
00073 typedef struct _st_MONITORED_COMPUTERS
00074 {
00075     LPSTR   szComputerName;
00076     HKEY    hRegistry;
00077 } ST_MONITORED_COMP;
00078 
00079 /* Global variables */
00080 HINSTANCE         g_hInstance = NULL;
00081 CHAR             *g_szTitle;          /* The title bar text */
00082 CHAR             *g_szWindowClass;    /* Window Class Name  */
00083 HICON             g_icoStop;
00084 HICON             g_icoRun;
00085 UINT              g_bUiTaskbarCreated;
00086 DWORD             g_dwOSVersion;
00087 BOOL              g_bDlgServiceOn = FALSE;
00088 BOOL              g_bConsoleRun = FALSE;
00089 ST_APACHE_SERVICE g_stServices[MAX_APACHE_SERVICES];
00090 ST_MONITORED_COMP g_stComputers[MAX_APACHE_COMPUTERS];
00091 
00092 HBITMAP           g_hBmpStart, g_hBmpStop; 
00093 HBITMAP           g_hBmpPicture, g_hBmpOld; 
00094 BOOL              g_bRescanServices;
00095 HWND              g_hwndServiceDlg;
00096 HWND              g_hwndMain;
00097 HWND              g_hwndStdoutList;
00098 HWND              g_hwndConnectDlg;
00099 HCURSOR           g_hCursorHourglass;
00100 HCURSOR           g_hCursorArrow;
00101 
00102 HANDLE            g_hpipeOutRead;
00103 HANDLE            g_hpipeOutWrite;
00104 HANDLE            g_hpipeInRead;
00105 HANDLE            g_hpipeInWrite;
00106 HANDLE            g_hpipeStdError;
00107 LANGID            g_LangID;
00108 PROCESS_INFORMATION g_lpRedirectProc;
00109 CRITICAL_SECTION  g_stcSection;
00110 LPSTR             g_szLocalHost;
00111 
00112 /* locale language support */
00113 static CHAR *g_lpMsg[IDS_MSG_LAST - IDS_MSG_FIRST + 1];
00114 
00115 
00116 void am_ClearServicesSt()
00117 {
00118     int i;
00119     for (i = 0; i < MAX_APACHE_SERVICES; i++) 
00120     {
00121         if (g_stServices[i].szServiceName) {
00122             free(g_stServices[i].szServiceName);
00123         }
00124         if (g_stServices[i].szDisplayName) {
00125             free(g_stServices[i].szDisplayName);
00126         }
00127         if (g_stServices[i].szDescription) {
00128             free(g_stServices[i].szDescription);
00129         }
00130         if (g_stServices[i].szImagePath) {
00131             free(g_stServices[i].szImagePath);
00132         }
00133         if (g_stServices[i].szComputerName) {
00134             free(g_stServices[i].szComputerName);
00135         }
00136 
00137     }
00138     memset(g_stServices, 0, sizeof(ST_APACHE_SERVICE) * MAX_APACHE_SERVICES);
00139 
00140 }
00141 
00142 
00143 void am_ClearComputersSt()
00144 {
00145     int i;
00146     for (i = 0; i < MAX_APACHE_COMPUTERS; i++) {
00147         if (g_stComputers[i].szComputerName) {
00148             free(g_stComputers[i].szComputerName);
00149             RegCloseKey(g_stComputers[i].hRegistry);
00150         }
00151     }
00152     memset(g_stComputers, 0, sizeof(ST_MONITORED_COMP) * MAX_APACHE_COMPUTERS);
00153 
00154 }
00155 
00156 
00157 BOOL am_IsComputerConnected(LPSTR szComputerName)
00158 {
00159     int i = 0;
00160     while (g_stComputers[i].szComputerName != NULL) {
00161         if (strcmp(g_stComputers[i].szComputerName, szComputerName) == 0) {
00162             return TRUE;
00163         }
00164         ++i;
00165     }
00166     return FALSE;
00167 }
00168 
00169 
00170 void am_DisconnectComputer(LPSTR szComputerName)
00171 {
00172     int i = 0, j;
00173     while (g_stComputers[i].szComputerName != NULL) {
00174         if (strcmp(g_stComputers[i].szComputerName, szComputerName) == 0) {
00175             break;
00176         }
00177         ++i;
00178     }
00179     if (g_stComputers[i].szComputerName != NULL) {
00180         free(g_stComputers[i].szComputerName);
00181         RegCloseKey(g_stComputers[i].hRegistry);
00182         for (j = i; j < MAX_APACHE_COMPUTERS - 1; j++) {
00183             g_stComputers[i].szComputerName= g_stComputers[i+1].szComputerName;
00184             g_stComputers[i].hRegistry = g_stComputers[i+1].hRegistry;
00185         }
00186         for (i = j; i < MAX_APACHE_COMPUTERS; i++) {
00187             g_stComputers[i].szComputerName = NULL;
00188             g_stComputers[i].hRegistry = NULL;
00189         }
00190     } 
00191 
00192 }
00193 
00194 
00195 void ErrorMessage(LPCSTR szError, BOOL bFatal)
00196 {
00197     LPVOID lpMsgBuf = NULL;
00198     if (szError) {
00199         MessageBox(NULL, szError, g_lpMsg[IDS_MSG_ERROR - IDS_MSG_FIRST],
00200                    MB_OK | (bFatal ? MB_ICONERROR : MB_ICONEXCLAMATION));
00201     }
00202     else {
00203         FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
00204                       FORMAT_MESSAGE_FROM_SYSTEM |
00205                       FORMAT_MESSAGE_IGNORE_INSERTS,
00206                       NULL, GetLastError(), g_LangID,
00207                       (LPSTR) &lpMsgBuf, 0, NULL);
00208         MessageBox(NULL, (LPCSTR)lpMsgBuf, 
00209                    g_lpMsg[IDS_MSG_ERROR - IDS_MSG_FIRST],
00210                    MB_OK | (bFatal ? MB_ICONERROR : MB_ICONEXCLAMATION));
00211         LocalFree(lpMsgBuf);
00212     }
00213     if (bFatal) {
00214         PostQuitMessage(0);
00215     }
00216 }
00217 
00218 
00219 BOOL am_ConnectComputer(LPSTR szComputerName)
00220 {
00221     int i = 0;
00222     HKEY hKeyRemote;
00223     char szTmp[MAX_PATH];
00224 
00225     while (g_stComputers[i].szComputerName != NULL) {
00226         if (strcmp(g_stComputers[i].szComputerName, szComputerName) == 0) {
00227             return FALSE;
00228         }
00229         ++i;
00230     }
00231     if (i > MAX_APACHE_COMPUTERS - 1) {
00232         return FALSE;
00233     }
00234     if (RegConnectRegistry(szComputerName, HKEY_LOCAL_MACHINE, &hKeyRemote) 
00235             != ERROR_SUCCESS) {
00236         sprintf(szTmp, g_lpMsg[IDS_MSG_ECONNECT - IDS_MSG_FIRST], 
00237                 szComputerName);
00238         ErrorMessage(szTmp, FALSE);
00239         return FALSE;
00240     }
00241     else {
00242         g_stComputers[i].szComputerName = strdup(szComputerName);
00243         g_stComputers[i].hRegistry = hKeyRemote;
00244         return TRUE;
00245     }
00246 } 
00247 
00248 
00249 LPSTR GetStringRes(int id)
00250 {
00251     static CHAR buffer[MAX_PATH];
00252 
00253     buffer[0] = 0;
00254     LoadString(GetModuleHandle(NULL), id, buffer, MAX_PATH);
00255     return buffer;
00256 }
00257 
00258 
00259 BOOL GetSystemOSVersion(LPDWORD dwVersion)
00260 {
00261     OSVERSIONINFO osvi;
00262     /* 
00263     Try calling GetVersionEx using the OSVERSIONINFOEX structure.
00264     If that fails, try using the OSVERSIONINFO structure.
00265     */
00266     memset(&osvi, 0, sizeof(OSVERSIONINFO));
00267     osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
00268 
00269     if (!GetVersionEx(&osvi)) {
00270         return FALSE;
00271     }
00272 
00273     switch (osvi.dwPlatformId)
00274     {
00275     case VER_PLATFORM_WIN32_NT:
00276         if (osvi.dwMajorVersion <= 4) {
00277             *dwVersion = OS_VERSION_WINNT;
00278         }
00279         else if (osvi.dwMajorVersion == 5) {
00280             *dwVersion = OS_VERSION_WIN2K;
00281         }
00282         else {
00283             return FALSE;
00284         }
00285         break;
00286 
00287     case VER_PLATFORM_WIN32_WINDOWS:
00288         *dwVersion = OS_VERSION_WIN9X;
00289         break;
00290 
00291     case VER_PLATFORM_WIN32s:
00292     default:
00293         *dwVersion = 0;
00294         return FALSE;
00295     }
00296     return TRUE; 
00297 }
00298 
00299 
00300 static VOID ShowNotifyIcon(HWND hWnd, DWORD dwMessage)
00301 {
00302     NOTIFYICONDATA nid;
00303     int i = 0, n = 0;
00304 
00305     memset(&nid, 0, sizeof(nid));
00306     nid.cbSize = sizeof(NOTIFYICONDATA);
00307     nid.hWnd = hWnd;
00308     nid.uID = 0xFF;
00309     nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
00310     nid.uCallbackMessage = WM_TRAYMESSAGE;
00311 
00312     while (g_stServices[i].szServiceName != NULL)
00313     {
00314         if (g_stServices[i].dwPid != 0) {
00315             ++n;
00316         }
00317         ++i;
00318     }
00319     if (dwMessage != NIM_DELETE)
00320     {
00321         if (n) {
00322             nid.hIcon = g_icoRun;
00323         }
00324         else {
00325             nid.hIcon = g_icoStop;
00326         }
00327     }
00328     else {
00329         nid.hIcon = NULL;
00330     }
00331     if (n == i && n > 0) {
00332         lstrcpy(nid.szTip, g_lpMsg[IDS_MSG_RUNNINGALL - IDS_MSG_FIRST]);
00333     }
00334     else if (n) {
00335         sprintf(nid.szTip, g_lpMsg[IDS_MSG_RUNNING - IDS_MSG_FIRST], n, i);
00336     }
00337     else if (i) {
00338         sprintf(nid.szTip, g_lpMsg[IDS_MSG_RUNNINGNONE - IDS_MSG_FIRST], i);
00339     }
00340     else {
00341         lstrcpy(nid.szTip, g_lpMsg[IDS_MSG_NOSERVICES - IDS_MSG_FIRST]);
00342     }
00343     Shell_NotifyIcon(dwMessage, &nid);
00344 }
00345 
00346 
00347 void appendMenuItem(HMENU hMenu, UINT uMenuId, LPSTR szName, 
00348                     BOOL fDefault, BOOL fEnabled)
00349 {
00350     MENUITEMINFO mii;
00351 
00352     memset(&mii, 0, sizeof(MENUITEMINFO));
00353     mii.cbSize = sizeof(MENUITEMINFO);
00354     mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
00355     if (lstrlen(szName))
00356     {
00357         mii.fType = MFT_STRING;
00358         mii.wID = uMenuId;
00359         if (fDefault) {
00360             mii.fState = MFS_DEFAULT;
00361         }
00362         if (!fEnabled) {
00363             mii.fState |= MFS_DISABLED;
00364         }
00365         mii.dwTypeData = szName;
00366     }
00367     else {
00368         mii.fType = MFT_SEPARATOR;
00369     }
00370     InsertMenuItem(hMenu, uMenuId, FALSE, &mii);
00371 }
00372 
00373 
00374 void appendServiceMenu(HMENU hMenu, UINT uMenuId, 
00375                        LPSTR szServiceName, BOOL fRunning)
00376 {
00377     MENUITEMINFO mii;
00378     HMENU smh;
00379 
00380     smh = CreatePopupMenu();
00381 
00382     appendMenuItem(smh, IDM_SM_START + uMenuId, 
00383                    g_lpMsg[IDS_MSG_SSTART - IDS_MSG_FIRST], FALSE, !fRunning);
00384     appendMenuItem(smh, IDM_SM_STOP + uMenuId, 
00385                    g_lpMsg[IDS_MSG_SSTOP - IDS_MSG_FIRST], FALSE, fRunning);
00386     appendMenuItem(smh, IDM_SM_RESTART + uMenuId, 
00387                    g_lpMsg[IDS_MSG_SRESTART - IDS_MSG_FIRST], FALSE, fRunning);
00388 
00389     memset(&mii, 0, sizeof(MENUITEMINFO));
00390     mii.cbSize = sizeof(MENUITEMINFO);
00391     mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE | MIIM_SUBMENU 
00392               | MIIM_CHECKMARKS;
00393     mii.fType = MFT_STRING;
00394     mii.wID = uMenuId;
00395     mii.hbmpChecked = g_hBmpStart;
00396     mii.hbmpUnchecked = g_hBmpStop;
00397     mii.dwTypeData = szServiceName;
00398     mii.hSubMenu = smh;
00399     mii.fState = fRunning ? MFS_CHECKED : MFS_UNCHECKED;
00400     InsertMenuItem(hMenu, IDM_SM_SERVICE + uMenuId, FALSE, &mii);
00401 }
00402 
00403 
00404 void ShowTryPopupMenu(HWND hWnd)
00405 {
00406     /* create popup menu */
00407     HMENU hMenu = CreatePopupMenu();
00408     POINT pt;
00409 
00410     if (hMenu)
00411     {
00412         appendMenuItem(hMenu, IDM_RESTORE, 
00413                        g_lpMsg[IDS_MSG_MNUSHOW - IDS_MSG_FIRST], 
00414                        TRUE, TRUE);
00415         if (g_dwOSVersion >= OS_VERSION_WINNT) {
00416             appendMenuItem(hMenu, IDC_SMANAGER, 
00417                            g_lpMsg[IDS_MSG_MNUSERVICES - IDS_MSG_FIRST], 
00418                            FALSE, TRUE);
00419         }
00420         appendMenuItem(hMenu, 0, "", FALSE, TRUE);
00421         appendMenuItem(hMenu, IDM_EXIT, 
00422                        g_lpMsg[IDS_MSG_MNUEXIT - IDS_MSG_FIRST],
00423                        FALSE, TRUE);
00424 
00425         if (!SetForegroundWindow(hWnd)) {
00426             SetForegroundWindow(NULL);
00427         }
00428         GetCursorPos(&pt);
00429         TrackPopupMenu(hMenu, TPM_LEFTALIGN|TPM_RIGHTBUTTON, 
00430                        pt.x, pt.y, 0, hWnd, NULL);
00431         DestroyMenu(hMenu);
00432     }
00433 }
00434 
00435 
00436 void ShowTryServicesMenu(HWND hWnd)
00437 {
00438     /* create services list popup menu and submenus */
00439     HMENU hMenu = CreatePopupMenu();
00440     POINT pt;
00441     int i = 0;
00442 
00443     if (hMenu)
00444     {
00445         while (g_stServices[i].szServiceName != NULL)
00446         {
00447             appendServiceMenu(hMenu, i, g_stServices[i].szDisplayName,
00448                               g_stServices[i].dwPid != 0);
00449             ++i;
00450         }
00451         if (i)
00452         {
00453             if (!SetForegroundWindow(hWnd)) {
00454                 SetForegroundWindow(NULL);
00455             }
00456             GetCursorPos(&pt);
00457             TrackPopupMenu(hMenu, TPM_LEFTALIGN|TPM_RIGHTBUTTON, 
00458                            pt.x, pt.y, 0, hWnd, NULL);
00459             DestroyMenu(hMenu);
00460         }
00461     }
00462 }
00463 
00464 
00465 BOOL CenterWindow(HWND hwndChild)
00466 {
00467    RECT rChild, rWorkArea;
00468    int wChild, hChild;
00469    int xNew, yNew;
00470    BOOL bResult;
00471 
00472    /* Get the Height and Width of the child window */
00473    GetWindowRect(hwndChild, &rChild);
00474    wChild = rChild.right - rChild.left;
00475    hChild = rChild.bottom - rChild.top;
00476 
00477    /* Get the limits of the 'workarea' */
00478    bResult = SystemParametersInfo(SPI_GETWORKAREA, sizeof(RECT),
00479                                   &rWorkArea, 0);
00480    if (!bResult) {
00481       rWorkArea.left = rWorkArea.top = 0;
00482       rWorkArea.right = GetSystemMetrics(SM_CXSCREEN);
00483       rWorkArea.bottom = GetSystemMetrics(SM_CYSCREEN);
00484    }
00485 
00486    /* Calculate new X and Y position*/
00487    xNew = (rWorkArea.right - wChild) / 2;
00488    yNew = (rWorkArea.bottom - hChild) / 2;
00489    return SetWindowPos(hwndChild, HWND_TOP, xNew, yNew, 0, 0, 
00490                        SWP_NOSIZE | SWP_SHOWWINDOW);
00491 }
00492 
00493 
00494 static void addListBoxItem(HWND hDlg, LPSTR lpStr, HBITMAP hBmp) 
00495 { 
00496     int nItem; 
00497  
00498     nItem = SendMessage(hDlg, LB_ADDSTRING, 0, (LPARAM)lpStr); 
00499     SendMessage(hDlg, LB_SETITEMDATA, nItem, (LPARAM)hBmp); 
00500 } 
00501 
00502 
00503 static void addListBoxString(HWND hListBox, LPSTR lpStr)
00504 {
00505     static int nItems = 0;
00506     if (!g_bDlgServiceOn) {
00507         return;
00508     }
00509     ++nItems;
00510     if (nItems > MAX_LOADSTRING) 
00511     {
00512         SendMessage(hListBox, LB_RESETCONTENT, 0, 0); 
00513         nItems = 1;
00514     }
00515     ListBox_SetCurSel(hListBox,
00516                       ListBox_AddString(hListBox, lpStr));
00517 
00518 }
00519 
00520 
00521 static DWORD WINAPI ConsoleOutputThread(LPVOID lpThreadParameter)
00522 {
00523     static BYTE lpBuffer[MAX_PATH+1];
00524     int nPtr = 0;
00525     BYTE ch;
00526     DWORD dwReaded;
00527 
00528     while (ReadFile(g_hpipeOutRead, &ch, 1, &dwReaded, NULL) == TRUE) 
00529     {
00530         if (dwReaded > 0) 
00531         {
00532             if (ch == '\n' || nPtr >= MAX_PATH) 
00533             {
00534                 lpBuffer[nPtr] = '\0';
00535                 addListBoxString(g_hwndStdoutList, lpBuffer);
00536                 nPtr = 0;
00537             } 
00538             else if (ch == '\t' && nPtr < (MAX_PATH - 4)) 
00539             {
00540                 int i;
00541                 for (i = 0; i < 4; ++i) {
00542                     lpBuffer[nPtr++] = ' ';
00543                 }
00544             }
00545             else if (ch != '\r') {
00546                 lpBuffer[nPtr++] = ch;
00547             }
00548         }
00549     }
00550     CloseHandle(g_hpipeInWrite);
00551     CloseHandle(g_hpipeOutRead);
00552     CloseHandle(g_hpipeStdError);
00553     return 0;
00554 }
00555 
00556 
00557 DWORD WINAPI ConsoleWaitingThread(LPVOID lpThreadParameter)
00558 {
00559     WaitForSingleObject(g_lpRedirectProc.hThread, INFINITE);
00560     CloseHandle(g_lpRedirectProc.hThread);
00561     MessageBeep(100);
00562     g_bConsoleRun = FALSE;
00563     SetCursor(g_hCursorArrow);
00564     return 0;
00565 }
00566 
00567 
00568 BOOL RunRedirectedConsole(LPSTR szCmdLine)
00569 {
00570     DWORD dwThreadId;
00571     HANDLE hProc;
00572     STARTUPINFO stInfo;
00573     BOOL bResult;
00574 
00575     memset(&stInfo, 0, sizeof(stInfo));
00576     stInfo.cb = sizeof(stInfo);
00577     stInfo.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
00578     stInfo.wShowWindow = SW_HIDE;
00579 
00580     hProc = GetCurrentProcess();
00581 
00582     if (!CreatePipe(&g_hpipeInRead, &g_hpipeInWrite, NULL, MAX_PATH)) {
00583         ErrorMessage(NULL, TRUE);
00584     }
00585     if (!CreatePipe(&g_hpipeOutRead, &g_hpipeOutWrite, NULL, MAX_PATH*8)) {
00586         ErrorMessage(NULL, TRUE);
00587     }
00588     DuplicateHandle(hProc, g_hpipeInRead, hProc, &g_hpipeInRead, 0, TRUE, 
00589                     DUPLICATE_CLOSE_SOURCE|DUPLICATE_SAME_ACCESS);
00590     DuplicateHandle(hProc, g_hpipeOutWrite, hProc, &g_hpipeOutWrite, 0, TRUE, 
00591                     DUPLICATE_CLOSE_SOURCE|DUPLICATE_SAME_ACCESS);
00592     DuplicateHandle(hProc, g_hpipeOutWrite, hProc, &g_hpipeStdError, 0, TRUE, 
00593                     DUPLICATE_SAME_ACCESS);
00594     if (!g_hpipeInRead && !g_hpipeOutWrite && !g_hpipeStdError) {
00595         ErrorMessage(NULL, TRUE);
00596     }
00597     stInfo.hStdInput  = g_hpipeInRead;
00598     stInfo.hStdOutput = g_hpipeOutWrite;
00599     stInfo.hStdError  = g_hpipeStdError;
00600 
00601     bResult = CreateProcess(NULL,
00602         szCmdLine,
00603         NULL,
00604         NULL,
00605         TRUE,
00606         CREATE_SUSPENDED,
00607         NULL,
00608         NULL,
00609         &stInfo,
00610         &g_lpRedirectProc);
00611 
00612 
00613     CloseHandle(g_hpipeInRead);
00614     CloseHandle(g_hpipeOutWrite);
00615     CloseHandle(g_hpipeStdError);
00616 
00617     if (!bResult)
00618     {
00619         CloseHandle(g_hpipeInWrite);
00620         CloseHandle(g_hpipeOutRead);
00621         CloseHandle(g_hpipeStdError);
00622         return FALSE;
00623     }
00624 
00625     CloseHandle(CreateThread(NULL, 0, ConsoleOutputThread, 
00626                              0, 0, &dwThreadId));
00627     ResumeThread(g_lpRedirectProc.hThread);
00628     CloseHandle(CreateThread(NULL, 0, ConsoleWaitingThread,
00629                              0, 0, &dwThreadId));
00630 
00631     return TRUE;
00632 }
00633 
00634 
00635 BOOL RunAndForgetConsole(LPSTR szCmdLine, BOOL bRedirectConsole)
00636 {
00637     STARTUPINFO stInfo;
00638     PROCESS_INFORMATION prInfo;
00639     BOOL bResult;
00640 
00641     if (bRedirectConsole) {
00642         return RunRedirectedConsole(szCmdLine);
00643     }
00644 
00645     memset(&stInfo, 0, sizeof(stInfo));
00646     stInfo.cb = sizeof(stInfo);
00647     stInfo.dwFlags = STARTF_USESHOWWINDOW;
00648     stInfo.wShowWindow = SW_HIDE;
00649 
00650     bResult = CreateProcess(NULL,
00651                             szCmdLine,
00652                             NULL,
00653                             NULL,
00654                             TRUE,
00655                             CREATE_NEW_CONSOLE,
00656                             NULL,
00657                             NULL,
00658                             &stInfo,
00659                             &prInfo);
00660 
00661     if (!bResult) {
00662         return FALSE;
00663     }
00664     if (g_dwOSVersion == OS_VERSION_WIN9X) {
00665         /* give some time to rescan the status */
00666         Sleep(2000);
00667     }
00668     CloseHandle(prInfo.hThread);
00669     CloseHandle(prInfo.hProcess);
00670     return TRUE;
00671 }
00672 
00673 
00674 BOOL ApacheManageService(LPCSTR szServiceName, LPCSTR szImagePath, 
00675                          LPSTR szComputerName, DWORD dwCommand)
00676 {
00677     CHAR szBuf[MAX_PATH];
00678     CHAR szMsg[MAX_PATH];
00679     LPSTR sPos;
00680     BOOL retValue;
00681     BOOL serviceFlag = TRUE;
00682     SC_HANDLE schService;
00683     SC_HANDLE schSCManager;
00684     SERVICE_STATUS schSStatus;
00685     int ticks;
00686 
00687     if (g_dwOSVersion == OS_VERSION_WIN9X)
00688     {
00689         sPos = strstr(szImagePath, "-k start");
00690         if (sPos)
00691         {
00692             lstrcpyn(szBuf, szImagePath, sPos - szImagePath);
00693             switch (dwCommand)
00694             {
00695             case SERVICE_CONTROL_STOP:
00696                 lstrcat(szBuf, " -k shutdown -n ");
00697                 break;
00698 
00699             case SERVICE_CONTROL_CONTINUE:
00700                 sprintf(szMsg, g_lpMsg[IDS_MSG_SRVSTART - IDS_MSG_FIRST], 
00701                         szServiceName);
00702                 addListBoxString(g_hwndStdoutList, szMsg);
00703                 lstrcat(szBuf, " -k start -n ");
00704                 serviceFlag = FALSE;
00705                 break;
00706 
00707             case SERVICE_APACHE_RESTART:
00708                 lstrcat(szBuf, " -k restart -n ");
00709                 break;
00710 
00711             default:
00712                 return FALSE;
00713             }
00714             lstrcat(szBuf, szServiceName);
00715         }
00716         else {
00717             return FALSE;
00718         }
00719         g_bConsoleRun = TRUE;
00720         SetCursor(g_hCursorHourglass);
00721         if (!RunAndForgetConsole(szBuf, serviceFlag))
00722         {
00723             ErrorMessage(NULL, FALSE);
00724             g_bConsoleRun = FALSE;
00725             SetCursor(g_hCursorArrow);
00726             return FALSE;
00727         }
00728         else if (!serviceFlag)
00729         {
00730             sprintf(szMsg, g_lpMsg[IDS_MSG_SRVSTARTED - IDS_MSG_FIRST], 
00731                     szServiceName);
00732             addListBoxString(g_hwndStdoutList, szMsg);
00733             g_bConsoleRun = FALSE;
00734             SetCursor(g_hCursorArrow);
00735             return TRUE;
00736         }
00737     }
00738     else
00739     {
00740         schSCManager = OpenSCManager(szComputerName, NULL,
00741                                      SC_MANAGER_CONNECT);
00742         if (!schSCManager) {
00743             return FALSE;
00744         }
00745 
00746         schService = OpenService(schSCManager, szServiceName, 
00747                                  SERVICE_QUERY_STATUS | SERVICE_START | 
00748                                  SERVICE_STOP | SERVICE_USER_DEFINED_CONTROL);
00749         if (schService != NULL)
00750         {
00751             retValue = FALSE;
00752             g_bConsoleRun = TRUE;
00753             SetCursor(g_hCursorHourglass);
00754             switch (dwCommand)
00755             {
00756             case SERVICE_CONTROL_STOP:
00757                 sprintf(szMsg, g_lpMsg[IDS_MSG_SRVSTOP - IDS_MSG_FIRST], 
00758                         szServiceName);
00759                 addListBoxString(g_hwndStdoutList, szMsg);
00760                 if (ControlService(schService, SERVICE_CONTROL_STOP, 
00761                                    &schSStatus)) {
00762                     Sleep(1000);
00763                     while (QueryServiceStatus(schService, &schSStatus)) 
00764                     {
00765                         if (schSStatus.dwCurrentState == SERVICE_STOP_PENDING)
00766                         {
00767                             Sleep(1000);
00768                         }
00769                         else {
00770                             break;
00771                         }
00772                     }
00773                 }
00774                 if (QueryServiceStatus(schService, &schSStatus))
00775                 {
00776                     if (schSStatus.dwCurrentState == SERVICE_STOPPED)
00777                     {
00778                         retValue = TRUE;
00779                         sprintf(szMsg, 
00780                                 g_lpMsg[IDS_MSG_SRVSTOPPED - IDS_MSG_FIRST], 
00781                                 szServiceName);
00782                         addListBoxString(g_hwndStdoutList, szMsg);
00783                     }
00784                 }
00785                 break;
00786 
00787             case SERVICE_CONTROL_CONTINUE:
00788                 sprintf(szMsg, g_lpMsg[IDS_MSG_SRVSTART - IDS_MSG_FIRST],
00789                         szServiceName);
00790                 addListBoxString(g_hwndStdoutList, szMsg);
00791 
00792                 if (StartService(schService, 0, NULL)) 
00793                 {
00794                     Sleep(1000);
00795                     while (QueryServiceStatus(schService, &schSStatus)) 
00796                     {
00797                         if (schSStatus.dwCurrentState == SERVICE_START_PENDING)
00798                         {
00799                             Sleep(1000);
00800                         }
00801                         else {
00802                             break;
00803                         }
00804                     }
00805                 }
00806                 if (QueryServiceStatus(schService, &schSStatus))
00807                 {
00808                     if (schSStatus.dwCurrentState == SERVICE_RUNNING)
00809                     {
00810                         retValue = TRUE;
00811                         sprintf(szMsg, 
00812                                 g_lpMsg[IDS_MSG_SRVSTARTED - IDS_MSG_FIRST],
00813                                 szServiceName);
00814                         addListBoxString(g_hwndStdoutList, szMsg);
00815                     }
00816                 }
00817                 break;
00818 
00819             case SERVICE_APACHE_RESTART:
00820                 sprintf(szMsg, g_lpMsg[IDS_MSG_SRVRESTART - IDS_MSG_FIRST],
00821                         szServiceName);
00822                 addListBoxString(g_hwndStdoutList, szMsg);
00823                 if (ControlService(schService, SERVICE_APACHE_RESTART,
00824                                    &schSStatus)) 
00825                 {
00826                     ticks = 60;
00827                     while (schSStatus.dwCurrentState == SERVICE_START_PENDING)
00828                     {
00829                         Sleep(1000);
00830                         if (!QueryServiceStatus(schService, &schSStatus))
00831                         {
00832                             CloseServiceHandle(schService);
00833                             CloseServiceHandle(schSCManager);
00834                             g_bConsoleRun = FALSE;
00835                             SetCursor(g_hCursorArrow);
00836                             return FALSE;
00837                         }
00838                         if (!--ticks) {
00839                             break;
00840                         }
00841                     }
00842                 }
00843                 if (schSStatus.dwCurrentState == SERVICE_RUNNING)
00844                 {
00845                     retValue = TRUE;
00846                     sprintf(szMsg, 
00847                             g_lpMsg[IDS_MSG_SRVRESTARTED - IDS_MSG_FIRST],
00848                             szServiceName);
00849                     addListBoxString(g_hwndStdoutList, szMsg);
00850                 }
00851                 break;
00852             }
00853             CloseServiceHandle(schService);
00854             CloseServiceHandle(schSCManager);
00855             if (!retValue) {
00856                 ErrorMessage(g_lpMsg[IDS_MSG_SRVFAILED - IDS_MSG_FIRST], 
00857                              FALSE);
00858             }
00859             g_bConsoleRun = FALSE;
00860             SetCursor(g_hCursorArrow);
00861             return retValue;
00862         }
00863         else {
00864             g_bRescanServices = TRUE;
00865         }
00866         CloseServiceHandle(schSCManager);
00867         return FALSE;
00868     }
00869 
00870     return FALSE;
00871 }
00872 
00873 
00874 BOOL IsServiceRunning(LPCSTR szServiceName, LPCSTR szComputerName, 
00875                       LPDWORD lpdwPid)
00876 {
00877     DWORD dwPid;
00878     HWND hWnd;
00879     SC_HANDLE schService;
00880     SC_HANDLE schSCManager;
00881     SERVICE_STATUS schSStatus;
00882 
00883     if (g_dwOSVersion == OS_VERSION_WIN9X)
00884     {
00885         hWnd = FindWindow("ApacheWin95ServiceMonitor", szServiceName);
00886         if (hWnd && GetWindowThreadProcessId(hWnd, &dwPid)) 
00887         {
00888             *lpdwPid = 1;
00889             return TRUE;
00890         }
00891         else {
00892             return FALSE;
00893         }
00894     }
00895     else
00896     {
00897         dwPid = 0;
00898         schSCManager = OpenSCManager(szComputerName, NULL,
00899                                      SC_MANAGER_CONNECT);
00900         if (!schSCManager) {
00901             return FALSE;
00902         }
00903 
00904         schService = OpenService(schSCManager, szServiceName, 
00905                                  SERVICE_QUERY_STATUS);
00906         if (schService != NULL)
00907         {
00908             if (QueryServiceStatus(schService, &schSStatus))
00909             {
00910                 dwPid = schSStatus.dwCurrentState;
00911                 if (lpdwPid) {
00912                     *lpdwPid = 1;
00913                 }
00914             }
00915             CloseServiceHandle(schService);
00916             CloseServiceHandle(schSCManager);
00917             return dwPid == SERVICE_RUNNING ? TRUE : FALSE;
00918         }
00919         else {
00920             g_bRescanServices = TRUE;
00921         }
00922         CloseServiceHandle(schSCManager);
00923         return FALSE;
00924 
00925     }
00926 
00927     return FALSE;
00928 }
00929 
00930 
00931 BOOL FindRunningServices(void)
00932 {
00933     int i = 0;
00934     DWORD dwPid;
00935     BOOL rv = FALSE;
00936     while (g_stServices[i].szServiceName != NULL)
00937     {
00938         if (!IsServiceRunning(g_stServices[i].szServiceName, 
00939                               g_stServices[i].szComputerName, &dwPid)) {
00940             dwPid = 0;
00941         }
00942         if (g_stServices[i].dwPid != dwPid) {
00943             rv = TRUE;
00944         }
00945         g_stServices[i].dwPid = dwPid;
00946         ++i;
00947     }
00948     return rv;
00949 }
00950 
00951 
00952 BOOL GetApacheServicesStatus()
00953 {
00954     CHAR szKey[MAX_PATH];
00955     CHAR achKey[MAX_PATH];
00956     CHAR szImagePath[MAX_PATH];
00957     CHAR szBuf[MAX_PATH];
00958     CHAR szTmp[MAX_PATH];
00959     HKEY hKey, hSubKey, hKeyRemote;
00960     DWORD retCode, rv, dwKeyType;
00961     DWORD dwBufLen = MAX_PATH;
00962     int i, stPos = 0;
00963     int computers = 0;
00964 
00965     g_bRescanServices = FALSE;
00966 
00967     am_ClearServicesSt();
00968     while (g_stComputers[computers].szComputerName != NULL) {
00969         hKeyRemote = g_stComputers[computers].hRegistry;
00970         retCode = RegOpenKeyEx(hKeyRemote,
00971                                "System\\CurrentControlSet\\Services\\",
00972                                0, KEY_READ, &hKey);
00973         if (retCode != ERROR_SUCCESS)
00974         {
00975             ErrorMessage(NULL, FALSE);
00976             return FALSE;
00977         }
00978         for (i = 0, retCode = ERROR_SUCCESS; retCode == ERROR_SUCCESS; i++)
00979         {
00980             retCode = RegEnumKey(hKey, i, achKey, MAX_PATH);
00981             if (retCode == ERROR_SUCCESS)
00982             {
00983                 lstrcpy(szKey, "System\\CurrentControlSet\\Services\\");
00984                 lstrcat(szKey, achKey);
00985 
00986                 if (RegOpenKeyEx(hKeyRemote, szKey, 0, 
00987                                  KEY_QUERY_VALUE, &hSubKey) == ERROR_SUCCESS)
00988                 {
00989                     dwBufLen = MAX_PATH;
00990                     rv = RegQueryValueEx(hSubKey, "ImagePath", NULL,
00991                                          &dwKeyType, szImagePath, &dwBufLen);
00992 
00993                     if (rv == ERROR_SUCCESS
00994                             && (dwKeyType == REG_SZ 
00995                              || dwKeyType == REG_EXPAND_SZ)
00996                             && dwBufLen)
00997                     {
00998                         lstrcpy(szBuf, szImagePath);
00999                         CharLower(szBuf);
01000                         /* the service name could be Apache*.exe */
01001                         if ((strstr(szBuf, "\\apache") != NULL)
01002                                 && strstr(szBuf, ".exe") 
01003                                 && (strstr(szBuf, "--ntservice") != NULL 
01004                                        || strstr(szBuf, "-k ") != NULL))
01005                         {
01006                             g_stServices[stPos].szServiceName = strdup(achKey);
01007                             g_stServices[stPos].szImagePath = 
01008                                                            strdup(szImagePath);
01009                             g_stServices[stPos].szComputerName = 
01010                                strdup(g_stComputers[computers].szComputerName);
01011                             dwBufLen = MAX_PATH;
01012                             if (RegQueryValueEx(hSubKey, "Description", NULL,
01013                                                 &dwKeyType, szBuf, &dwBufLen) 
01014                                     == ERROR_SUCCESS) {
01015                                 g_stServices[stPos].szDescription = 
01016                                                                  strdup(szBuf);
01017                             }
01018                             dwBufLen = MAX_PATH;
01019                             if (RegQueryValueEx(hSubKey, "DisplayName", NULL,
01020                                                 &dwKeyType, szBuf, &dwBufLen) 
01021                                     == ERROR_SUCCESS) 
01022                             {
01023                                 if (strcmp(g_stComputers[computers]
01024                                         .szComputerName, g_szLocalHost) != 0) 
01025                                 { 
01026                                     strcpy(szTmp, g_stComputers[computers]
01027                                                       .szComputerName + 2);
01028                                     strcat(szTmp, "@");
01029                                     strcat(szTmp, szBuf);
01030                                 }
01031                                 else {
01032                                     strcpy(szTmp, szBuf);
01033                                 }
01034                                 g_stServices[stPos].szDisplayName 
01035                                                         = strdup(szTmp);
01036 
01037                             }
01038                             ++stPos;
01039                             if (stPos >= MAX_APACHE_SERVICES) {
01040                                 retCode = !ERROR_SUCCESS;
01041                             }
01042                         }
01043                     }
01044                     RegCloseKey(hSubKey);
01045                 }
01046             }
01047         }
01048         ++computers;
01049     }
01050     RegCloseKey(hKey);
01051     FindRunningServices();
01052     return TRUE;
01053 }
01054 
01055 
01056 LRESULT CALLBACK ConnectDlgProc(HWND hDlg, UINT message, 
01057                                 WPARAM wParam, LPARAM lParam)
01058 {
01059     CHAR szCmp[MAX_COMPUTERNAME_LENGTH+4];
01060     switch (message) 
01061     { 
01062     case WM_INITDIALOG: 
01063         ShowWindow(hDlg, SW_HIDE);
01064         g_hwndConnectDlg = hDlg;
01065         CenterWindow(hDlg);
01066         ShowWindow(hDlg, SW_SHOW);
01067         SetFocus(GetDlgItem(hDlg, IDC_COMPUTER));
01068         return TRUE;
01069 
01070     case WM_COMMAND: 
01071         switch (LOWORD(wParam)) 
01072         { 
01073         case IDOK: 
01074             memset(szCmp, 0, MAX_COMPUTERNAME_LENGTH+4);
01075             strcpy(szCmp, "\\\\");
01076             SendMessage(GetDlgItem(hDlg, IDC_COMPUTER), WM_GETTEXT, 
01077                         (WPARAM) MAX_COMPUTERNAME_LENGTH, 
01078                         (LPARAM) szCmp+2); 
01079 
01080             strupr(szCmp);
01081             if (strlen(szCmp) < 3) {
01082                 EndDialog(hDlg, TRUE); 
01083                 return TRUE;
01084             }
01085             am_ConnectComputer(szCmp);
01086             SendMessage(g_hwndMain, WM_TIMER, WM_TIMER_RESCAN, 0);
01087 
01088         case IDCANCEL:
01089             EndDialog(hDlg, TRUE); 
01090             return TRUE; 
01091 
01092         case IDC_LBROWSE:
01093         {
01094             BROWSEINFO bi;
01095             ITEMIDLIST *il;
01096             LPMALLOC pMalloc;
01097             memset(&bi, 0, sizeof(BROWSEINFO));
01098             SHGetSpecialFolderLocation(hDlg, CSIDL_NETWORK, &il);
01099 
01100             bi.lpszTitle      = "ApacheMonitor :\nSelect Network Computer!";
01101             bi.pszDisplayName = szCmp;
01102             bi.hwndOwner =      hDlg;
01103             bi.ulFlags =        BIF_BROWSEFORCOMPUTER;
01104             bi.lpfn =           NULL;
01105             bi.lParam =         0;
01106             bi.iImage =         0;
01107             bi.pidlRoot =       il;
01108 
01109             if (SHBrowseForFolder(&bi) != NULL) {
01110                 SendMessage(GetDlgItem(hDlg, IDC_COMPUTER), 
01111                             WM_SETTEXT, 
01112                             (WPARAM) NULL, (LPARAM) szCmp); 
01113             }
01114             if (SHGetMalloc(&pMalloc)) {
01115                 pMalloc->lpVtbl->Free(pMalloc, il);
01116                 pMalloc->lpVtbl->Release(pMalloc);
01117             }
01118             return TRUE;
01119         }
01120         }
01121         break;
01122 
01123     case WM_QUIT:
01124     case WM_CLOSE: 
01125         EndDialog(hDlg, TRUE);
01126         return TRUE;
01127 
01128     default:
01129         return FALSE;
01130     }
01131     return FALSE;
01132 
01133 }
01134 
01135 
01136 LRESULT CALLBACK ServiceDlgProc(HWND hDlg, UINT message, 
01137                                 WPARAM wParam, LPARAM lParam)
01138 {
01139     CHAR szBuf[MAX_PATH]; 
01140     HWND hListBox;
01141     static HWND hStatusBar; 
01142     TEXTMETRIC tm; 
01143     int i, y; 
01144     HDC hdcMem; 
01145     RECT rcBitmap; 
01146     UINT nItem;
01147     LPMEASUREITEMSTRUCT lpmis; 
01148     LPDRAWITEMSTRUCT lpdis; 
01149 
01150     memset(szBuf, 0, MAX_PATH);
01151     switch (message) 
01152     {
01153     case WM_INITDIALOG: 
01154         ShowWindow(hDlg, SW_HIDE);
01155         g_hwndServiceDlg = hDlg;
01156         SetWindowText(hDlg, g_szTitle);
01157         Button_Enable(GetDlgItem(hDlg, IDC_SSTART), FALSE);
01158         Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), FALSE);
01159         Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), FALSE);
01160         Button_Enable(GetDlgItem(hDlg, IDC_SDISCONN), FALSE);
01161         SetWindowText(GetDlgItem(hDlg, IDC_SSTART), 
01162                       g_lpMsg[IDS_MSG_SSTART - IDS_MSG_FIRST]);
01163         SetWindowText(GetDlgItem(hDlg, IDC_SSTOP), 
01164                       g_lpMsg[IDS_MSG_SSTOP - IDS_MSG_FIRST]);
01165         SetWindowText(GetDlgItem(hDlg, IDC_SRESTART), 
01166                       g_lpMsg[IDS_MSG_SRESTART - IDS_MSG_FIRST]);
01167         SetWindowText(GetDlgItem(hDlg, IDC_SMANAGER), 
01168                       g_lpMsg[IDS_MSG_SERVICES - IDS_MSG_FIRST]);
01169         SetWindowText(GetDlgItem(hDlg, IDC_SCONNECT), 
01170                       g_lpMsg[IDS_MSG_CONNECT - IDS_MSG_FIRST]);
01171         SetWindowText(GetDlgItem(hDlg, IDC_SEXIT), 
01172                       g_lpMsg[IDS_MSG_MNUEXIT - IDS_MSG_FIRST]);
01173         if (g_dwOSVersion < OS_VERSION_WINNT)
01174         {
01175             ShowWindow(GetDlgItem(hDlg, IDC_SMANAGER), SW_HIDE);
01176             ShowWindow(GetDlgItem(hDlg, IDC_SCONNECT), SW_HIDE);
01177             ShowWindow(GetDlgItem(hDlg, IDC_SDISCONN), SW_HIDE);
01178         }
01179         hListBox = GetDlgItem(hDlg, IDL_SERVICES); 
01180         g_hwndStdoutList = GetDlgItem(hDlg, IDL_STDOUT);
01181         hStatusBar = CreateStatusWindow(0x0800 /* SBT_TOOLTIPS */
01182                                       | WS_CHILD | WS_VISIBLE,
01183                                         "", hDlg, IDC_STATBAR);
01184         if (GetApacheServicesStatus())
01185         {
01186             i = 0;
01187             while (g_stServices[i].szServiceName != NULL)
01188             {
01189                 addListBoxItem(hListBox, g_stServices[i].szDisplayName,
01190                                g_stServices[i].dwPid == 0 ? g_hBmpStop 
01191                                                           : g_hBmpStart);
01192                 ++i;
01193             }
01194         }
01195         CenterWindow(hDlg);
01196         ShowWindow(hDlg, SW_SHOW);
01197         SetFocus(hListBox); 
01198         SendMessage(hListBox, LB_SETCURSEL, 0, 0); 
01199         return TRUE;
01200         break;
01201 
01202     case WM_MANAGEMESSAGE:
01203         ApacheManageService(g_stServices[LOWORD(wParam)].szServiceName,
01204                     g_stServices[LOWORD(wParam)].szImagePath,
01205                     g_stServices[LOWORD(wParam)].szComputerName,
01206                     LOWORD(lParam));
01207 
01208         return TRUE;
01209         break;
01210 
01211     case WM_UPDATEMESSAGE:
01212         hListBox = GetDlgItem(hDlg, IDL_SERVICES); 
01213         SendMessage(hListBox, LB_RESETCONTENT, 0, 0); 
01214         SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)"");
01215         Button_Enable(GetDlgItem(hDlg, IDC_SSTART), FALSE);
01216         Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), FALSE);
01217         Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), FALSE);
01218         Button_Enable(GetDlgItem(hDlg, IDC_SDISCONN), FALSE);
01219         i = 0;
01220         while (g_stServices[i].szServiceName != NULL)
01221         {
01222             addListBoxItem(hListBox, g_stServices[i].szDisplayName, 
01223                 g_stServices[i].dwPid == 0 ? g_hBmpStop : g_hBmpStart);
01224             ++i;
01225         }
01226         SendMessage(hListBox, LB_SETCURSEL, 0, 0); 
01227         /* Dirty hack to bring the window to the foreground */
01228         SetWindowPos(hDlg, HWND_TOPMOST, 0, 0, 0, 0,
01229                                 SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
01230         SetWindowPos(hDlg, HWND_NOTOPMOST, 0, 0, 0, 0,
01231                                 SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
01232         SetFocus(hListBox); 
01233         return TRUE;
01234         break;
01235 
01236     case WM_MEASUREITEM: 
01237         lpmis = (LPMEASUREITEMSTRUCT) lParam; 
01238         lpmis->itemHeight = YBITMAP; 
01239         return TRUE; 
01240 
01241     case WM_SETCURSOR:
01242         if (g_bConsoleRun) {
01243             SetCursor(g_hCursorHourglass);
01244         }
01245         else {
01246             SetCursor(g_hCursorArrow);
01247         }
01248         return TRUE;
01249 
01250     case WM_DRAWITEM: 
01251         lpdis = (LPDRAWITEMSTRUCT) lParam; 
01252         if (lpdis->itemID == -1) { 
01253             break; 
01254         } 
01255         switch (lpdis->itemAction) 
01256         { 
01257         case ODA_SELECT: 
01258         case ODA_DRAWENTIRE: 
01259             g_hBmpPicture = (HBITMAP)SendMessage(lpdis->hwndItem, 
01260                                                  LB_GETITEMDATA,
01261                                                  lpdis->itemID, (LPARAM) 0);
01262 
01263             hdcMem = CreateCompatibleDC(lpdis->hDC); 
01264             g_hBmpOld = SelectObject(hdcMem, g_hBmpPicture); 
01265 
01266             BitBlt(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
01267                    lpdis->rcItem.right - lpdis->rcItem.left,
01268                    lpdis->rcItem.bottom - lpdis->rcItem.top,
01269                    hdcMem, 0, 0, SRCCOPY);
01270             SendMessage(lpdis->hwndItem, LB_GETTEXT, 
01271                         lpdis->itemID, (LPARAM) szBuf); 
01272 
01273             GetTextMetrics(lpdis->hDC, &tm);
01274             y = (lpdis->rcItem.bottom + lpdis->rcItem.top - tm.tmHeight) / 2;
01275 
01276             SelectObject(hdcMem, g_hBmpOld); 
01277             DeleteDC(hdcMem); 
01278 
01279             rcBitmap.left = lpdis->rcItem.left + XBITMAP + 2; 
01280             rcBitmap.top = lpdis->rcItem.top; 
01281             rcBitmap.right = lpdis->rcItem.right; 
01282             rcBitmap.bottom = lpdis->rcItem.top + YBITMAP; 
01283 
01284             if (lpdis->itemState & ODS_SELECTED) 
01285             { 
01286                 if (g_hBmpPicture == g_hBmpStop)
01287                 {
01288                     Button_Enable(GetDlgItem(hDlg, IDC_SSTART), TRUE);
01289                     Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), FALSE);
01290                     Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), FALSE);
01291                 }
01292                 else if (g_hBmpPicture == g_hBmpStart) 
01293                 {
01294                     Button_Enable(GetDlgItem(hDlg, IDC_SSTART), FALSE);
01295                     Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), TRUE);
01296                     Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), TRUE);
01297                 }
01298                 else {
01299                     Button_Enable(GetDlgItem(hDlg, IDC_SSTART), FALSE);
01300                     Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), FALSE);
01301                     Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), FALSE);
01302                 }
01303                 if (strcmp(g_stServices[lpdis->itemID].szComputerName, 
01304                            g_szLocalHost) == 0) {
01305                     Button_Enable(GetDlgItem(hDlg, IDC_SDISCONN), FALSE);
01306                 }
01307                 else {
01308                     Button_Enable(GetDlgItem(hDlg, IDC_SDISCONN), TRUE);
01309                 }
01310 
01311                 if (g_stServices[lpdis->itemID].szDescription) {
01312                     SendMessage(hStatusBar, SB_SETTEXT, 0, 
01313                             (LPARAM)g_stServices[lpdis->itemID].szDescription);
01314                 }
01315                 else {
01316                     SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)"");
01317                 }
01318                 SetTextColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); 
01319                 SetBkColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHT)); 
01320                 FillRect(lpdis->hDC, &rcBitmap, (HBRUSH)(COLOR_HIGHLIGHTTEXT));
01321             } 
01322             else
01323             {
01324                SetTextColor(lpdis->hDC, GetSysColor(COLOR_MENUTEXT)); 
01325                SetBkColor(lpdis->hDC, GetSysColor(COLOR_WINDOW)); 
01326                FillRect(lpdis->hDC, &rcBitmap, (HBRUSH)(COLOR_WINDOW+1)); 
01327             }
01328             TextOut(lpdis->hDC, XBITMAP + 6, y, szBuf, strlen(szBuf)); 
01329             break; 
01330 
01331         case ODA_FOCUS: 
01332             break; 
01333         } 
01334         return TRUE;
01335     case WM_COMMAND: 
01336         switch (LOWORD(wParam)) 
01337         { 
01338         case IDL_SERVICES:
01339             switch (HIWORD(wParam))
01340             {
01341             case LBN_DBLCLK:
01342                 /* if started then stop, if stopped then start */
01343                 hListBox = GetDlgItem(hDlg, IDL_SERVICES); 
01344                 nItem = SendMessage(hListBox, LB_GETCURSEL, 0, 0);
01345                 if (nItem != LB_ERR)
01346                 {
01347                     g_hBmpPicture = (HBITMAP)SendMessage(hListBox, 
01348                                                          LB_GETITEMDATA,
01349                                                          nItem, (LPARAM) 0);
01350                     if (g_hBmpPicture == g_hBmpStop) {
01351                         SendMessage(hDlg, WM_MANAGEMESSAGE, nItem, 
01352                                     SERVICE_CONTROL_CONTINUE);
01353                     }
01354                     else {
01355                         SendMessage(hDlg, WM_MANAGEMESSAGE, nItem, 
01356                                     SERVICE_CONTROL_STOP);
01357                     }
01358 
01359                 }
01360                 return TRUE;
01361             }
01362             break;
01363 
01364         case IDOK: 
01365             EndDialog(hDlg, TRUE); 
01366             return TRUE; 
01367 
01368         case IDC_SSTART: 
01369             Button_Enable(GetDlgItem(hDlg, IDC_SSTART), FALSE);
01370             hListBox = GetDlgItem(hDlg, IDL_SERVICES); 
01371             nItem = SendMessage(hListBox, LB_GETCURSEL, 0, 0); 
01372             if (nItem != LB_ERR) {
01373                 SendMessage(hDlg, WM_MANAGEMESSAGE, nItem, 
01374                             SERVICE_CONTROL_CONTINUE);
01375             }
01376             Button_Enable(GetDlgItem(hDlg, IDC_SSTART), TRUE);
01377             return TRUE;
01378 
01379         case IDC_SSTOP: 
01380             Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), FALSE);
01381             hListBox = GetDlgItem(hDlg, IDL_SERVICES); 
01382             nItem = SendMessage(hListBox, LB_GETCURSEL, 0, 0); 
01383             if (nItem != LB_ERR) {
01384                 SendMessage(hDlg, WM_MANAGEMESSAGE, nItem, 
01385                             SERVICE_CONTROL_STOP);
01386             }
01387             Button_Enable(GetDlgItem(hDlg, IDC_SSTOP), TRUE);
01388             return TRUE;
01389 
01390         case IDC_SRESTART: 
01391             Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), FALSE);
01392             hListBox = GetDlgItem(hDlg, IDL_SERVICES); 
01393             nItem = SendMessage(hListBox, LB_GETCURSEL, 0, 0); 
01394             if (nItem != LB_ERR) {
01395                 SendMessage(hDlg, WM_MANAGEMESSAGE, nItem, 
01396                             SERVICE_APACHE_RESTART);
01397             }
01398             Button_Enable(GetDlgItem(hDlg, IDC_SRESTART), TRUE);
01399             return TRUE;
01400 
01401         case IDC_SMANAGER: 
01402             if (g_dwOSVersion >= OS_VERSION_WIN2K) {
01403                 ShellExecute(hDlg, "open", "services.msc", "/s",
01404                              NULL, SW_NORMAL);
01405             }
01406             else {
01407                 WinExec("Control.exe SrvMgr.cpl Services", SW_NORMAL);
01408             }
01409             return TRUE;
01410 
01411         case IDC_SEXIT: 
01412             EndDialog(hDlg, TRUE);
01413             SendMessage(g_hwndMain, WM_COMMAND, (WPARAM)IDM_EXIT, 0);
01414             return TRUE;
01415 
01416         case IDC_SCONNECT: 
01417             DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_DLGCONNECT),
01418                       hDlg, (DLGPROC)ConnectDlgProc);
01419             return TRUE;
01420 
01421         case IDC_SDISCONN: 
01422             hListBox = GetDlgItem(hDlg, IDL_SERVICES); 
01423             nItem = SendMessage(hListBox, LB_GETCURSEL, 0, 0); 
01424             if (nItem != LB_ERR) {
01425                 am_DisconnectComputer(g_stServices[nItem].szComputerName);
01426                 SendMessage(g_hwndMain, WM_TIMER, WM_TIMER_RESCAN, 0);
01427             }
01428             return TRUE;
01429         }
01430         break;
01431 
01432     case WM_SIZE:
01433         switch (LOWORD(wParam)) 
01434         { 
01435         case SIZE_MINIMIZED:
01436             EndDialog(hDlg, TRUE); 
01437             return TRUE; 
01438             break;
01439         }
01440         break;
01441 
01442     case WM_QUIT:
01443     case WM_CLOSE: 
01444         EndDialog(hDlg, TRUE);
01445         return TRUE;
01446 
01447     default:
01448         return FALSE;
01449     }
01450     return FALSE;
01451 }
01452 
01453 
01454 LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
01455                           WPARAM wParam, LPARAM lParam)
01456 {
01457     if (message == g_bUiTaskbarCreated)
01458     {
01459         /* restore the tray icon on shell restart */
01460         ShowNotifyIcon(hWnd, NIM_ADD);
01461         return DefWindowProc(hWnd, message, wParam, lParam);
01462     }
01463     switch (message) 
01464     {
01465     case WM_CREATE:
01466         GetApacheServicesStatus();
01467         ShowNotifyIcon(hWnd, NIM_ADD);
01468         SetTimer(hWnd, WM_TIMER_REFRESH, REFRESH_TIME, NULL);
01469         SetTimer(hWnd, WM_TIMER_RESCAN,  RESCAN_TIME, NULL);
01470         break;
01471 
01472     case WM_TIMER:
01473         switch (wParam)
01474         {
01475         case WM_TIMER_RESCAN:
01476         {
01477             int nPrev = 0, nNew = 0;
01478             EnterCriticalSection(&g_stcSection);
01479             if (FindRunningServices() || g_bRescanServices)
01480             {
01481                 ShowNotifyIcon(hWnd, NIM_MODIFY);
01482                 if (g_hwndServiceDlg)
01483                     PostMessage(g_hwndServiceDlg, WM_UPDATEMESSAGE, 0, 0);
01484             }
01485             /* check if services list changed */
01486             while (g_stServices[nPrev].szServiceName != NULL)
01487                 ++nPrev;
01488             GetApacheServicesStatus();
01489             while (g_stServices[nNew].szServiceName != NULL)
01490                 ++nNew;
01491             if (nPrev != nNew)
01492             {
01493                 ShowNotifyIcon(hWnd, NIM_MODIFY);
01494                 if (g_hwndServiceDlg) {
01495                     PostMessage(g_hwndServiceDlg, WM_UPDATEMESSAGE, 0, 0);
01496                 }
01497             }
01498             LeaveCriticalSection(&g_stcSection);
01499             break;
01500         }
01501 
01502         case WM_TIMER_REFRESH:
01503         {
01504             int nPrev = 0, nNew = 0;
01505             EnterCriticalSection(&g_stcSection);
01506             if (g_bRescanServices)
01507             {
01508                 GetApacheServicesStatus();
01509                 ShowNotifyIcon(hWnd, NIM_MODIFY);
01510                 if (g_hwndServiceDlg) {
01511                     PostMessage(g_hwndServiceDlg, WM_UPDATEMESSAGE, 0, 0);
01512                 }
01513             }
01514             else if (FindRunningServices())
01515             {
01516                 ShowNotifyIcon(hWnd, NIM_MODIFY);
01517                 if (g_hwndServiceDlg) {
01518                     PostMessage(g_hwndServiceDlg, WM_UPDATEMESSAGE, 0, 0);
01519                 }
01520             }
01521             LeaveCriticalSection(&g_stcSection);
01522             break;
01523         }
01524         }
01525         break;
01526 
01527     case WM_QUIT:
01528         ShowNotifyIcon(hWnd, NIM_DELETE);
01529         break;
01530 
01531     case WM_TRAYMESSAGE:
01532         switch (lParam)
01533         {
01534         case WM_LBUTTONDBLCLK:
01535             if (!g_bDlgServiceOn)
01536             {
01537                 g_bDlgServiceOn = TRUE;
01538                 DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_DLGSERVICES),
01539                           hWnd, (DLGPROC)ServiceDlgProc);
01540                 g_bDlgServiceOn = FALSE;
01541                 g_hwndServiceDlg = NULL;
01542             }
01543             else if (IsWindow(g_hwndServiceDlg))
01544             {
01545                 /* Dirty hack to bring the window to the foreground */
01546                 SetWindowPos(g_hwndServiceDlg, HWND_TOPMOST, 0, 0, 0, 0,
01547                              SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
01548                 SetWindowPos(g_hwndServiceDlg, HWND_NOTOPMOST, 0, 0, 0, 0,
01549                              SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
01550                 SetFocus(g_hwndServiceDlg);
01551             }
01552             break;
01553 
01554         case WM_LBUTTONUP:
01555             ShowTryServicesMenu(hWnd);
01556             break;
01557 
01558         case WM_RBUTTONUP:
01559             ShowTryPopupMenu(hWnd);
01560             break;
01561         }
01562         break;
01563 
01564     case WM_COMMAND:
01565         if ((LOWORD(wParam) & IDM_SM_START) == IDM_SM_START)
01566         {
01567             ApacheManageService(g_stServices[LOWORD(wParam) 
01568                                            - IDM_SM_START].szServiceName,
01569                                 g_stServices[LOWORD(wParam) 
01570                                            - IDM_SM_START].szImagePath,
01571                                 g_stServices[LOWORD(wParam) 
01572                                            - IDM_SM_START].szComputerName,
01573                                 SERVICE_CONTROL_CONTINUE);
01574             return TRUE;
01575         }
01576         else if ((LOWORD(wParam) & IDM_SM_STOP) == IDM_SM_STOP)
01577         {
01578             ApacheManageService(g_stServices[LOWORD(wParam) 
01579                                            - IDM_SM_STOP].szServiceName,
01580                                 g_stServices[LOWORD(wParam) 
01581                                            - IDM_SM_STOP].szImagePath,
01582                                 g_stServices[LOWORD(wParam) 
01583                                            - IDM_SM_STOP].szComputerName,
01584                                 SERVICE_CONTROL_STOP);
01585             return TRUE;
01586         }
01587         else if ((LOWORD(wParam) & IDM_SM_RESTART) == IDM_SM_RESTART)
01588         {
01589             ApacheManageService(g_stServices[LOWORD(wParam) 
01590                                            - IDM_SM_RESTART].szServiceName,
01591                                 g_stServices[LOWORD(wParam) 
01592                                            - IDM_SM_RESTART].szImagePath,
01593                                 g_stServices[LOWORD(wParam) 
01594                                            - IDM_SM_RESTART].szComputerName,
01595                                 SERVICE_APACHE_RESTART);
01596             return TRUE;
01597         }
01598         switch (LOWORD(wParam))
01599         {
01600         case IDM_RESTORE:
01601             if (!g_bDlgServiceOn)
01602             {
01603                 g_bDlgServiceOn = TRUE;
01604                 DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_DLGSERVICES),
01605                           hWnd, (DLGPROC)ServiceDlgProc);
01606                 g_bDlgServiceOn = FALSE;
01607                 g_hwndServiceDlg = NULL;
01608             }
01609             else if (IsWindow(g_hwndServiceDlg)) {
01610                 SetFocus(g_hwndServiceDlg);
01611             }
01612             break;
01613 
01614         case IDC_SMANAGER: 
01615             if (g_dwOSVersion >= OS_VERSION_WIN2K) {
01616                 ShellExecute(NULL, "open",