[PATCH 2 of 2] Add Process Management functions and ther implementation for windows
Wald Commits
scm-commit at wald.intevation.org
Tue Jun 17 17:26:16 CEST 2014
# HG changeset patch
# User Andre Heinecke <andre.heinecke at intevation.de>
# Date 1403018770 -7200
# Node ID cfef809b890dee1017e360fd466fa34319628139
# Parent 854248d81ba41dc0031818c321786fb3befcb87b
Add Process Management functions and ther implementation for windows.
diff -r 854248d81ba4 -r cfef809b890d ui/CMakeLists.txt
--- a/ui/CMakeLists.txt Tue Jun 17 17:25:12 2014 +0200
+++ b/ui/CMakeLists.txt Tue Jun 17 17:26:10 2014 +0200
@@ -20,6 +20,8 @@
${CMAKE_CURRENT_SOURCE_DIR}/downloader.cpp
${CMAKE_CURRENT_SOURCE_DIR}/sslconnection.cpp
${CMAKE_CURRENT_SOURCE_DIR}/sslhelp.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/processhelp_win.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/processhelp_linux.cpp
)
# Cmake does not correctly identify gcc windres when cross compiling
diff -r 854248d81ba4 -r cfef809b890d ui/processhelp.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/processhelp.h Tue Jun 17 17:26:10 2014 +0200
@@ -0,0 +1,48 @@
+/* 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.
+ *
+ * Parts of this code (especially windows) are based on kpimutils processes.cpp
+ * available under LGPL 2.1 or later.
+ */
+#ifndef PROCESSHELP_H
+#define PROCESSHELP_H
+
+#include <QList>
+#include <QString>
+
+/**
+ * @file Static helper functions for process handling
+ * @brief process handling functions
+ */
+
+namespace ProcessHelp {
+ /**
+ * @brief look up process id's for a processName
+ *
+ * Looks up processes run by the current user.
+ *
+ * @param[in] processName the name of the process to look for
+ * @returns a list of pids that match this process. May be empty
+ */
+ const QList<int> getProcessesIdForName(const QString &processName);
+
+ /**
+ * @brief check if another process with the same name exists
+ *
+ * @param[in] processName name of the process to look for.
+ *
+ * @returns true if one or more processes (other than the current process) exist
+ */
+ bool otherProcessesExist(const QString &processName);
+
+ /**
+ * @brief Activates the window for first found process
+ * @param [in] executableName executableName (without path and .exe extension)
+ */
+ void activateWindowForProcess(const QString &executableName);
+}
+#endif // PROCESSHELP_H
diff -r 854248d81ba4 -r cfef809b890d ui/processhelp_linux.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/processhelp_linux.cpp Tue Jun 17 17:26:10 2014 +0200
@@ -0,0 +1,30 @@
+/* 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.
+ */
+#ifndef WIN32
+
+#include "processhelp.h"
+
+const QList<int> ProcessHelp::getProcessesIdForName(const QString &processName) {
+ // TODO
+ Q_UNUSED(processName);
+ return QList<int>();
+}
+
+bool ProcessHelp::otherProcessesExist(const QString &processName) {
+ // TODO
+ Q_UNUSED(processName);
+ return false;
+}
+
+void ProcessHelp::activateWindowForProcess(const QString &executableName) {
+ // TODO
+ Q_UNUSED(executableName);
+ return;
+}
+
+#endif /* Not WIN32 */
diff -r 854248d81ba4 -r cfef809b890d ui/processhelp_win.cpp
--- /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
+
More information about the Trustbridge-commits
mailing list