1 |
|
---|
2 | /******************************************************************************
|
---|
3 | Code derived from the following at http://www.microsoft.com/msj/0698/win320698.aspx
|
---|
4 | Module name: MainApp.cpp
|
---|
5 | Written by: Jeffrey Richter
|
---|
6 | Purpose: Runs a set of processes with the ability to kill them all.
|
---|
7 | ******************************************************************************/
|
---|
8 |
|
---|
9 | //#define UNICODE
|
---|
10 | //#define _UNICODE
|
---|
11 |
|
---|
12 | #define STRICT
|
---|
13 | #include <Windows.h>
|
---|
14 | #include <process.h>
|
---|
15 | #include <tchar.h>
|
---|
16 | #include <stdio.h>
|
---|
17 |
|
---|
18 | /******************************************************************************
|
---|
19 | This program launches the httpd.exe process and sets it up with an event
|
---|
20 | to respond to when it is required to terminate.
|
---|
21 | *******************************************************************************/
|
---|
22 |
|
---|
23 | ///////////////////////////////////////////////////////////////////////////////
|
---|
24 |
|
---|
25 | // Event used to forcibly kill the spawned Process Group
|
---|
26 | // Used to terminate the httpd.exe (upon receiving this event, a Ctrl-C is sent)
|
---|
27 | HANDLE g_heventTerminateProcessGroup = NULL;
|
---|
28 |
|
---|
29 | ///////////////////////////////////////////////////////////////////////////////
|
---|
30 |
|
---|
31 | unsigned int _stdcall StartProcessGroup(void* pv)
|
---|
32 | {
|
---|
33 | // Construct the path of our spawn-helper application
|
---|
34 | TCHAR szCmdLine[MAX_PATH];
|
---|
35 | GetModuleFileName(NULL, szCmdLine, MAX_PATH);
|
---|
36 | *(_tcsrchr(szCmdLine, __TEXT('\\')) + 1) = 0; // truncate EXE filename
|
---|
37 | _stprintf(_tcschr(szCmdLine, 0), __TEXT("StartHttpdChild.exe %d"),
|
---|
38 | g_heventTerminateProcessGroup);
|
---|
39 |
|
---|
40 | // Our command-line arguments indicate the process that we want to run
|
---|
41 | for (int x = 2; x < __argc; x++) {
|
---|
42 | _tcscat(szCmdLine, __TEXT(" "));
|
---|
43 | _tcscat(szCmdLine, __targv[x]);
|
---|
44 | }
|
---|
45 |
|
---|
46 | STARTUPINFO si = { sizeof(si) };
|
---|
47 | si.dwFlags = STARTF_USESHOWWINDOW;
|
---|
48 | si.wShowWindow = SW_HIDE; // Processes in the Process Group are hidden
|
---|
49 |
|
---|
50 | PROCESS_INFORMATION pi;
|
---|
51 |
|
---|
52 | // Spawn the process (make sure it inherits our event handle)
|
---|
53 | BOOL f = CreateProcess(NULL, szCmdLine, NULL, NULL, TRUE,
|
---|
54 | CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
|
---|
55 |
|
---|
56 | DWORD dw = 0; // Return value
|
---|
57 |
|
---|
58 | if (f) {
|
---|
59 | // The process was successfully spawned, wait for it to terminate
|
---|
60 | CloseHandle(pi.hThread);
|
---|
61 | WaitForSingleObject(pi.hProcess, INFINITE);
|
---|
62 | GetExitCodeProcess(pi.hProcess, &dw); // Its exit code is ours
|
---|
63 | CloseHandle(pi.hProcess);
|
---|
64 | } else {
|
---|
65 | // Couldn't spawn the process group application
|
---|
66 | }
|
---|
67 | return(dw);
|
---|
68 | }
|
---|
69 |
|
---|
70 | ////////////////////////////////////////////////////////////////////////////////
|
---|
71 |
|
---|
72 | // If using the following non-GUI method definition, need to launch
|
---|
73 | // the StartHttpd.exe program with: cmd /c StartHttpd.exe
|
---|
74 | // int _tmain( int argc, TCHAR *argv[] )
|
---|
75 |
|
---|
76 |
|
---|
77 | extern "C" int WINAPI _tWinMain(HINSTANCE hinst, HINSTANCE hinstExePrev,
|
---|
78 | LPTSTR pszCmdLine, int nShowCmd)
|
---|
79 | {
|
---|
80 | if(__argc != 3) {
|
---|
81 | MessageBox(NULL, "Usage: starthttpd.exe <event-name> <httpd.exe program path>",
|
---|
82 | TEXT("Error"), MB_OK);
|
---|
83 | return(-1);
|
---|
84 | }
|
---|
85 |
|
---|
86 | DWORD dwThreadId;
|
---|
87 |
|
---|
88 | // Create an inheritable event handle to use as our IPC mechanism
|
---|
89 | // to terminate the processes in the process group
|
---|
90 | // NOTE: Keep this handle forthe entire lifetime of this application
|
---|
91 |
|
---|
92 | g_heventTerminateProcessGroup = CreateEvent(NULL, TRUE, FALSE, __argv[1]);
|
---|
93 | SetHandleInformation(g_heventTerminateProcessGroup,
|
---|
94 | HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
|
---|
95 |
|
---|
96 | // Spawn the processes in the process group.
|
---|
97 | ResetEvent(g_heventTerminateProcessGroup); // Do this before each spawn
|
---|
98 | HANDLE hThread = (HANDLE) _beginthreadex(NULL, 0, StartProcessGroup,
|
---|
99 | NULL, 0, (UINT*) &dwThreadId);
|
---|
100 |
|
---|
101 | WaitForSingleObject(hThread, INFINITE);
|
---|
102 |
|
---|
103 | // The spawned processes have terminated, clean up
|
---|
104 | CloseHandle(hThread);
|
---|
105 |
|
---|
106 | // When this application is terminating, close the event
|
---|
107 | CloseHandle(g_heventTerminateProcessGroup);
|
---|
108 |
|
---|
109 | return(0);
|
---|
110 | }
|
---|
111 |
|
---|
112 | //////////////////////////////// End of File //////////////////////////////////
|
---|
113 |
|
---|