/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sal.hxx"

#include <tchar.h>

#ifdef _MSC_VER
#pragma warning(push,1) // disable warnings within system headers
#endif
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <tlhelp32.h>
#include <psapi.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif

#include <signal.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>

#ifndef SIGNULL
#define SIGNULL	0
#endif

#ifndef SIGKILL
#define SIGKILL	9
#endif

#include <signal.h>

#define MAX_MODULES	1024

/////////////////////////////////////////////////////////////////////////////
// Determines if a returned handle value is valid
/////////////////////////////////////////////////////////////////////////////

static inline bool IsValidHandle( HANDLE handle )
{
	return INVALID_HANDLE_VALUE != handle && NULL != handle;
}


#define elementsof( a ) (sizeof(a) / sizeof( (a)[0] ))

/////////////////////////////////////////////////////////////////////////////
// Retrieves function address in another process
/////////////////////////////////////////////////////////////////////////////

#if 1
#define GetProcAddressEx( hProcess, hModule, lpProcName ) GetProcAddress( hModule, lpProcName )
#else
FARPROC WINAPI GetProcAddressEx( HANDLE hProcess, HMODULE hModule, LPCSTR lpProcName )
{
	FARPROC	lpfnProcAddress = GetProcAddress( hModule, lpProcName );

	if ( lpfnProcAddress )
	{
		DWORD	dwProcessId = GetProcessId( hProcess );

		if ( GetCurrentProcessId() != dwProcessId )
		{
			FARPROC	lpfnRemoteProcAddress = NULL;
			TCHAR	szBaseName[MAX_PATH];

			if ( GetModuleBaseName( GetCurrentProcess(), hModule, szBaseName, elementsof(szBaseName) ) )
			{
				HMODULE	ahModules[MAX_MODULES];
				DWORD	cbNeeded = 0;

				if ( EnumProcessModules( hProcess, ahModules, sizeof(ahModules), &cbNeeded ) )
				{
					ULONG	nModules = cbNeeded / sizeof(ahModules[0]);

					for ( ULONG n = 0; n < nModules; n++ )
					{
						TCHAR	szRemoteBaseName[MAX_PATH];

						if ( GetModuleBaseName(
                            hProcess, ahModules[n], szRemoteBaseName, elementsof(szRemoteBaseName) ) &&
							0 == lstrcmpi( szRemoteBaseName, szBaseName )
							)
						{
							lpfnRemoteProcAddress = lpfnProcAddress;

							if ( ahModules[n] != hModule )
								*(LPBYTE*)&lpfnRemoteProcAddress += (LPBYTE)ahModules[n] - (LPBYTE)hModule;
							break;
						}
					}
				}
			}

			lpfnProcAddress = lpfnRemoteProcAddress;
		}
	}

	return lpfnProcAddress;
}
#endif

/////////////////////////////////////////////////////////////////////////////
// Raises a signal in an other process
/////////////////////////////////////////////////////////////////////////////

static DWORD SignalToExceptionCode( int signal )
{
	switch ( signal )
	{
	case SIGSEGV:
		return EXCEPTION_ACCESS_VIOLATION;
	case SIGFPE:
		return EXCEPTION_FLT_INVALID_OPERATION;
	case SIGILL:
		return EXCEPTION_ILLEGAL_INSTRUCTION;
	case SIGINT:
		return CONTROL_C_EXIT;
	case SIGBREAK:
		return CONTROL_C_EXIT;
	default:
		return 0;
	}
}

static BOOL RaiseSignalEx( HANDLE hProcess, int sig )
{
	DWORD	dwProcessId = GetProcessId( hProcess );

	HANDLE	hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 );
	HANDLE	hThread = 0;
	BOOL fSuccess = FALSE;

	if ( IsValidHandle(hSnapshot) )
	{
		THREADENTRY32	te;

		te.dwSize = sizeof(te);
		fSuccess = Thread32First( hSnapshot, &te );
		while ( fSuccess )
		{
			if ( te.th32OwnerProcessID == dwProcessId )
			{
				hThread = OpenThread( 
					THREAD_SUSPEND_RESUME | THREAD_QUERY_INFORMATION |
					THREAD_GET_CONTEXT | THREAD_SET_CONTEXT,
					FALSE, te.th32ThreadID );
				if ( IsValidHandle(hThread) )
					break;
			}

			fSuccess = Thread32Next( hSnapshot, &te );
		}

		CloseHandle( hSnapshot );
	}

	if ( fSuccess )
	{
		CONTEXT	aContext;

		if ( SuspendThread( hThread ) != (DWORD)-1 )
		{
			ZeroMemory( &aContext, sizeof(aContext) );
			aContext.ContextFlags = CONTEXT_FULL;
			
			fSuccess = GetThreadContext( hThread, &aContext );

			if ( fSuccess )
			{
				if ( sig )
				{
					DWORD	dwStackBuffer[] =
					{
						aContext.Eip,
						SignalToExceptionCode( sig ),
						EXCEPTION_NONCONTINUABLE,
						0,
						0
					};

					aContext.Esp -= sizeof(dwStackBuffer);
					WriteProcessMemory( hProcess, (LPVOID)aContext.Esp, dwStackBuffer, sizeof(dwStackBuffer), NULL );
					aContext.Eip = (DWORD)GetProcAddressEx( hProcess, GetModuleHandleA("KERNEL32"), "RaiseException" );
				}
				else
				{
					aContext.Ecx = aContext.Eax = aContext.Ebx = aContext.Edx = aContext.Esi = aContext.Edi = 0;
				}

				fSuccess = SetThreadContext( hThread, &aContext );
			}

			fSuccess = ResumeThread( hThread ) && fSuccess;

			DWORD	dwLastError = GetLastError();
			CloseHandle( hThread );
			SetLastError( dwLastError );

			return fSuccess;
		}
	}

	return FALSE;
}
/////////////////////////////////////////////////////////////////////////////
// Command line parameter parsing
/////////////////////////////////////////////////////////////////////////////

static void ParseCommandArgs( LPDWORD lpProcesses, LPDWORD lpdwNumProcesses, int *pSig )
{
	typedef struct _SignalEntry
	{
		LPCTSTR lpSignalName;
		int iSignalValue;
	} SignalEntry;

	#define SIG_ENTRY( signal ) { TEXT(#signal), SIG##signal }

	static SignalEntry SupportedSignals[] =
	{
		SIG_ENTRY( NULL ),
		SIG_ENTRY( SEGV ),
		SIG_ENTRY( ILL ),
		SIG_ENTRY( FPE ),
		SIG_ENTRY( INT ),
		SIG_ENTRY( BREAK ),
		SIG_ENTRY( TERM ),
		SIG_ENTRY( ABRT ),
		SIG_ENTRY( KILL )
	};

	const int NumSupportedSignals = elementsof(SupportedSignals);

	DWORD	dwMaxProcesses = *lpdwNumProcesses;
	int		argc = __argc;
	TCHAR	**argv = __targv;

	*lpdwNumProcesses = 0;

	for ( int argn = 1; argn < argc; argn++ )
	{
		if ( 0 == lstrcmpi( argv[argn], TEXT("-l") ) ||
			 0 == lstrcmpi( argv[argn], TEXT("/l") ) )

		{
			for ( int n = 0; n < NumSupportedSignals; n++ )
			{
				_tprintf( _T("%s "), SupportedSignals[n].lpSignalName );
			}
			_tprintf( _T("\n") );
			ExitProcess( 0 );
		}
		else if ( 0 == lstrcmpi( argv[argn], TEXT("-?") ) ||
			      0 == lstrcmpi( argv[argn], TEXT("/?") ) ||
			      0 == lstrcmpi( argv[argn], TEXT("-h") ) ||
			      0 == lstrcmpi( argv[argn], TEXT("/h") ) ||
			      0 == lstrcmpi( argv[argn], TEXT("--help") ) )
		{
			_tprintf(  
				_T("Terminates a process by sending a signal.\n\n")
				_T("Usage: kill [ -l ] [ -signal ] pid ...\n\n")
				_T("-l        Lists supported signals\n")
				_T("-signal   Sends the specified signal to the given processes.\n")
				_T("          signal can be a numeric value specifying the signal number\n")
				_T("          or a string listed by the -l parameter. If no signal is\n")
				_T("          given SIGTERM (-TERM) is used.\n")
				_T("pid       Process id(s) or executables names(s) of processes to \n")
				_T("          signal or terminate.\n\n")
				);
			ExitProcess( 0 );
		}
		else if ( argv[argn] && ( *argv[argn] == '-' || *argv[argn] == '/' ) )
		{
			LPCTSTR	argsig = CharNext( argv[argn] );

			int	n;
			for ( n = 0; n < NumSupportedSignals; n++ )
			{
				_TCHAR *endptr = NULL;

				if ( 0 == lstrcmpi( SupportedSignals[n].lpSignalName, argsig ) || 
					 _tcstoul( argsig, &endptr, 0 ) == static_cast< unsigned >(SupportedSignals[n].iSignalValue) && (!endptr || !*endptr) )
				{
					*pSig = SupportedSignals[n].iSignalValue;
					break;
				}
			}

			if ( n >= NumSupportedSignals )
			{
				_ftprintf( stderr,  
					_T("kill: Illegal argument %s\n")
					_T("Type 'kill --help' to show allowed syntax.\n") 
					_T("Type 'kill -l' to show supported signals.\n"), 
					argv[argn] );
				ExitProcess( 0 );
			}
		}
		else
		{
			unsigned long value = 0;
			_TCHAR	*endptr = NULL;
			
			value = _tcstoul( argv[argn], &endptr, 0 );

			if ( !endptr || !*endptr ) 
			{
				if ( *lpdwNumProcesses < dwMaxProcesses )
				{
					*(lpProcesses++) = value;
					(*lpdwNumProcesses)++;
				}
			}
			else
			{
				HANDLE	hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );

				if ( IsValidHandle( hSnapshot ) )
				{
					PROCESSENTRY32	pe;

					pe.dwSize = sizeof(pe);
					BOOL fSuccess = Process32First( hSnapshot, &pe );

					while ( fSuccess )
					{
						if ( 0 == lstrcmpi( argv[argn], pe.szExeFile ) )
						{
							if ( *lpdwNumProcesses < dwMaxProcesses )
							{
								*(lpProcesses++) = pe.th32ProcessID;
								(*lpdwNumProcesses)++;
							}
						}
						fSuccess = Process32Next( hSnapshot, &pe );
					}

					CloseHandle( hSnapshot );
				}
			}
		}
	}

	if ( !*lpdwNumProcesses )
	{
		_ftprintf( stderr, 
			_T("kill: No process specified.\n")
			_T("Use kill --help to show allowed syntax.\n") 
			);
		ExitProcess( 0 );
	}

}

void OutputSystemMessage( DWORD dwErrorCode )
{
	LPVOID lpMsgBuf;
	FormatMessageA(
					FORMAT_MESSAGE_ALLOCATE_BUFFER |
					FORMAT_MESSAGE_FROM_SYSTEM |
					FORMAT_MESSAGE_IGNORE_INSERTS,
					NULL,
					dwErrorCode,
					MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
					(LPSTR)&lpMsgBuf,
					0,
					NULL
				);

	printf( (LPSTR)lpMsgBuf );
	LocalFree( lpMsgBuf );
}

int _tmain()
{
	DWORD	dwProcessIds[1024];
	DWORD	nProcesses = elementsof(dwProcessIds);
	int		sig = SIGTERM;


	ParseCommandArgs( dwProcessIds, &nProcesses, &sig );

	for ( ULONG n = 0; n < nProcesses; n++ )
	{
		HANDLE	hProcess;

		_tprintf( _T("Sending signal to process id %d..."), dwProcessIds[n] );
		hProcess = OpenProcess( PROCESS_TERMINATE | PROCESS_CREATE_THREAD | SYNCHRONIZE |
			PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,
			FALSE, dwProcessIds[n] );

		if ( IsValidHandle( hProcess ) )
		{
			if ( SIGKILL == sig )
				TerminateProcess( hProcess, 255 );
			else
			{
				if ( RaiseSignalEx( hProcess, sig ) )
					_tprintf( _T("OK\n") );
				else
				{
					OutputSystemMessage( GetLastError() );
				}
			}

			CloseHandle( hProcess );
		}
		else
		{
			OutputSystemMessage( GetLastError() );
		}
	}

	return 0;
}

