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
+

http://wald.intevation.org/projects/trustbridge/