1
////////////////////////////////////////////////////////////////////////////////
3
// Copyright (C) 2011-2014, Armory Technologies, Inc. //
4
// Distributed under the GNU Affero General Public License (AGPL v3) //
5
// See LICENSE or http://www.gnu.org/licenses/agpl.html //
7
////////////////////////////////////////////////////////////////////////////////
9
// A very simple program that simply monitors one PID, and kills another one
10
// when it disappears. This is needed for when Armory spawns a bitcoind
11
// process in the background, but crashes before it can close it. Armory
12
// will launch this "guardian" to kill bitcoind.exe if Armory.exe disappears.
20
// Forward declarations:
21
BOOL GetProcessList( );
22
BOOL ListProcessModules( DWORD dwPID );
23
BOOL ListProcessThreads( DWORD dwOwnerPID );
25
bool processIsStillRunning(HANDLE hndl)
28
GetExitCodeProcess(hndl, &exitCode);
29
return (exitCode==STILL_ACTIVE);
32
DWORD getProcessWithParent(int pid)
37
// Take a snapshot of all processes in the system.
38
hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
39
if( hProcessSnap == INVALID_HANDLE_VALUE )
44
// Set the size of the structure before using it.
45
pe32.dwSize = sizeof( PROCESSENTRY32 );
47
// Retrieve information about the first process,
48
// and exit if unsuccessful
49
if( !Process32First( hProcessSnap, &pe32 ) )
51
CloseHandle( hProcessSnap ); // clean the snapshot object
55
// Now walk the snapshot of processes, and
56
// display information about each process in turn
57
DWORD parent = static_cast<DWORD>(pid);
58
DWORD childID = 0xffffffff;
61
if(pe32.th32ParentProcessID == parent)
62
return static_cast<int>(pe32.th32ProcessID);
63
} while( Process32Next( hProcessSnap, &pe32 ) );
65
_tprintf( TEXT("Never found process with parent!") );
69
int main(int argc, char** argv )
73
_tprintf( TEXT("\nInvalid arguments:"));
74
_tprintf( TEXT("\nUSAGE: guardian.exe pidWatch pidKill"));
75
// I know I should use argv[0] instead of "guardian.exe", but I
76
// don't feel like messing with strings<->windows.h. I had a bad
80
int pidWatch = atoi(argv[1]);
81
int pidKillA = atoi(argv[2]);
82
int pidKillB = getProcessWithParent(pidKillA);
84
_tprintf( TEXT("Found two processes to kill: "), pidKillA, TEXT(" "), pidKillB);
86
HANDLE hWatch = OpenProcess(PROCESS_ALL_ACCESS, FALSE, static_cast<DWORD>(pidWatch));
87
HANDLE hKillA = OpenProcess(PROCESS_ALL_ACCESS, FALSE, static_cast<DWORD>(pidKillA));
88
HANDLE hKillB = OpenProcess(PROCESS_ALL_ACCESS, FALSE, static_cast<DWORD>(pidKillB));
90
while(processIsStillRunning(hWatch))
91
Sleep(static_cast<DWORD>(2000));
93
_tprintf( TEXT("\nThe watched process died!"));
94
TerminateProcess(hKillA, 0);
95
TerminateProcess(hKillB, 0);
96
_tprintf( TEXT("\nAttempted to kill the two processes! "), pidKillA, TEXT(" "), pidKillB);