PLUGIN_EXPORT void Finalize(void* data) { Measure* measure = (Measure*)data; std::unique_lock<std::recursive_mutex> lock(measure->mutex); if (measure->threadActive) { // Increment ref count of this module so that it will not be // unloaded prior to thread completion. DWORD flags = GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS; HMODULE module; GetModuleHandleEx(flags, (LPCWSTR)DllMain, &module); if (measure->hProc != INVALID_HANDLE_VALUE && !TerminateApp(measure->hProc, measure->dwPID, (measure->state == SW_HIDE))) { measure->value = 105.0f; RmLogF(measure->rm, LOG_ERROR, err_Terminate, measure->program.c_str()); // Could not terminate process (very rare!) } // Tell the thread to perform any cleanup measure->threadActive = false; return; } lock.unlock(); delete measure; }
BOOL SafeTerminateProcess( HANDLE hProcess, // handle to the process UINT uExitCode // exit code for the process ) { DWORD ProcessId = GetProcessId(hProcess); //SendToProcessThreads(ProcessId); DWORD dwRet; dwRet = TerminateApp(ProcessId, 1000); TCHAR tmpbuf[128]; _stprintf(tmpbuf, _T("SafeTerminateProcess Id %.8X (%d) TerminateApp %d"), ProcessId, ProcessId, dwRet); WriteLogToFile(tmpbuf, _T("ExecProcess")); return TRUE; // BOOL fOk; // // PROCESSENTRY32 pe = { sizeof(pe) }; // // HANDLE hSnapshot= CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0 ); // // if(hSnapshot == INVALID_HANDLE_VALUE) // return FALSE; // // int iCount = 0; // for ( fOk = Process32First(hSnapshot,&pe); fOk ; fOk = Process32Next(hSnapshot,&pe) ) // { // iCount++; // // if (ProcessId == pe.th32ProcessID) // { // SendToProcessThreads(ProcessId); // } // } // // CloseHandle(hSnapshot); // /* LRESULT SendMessage( HWND hWnd, // handle to destination window UINT Msg, // message WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ); BOOL PostThreadMessage( DWORD idThread, // thread identifier UINT Msg, // message WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ); */ }
int SampleApp::Run() { int retcode = -1; if (InitializeApp()) { retcode = MainLoop(); } TerminateApp(); return retcode; }
VOID main(VOID) { DWORD pid = NULL; HWND h = NULL; int i = 0, j = 0; for (j = 0; j < 2; j++) { for (i = 0; i < NUM_WINDOW_NAMES; i++) { if (h = FindWindow(NULL, WindowNames[i])) { GetWindowThreadProcessId(h, &pid); if (pid) { TerminateApp(pid, 500); } pid = NULL; h = NULL; } } for (i = 0; i < NUM_CLASS_NAMES; i++) { if (h = FindWindow(ClassNames[i], NULL)) { GetWindowThreadProcessId(h, &pid); if (pid) { TerminateApp(pid, 500); } pid = NULL; h = NULL; } } } return; }
/* * ReqProg_kill * * If it was a task that we attached to (WasStarted), all we do is * forgive the last interrupt, and then exit * * If it was a task we started, we TerminateApp it, and then wait for * the task ended notification. Note: Task ended isn't quite good enough, * since the module isn't unloaded. However, you may never get the module * unloaded notification, if you are debugging the 2nd, 3rd etc instance * of an app, since the module is loaded more than once. BUT, a NEW command * from the debugger ends up restarting the app "too fast" - the module isn't * deleted yet, and so it ends up running a second instance, even if you * really don't have a first instance. This is the reason for that half * second pause - to allow Windows to get on with the unloading of the module, * if it is going to. Ack. */ unsigned ReqProg_kill( void ) { prog_kill_ret *ret; ret = GetOutPtr( 0 ); ret->err = 0; Out((OUT_LOAD,"KILL: DebugeeTask=%04x, WasStarted=%d", DebugeeTask, WasStarted )); if( DebugeeTask != NULL ) { IntResult.EFlags &= ~TRACE_BIT; if( WasStarted ) { Out((OUT_LOAD,"Doing Release Debugee")); DebuggerWaitForMessage( RELEASE_DEBUGEE, DebugeeTask, RESTART_APP ); } else { TerminateApp( DebugeeTask, NO_UAE_BOX ); DebuggerWaitForMessage( KILLING_DEBUGEE, NULL, -1 ); Out((OUT_LOAD,"Task Terminated(not current)")); { DWORD a; a = GetTickCount(); while( GetTickCount() < a + 500 ) { Yield(); } } } #if 0 FiniASynchHook(); #endif } ExitSoftMode(); if( WDebug386 ) { if( WasInt32 ) { WasInt32 = FALSE; DoneWithInterrupt( NULL ); } } DebugeeTask = NULL; ModuleTop = 0; CurrentModule = 1; FaultHandlerEntered = FALSE; PendingTrap = FALSE; SaveStdIn = NIL_HANDLE; SaveStdOut = NIL_HANDLE; Debugging32BitApp = FALSE; return( sizeof( *ret ) ); }
PLUGIN_EXPORT void ExecuteBang(void* data, LPCWSTR args) { Measure* measure = (Measure*)data; std::lock_guard<std::recursive_mutex> lock(measure->mutex); if (_wcsicmp(args, L"RUN") == 0) { if (!measure->threadActive && !measure->program.empty()) { std::thread thread(RunCommand, measure); thread.detach(); measure->value = 0.0f; measure->threadActive = true; } else { measure->value = 101.0f; RmLogF(measure->rm, LOG_NOTICE, err_CmdRunning, measure->program.c_str()); // Command still running } } else if (_wcsicmp(args, L"CLOSE") == 0 || _wcsicmp(args, L"KILL") == 0) { if (measure->threadActive && measure->hProc != INVALID_HANDLE_VALUE) { if (!TerminateApp(measure->hProc, measure->dwPID, (_wcsicmp(args, L"KILL") == 0))) { measure->value = 105.0f; RmLogF(measure->rm, LOG_ERROR, err_Terminate, measure->program.c_str()); // Could not terminate process (very rare!) } } else { measure->value = 102.0f; RmLogF(measure->rm, LOG_ERROR, err_NotRunning, measure->program.c_str()); // Command not running } } else { measure->value = 100.0f; RmLogF(measure->rm, LOG_NOTICE, err_UnknownCmd, args); // Unknown command } }
int _tmain(int argc, _TCHAR* argv[]) { if (__argc != 2) return 1; LPWSTR* wide_commandline = NULL; int commandline_argument_number; wide_commandline = CommandLineToArgvW(GetCommandLineW(), &commandline_argument_number); //if (!iswdigit(wide_commandline[1])) // return 1; int pid = _wtoi(wide_commandline[1]); TerminateApp(pid, 1500); return 0; }
void app_stop(DWORD timeOut) { DWORD pid = 0; HANDLE hFind = INVALID_HANDLE_VALUE; WIN32_FIND_DATA find_file_data; DWORD dwError; char *u3_host_exec_path; char dir_spec[MAX_PATH+1]; char file_name[MAX_PATH+1]; u3_host_exec_path = getenv("U3_HOST_EXEC_PATH"); strncpy(dir_spec, u3_host_exec_path, strlen(u3_host_exec_path) + 1); strncat(dir_spec, "\\*.pid", 7); hFind = FindFirstFile(dir_spec, &find_file_data); if(hFind != INVALID_HANDLE_VALUE) { do { pid = (DWORD)atoi(find_file_data.cFileName); if(pid) TerminateApp(pid, timeOut); strncpy(file_name, u3_host_exec_path, strlen(u3_host_exec_path) + 1); strncat(file_name, "\\", 2); strncat(file_name, find_file_data.cFileName, strlen(find_file_data.cFileName) + 1); DeleteFile(TEXT(file_name)); } while(FindNextFile(hFind, &find_file_data) != 0); FindClose(hFind); } }
//--------------------------------------------------------------------------- int TConsoleRunner::TerminateApp(){ return TerminateApp(childPid, 5000, true); }
void RunCommand(Measure* measure) { std::unique_lock<std::recursive_mutex> lock(measure->mutex); std::wstring command = measure->program + L" " + measure->parameter; std::wstring folder = measure->folder; WORD state = measure->state; int timeout = measure->timeout; OutputType type = measure->outputType; lock.unlock(); std::wstring result = L""; bool error = false; HANDLE read = INVALID_HANDLE_VALUE; HANDLE write = INVALID_HANDLE_VALUE; /* Instead of trying to keep track of the following handles, use an array to make cleanup easier. HANDLE hOutputReadTmp; 0 HANDLE hOutputWrite; 1 HANDLE hInputWriteTmp; 2 HANDLE hInputRead; 3 HANDLE hErrorWrite; 4 */ HANDLE loadHandles[5]; for (int i = 0; i < sizeof(loadHandles) / sizeof(loadHandles[0]); ++i) { loadHandles[i] = INVALID_HANDLE_VALUE; } SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.bInheritHandle = TRUE; sa.lpSecurityDescriptor = NULL; HANDLE hProc = GetCurrentProcess(); // Create pipe for stdin, stdout, stderr if (CreatePipe(&loadHandles[0], &loadHandles[1], &sa, 0) && DuplicateHandle(hProc, loadHandles[1], hProc, &loadHandles[4], 0, TRUE, DUPLICATE_SAME_ACCESS) && CreatePipe(&loadHandles[3], &loadHandles[2], &sa, 0) && DuplicateHandle(hProc, loadHandles[0], hProc, &read, 0, FALSE, DUPLICATE_SAME_ACCESS) && DuplicateHandle(hProc, loadHandles[2], hProc, &write, 0, FALSE, DUPLICATE_SAME_ACCESS)) { BYTE buffer[MAX_LINE_LENGTH + 3]; DWORD bytesRead = 0; DWORD totalBytes = 0; DWORD bytesLeft = 0; DWORD exit = 0; PROCESS_INFORMATION pi; SecureZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); STARTUPINFO si; SecureZeroMemory(&si, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; si.wShowWindow = state; si.hStdOutput = loadHandles[1]; si.hStdInput = loadHandles[3]; si.hStdError = loadHandles[4]; if (CreateProcess(NULL, &command[0], NULL, NULL, TRUE, CREATE_NEW_PROCESS_GROUP, NULL, &folder[0], &si, &pi)) { // Store values inside measure for the "Close" or "Kill" command lock.lock(); measure->hProc = pi.hProcess; measure->dwPID = pi.dwProcessId; lock.unlock(); // Send command DWORD written; WriteFile(write, &command[0], MAX_LINE_LENGTH, &written, NULL); std::chrono::system_clock::time_point start = std::chrono::system_clock::now(); // Read output of program (if any) while(true) { auto ReadFileAndSetResult = [&]() -> void { ReadFile(read, buffer, MAX_LINE_LENGTH, &bytesRead, NULL); // Triple "null" the buffer in case an odd number bytes is // converted to a multi-byte string. buffer[bytesRead] = '\0'; buffer[bytesRead + 1] = '\0'; buffer[bytesRead + 2] = '\0'; switch (type) { case OUTPUTTYPE_ANSI: result += StringUtil::Widen((LPCSTR)buffer); break; case OUTPUTTYPE_UTF8: result += StringUtil::WidenUTF8((LPCSTR)buffer); break; default: case OUTPUTTYPE_UTF16: result += (LPCWSTR)buffer; break; } SecureZeroMemory(buffer, sizeof(buffer)); // clear the buffer }; // Wait for a signal from the process (or timeout). // This reduced CPU usage significantly. WaitForSingleObject(pi.hThread, 1); // Check if there is any data to to read PeekNamedPipe(read, buffer, MAX_LINE_LENGTH, &bytesRead, &totalBytes, &bytesLeft); if (bytesRead != 0) { if (totalBytes > MAX_LINE_LENGTH) { while (bytesRead >= MAX_LINE_LENGTH) { ReadFileAndSetResult(); } } else { ReadFileAndSetResult(); } } // If a timeout is defined, attempt to terminate program and detach it from the plugin if ((timeout >= 0 && std::chrono::duration_cast<std::chrono::milliseconds> (std::chrono::system_clock::now() - start).count() > timeout)) { if (!TerminateApp(pi.hProcess, pi.dwProcessId, (state == SW_HIDE))) { lock.lock(); measure->value = 105.0f; RmLogF(measure->rm, LOG_ERROR, err_Terminate, measure->program.c_str()); // Could not terminate process (very rare!) error = true; lock.unlock(); } break; } // Check to see if the program is still running GetExitCodeProcess(pi.hProcess, &exit); if (exit != STILL_ACTIVE) break; } // Close process handles CloseHandle(pi.hThread); CloseHandle(pi.hProcess); // Update values in case the "Close" or "Kill" command is called lock.lock(); measure->hProc = INVALID_HANDLE_VALUE; measure->dwPID = 0; lock.unlock(); } else { lock.lock(); measure->value = 103.0f; RmLogF(measure->rm, LOG_ERROR, err_Process, measure->program.c_str()); // Cannot start process error = true; lock.unlock(); } } else { lock.lock(); measure->value = 106.0f; RmLog(measure->rm, LOG_ERROR, err_CreatePipe); // Cannot create pipe error = true; lock.unlock(); } // Close handles for (int i = 0; i < sizeof(loadHandles) / sizeof(loadHandles[0]); ++i) { if (loadHandles[i] != INVALID_HANDLE_VALUE) { CloseHandle(loadHandles[i]); } } CloseHandle(write); CloseHandle(read); // Remove any carriage returns result.erase(std::remove(result.begin(), result.end(), L'\r'), result.end()); HMODULE module = nullptr; lock.lock(); if (measure->threadActive) { measure->result = result; measure->result.shrink_to_fit(); if (!measure->outputFile.empty()) { std::wstring encoding = L"w+"; switch (type) { case OUTPUTTYPE_UTF8: { encoding.append(L", ccs=UTF-8"); break; } case OUTPUTTYPE_UTF16: { encoding.append(L", ccs=UTF-16LE"); break; } } FILE* file; if (_wfopen_s(&file, measure->outputFile.c_str(), encoding.c_str()) == 0) { fputws(result.c_str(), file); } else { measure->value = 104.0f; RmLogF(measure->rm, LOG_ERROR, err_SaveFile, measure->outputFile.c_str()); // Cannot save file error = true; } if (file) { fclose(file); } } // If no errors from the thread, // set number value of measure to 1 to indicate "Success". if (!error) { measure->value = 1.0f; } measure->threadActive = false; lock.unlock(); if (!measure->finishAction.empty()) { RmExecute(measure->skin, measure->finishAction.c_str()); } return; } lock.unlock(); delete measure; DWORD flags = GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT; GetModuleHandleEx(flags, (LPCWSTR)DllMain, &module); if (module) { // Decrement the ref count and possibly unload the module if this is the last instance. FreeLibraryAndExitThread(module, 0); } }
static int proc_term(int pid) { TerminateApp(pid, EXIT_TIMEOUT); return 0; }
void MainFrame::OnExit(wxCloseEvent& WXUNUSED(event)){ TerminateApp(); }
void MainFrame::OnFileExit(wxCommandEvent &event){ TerminateApp(); }
MainFrame::~MainFrame(){ TerminateApp(); _frameManager.UnInit(); }
void TerminateMovePoint() { TerminateApp(controllerProcInfo.dwProcessId, 0); ZeroMemory(&controllerProcInfo, sizeof(_PROCESS_INFORMATION)); }
SampleApp::~SampleApp() { TerminateApp(); }