1 | /******************************************************************************
|
---|
2 | Code derived from the following at http://www.microsoft.com/msj/0698/win320698.aspx
|
---|
3 | Module name: SmallApp.cpp
|
---|
4 | Written by: Jeffrey Richter
|
---|
5 | Purpose: Spawn helper that kills everything in its Process Group.
|
---|
6 | ******************************************************************************/
|
---|
7 |
|
---|
8 | //#define UNICODE
|
---|
9 | //#define _UNICODE
|
---|
10 |
|
---|
11 | #define STRICT
|
---|
12 | #include <Windows.h>
|
---|
13 | #include <process.h>
|
---|
14 | #include <tchar.h>
|
---|
15 | #include <stdio.h>
|
---|
16 |
|
---|
17 | ///////////////////////////////////////////////////////////////////////////////
|
---|
18 |
|
---|
19 | /******************************************************************************
|
---|
20 | Sends the Ctrl-C to all processes spawned in this process' own console.
|
---|
21 | (Sends Ctrl-C to the two connected httpd.exe instances launched together)
|
---|
22 | *******************************************************************************/
|
---|
23 |
|
---|
24 | extern "C" int _tmain(int argc, TCHAR* argv[])
|
---|
25 | {
|
---|
26 |
|
---|
27 | // Make sure that we've been passed the right number of arguments
|
---|
28 | if (argc < 3) {
|
---|
29 | _tprintf(
|
---|
30 | __TEXT("Usage: %s (InheritableEventHandle) (CommandLineToSpawn)\n"),
|
---|
31 | argv[0]);
|
---|
32 | return(-1);
|
---|
33 | }
|
---|
34 |
|
---|
35 | // Construct the full command line
|
---|
36 | TCHAR szCmdLine[MAX_PATH] = { 0 };
|
---|
37 | for (int x = 2; x < argc; x++) {
|
---|
38 | _tcscat(szCmdLine, argv[x]);
|
---|
39 | _tcscat(szCmdLine, __TEXT(" "));
|
---|
40 | }
|
---|
41 |
|
---|
42 | STARTUPINFO si = { sizeof(si) };
|
---|
43 | PROCESS_INFORMATION pi = { 0 };
|
---|
44 | DWORD dwExitCode = 0;
|
---|
45 |
|
---|
46 | HANDLE h[2];
|
---|
47 | h[0] = (HANDLE) _ttoi(argv[1]); // The inherited event handle
|
---|
48 |
|
---|
49 | // Spawn the other processes as part of this Process Group
|
---|
50 | BOOL f = CreateProcess(NULL, szCmdLine, NULL, NULL, TRUE,
|
---|
51 | 0, NULL, NULL, &si, &pi);
|
---|
52 |
|
---|
53 | if (f) {
|
---|
54 | CloseHandle(pi.hThread);
|
---|
55 | h[1] = pi.hProcess;
|
---|
56 |
|
---|
57 | // Wait for the spawned-process to die or for the event
|
---|
58 | // indicating that the processes should be forcibly killed.
|
---|
59 | switch (WaitForMultipleObjects(2, h, FALSE, INFINITE)) {
|
---|
60 | case WAIT_OBJECT_0 + 0: // Force termination
|
---|
61 | GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
|
---|
62 | WaitForSingleObject(pi.hProcess, INFINITE);
|
---|
63 | break;
|
---|
64 |
|
---|
65 | case WAIT_OBJECT_0 + 1: // App terminated normally
|
---|
66 | // Make its exit code our exit code
|
---|
67 | GetExitCodeProcess(pi.hProcess, &dwExitCode);
|
---|
68 | break;
|
---|
69 | }
|
---|
70 | CloseHandle(pi.hProcess);
|
---|
71 | }
|
---|
72 | CloseHandle(h[0]); // Close the inherited event handle
|
---|
73 | return(dwExitCode);
|
---|
74 | }
|
---|
75 |
|
---|
76 | //////////////////////////////// End of File //////////////////////////////////
|
---|
77 |
|
---|
78 |
|
---|