andre@603: /* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik andre@603: * Software engineering by Intevation GmbH andre@603: * andre@603: * This file is Free Software under the GNU GPL (v>=2) andre@603: * and comes with ABSOLUTELY NO WARRANTY! andre@603: * See LICENSE.txt for details. */ andre@603: andre@603: #ifdef WIN32 andre@603: #include "processhelp.h" andre@603: #include "strhelp.h" andre@670: #include "util.h" andre@603: andre@603: #include andre@603: #include andre@603: #include andre@603: #include andre@603: andre@603: #include andre@603: andre@606: struct EnumWindowsStruct { andre@606: EnumWindowsStruct() : windowId(0) {} andre@606: DWORD pid; andre@606: HWND windowId; andre@603: }; andre@603: andre@603: BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) andre@603: { andre@603: if (GetWindowLong(hwnd, GWL_STYLE) & WS_VISIBLE) { andre@603: andre@603: DWORD pidwin; andre@603: andre@603: GetWindowThreadProcessId(hwnd, &pidwin); andre@603: if (pidwin == ((EnumWindowsStruct *)lParam)->pid) { andre@603: ((EnumWindowsStruct *)lParam)->windowId = hwnd; andre@603: return FALSE; andre@603: } andre@603: } andre@603: return TRUE; andre@603: } andre@603: andre@603: static HANDLE getProcessHandle(int processID) andre@603: { andre@603: return OpenProcess(SYNCHRONIZE | andre@603: PROCESS_QUERY_INFORMATION | andre@603: PROCESS_VM_READ | andre@603: PROCESS_TERMINATE, andre@603: false, processID); andre@603: } andre@603: andre@603: const QList ProcessHelp::getProcessesIdForName(const QString &processName) andre@603: { andre@603: HANDLE h; andre@603: PROCESSENTRY32 pe32; andre@603: QList pids; andre@603: andre@603: h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); andre@603: if (h == INVALID_HANDLE_VALUE) { andre@603: return pids; andre@603: } andre@603: andre@603: pe32.dwSize = sizeof(PROCESSENTRY32); // Necessary according to MSDN andre@603: if (!Process32First(h, &pe32)) { andre@603: return pids; andre@603: } andre@603: andre@603: pids.clear(); andre@603: andre@608: const QString processNameLower = processName.toLower().replace(".exe", ""); andre@608: const QString processNameExe = processNameLower + ".exe"; andre@608: andre@603: do { andre@608: const QString exeFile = QString::fromWCharArray(pe32.szExeFile).toLower(); andre@608: if (exeFile == processNameLower || exeFile == processNameExe) { andre@670: PSID user_sid = get_process_owner(GetCurrentProcess()); andre@606: if (user_sid) { andre@603: // Also check that we are the owner of that process andre@603: HANDLE hProcess = getProcessHandle(pe32.th32ProcessID); andre@606: if (!hProcess) { andre@603: continue; andre@603: } andre@603: andre@670: PSID sid = get_process_owner(hProcess); andre@670: PSID userSid = get_process_owner(GetCurrentProcess()); andre@606: if (!sid || (userSid && !EqualSid(userSid, sid))) { andre@606: free(sid); andre@603: continue; andre@603: } andre@603: } andre@603: pids.append((int)pe32.th32ProcessID); andre@603: qDebug() << "found PID: " << (int)pe32.th32ProcessID; andre@603: } andre@603: } while (Process32Next(h, &pe32)); andre@606: CloseHandle(h); andre@603: return pids; andre@603: } andre@603: andre@603: bool ProcessHelp::otherProcessesExist(const QString &processName) andre@603: { andre@603: const QList pids = getProcessesIdForName(processName); andre@603: int myPid = getpid(); andre@606: foreach(int pid, pids) { andre@603: if (myPid != pid) { andre@603: qDebug() << "Found another process with id: " << pid; andre@603: return true; andre@603: } andre@603: } andre@603: return false; andre@603: } andre@603: andre@606: void ProcessHelp::activateWindowForProcess(const QString &executableName) andre@606: { andre@603: const QList pids = getProcessesIdForName(executableName); andre@603: int myPid = getpid(); andre@603: int foundPid = 0; andre@606: foreach(int pid, pids) { andre@603: if (myPid != pid) { andre@603: qDebug() << "activateWindowForProcess(): PID to activate:" << pid; andre@603: foundPid = pid; andre@603: break; andre@603: } andre@603: } andre@606: if (foundPid == 0) { andre@603: return; andre@603: } andre@603: EnumWindowsStruct winStruct; andre@603: winStruct.pid = foundPid; andre@606: EnumWindows(EnumWindowsProc, (LPARAM)&winStruct); andre@606: if (winStruct.windowId == 0) { andre@603: return; andre@603: } andre@606: SetForegroundWindow(winStruct.windowId); andre@603: } andre@603: #endif // WIN32 andre@603: