xref: /aoo41x/main/sal/systools/win32/kill/kill.cxx (revision 87d2adbc)
1*87d2adbcSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*87d2adbcSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*87d2adbcSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*87d2adbcSAndrew Rist  * distributed with this work for additional information
6*87d2adbcSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*87d2adbcSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*87d2adbcSAndrew Rist  * "License"); you may not use this file except in compliance
9*87d2adbcSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*87d2adbcSAndrew Rist  *
11*87d2adbcSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*87d2adbcSAndrew Rist  *
13*87d2adbcSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*87d2adbcSAndrew Rist  * software distributed under the License is distributed on an
15*87d2adbcSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*87d2adbcSAndrew Rist  * KIND, either express or implied.  See the License for the
17*87d2adbcSAndrew Rist  * specific language governing permissions and limitations
18*87d2adbcSAndrew Rist  * under the License.
19*87d2adbcSAndrew Rist  *
20*87d2adbcSAndrew Rist  *************************************************************/
21*87d2adbcSAndrew Rist 
22*87d2adbcSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sal.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <tchar.h>
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #ifdef _MSC_VER
30cdf0e10cSrcweir #pragma warning(push,1) // disable warnings within system headers
31cdf0e10cSrcweir #endif
32cdf0e10cSrcweir #define WIN32_LEAN_AND_MEAN
33cdf0e10cSrcweir #include <windows.h>
34cdf0e10cSrcweir #include <tlhelp32.h>
35cdf0e10cSrcweir #include <psapi.h>
36cdf0e10cSrcweir #ifdef _MSC_VER
37cdf0e10cSrcweir #pragma warning(pop)
38cdf0e10cSrcweir #endif
39cdf0e10cSrcweir 
40cdf0e10cSrcweir #include <signal.h>
41cdf0e10cSrcweir #include <stdarg.h>
42cdf0e10cSrcweir #include <stdlib.h>
43cdf0e10cSrcweir #include <stdio.h>
44cdf0e10cSrcweir 
45cdf0e10cSrcweir #ifndef SIGNULL
46cdf0e10cSrcweir #define SIGNULL	0
47cdf0e10cSrcweir #endif
48cdf0e10cSrcweir 
49cdf0e10cSrcweir #ifndef SIGKILL
50cdf0e10cSrcweir #define SIGKILL	9
51cdf0e10cSrcweir #endif
52cdf0e10cSrcweir 
53cdf0e10cSrcweir #include <signal.h>
54cdf0e10cSrcweir 
55cdf0e10cSrcweir #define MAX_MODULES	1024
56cdf0e10cSrcweir 
57cdf0e10cSrcweir /////////////////////////////////////////////////////////////////////////////
58cdf0e10cSrcweir // Determines if a returned handle value is valid
59cdf0e10cSrcweir /////////////////////////////////////////////////////////////////////////////
60cdf0e10cSrcweir 
IsValidHandle(HANDLE handle)61cdf0e10cSrcweir static inline bool IsValidHandle( HANDLE handle )
62cdf0e10cSrcweir {
63cdf0e10cSrcweir 	return INVALID_HANDLE_VALUE != handle && NULL != handle;
64cdf0e10cSrcweir }
65cdf0e10cSrcweir 
66cdf0e10cSrcweir 
67cdf0e10cSrcweir #define elementsof( a ) (sizeof(a) / sizeof( (a)[0] ))
68cdf0e10cSrcweir 
69cdf0e10cSrcweir /////////////////////////////////////////////////////////////////////////////
70cdf0e10cSrcweir // Retrieves function adress in another process
71cdf0e10cSrcweir /////////////////////////////////////////////////////////////////////////////
72cdf0e10cSrcweir 
73cdf0e10cSrcweir #if 1
74cdf0e10cSrcweir #define GetProcAddressEx( hProcess, hModule, lpProcName ) GetProcAddress( hModule, lpProcName )
75cdf0e10cSrcweir #else
GetProcAddressEx(HANDLE hProcess,HMODULE hModule,LPCSTR lpProcName)76cdf0e10cSrcweir FARPROC WINAPI GetProcAddressEx( HANDLE hProcess, HMODULE hModule, LPCSTR lpProcName )
77cdf0e10cSrcweir {
78cdf0e10cSrcweir 	FARPROC	lpfnProcAddress = GetProcAddress( hModule, lpProcName );
79cdf0e10cSrcweir 
80cdf0e10cSrcweir 	if ( lpfnProcAddress )
81cdf0e10cSrcweir 	{
82cdf0e10cSrcweir 		DWORD	dwProcessId = GetProcessId( hProcess );
83cdf0e10cSrcweir 
84cdf0e10cSrcweir 		if ( GetCurrentProcessId() != dwProcessId )
85cdf0e10cSrcweir 		{
86cdf0e10cSrcweir 			FARPROC	lpfnRemoteProcAddress = NULL;
87cdf0e10cSrcweir 			TCHAR	szBaseName[MAX_PATH];
88cdf0e10cSrcweir 
89cdf0e10cSrcweir 			if ( GetModuleBaseName( GetCurrentProcess(), hModule, szBaseName, elementsof(szBaseName) ) )
90cdf0e10cSrcweir 			{
91cdf0e10cSrcweir 				HMODULE	ahModules[MAX_MODULES];
92cdf0e10cSrcweir 				DWORD	cbNeeded = 0;
93cdf0e10cSrcweir 
94cdf0e10cSrcweir 				if ( EnumProcessModules( hProcess, ahModules, sizeof(ahModules), &cbNeeded ) )
95cdf0e10cSrcweir 				{
96cdf0e10cSrcweir 					ULONG	nModules = cbNeeded / sizeof(ahModules[0]);
97cdf0e10cSrcweir 
98cdf0e10cSrcweir 					for ( ULONG n = 0; n < nModules; n++ )
99cdf0e10cSrcweir 					{
100cdf0e10cSrcweir 						TCHAR	szRemoteBaseName[MAX_PATH];
101cdf0e10cSrcweir 
102cdf0e10cSrcweir 						if ( GetModuleBaseName(
103cdf0e10cSrcweir                             hProcess, ahModules[n], szRemoteBaseName, elementsof(szRemoteBaseName) ) &&
104cdf0e10cSrcweir 							0 == lstrcmpi( szRemoteBaseName, szBaseName )
105cdf0e10cSrcweir 							)
106cdf0e10cSrcweir 						{
107cdf0e10cSrcweir 							lpfnRemoteProcAddress = lpfnProcAddress;
108cdf0e10cSrcweir 
109cdf0e10cSrcweir 							if ( ahModules[n] != hModule )
110cdf0e10cSrcweir 								*(LPBYTE*)&lpfnRemoteProcAddress += (LPBYTE)ahModules[n] - (LPBYTE)hModule;
111cdf0e10cSrcweir 							break;
112cdf0e10cSrcweir 						}
113cdf0e10cSrcweir 					}
114cdf0e10cSrcweir 				}
115cdf0e10cSrcweir 			}
116cdf0e10cSrcweir 
117cdf0e10cSrcweir 			lpfnProcAddress = lpfnRemoteProcAddress;
118cdf0e10cSrcweir 		}
119cdf0e10cSrcweir 	}
120cdf0e10cSrcweir 
121cdf0e10cSrcweir 	return lpfnProcAddress;
122cdf0e10cSrcweir }
123cdf0e10cSrcweir #endif
124cdf0e10cSrcweir 
125cdf0e10cSrcweir /////////////////////////////////////////////////////////////////////////////
126cdf0e10cSrcweir // Raises a signal in an other process
127cdf0e10cSrcweir /////////////////////////////////////////////////////////////////////////////
128cdf0e10cSrcweir 
SignalToExceptionCode(int signal)129cdf0e10cSrcweir static DWORD SignalToExceptionCode( int signal )
130cdf0e10cSrcweir {
131cdf0e10cSrcweir 	switch ( signal )
132cdf0e10cSrcweir 	{
133cdf0e10cSrcweir 	case SIGSEGV:
134cdf0e10cSrcweir 		return EXCEPTION_ACCESS_VIOLATION;
135cdf0e10cSrcweir 	case SIGFPE:
136cdf0e10cSrcweir 		return EXCEPTION_FLT_INVALID_OPERATION;
137cdf0e10cSrcweir 	case SIGILL:
138cdf0e10cSrcweir 		return EXCEPTION_ILLEGAL_INSTRUCTION;
139cdf0e10cSrcweir 	case SIGINT:
140cdf0e10cSrcweir 		return CONTROL_C_EXIT;
141cdf0e10cSrcweir 	case SIGBREAK:
142cdf0e10cSrcweir 		return CONTROL_C_EXIT;
143cdf0e10cSrcweir 	default:
144cdf0e10cSrcweir 		return 0;
145cdf0e10cSrcweir 	}
146cdf0e10cSrcweir }
147cdf0e10cSrcweir 
RaiseSignalEx(HANDLE hProcess,int sig)148cdf0e10cSrcweir static BOOL RaiseSignalEx( HANDLE hProcess, int sig )
149cdf0e10cSrcweir {
150cdf0e10cSrcweir 	DWORD	dwProcessId = GetProcessId( hProcess );
151cdf0e10cSrcweir 
152cdf0e10cSrcweir 	HANDLE	hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 );
153cdf0e10cSrcweir 	HANDLE	hThread = 0;
154cdf0e10cSrcweir 	BOOL fSuccess = FALSE;
155cdf0e10cSrcweir 
156cdf0e10cSrcweir 	if ( IsValidHandle(hSnapshot) )
157cdf0e10cSrcweir 	{
158cdf0e10cSrcweir 		THREADENTRY32	te;
159cdf0e10cSrcweir 
160cdf0e10cSrcweir 		te.dwSize = sizeof(te);
161cdf0e10cSrcweir 		fSuccess = Thread32First( hSnapshot, &te );
162cdf0e10cSrcweir 		while ( fSuccess )
163cdf0e10cSrcweir 		{
164cdf0e10cSrcweir 			if ( te.th32OwnerProcessID == dwProcessId )
165cdf0e10cSrcweir 			{
166cdf0e10cSrcweir 				hThread = OpenThread(
167cdf0e10cSrcweir 					THREAD_SUSPEND_RESUME | THREAD_QUERY_INFORMATION |
168cdf0e10cSrcweir 					THREAD_GET_CONTEXT | THREAD_SET_CONTEXT,
169cdf0e10cSrcweir 					FALSE, te.th32ThreadID );
170cdf0e10cSrcweir 				if ( IsValidHandle(hThread) )
171cdf0e10cSrcweir 					break;
172cdf0e10cSrcweir 			}
173cdf0e10cSrcweir 
174cdf0e10cSrcweir 			fSuccess = Thread32Next( hSnapshot, &te );
175cdf0e10cSrcweir 		}
176cdf0e10cSrcweir 
177cdf0e10cSrcweir 		CloseHandle( hSnapshot );
178cdf0e10cSrcweir 	}
179cdf0e10cSrcweir 
180cdf0e10cSrcweir 	if ( fSuccess )
181cdf0e10cSrcweir 	{
182cdf0e10cSrcweir 		CONTEXT	aContext;
183cdf0e10cSrcweir 
184cdf0e10cSrcweir 		if ( SuspendThread( hThread ) != (DWORD)-1 )
185cdf0e10cSrcweir 		{
186cdf0e10cSrcweir 			ZeroMemory( &aContext, sizeof(aContext) );
187cdf0e10cSrcweir 			aContext.ContextFlags = CONTEXT_FULL;
188cdf0e10cSrcweir 
189cdf0e10cSrcweir 			fSuccess = GetThreadContext( hThread, &aContext );
190cdf0e10cSrcweir 
191cdf0e10cSrcweir 			if ( fSuccess )
192cdf0e10cSrcweir 			{
193cdf0e10cSrcweir 				if ( sig )
194cdf0e10cSrcweir 				{
195cdf0e10cSrcweir 					DWORD	dwStackBuffer[] =
196cdf0e10cSrcweir 					{
197cdf0e10cSrcweir 						aContext.Eip,
198cdf0e10cSrcweir 						SignalToExceptionCode( sig ),
199cdf0e10cSrcweir 						EXCEPTION_NONCONTINUABLE,
200cdf0e10cSrcweir 						0,
201cdf0e10cSrcweir 						0
202cdf0e10cSrcweir 					};
203cdf0e10cSrcweir 
204cdf0e10cSrcweir 					aContext.Esp -= sizeof(dwStackBuffer);
205cdf0e10cSrcweir 					WriteProcessMemory( hProcess, (LPVOID)aContext.Esp, dwStackBuffer, sizeof(dwStackBuffer), NULL );
206cdf0e10cSrcweir 					aContext.Eip = (DWORD)GetProcAddressEx( hProcess, GetModuleHandleA("KERNEL32"), "RaiseException" );
207cdf0e10cSrcweir 				}
208cdf0e10cSrcweir 				else
209cdf0e10cSrcweir 				{
210cdf0e10cSrcweir 					aContext.Ecx = aContext.Eax = aContext.Ebx = aContext.Edx = aContext.Esi = aContext.Edi = 0;
211cdf0e10cSrcweir 				}
212cdf0e10cSrcweir 
213cdf0e10cSrcweir 				fSuccess = SetThreadContext( hThread, &aContext );
214cdf0e10cSrcweir 			}
215cdf0e10cSrcweir 
216cdf0e10cSrcweir 			fSuccess = ResumeThread( hThread ) && fSuccess;
217cdf0e10cSrcweir 
218cdf0e10cSrcweir 			DWORD	dwLastError = GetLastError();
219cdf0e10cSrcweir 			CloseHandle( hThread );
220cdf0e10cSrcweir 			SetLastError( dwLastError );
221cdf0e10cSrcweir 
222cdf0e10cSrcweir 			return fSuccess;
223cdf0e10cSrcweir 		}
224cdf0e10cSrcweir 	}
225cdf0e10cSrcweir 
226cdf0e10cSrcweir 	return FALSE;
227cdf0e10cSrcweir }
228cdf0e10cSrcweir /////////////////////////////////////////////////////////////////////////////
229cdf0e10cSrcweir // Command line parameter parsing
230cdf0e10cSrcweir /////////////////////////////////////////////////////////////////////////////
231cdf0e10cSrcweir 
ParseCommandArgs(LPDWORD lpProcesses,LPDWORD lpdwNumProcesses,int * pSig)232cdf0e10cSrcweir static void ParseCommandArgs( LPDWORD lpProcesses, LPDWORD lpdwNumProcesses, int *pSig )
233cdf0e10cSrcweir {
234cdf0e10cSrcweir 	typedef struct _SignalEntry
235cdf0e10cSrcweir 	{
236cdf0e10cSrcweir 		LPCTSTR lpSignalName;
237cdf0e10cSrcweir 		int iSignalValue;
238cdf0e10cSrcweir 	} SignalEntry;
239cdf0e10cSrcweir 
240cdf0e10cSrcweir 	#define SIG_ENTRY( signal ) { TEXT(#signal), SIG##signal }
241cdf0e10cSrcweir 
242cdf0e10cSrcweir 	static SignalEntry SupportedSignals[] =
243cdf0e10cSrcweir 	{
244cdf0e10cSrcweir 		SIG_ENTRY( NULL ),
245cdf0e10cSrcweir 		SIG_ENTRY( SEGV ),
246cdf0e10cSrcweir 		SIG_ENTRY( ILL ),
247cdf0e10cSrcweir 		SIG_ENTRY( FPE ),
248cdf0e10cSrcweir 		SIG_ENTRY( INT ),
249cdf0e10cSrcweir 		SIG_ENTRY( BREAK ),
250cdf0e10cSrcweir 		SIG_ENTRY( TERM ),
251cdf0e10cSrcweir 		SIG_ENTRY( ABRT ),
252cdf0e10cSrcweir 		SIG_ENTRY( KILL )
253cdf0e10cSrcweir 	};
254cdf0e10cSrcweir 
255cdf0e10cSrcweir 	const int NumSupportedSignals = elementsof(SupportedSignals);
256cdf0e10cSrcweir 
257cdf0e10cSrcweir 	DWORD	dwMaxProcesses = *lpdwNumProcesses;
258cdf0e10cSrcweir 	int		argc = __argc;
259cdf0e10cSrcweir 	TCHAR	**argv = __targv;
260cdf0e10cSrcweir 
261cdf0e10cSrcweir 	*lpdwNumProcesses = 0;
262cdf0e10cSrcweir 
263cdf0e10cSrcweir 	for ( int argn = 1; argn < argc; argn++ )
264cdf0e10cSrcweir 	{
265cdf0e10cSrcweir 		if ( 0 == lstrcmpi( argv[argn], TEXT("-l") ) ||
266cdf0e10cSrcweir 			 0 == lstrcmpi( argv[argn], TEXT("/l") ) )
267cdf0e10cSrcweir 
268cdf0e10cSrcweir 		{
269cdf0e10cSrcweir 			for ( int n = 0; n < NumSupportedSignals; n++ )
270cdf0e10cSrcweir 			{
271cdf0e10cSrcweir 				_tprintf( _T("%s "), SupportedSignals[n].lpSignalName );
272cdf0e10cSrcweir 			}
273cdf0e10cSrcweir 			_tprintf( _T("\n") );
274cdf0e10cSrcweir 			ExitProcess( 0 );
275cdf0e10cSrcweir 		}
276cdf0e10cSrcweir 		else if ( 0 == lstrcmpi( argv[argn], TEXT("-?") ) ||
277cdf0e10cSrcweir 			      0 == lstrcmpi( argv[argn], TEXT("/?") ) ||
278cdf0e10cSrcweir 			      0 == lstrcmpi( argv[argn], TEXT("-h") ) ||
279cdf0e10cSrcweir 			      0 == lstrcmpi( argv[argn], TEXT("/h") ) ||
280cdf0e10cSrcweir 			      0 == lstrcmpi( argv[argn], TEXT("--help") ) )
281cdf0e10cSrcweir 		{
282cdf0e10cSrcweir 			_tprintf(
283cdf0e10cSrcweir 				_T("Terminates a process by sending a signal.\n\n")
284cdf0e10cSrcweir 				_T("Usage: kill [ -l ] [ -signal ] pid ...\n\n")
285cdf0e10cSrcweir 				_T("-l        Lists supported signals\n")
286cdf0e10cSrcweir 				_T("-signal   Sends the specified signal to the given processes.\n")
287cdf0e10cSrcweir 				_T("          signal can be a numeric value specifying the signal number\n")
288cdf0e10cSrcweir 				_T("          or a string listed by the -l parameter. If no signal is\n")
289cdf0e10cSrcweir 				_T("          given SIGTERM (-TERM) is used.\n")
290cdf0e10cSrcweir 				_T("pid       Process id(s) or executables names(s) of processes to \n")
291cdf0e10cSrcweir 				_T("          signal or terminate.\n\n")
292cdf0e10cSrcweir 				);
293cdf0e10cSrcweir 			ExitProcess( 0 );
294cdf0e10cSrcweir 		}
295cdf0e10cSrcweir 		else if ( argv[argn] && ( *argv[argn] == '-' || *argv[argn] == '/' ) )
296cdf0e10cSrcweir 		{
297cdf0e10cSrcweir 			LPCTSTR	argsig = CharNext( argv[argn] );
298cdf0e10cSrcweir 
299cdf0e10cSrcweir 			int	n;
300cdf0e10cSrcweir 			for ( n = 0; n < NumSupportedSignals; n++ )
301cdf0e10cSrcweir 			{
302cdf0e10cSrcweir 				_TCHAR *endptr = NULL;
303cdf0e10cSrcweir 
304cdf0e10cSrcweir 				if ( 0 == lstrcmpi( SupportedSignals[n].lpSignalName, argsig ) ||
305cdf0e10cSrcweir 					 _tcstoul( argsig, &endptr, 0 ) == static_cast< unsigned >(SupportedSignals[n].iSignalValue) && (!endptr || !*endptr) )
306cdf0e10cSrcweir 				{
307cdf0e10cSrcweir 					*pSig = SupportedSignals[n].iSignalValue;
308cdf0e10cSrcweir 					break;
309cdf0e10cSrcweir 				}
310cdf0e10cSrcweir 			}
311cdf0e10cSrcweir 
312cdf0e10cSrcweir 			if ( n >= NumSupportedSignals )
313cdf0e10cSrcweir 			{
314cdf0e10cSrcweir 				_ftprintf( stderr,
315cdf0e10cSrcweir 					_T("kill: Illegal argument %s\n")
316cdf0e10cSrcweir 					_T("Type 'kill --help' to show allowed syntax.\n")
317cdf0e10cSrcweir 					_T("Type 'kill -l' to show supported signals.\n"),
318cdf0e10cSrcweir 					argv[argn] );
319cdf0e10cSrcweir 				ExitProcess( 0 );
320cdf0e10cSrcweir 			}
321cdf0e10cSrcweir 		}
322cdf0e10cSrcweir 		else
323cdf0e10cSrcweir 		{
324cdf0e10cSrcweir 			unsigned long value = 0;
325cdf0e10cSrcweir 			_TCHAR	*endptr = NULL;
326cdf0e10cSrcweir 
327cdf0e10cSrcweir 			value = _tcstoul( argv[argn], &endptr, 0 );
328cdf0e10cSrcweir 
329cdf0e10cSrcweir 			if ( !endptr || !*endptr )
330cdf0e10cSrcweir 			{
331cdf0e10cSrcweir 				if ( *lpdwNumProcesses < dwMaxProcesses )
332cdf0e10cSrcweir 				{
333cdf0e10cSrcweir 					*(lpProcesses++) = value;
334cdf0e10cSrcweir 					(*lpdwNumProcesses)++;
335cdf0e10cSrcweir 				}
336cdf0e10cSrcweir 			}
337cdf0e10cSrcweir 			else
338cdf0e10cSrcweir 			{
339cdf0e10cSrcweir 				HANDLE	hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
340cdf0e10cSrcweir 
341cdf0e10cSrcweir 				if ( IsValidHandle( hSnapshot ) )
342cdf0e10cSrcweir 				{
343cdf0e10cSrcweir 					PROCESSENTRY32	pe;
344cdf0e10cSrcweir 
345cdf0e10cSrcweir 					pe.dwSize = sizeof(pe);
346cdf0e10cSrcweir 					BOOL fSuccess = Process32First( hSnapshot, &pe );
347cdf0e10cSrcweir 
348cdf0e10cSrcweir 					while ( fSuccess )
349cdf0e10cSrcweir 					{
350cdf0e10cSrcweir 						if ( 0 == lstrcmpi( argv[argn], pe.szExeFile ) )
351cdf0e10cSrcweir 						{
352cdf0e10cSrcweir 							if ( *lpdwNumProcesses < dwMaxProcesses )
353cdf0e10cSrcweir 							{
354cdf0e10cSrcweir 								*(lpProcesses++) = pe.th32ProcessID;
355cdf0e10cSrcweir 								(*lpdwNumProcesses)++;
356cdf0e10cSrcweir 							}
357cdf0e10cSrcweir 						}
358cdf0e10cSrcweir 						fSuccess = Process32Next( hSnapshot, &pe );
359cdf0e10cSrcweir 					}
360cdf0e10cSrcweir 
361cdf0e10cSrcweir 					CloseHandle( hSnapshot );
362cdf0e10cSrcweir 				}
363cdf0e10cSrcweir 			}
364cdf0e10cSrcweir 		}
365cdf0e10cSrcweir 	}
366cdf0e10cSrcweir 
367cdf0e10cSrcweir 	if ( !*lpdwNumProcesses )
368cdf0e10cSrcweir 	{
369cdf0e10cSrcweir 		_ftprintf( stderr,
370cdf0e10cSrcweir 			_T("kill: No process specified.\n")
371cdf0e10cSrcweir 			_T("Use kill --help to show allowed syntax.\n")
372cdf0e10cSrcweir 			);
373cdf0e10cSrcweir 		ExitProcess( 0 );
374cdf0e10cSrcweir 	}
375cdf0e10cSrcweir 
376cdf0e10cSrcweir }
377cdf0e10cSrcweir 
OutputSystemMessage(DWORD dwErrorCode)378cdf0e10cSrcweir void OutputSystemMessage( DWORD dwErrorCode )
379cdf0e10cSrcweir {
380cdf0e10cSrcweir 	LPVOID lpMsgBuf;
381cdf0e10cSrcweir 	FormatMessageA(
382cdf0e10cSrcweir 					FORMAT_MESSAGE_ALLOCATE_BUFFER |
383cdf0e10cSrcweir 					FORMAT_MESSAGE_FROM_SYSTEM |
384cdf0e10cSrcweir 					FORMAT_MESSAGE_IGNORE_INSERTS,
385cdf0e10cSrcweir 					NULL,
386cdf0e10cSrcweir 					dwErrorCode,
387cdf0e10cSrcweir 					MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
388cdf0e10cSrcweir 					(LPSTR)&lpMsgBuf,
389cdf0e10cSrcweir 					0,
390cdf0e10cSrcweir 					NULL
391cdf0e10cSrcweir 				);
392cdf0e10cSrcweir 
393cdf0e10cSrcweir 	printf( (LPSTR)lpMsgBuf );
394cdf0e10cSrcweir 	LocalFree( lpMsgBuf );
395cdf0e10cSrcweir }
396cdf0e10cSrcweir 
_tmain()397cdf0e10cSrcweir int _tmain()
398cdf0e10cSrcweir {
399cdf0e10cSrcweir 	DWORD	dwProcessIds[1024];
400cdf0e10cSrcweir 	DWORD	nProcesses = elementsof(dwProcessIds);
401cdf0e10cSrcweir 	int		sig = SIGTERM;
402cdf0e10cSrcweir 
403cdf0e10cSrcweir 
404cdf0e10cSrcweir 	ParseCommandArgs( dwProcessIds, &nProcesses, &sig );
405cdf0e10cSrcweir 
406cdf0e10cSrcweir 	for ( ULONG n = 0; n < nProcesses; n++ )
407cdf0e10cSrcweir 	{
408cdf0e10cSrcweir 		HANDLE	hProcess;
409cdf0e10cSrcweir 
410cdf0e10cSrcweir 		_tprintf( _T("Sending signal to process id %d..."), dwProcessIds[n] );
411cdf0e10cSrcweir 		hProcess = OpenProcess( PROCESS_TERMINATE | PROCESS_CREATE_THREAD | SYNCHRONIZE |
412cdf0e10cSrcweir 			PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,
413cdf0e10cSrcweir 			FALSE, dwProcessIds[n] );
414cdf0e10cSrcweir 
415cdf0e10cSrcweir 		if ( IsValidHandle( hProcess ) )
416cdf0e10cSrcweir 		{
417cdf0e10cSrcweir 			if ( SIGKILL == sig )
418cdf0e10cSrcweir 				TerminateProcess( hProcess, 255 );
419cdf0e10cSrcweir 			else
420cdf0e10cSrcweir 			{
421cdf0e10cSrcweir 				if ( RaiseSignalEx( hProcess, sig ) )
422cdf0e10cSrcweir 					_tprintf( _T("OK\n") );
423cdf0e10cSrcweir 				else
424cdf0e10cSrcweir 				{
425cdf0e10cSrcweir 					OutputSystemMessage( GetLastError() );
426cdf0e10cSrcweir 				}
427cdf0e10cSrcweir 			}
428cdf0e10cSrcweir 
429cdf0e10cSrcweir 			CloseHandle( hProcess );
430cdf0e10cSrcweir 		}
431cdf0e10cSrcweir 		else
432cdf0e10cSrcweir 		{
433cdf0e10cSrcweir 			OutputSystemMessage( GetLastError() );
434cdf0e10cSrcweir 		}
435cdf0e10cSrcweir 	}
436cdf0e10cSrcweir 
437cdf0e10cSrcweir 	return 0;
438cdf0e10cSrcweir }
439cdf0e10cSrcweir 
440