44
45
#include <QtCore/QList>
45
46
#include <QtCore/QtDebug>
47
static PPERF_OBJECT_TYPE FirstObject( PPERF_DATA_BLOCK PerfData )
49
return (PPERF_OBJECT_TYPE)( (PBYTE)PerfData + PerfData->HeaderLength );
52
static PPERF_INSTANCE_DEFINITION FirstInstance( PPERF_OBJECT_TYPE PerfObj )
54
return (PPERF_INSTANCE_DEFINITION)( (PBYTE)PerfObj + PerfObj->DefinitionLength );
57
static PPERF_OBJECT_TYPE NextObject( PPERF_OBJECT_TYPE PerfObj )
59
return (PPERF_OBJECT_TYPE)( (PBYTE)PerfObj + PerfObj->TotalByteLength );
62
static PPERF_COUNTER_DEFINITION FirstCounter( PPERF_OBJECT_TYPE PerfObj )
64
return (PPERF_COUNTER_DEFINITION) ( (PBYTE)PerfObj + PerfObj->HeaderLength );
67
static PPERF_INSTANCE_DEFINITION NextInstance( PPERF_INSTANCE_DEFINITION PerfInst )
69
PPERF_COUNTER_BLOCK PerfCntrBlk =
70
(PPERF_COUNTER_BLOCK)( (PBYTE)PerfInst + PerfInst->ByteLength );
71
return (PPERF_INSTANCE_DEFINITION)( (PBYTE)PerfCntrBlk + PerfCntrBlk->ByteLength );
74
static PPERF_COUNTER_DEFINITION NextCounter( PPERF_COUNTER_DEFINITION PerfCntr )
76
return (PPERF_COUNTER_DEFINITION)( (PBYTE)PerfCntr + PerfCntr->ByteLength );
79
static PPERF_COUNTER_BLOCK CounterBlock( PPERF_INSTANCE_DEFINITION PerfInst )
81
return (PPERF_COUNTER_BLOCK) ( (LPBYTE) PerfInst + PerfInst->ByteLength );
84
#define GETPID_TOTAL 64 * 1024
85
#define GETPID_BYTEINCREMENT 1024
86
#define GETPID_PROCESS_OBJECT_INDEX 230
87
#define GETPID_PROC_ID_COUNTER 784
89
static QString fromWChar( const wchar_t *string, int size = -1 )
91
return ( sizeof(wchar_t) == sizeof(QChar) ) ?
92
QString::fromUtf16( (ushort *)string, size )
93
: QString::fromUcs4( (uint *)string, size );
50
// Copy from kdelibs/kinit/kinit_win.cpp
51
PSID copySid(PSID from)
55
int sidLength = GetLengthSid(from);
56
PSID to = (PSID) malloc(sidLength);
57
CopySid(sidLength, to, from);
61
// Copy from kdelibs/kinit/kinit_win.cpp
62
static PSID getProcessOwner(HANDLE hProcess)
68
OpenProcessToken(hProcess, TOKEN_READ, &hToken);
72
PTOKEN_USER userStruct;
74
// check how much space is needed
75
GetTokenInformation(hToken, TokenUser, NULL, 0, &size);
76
if( ERROR_INSUFFICIENT_BUFFER == GetLastError() )
78
userStruct = reinterpret_cast<PTOKEN_USER>( new BYTE[size] );
79
GetTokenInformation(hToken, TokenUser, userStruct, size, &size);
81
sid = copySid(userStruct->User.Sid);
91
// Copy from kdelibs/kinit/kinit_win.cpp
92
static HANDLE getProcessHandle(int processID)
94
return OpenProcess( SYNCHRONIZE|PROCESS_QUERY_INFORMATION |
95
PROCESS_VM_READ | PROCESS_TERMINATE,
96
99
void KPIMUtils::getProcessesIdForName( const QString &processName, QList<int> &pids )
98
qDebug() << "KPIMUtils::getProcessesIdForName" << processName;
100
PPERF_OBJECT_TYPE perfObject;
101
PPERF_INSTANCE_DEFINITION perfInstance;
102
PPERF_COUNTER_DEFINITION perfCounter, curCounter;
103
PPERF_COUNTER_BLOCK counterPtr;
104
DWORD bufSize = GETPID_TOTAL;
105
PPERF_DATA_BLOCK perfData = (PPERF_DATA_BLOCK) malloc( bufSize );
108
sprintf( key,"%d %d", GETPID_PROCESS_OBJECT_INDEX, GETPID_PROC_ID_COUNTER );
110
while ( ( lRes = RegQueryValueExA( HKEY_PERFORMANCE_DATA,
115
&bufSize ) ) == ERROR_MORE_DATA ) {
116
// get a buffer that is big enough
117
bufSize += GETPID_BYTEINCREMENT;
118
perfData = (PPERF_DATA_BLOCK) realloc( perfData, bufSize );
121
// Get the first object type.
122
perfObject = FirstObject( perfData );
127
// Process all objects.
128
for ( uint i = 0; i < perfData->NumObjectTypes; i++ ) {
129
if ( perfObject->ObjectNameTitleIndex != GETPID_PROCESS_OBJECT_INDEX ) {
130
perfObject = NextObject( perfObject );
134
perfCounter = FirstCounter( perfObject );
135
perfInstance = FirstInstance( perfObject );
136
// retrieve the instances
137
qDebug() << "INSTANCES: " << perfObject->NumInstances;
138
for ( int instance = 0; instance < perfObject->NumInstances; instance++ ) {
139
curCounter = perfCounter;
140
const QString foundProcessName(
141
fromWChar( ( wchar_t * )( (PBYTE)perfInstance + perfInstance->NameOffset ) ) );
142
qDebug() << "foundProcessName: " << foundProcessName;
143
if ( foundProcessName == processName ) {
144
// retrieve the counters
145
for ( uint counter = 0; counter < perfObject->NumCounters; counter++ ) {
146
if ( curCounter->CounterNameTitleIndex == GETPID_PROC_ID_COUNTER ) {
147
counterPtr = CounterBlock( perfInstance );
148
DWORD *value = (DWORD*)( (LPBYTE) counterPtr + curCounter->CounterOffset );
149
pids.append( int( *value ) );
150
qDebug() << "found PID: " << int( *value );
153
curCounter = NextCounter( curCounter );
156
perfInstance = NextInstance( perfInstance );
160
RegCloseKey( HKEY_PERFORMANCE_DATA );
163
102
PROCESSENTRY32 pe32;
166
105
if ( h == INVALID_HANDLE_VALUE ) {
169
pe32.dwSize = sizeof(PROCESSENTRY32);
109
pe32.dwSize = sizeof(PROCESSENTRY32); // Necessary according to MSDN
170
110
if ( !Process32First( h, &pe32 ) ) {
176
117
if ( QString::fromWCharArray( pe32.szExeFile ) == processName ) {
118
PSID user_sid = getProcessOwner( GetCurrentProcess() );
120
// Also check that we are the Owner of that process
121
HANDLE hProcess = getProcessHandle( pe32.th32ProcessID );
126
PSID sid = getProcessOwner( hProcess );
127
PSID userSid = getProcessOwner( GetCurrentProcess() );
128
if (!sid || userSid && !EqualSid( userSid, sid )) {
177
133
pids.append( (int)pe32.th32ProcessID );
178
qDebug() << "found PID: " << (int)pe32.th32ProcessID;
134
kDebug() << "found PID: " << (int)pe32.th32ProcessID;
181
136
} while( Process32Next( h, &pe32 ) );
182
CloseToolhelp32Snapshot(h);
140
CloseToolhelp32Snapshot(h);