Mercurial > trustbridge
view ui/processhelp_win.cpp @ 603:cfef809b890d
Add Process Management functions and ther implementation for windows.
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Tue, 17 Jun 2014 17:26:10 +0200 |
parents | |
children | 91dd38a71783 |
line wrap: on
line source
/* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik * Software engineering by Intevation GmbH * * This file is Free Software under the GNU GPL (v>=2) * and comes with ABSOLUTELY NO WARRANTY! * See LICENSE.txt for details. */ #ifdef WIN32 #include "processhelp.h" #include "strhelp.h" #include <windows.h> #include <tlhelp32.h> #include <psapi.h> #include <unistd.h> #include <QDebug> struct EnumWindowsStruct { EnumWindowsStruct() : windowId( 0 ) {} DWORD pid; HWND windowId; }; PSID copySid(PSID from) { if ( !from ) { return 0; } int sidLength = GetLengthSid( from ); PSID to = (PSID) xmalloc( sidLength ); CopySid(sidLength, to, from); return to; } static PSID getProcessOwner(HANDLE hProcess) { HANDLE hToken = NULL; PSID sid; OpenProcessToken(hProcess, TOKEN_READ, &hToken); if ( hToken ) { DWORD size; PTOKEN_USER userStruct; // check how much space is needed GetTokenInformation( hToken, TokenUser, NULL, 0, &size ); if ( ERROR_INSUFFICIENT_BUFFER == GetLastError() ) { userStruct = reinterpret_cast<PTOKEN_USER>( new BYTE[size] ); GetTokenInformation( hToken, TokenUser, userStruct, size, &size ); sid = copySid( userStruct->User.Sid ); CloseHandle( hToken ); delete [] userStruct; return sid; } } return 0; } BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) { if (GetWindowLong(hwnd, GWL_STYLE) & WS_VISIBLE) { DWORD pidwin; GetWindowThreadProcessId(hwnd, &pidwin); if (pidwin == ((EnumWindowsStruct *)lParam)->pid) { ((EnumWindowsStruct *)lParam)->windowId = hwnd; return FALSE; } } return TRUE; } static HANDLE getProcessHandle(int processID) { return OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_TERMINATE, false, processID); } const QList<int> ProcessHelp::getProcessesIdForName(const QString &processName) { HANDLE h; PROCESSENTRY32 pe32; QList <int> pids; h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (h == INVALID_HANDLE_VALUE) { return pids; } pe32.dwSize = sizeof(PROCESSENTRY32); // Necessary according to MSDN if (!Process32First(h, &pe32)) { return pids; } pids.clear(); do { if ( QString::fromWCharArray(pe32.szExeFile) == processName ) { PSID user_sid = getProcessOwner(GetCurrentProcess()); if ( user_sid ) { // Also check that we are the owner of that process HANDLE hProcess = getProcessHandle(pe32.th32ProcessID); if ( !hProcess ) { continue; } PSID sid = getProcessOwner(hProcess); PSID userSid = getProcessOwner(GetCurrentProcess()); if ( !sid || (userSid && !EqualSid(userSid, sid))) { free (sid); continue; } } pids.append((int)pe32.th32ProcessID); qDebug() << "found PID: " << (int)pe32.th32ProcessID; } } while (Process32Next(h, &pe32)); CloseHandle( h ); return pids; } bool ProcessHelp::otherProcessesExist(const QString &processName) { const QList<int> pids = getProcessesIdForName(processName); int myPid = getpid(); foreach (int pid, pids) { if (myPid != pid) { qDebug() << "Found another process with id: " << pid; return true; } } return false; } void ProcessHelp::activateWindowForProcess(const QString &executableName) { const QList<int> pids = getProcessesIdForName(executableName); int myPid = getpid(); int foundPid = 0; foreach (int pid, pids) { if (myPid != pid) { qDebug() << "activateWindowForProcess(): PID to activate:" << pid; foundPid = pid; break; } } if ( foundPid == 0 ) { return; } EnumWindowsStruct winStruct; winStruct.pid = foundPid; EnumWindows( EnumWindowsProc, (LPARAM)&winStruct ); if ( winStruct.windowId == 0 ) { return; } SetForegroundWindow( winStruct.windowId ); } #endif // WIN32