From 982b2135d29fbca150140c68e8e40b95f4c6f2cb Mon Sep 17 00:00:00 2001 From: Alain Magloire Date: Thu, 24 Apr 2003 21:15:25 +0000 Subject: [PATCH] New file added to do interrupt on a pid. --- .../library/raise.c | 181 ++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 core/org.eclipse.cdt.core.win32/library/raise.c diff --git a/core/org.eclipse.cdt.core.win32/library/raise.c b/core/org.eclipse.cdt.core.win32/library/raise.c new file mode 100644 index 00000000000..5148b4a45b2 --- /dev/null +++ b/core/org.eclipse.cdt.core.win32/library/raise.c @@ -0,0 +1,181 @@ +/* Copyright, 2002, QNX Software Systems Ltd. All Rights Reserved + + * This source code has been published by QNX Software Systems + * Ltd. (QSSL). However, any use, reproduction, modification, distribution + * or transfer of this software, or any software which includes or is based + * upon any of this code, is only permitted if expressly authorized by a + * written license agreement from QSSL. Contact the QNX Developer's Network + * or contact QSSL's legal department for more information. + * + * + * Win32ProcessEx.c + * + * This is a JNI implementation of spawner + */ +#include "stdafx.h" +#include "Spawner.h" + + +#include "jni.h" + +extern void JNICALL ThrowByName(JNIEnv *env, const char *name, const char *msg); + +// #define DEBUG_MONITOR + +static HWND consoleHWND; + +static BOOL CALLBACK +find_child_console (HWND hwnd, LPARAM arg) +{ + DWORD thread_id; + DWORD process_id; + DWORD pid = arg; + + thread_id = GetWindowThreadProcessId (hwnd, &process_id); + if (process_id == pid) + { + char window_class[32]; + + GetClassName (hwnd, window_class, sizeof (window_class)); + if (strcmp (window_class, "ConsoleWindowClass") == 0) + { + consoleHWND = hwnd; + return FALSE; + } + } + /* keep looking */ + return TRUE; +} + +/* +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_raise__Ljava_lang_Object_2 + (JNIEnv * env, jobject process, jobject jpid) +{ + jint pid; + jclass integerClass = (*env) -> FindClass(env, "java/lang/Integer"); + jmethodID intValue; + if(NULL == integerClass) { + ThrowByName(env, "java/lang/IOException", "Cannot find Integer class"); + return -1; + } + if(!((*env) -> IsInstanceOf(env, jpid, integerClass))) { + ThrowByName(env, "java/lang/IOException", "Wrong argument"); + return -1; + } + + intValue = (*env) -> GetMethodID(env, integerClass, "intValue", "()I"); + if(NULL == intValue) { + ThrowByName(env, "java/lang/IOException", "Cannot find intValue method in Integer class"); + return -1; + } + + pid = (*env) -> CallIntMethod(env, jpid, intValue); + + return interruptProcess(pid); + +} +*/ + +int interruptProcess(int pid) +{ +#ifdef DEBUG_MONITOR + char buffer[1000]; +#endif + int rc; + // Try another method + rc = 0; + consoleHWND = NULL; + +#ifdef DEBUG_MONITOR + sprintf(buffer, "Try to interrupt process %i\n", pid); + OutputDebugString(buffer); +#endif + EnumWindows (find_child_console, (LPARAM) pid); + + if(NULL != consoleHWND) + { + BYTE control_scan_code = (BYTE) MapVirtualKey (VK_CONTROL, 0); + /* Fake Ctrl-C for SIGINT, and Ctrl-Break for SIGQUIT. */ + BYTE vk_c_code = 'C'; + BYTE vk_break_code = VK_CANCEL; + BYTE c_scan_code = (BYTE) MapVirtualKey (vk_c_code, 0); + BYTE break_scan_code = (BYTE) MapVirtualKey (vk_break_code, 0); + HWND foreground_window; + + + foreground_window = GetForegroundWindow (); + if (foreground_window) + { + /* NT 5.0, and apparently also Windows 98, will not allow + a Window to be set to foreground directly without the + user's involvement. The workaround is to attach + ourselves to the thread that owns the foreground + window, since that is the only thread that can set the + foreground window. */ + DWORD foreground_thread, child_thread; + foreground_thread = + GetWindowThreadProcessId (foreground_window, NULL); + if (foreground_thread == GetCurrentThreadId () + || !AttachThreadInput (GetCurrentThreadId (), + foreground_thread, TRUE)) + foreground_thread = 0; + + child_thread = GetWindowThreadProcessId (consoleHWND, NULL); + if (child_thread == GetCurrentThreadId () + || !AttachThreadInput (GetCurrentThreadId (), + child_thread, TRUE)) + child_thread = 0; + + /* Set the foreground window to the child. */ + if (SetForegroundWindow (consoleHWND)) + { + /* + if(0 != c_scan_code) { + // Generate keystrokes as if user had typed Ctrl-C. + keybd_event (VK_CONTROL, control_scan_code, 0, 0); + keybd_event (vk_c_code, c_scan_code, 0, 0); + keybd_event (vk_c_code, c_scan_code, KEYEVENTF_KEYUP, 0); + keybd_event (VK_CONTROL, control_scan_code, KEYEVENTF_KEYUP, 0); + } + */ + /* Sleep for a bit to give time for respond */ + Sleep (100); + if(0 != break_scan_code) { + /* Generate keystrokes as if user had typed Ctrl-Break */ + keybd_event (VK_CONTROL, control_scan_code, 0, 0); + keybd_event (vk_break_code, break_scan_code, KEYEVENTF_EXTENDEDKEY, 0); + keybd_event (vk_break_code, break_scan_code, + KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); + keybd_event (VK_CONTROL, control_scan_code, KEYEVENTF_KEYUP, 0); + } + + /* Sleep for a bit to give time for respond */ + Sleep (100); + + SetForegroundWindow (foreground_window); + } + /* Detach from the foreground and child threads now that + the foreground switching is over. */ + if (foreground_thread) + AttachThreadInput (GetCurrentThreadId (), + foreground_thread, FALSE); + if (child_thread) + AttachThreadInput (GetCurrentThreadId (), + child_thread, FALSE); +#ifdef DEBUG_MONITOR + sprintf(buffer, "Sent Ctrl-C & Ctrl-Break to process %i\n", pid); + OutputDebugString(buffer); +#endif + } + } +#ifdef DEBUG_MONITOR + else { + sprintf(buffer, "Cannot find console for process %i\n", pid); + + OutputDebugString(buffer); + } +#endif + + return rc; +} +