~ubuntu-branches/ubuntu/raring/kdepimlibs/raring

« back to all changes in this revision

Viewing changes to kpimutils/processes.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2012-07-26 17:13:11 UTC
  • mfrom: (1.1.81)
  • Revision ID: package-import@ubuntu.com-20120726171311-j2heoxylb6lbhg4w
Tags: 4:4.9.0-0ubuntu1
* New upstream release
* Use direct build-depends versions rather than kde-sc-dev-latest

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 * This file is part of the kpimutils library.
3
3
 *
4
4
 * Copyright (C) 2008 Jarosław Staniek <staniek@kde.org>
 
5
 * Copyright (C) 2012 Andre Heinecke <aheinecke@intevation.de>
5
6
 *
6
7
 * This library is free software; you can redistribute it and/or
7
8
 * modify it under the terms of the GNU Lesser General Public
32
33
#ifdef Q_WS_WIN
33
34
 
34
35
#include <windows.h>
35
 
#include <winperf.h>
 
36
#include <tlhelp32.h>
36
37
#include <psapi.h>
37
38
#include <signal.h>
38
39
#include <unistd.h>
44
45
#include <QtCore/QList>
45
46
#include <QtCore/QtDebug>
46
47
 
47
 
static PPERF_OBJECT_TYPE FirstObject( PPERF_DATA_BLOCK PerfData )
48
 
{
49
 
  return (PPERF_OBJECT_TYPE)( (PBYTE)PerfData + PerfData->HeaderLength );
50
 
}
51
 
 
52
 
static PPERF_INSTANCE_DEFINITION FirstInstance( PPERF_OBJECT_TYPE PerfObj )
53
 
{
54
 
  return (PPERF_INSTANCE_DEFINITION)( (PBYTE)PerfObj + PerfObj->DefinitionLength );
55
 
}
56
 
 
57
 
static PPERF_OBJECT_TYPE NextObject( PPERF_OBJECT_TYPE PerfObj )
58
 
{
59
 
  return (PPERF_OBJECT_TYPE)( (PBYTE)PerfObj + PerfObj->TotalByteLength );
60
 
}
61
 
 
62
 
static PPERF_COUNTER_DEFINITION FirstCounter( PPERF_OBJECT_TYPE PerfObj )
63
 
{
64
 
  return (PPERF_COUNTER_DEFINITION) ( (PBYTE)PerfObj + PerfObj->HeaderLength );
65
 
}
66
 
 
67
 
static PPERF_INSTANCE_DEFINITION NextInstance( PPERF_INSTANCE_DEFINITION PerfInst )
68
 
{
69
 
  PPERF_COUNTER_BLOCK PerfCntrBlk =
70
 
    (PPERF_COUNTER_BLOCK)( (PBYTE)PerfInst + PerfInst->ByteLength );
71
 
  return (PPERF_INSTANCE_DEFINITION)( (PBYTE)PerfCntrBlk + PerfCntrBlk->ByteLength );
72
 
}
73
 
 
74
 
static PPERF_COUNTER_DEFINITION NextCounter( PPERF_COUNTER_DEFINITION PerfCntr )
75
 
{
76
 
  return (PPERF_COUNTER_DEFINITION)( (PBYTE)PerfCntr + PerfCntr->ByteLength );
77
 
}
78
 
 
79
 
static PPERF_COUNTER_BLOCK CounterBlock( PPERF_INSTANCE_DEFINITION PerfInst )
80
 
{
81
 
  return (PPERF_COUNTER_BLOCK) ( (LPBYTE) PerfInst + PerfInst->ByteLength );
82
 
}
83
 
 
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
88
 
 
89
 
static QString fromWChar( const wchar_t *string, int size = -1 )
90
 
{
91
 
  return ( sizeof(wchar_t) == sizeof(QChar) ) ?
92
 
    QString::fromUtf16( (ushort *)string, size )
93
 
    : QString::fromUcs4( (uint *)string, size );
 
48
#include <KDebug>
 
49
 
 
50
// Copy from kdelibs/kinit/kinit_win.cpp
 
51
PSID copySid(PSID from)
 
52
{
 
53
    if (!from)
 
54
        return 0;
 
55
    int sidLength = GetLengthSid(from);
 
56
    PSID to = (PSID) malloc(sidLength);
 
57
    CopySid(sidLength, to, from);
 
58
    return to;
 
59
}
 
60
 
 
61
// Copy from kdelibs/kinit/kinit_win.cpp
 
62
static PSID getProcessOwner(HANDLE hProcess)
 
63
{
 
64
#ifndef _WIN32_WCE
 
65
    HANDLE hToken = NULL;
 
66
    PSID sid;
 
67
 
 
68
    OpenProcessToken(hProcess, TOKEN_READ, &hToken);
 
69
    if(hToken)
 
70
    {
 
71
        DWORD size;
 
72
        PTOKEN_USER userStruct;
 
73
 
 
74
        // check how much space is needed
 
75
        GetTokenInformation(hToken, TokenUser, NULL, 0, &size);
 
76
        if( ERROR_INSUFFICIENT_BUFFER == GetLastError() )
 
77
        {
 
78
            userStruct = reinterpret_cast<PTOKEN_USER>( new BYTE[size] );
 
79
            GetTokenInformation(hToken, TokenUser, userStruct, size, &size);
 
80
 
 
81
            sid = copySid(userStruct->User.Sid);
 
82
            CloseHandle(hToken);
 
83
            delete [] userStruct;
 
84
            return sid;
 
85
        }
 
86
    }
 
87
#endif
 
88
    return 0;
 
89
}
 
90
 
 
91
// Copy from kdelibs/kinit/kinit_win.cpp
 
92
static HANDLE getProcessHandle(int processID)
 
93
{
 
94
    return OpenProcess( SYNCHRONIZE|PROCESS_QUERY_INFORMATION |
 
95
                        PROCESS_VM_READ | PROCESS_TERMINATE,
 
96
                        false, processID );
94
97
}
95
98
 
96
99
void KPIMUtils::getProcessesIdForName( const QString &processName, QList<int> &pids )
97
100
{
98
 
  qDebug() << "KPIMUtils::getProcessesIdForName" << processName;
99
 
#ifndef Q_OS_WINCE
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 );
106
 
 
107
 
  char key[64];
108
 
  sprintf( key,"%d %d", GETPID_PROCESS_OBJECT_INDEX, GETPID_PROC_ID_COUNTER );
109
 
  LONG lRes;
110
 
  while ( ( lRes = RegQueryValueExA( HKEY_PERFORMANCE_DATA,
111
 
                                     key,
112
 
                                     0,
113
 
                                     0,
114
 
                                     (LPBYTE) perfData,
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 );
119
 
  }
120
 
 
121
 
  // Get the first object type.
122
 
  perfObject = FirstObject( perfData );
123
 
  if ( !perfObject ) {
124
 
    return;
125
 
  }
126
 
 
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 );
131
 
      continue;
132
 
    }
133
 
    pids.clear();
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 );
151
 
            break;
152
 
          }
153
 
          curCounter = NextCounter( curCounter );
154
 
        }
155
 
      }
156
 
      perfInstance = NextInstance( perfInstance );
157
 
    }
158
 
  }
159
 
  free( perfData );
160
 
  RegCloseKey( HKEY_PERFORMANCE_DATA );
161
 
#else
162
101
  HANDLE h;
163
102
  PROCESSENTRY32 pe32;
164
103
 
166
105
  if ( h == INVALID_HANDLE_VALUE ) {
167
106
    return;
168
107
  }
169
 
  pe32.dwSize = sizeof(PROCESSENTRY32);
 
108
 
 
109
  pe32.dwSize = sizeof(PROCESSENTRY32); // Necessary according to MSDN
170
110
  if ( !Process32First( h, &pe32 ) ) {
171
111
    return;
172
112
  }
 
113
 
173
114
  pids.clear();
174
 
  do
175
 
  {
 
115
 
 
116
  do {
176
117
    if ( QString::fromWCharArray( pe32.szExeFile ) == processName ) {
 
118
      PSID user_sid = getProcessOwner( GetCurrentProcess() );
 
119
      if ( user_sid ) {
 
120
        // Also check that we are the Owner of that process
 
121
        HANDLE hProcess = getProcessHandle( pe32.th32ProcessID );
 
122
        if (!hProcess) {
 
123
          continue;
 
124
        }
 
125
 
 
126
        PSID sid = getProcessOwner( hProcess );
 
127
        PSID userSid = getProcessOwner( GetCurrentProcess() );
 
128
        if (!sid || userSid && !EqualSid( userSid, sid )) {
 
129
          free ( sid );
 
130
          continue;
 
131
        }
 
132
      }
177
133
      pids.append( (int)pe32.th32ProcessID );
178
 
      qDebug() << "found PID: " << (int)pe32.th32ProcessID;
 
134
      kDebug() << "found PID: " << (int)pe32.th32ProcessID;
179
135
    }
180
 
 
181
136
  } while( Process32Next( h, &pe32 ) );
182
 
  CloseToolhelp32Snapshot(h);
 
137
#ifndef _WIN32_WCE
 
138
    CloseHandle(h);
 
139
#else
 
140
    CloseToolhelp32Snapshot(h);
183
141
#endif
184
142
}
185
143
 
253
211
  int foundPid = 0;
254
212
  foreach ( int pid, pids ) {
255
213
    if ( myPid != pid ) {
256
 
      qDebug() << "activateWindowForProcess(): PID to activate:" << pid;
 
214
      kDebug() << "activateWindowForProcess(): PID to activate:" << pid;
257
215
      foundPid = pid;
258
216
      break;
259
217
    }