kpimutils
processes.cpp
Go to the documentation of this file.00001
00029 #include "processes.h"
00030 using namespace KPIMUtils;
00031
00032 #ifdef Q_WS_WIN
00033
00034 #include <windows.h>
00035 #include <winperf.h>
00036 #include <psapi.h>
00037 #include <signal.h>
00038 #include <unistd.h>
00039
00040 #include <QtCore/QList>
00041 #include <QtCore/QtDebug>
00042
00043 static PPERF_OBJECT_TYPE FirstObject( PPERF_DATA_BLOCK PerfData )
00044 {
00045 return (PPERF_OBJECT_TYPE)( (PBYTE)PerfData + PerfData->HeaderLength );
00046 }
00047
00048 static PPERF_INSTANCE_DEFINITION FirstInstance( PPERF_OBJECT_TYPE PerfObj )
00049 {
00050 return (PPERF_INSTANCE_DEFINITION)( (PBYTE)PerfObj + PerfObj->DefinitionLength );
00051 }
00052
00053 static PPERF_OBJECT_TYPE NextObject( PPERF_OBJECT_TYPE PerfObj )
00054 {
00055 return (PPERF_OBJECT_TYPE)( (PBYTE)PerfObj + PerfObj->TotalByteLength );
00056 }
00057
00058 static PPERF_COUNTER_DEFINITION FirstCounter( PPERF_OBJECT_TYPE PerfObj )
00059 {
00060 return (PPERF_COUNTER_DEFINITION) ( (PBYTE)PerfObj + PerfObj->HeaderLength );
00061 }
00062
00063 static PPERF_INSTANCE_DEFINITION NextInstance( PPERF_INSTANCE_DEFINITION PerfInst )
00064 {
00065 PPERF_COUNTER_BLOCK PerfCntrBlk =
00066 (PPERF_COUNTER_BLOCK)( (PBYTE)PerfInst + PerfInst->ByteLength );
00067 return (PPERF_INSTANCE_DEFINITION)( (PBYTE)PerfCntrBlk + PerfCntrBlk->ByteLength );
00068 }
00069
00070 static PPERF_COUNTER_DEFINITION NextCounter( PPERF_COUNTER_DEFINITION PerfCntr )
00071 {
00072 return (PPERF_COUNTER_DEFINITION)( (PBYTE)PerfCntr + PerfCntr->ByteLength );
00073 }
00074
00075 static PPERF_COUNTER_BLOCK CounterBlock( PPERF_INSTANCE_DEFINITION PerfInst )
00076 {
00077 return (PPERF_COUNTER_BLOCK) ( (LPBYTE) PerfInst + PerfInst->ByteLength );
00078 }
00079
00080 #define GETPID_TOTAL 64 * 1024
00081 #define GETPID_BYTEINCREMENT 1024
00082 #define GETPID_PROCESS_OBJECT_INDEX 230
00083 #define GETPID_PROC_ID_COUNTER 784
00084
00085 static QString fromWChar( const wchar_t *string, int size = -1 )
00086 {
00087 return ( sizeof(wchar_t) == sizeof(QChar) ) ?
00088 QString::fromUtf16( (ushort *)string, size )
00089 : QString::fromUcs4( (uint *)string, size );
00090 }
00091
00092 void KPIMUtils::getProcessesIdForName( const QString &processName, QList<int> &pids )
00093 {
00094 qDebug() << "KPIMUtils::getProcessesIdForName" << processName;
00095 PPERF_OBJECT_TYPE perfObject;
00096 PPERF_INSTANCE_DEFINITION perfInstance;
00097 PPERF_COUNTER_DEFINITION perfCounter, curCounter;
00098 PPERF_COUNTER_BLOCK counterPtr;
00099 DWORD bufSize = GETPID_TOTAL;
00100 PPERF_DATA_BLOCK perfData = (PPERF_DATA_BLOCK) malloc( bufSize );
00101
00102 char key[64];
00103 sprintf( key,"%d %d", GETPID_PROCESS_OBJECT_INDEX, GETPID_PROC_ID_COUNTER );
00104 LONG lRes;
00105 while ( ( lRes = RegQueryValueExA( HKEY_PERFORMANCE_DATA,
00106 key,
00107 NULL,
00108 NULL,
00109 (LPBYTE) perfData,
00110 &bufSize ) ) == ERROR_MORE_DATA ) {
00111
00112 bufSize += GETPID_BYTEINCREMENT;
00113 perfData = (PPERF_DATA_BLOCK) realloc( perfData, bufSize );
00114 }
00115
00116
00117 perfObject = FirstObject( perfData );
00118 if ( !perfObject ) {
00119 return;
00120 }
00121
00122
00123 for ( uint i = 0; i < perfData->NumObjectTypes; i++ ) {
00124 if ( perfObject->ObjectNameTitleIndex != GETPID_PROCESS_OBJECT_INDEX ) {
00125 perfObject = NextObject( perfObject );
00126 continue;
00127 }
00128 pids.clear();
00129 perfCounter = FirstCounter( perfObject );
00130 perfInstance = FirstInstance( perfObject );
00131
00132 qDebug() << "INSTANCES: " << perfObject->NumInstances;
00133 for ( int instance = 0; instance < perfObject->NumInstances; instance++ ) {
00134 curCounter = perfCounter;
00135 const QString foundProcessName(
00136 fromWChar( ( wchar_t * )( (PBYTE)perfInstance + perfInstance->NameOffset ) ) );
00137 qDebug() << "foundProcessName: " << foundProcessName;
00138 if ( foundProcessName == processName ) {
00139
00140 for ( uint counter = 0; counter < perfObject->NumCounters; counter++ ) {
00141 if ( curCounter->CounterNameTitleIndex == GETPID_PROC_ID_COUNTER ) {
00142 counterPtr = CounterBlock( perfInstance );
00143 DWORD *value = (DWORD*)( (LPBYTE) counterPtr + curCounter->CounterOffset );
00144 pids.append( int( *value ) );
00145 qDebug() << "found PID: " << int( *value );
00146 break;
00147 }
00148 curCounter = NextCounter( curCounter );
00149 }
00150 }
00151 perfInstance = NextInstance( perfInstance );
00152 }
00153 }
00154 free( perfData );
00155 RegCloseKey( HKEY_PERFORMANCE_DATA );
00156 }
00157
00158 bool KPIMUtils::otherProcessesExist( const QString &processName )
00159 {
00160 QList<int> pids;
00161 getProcessesIdForName( processName, pids );
00162 int myPid = getpid();
00163 foreach ( int pid, pids ) {
00164 if ( myPid != pid ) {
00165
00166 return true;
00167 }
00168 }
00169 return false;
00170 }
00171
00172 bool KPIMUtils::killProcesses( const QString &processName )
00173 {
00174 QList<int> pids;
00175 getProcessesIdForName( processName, pids );
00176 if ( pids.empty() ) {
00177 return true;
00178 }
00179
00180 qWarning() << "Killing process \"" << processName << " (pid=" << pids[0] << ")..";
00181 int overallResult = 0;
00182 foreach ( int pid, pids ) {
00183 int result = kill( pid, SIGTERM );
00184 if ( result == 0 ) {
00185 continue;
00186 }
00187 result = kill( pid, SIGKILL );
00188 if ( result != 0 ) {
00189 overallResult = result;
00190 }
00191 }
00192 return overallResult == 0;
00193 }
00194
00195 struct EnumWindowsStruct
00196 {
00197 EnumWindowsStruct() : windowId( 0 ) {}
00198 int pid;
00199 HWND windowId;
00200 };
00201
00202 BOOL CALLBACK EnumWindowsProc( HWND hwnd, LPARAM lParam )
00203 {
00204 if ( GetWindowLong( hwnd, GWL_STYLE ) & WS_VISIBLE ) {
00205
00206 DWORD pidwin;
00207
00208 GetWindowThreadProcessId( hwnd, &pidwin );
00209 if ( pidwin == ( (EnumWindowsStruct *)lParam )->pid ) {
00210 ( (EnumWindowsStruct *)lParam )->windowId = hwnd;
00211 return FALSE;
00212 }
00213 }
00214 return TRUE;
00215 }
00216
00217 void KPIMUtils::activateWindowForProcess( const QString &executableName )
00218 {
00219 QList<int> pids;
00220 KPIMUtils::getProcessesIdForName( executableName, pids );
00221 int myPid = getpid();
00222 int foundPid = 0;
00223 foreach ( int pid, pids ) {
00224 if ( myPid != pid ) {
00225 qDebug() << "activateWindowForProcess(): PID to activate:" << pid;
00226 foundPid = pid;
00227 break;
00228 }
00229 }
00230 if ( foundPid == 0 ) {
00231 return;
00232 }
00233 EnumWindowsStruct winStruct;
00234 winStruct.pid = foundPid;
00235 EnumWindows( EnumWindowsProc, (LPARAM)&winStruct );
00236 if ( winStruct.windowId == NULL ) {
00237 return;
00238 }
00239 SetForegroundWindow( winStruct.windowId );
00240 }
00241
00242 #endif // Q_WS_WIN