comparison 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
comparison
equal deleted inserted replaced
602:854248d81ba4 603:cfef809b890d
1 /* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik
2 * Software engineering by Intevation GmbH
3 *
4 * This file is Free Software under the GNU GPL (v>=2)
5 * and comes with ABSOLUTELY NO WARRANTY!
6 * See LICENSE.txt for details. */
7
8 #ifdef WIN32
9 #include "processhelp.h"
10 #include "strhelp.h"
11
12 #include <windows.h>
13 #include <tlhelp32.h>
14 #include <psapi.h>
15 #include <unistd.h>
16
17 #include <QDebug>
18
19 struct EnumWindowsStruct
20 {
21 EnumWindowsStruct() : windowId( 0 ) {}
22 DWORD pid;
23 HWND windowId;
24 };
25
26 PSID copySid(PSID from)
27 {
28 if ( !from ) {
29 return 0;
30 }
31
32 int sidLength = GetLengthSid( from );
33 PSID to = (PSID) xmalloc( sidLength );
34 CopySid(sidLength, to, from);
35 return to;
36 }
37
38 static PSID getProcessOwner(HANDLE hProcess)
39 {
40 HANDLE hToken = NULL;
41 PSID sid;
42
43 OpenProcessToken(hProcess, TOKEN_READ, &hToken);
44 if ( hToken ) {
45 DWORD size;
46 PTOKEN_USER userStruct;
47
48 // check how much space is needed
49 GetTokenInformation( hToken, TokenUser, NULL, 0, &size );
50 if ( ERROR_INSUFFICIENT_BUFFER == GetLastError() ) {
51 userStruct = reinterpret_cast<PTOKEN_USER>( new BYTE[size] );
52 GetTokenInformation( hToken, TokenUser, userStruct, size, &size );
53
54 sid = copySid( userStruct->User.Sid );
55 CloseHandle( hToken );
56 delete [] userStruct;
57 return sid;
58 }
59 }
60 return 0;
61 }
62
63 BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
64 {
65 if (GetWindowLong(hwnd, GWL_STYLE) & WS_VISIBLE) {
66
67 DWORD pidwin;
68
69 GetWindowThreadProcessId(hwnd, &pidwin);
70 if (pidwin == ((EnumWindowsStruct *)lParam)->pid) {
71 ((EnumWindowsStruct *)lParam)->windowId = hwnd;
72 return FALSE;
73 }
74 }
75 return TRUE;
76 }
77
78
79 static HANDLE getProcessHandle(int processID)
80 {
81 return OpenProcess(SYNCHRONIZE |
82 PROCESS_QUERY_INFORMATION |
83 PROCESS_VM_READ |
84 PROCESS_TERMINATE,
85 false, processID);
86 }
87
88 const QList<int> ProcessHelp::getProcessesIdForName(const QString &processName)
89 {
90 HANDLE h;
91 PROCESSENTRY32 pe32;
92 QList <int> pids;
93
94 h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
95 if (h == INVALID_HANDLE_VALUE) {
96 return pids;
97 }
98
99 pe32.dwSize = sizeof(PROCESSENTRY32); // Necessary according to MSDN
100 if (!Process32First(h, &pe32)) {
101 return pids;
102 }
103
104 pids.clear();
105
106 do {
107 if ( QString::fromWCharArray(pe32.szExeFile) == processName ) {
108 PSID user_sid = getProcessOwner(GetCurrentProcess());
109 if ( user_sid ) {
110 // Also check that we are the owner of that process
111 HANDLE hProcess = getProcessHandle(pe32.th32ProcessID);
112 if ( !hProcess ) {
113 continue;
114 }
115
116 PSID sid = getProcessOwner(hProcess);
117 PSID userSid = getProcessOwner(GetCurrentProcess());
118 if ( !sid || (userSid && !EqualSid(userSid, sid))) {
119 free (sid);
120 continue;
121 }
122 }
123 pids.append((int)pe32.th32ProcessID);
124 qDebug() << "found PID: " << (int)pe32.th32ProcessID;
125 }
126 } while (Process32Next(h, &pe32));
127 CloseHandle( h );
128 return pids;
129 }
130
131 bool ProcessHelp::otherProcessesExist(const QString &processName)
132 {
133 const QList<int> pids = getProcessesIdForName(processName);
134 int myPid = getpid();
135 foreach (int pid, pids) {
136 if (myPid != pid) {
137 qDebug() << "Found another process with id: " << pid;
138 return true;
139 }
140 }
141 return false;
142 }
143
144 void ProcessHelp::activateWindowForProcess(const QString &executableName) {
145 const QList<int> pids = getProcessesIdForName(executableName);
146 int myPid = getpid();
147 int foundPid = 0;
148 foreach (int pid, pids) {
149 if (myPid != pid) {
150 qDebug() << "activateWindowForProcess(): PID to activate:" << pid;
151 foundPid = pid;
152 break;
153 }
154 }
155 if ( foundPid == 0 ) {
156 return;
157 }
158 EnumWindowsStruct winStruct;
159 winStruct.pid = foundPid;
160 EnumWindows( EnumWindowsProc, (LPARAM)&winStruct );
161 if ( winStruct.windowId == 0 ) {
162 return;
163 }
164 SetForegroundWindow( winStruct.windowId );
165 }
166 #endif // WIN32
167

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