Mercurial > trustbridge
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 |