Mercurial > trustbridge
diff 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 diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ui/processhelp_win.cpp Tue Jun 17 17:26:10 2014 +0200 @@ -0,0 +1,167 @@ +/* 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 +