/****************************************************************************** Code derived from the following at http://www.microsoft.com/msj/0698/win320698.aspx Module name: MainApp.cpp Written by: Jeffrey Richter Purpose: Runs a set of processes with the ability to kill them all. ******************************************************************************/ //#define UNICODE //#define _UNICODE #define STRICT #include #include #include #include /****************************************************************************** This program launches the httpd.exe process and sets it up with an event to respond to when it is required to terminate. *******************************************************************************/ /////////////////////////////////////////////////////////////////////////////// // Event used to forcibly kill the spawned Process Group // Used to terminate the httpd.exe (upon receiving this event, a Ctrl-C is sent) HANDLE g_heventTerminateProcessGroup = NULL; /////////////////////////////////////////////////////////////////////////////// unsigned int _stdcall StartProcessGroup(void* pv) { // Construct the path of our spawn-helper application TCHAR szCmdLine[MAX_PATH]; GetModuleFileName(NULL, szCmdLine, MAX_PATH); *(_tcsrchr(szCmdLine, __TEXT('\\')) + 1) = 0; // truncate EXE filename _stprintf(_tcschr(szCmdLine, 0), __TEXT("StartHttpdChild.exe %d"), g_heventTerminateProcessGroup); // Our command-line arguments indicate the process that we want to run for (int x = 2; x < __argc; x++) { _tcscat(szCmdLine, __TEXT(" ")); _tcscat(szCmdLine, __targv[x]); } STARTUPINFO si = { sizeof(si) }; si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE; // Processes in the Process Group are hidden PROCESS_INFORMATION pi; // Spawn the process (make sure it inherits our event handle) BOOL f = CreateProcess(NULL, szCmdLine, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi); DWORD dw = 0; // Return value if (f) { // The process was successfully spawned, wait for it to terminate CloseHandle(pi.hThread); WaitForSingleObject(pi.hProcess, INFINITE); GetExitCodeProcess(pi.hProcess, &dw); // Its exit code is ours CloseHandle(pi.hProcess); } else { // Couldn't spawn the process group application } return(dw); } //////////////////////////////////////////////////////////////////////////////// // If using the following non-GUI method definition, need to launch // the StartHttpd.exe program with: cmd /c StartHttpd.exe // int _tmain( int argc, TCHAR *argv[] ) extern "C" int WINAPI _tWinMain(HINSTANCE hinst, HINSTANCE hinstExePrev, LPTSTR pszCmdLine, int nShowCmd) { if(__argc != 3) { MessageBox(NULL, "Usage: starthttpd.exe ", TEXT("Error"), MB_OK); return(-1); } DWORD dwThreadId; // Create an inheritable event handle to use as our IPC mechanism // to terminate the processes in the process group // NOTE: Keep this handle forthe entire lifetime of this application g_heventTerminateProcessGroup = CreateEvent(NULL, TRUE, FALSE, __argv[1]); SetHandleInformation(g_heventTerminateProcessGroup, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT); // Spawn the processes in the process group. ResetEvent(g_heventTerminateProcessGroup); // Do this before each spawn HANDLE hThread = (HANDLE) _beginthreadex(NULL, 0, StartProcessGroup, NULL, 0, (UINT*) &dwThreadId); WaitForSingleObject(hThread, INFINITE); // The spawned processes have terminated, clean up CloseHandle(hThread); // When this application is terminating, close the event CloseHandle(g_heventTerminateProcessGroup); return(0); } //////////////////////////////// End of File //////////////////////////////////