• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.8.3 API Reference
  • KDE Home
  • Contact Us
 

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 #ifdef Q_OS_WINCE
00041 #include <Tlhelp32.h>
00042 #endif
00043 
00044 #include <QtCore/QList>
00045 #include <QtCore/QtDebug>
00046 
00047 static PPERF_OBJECT_TYPE FirstObject( PPERF_DATA_BLOCK PerfData )
00048 {
00049   return (PPERF_OBJECT_TYPE)( (PBYTE)PerfData + PerfData->HeaderLength );
00050 }
00051 
00052 static PPERF_INSTANCE_DEFINITION FirstInstance( PPERF_OBJECT_TYPE PerfObj )
00053 {
00054   return (PPERF_INSTANCE_DEFINITION)( (PBYTE)PerfObj + PerfObj->DefinitionLength );
00055 }
00056 
00057 static PPERF_OBJECT_TYPE NextObject( PPERF_OBJECT_TYPE PerfObj )
00058 {
00059   return (PPERF_OBJECT_TYPE)( (PBYTE)PerfObj + PerfObj->TotalByteLength );
00060 }
00061 
00062 static PPERF_COUNTER_DEFINITION FirstCounter( PPERF_OBJECT_TYPE PerfObj )
00063 {
00064   return (PPERF_COUNTER_DEFINITION) ( (PBYTE)PerfObj + PerfObj->HeaderLength );
00065 }
00066 
00067 static PPERF_INSTANCE_DEFINITION NextInstance( PPERF_INSTANCE_DEFINITION PerfInst )
00068 {
00069   PPERF_COUNTER_BLOCK PerfCntrBlk =
00070     (PPERF_COUNTER_BLOCK)( (PBYTE)PerfInst + PerfInst->ByteLength );
00071   return (PPERF_INSTANCE_DEFINITION)( (PBYTE)PerfCntrBlk + PerfCntrBlk->ByteLength );
00072 }
00073 
00074 static PPERF_COUNTER_DEFINITION NextCounter( PPERF_COUNTER_DEFINITION PerfCntr )
00075 {
00076   return (PPERF_COUNTER_DEFINITION)( (PBYTE)PerfCntr + PerfCntr->ByteLength );
00077 }
00078 
00079 static PPERF_COUNTER_BLOCK CounterBlock( PPERF_INSTANCE_DEFINITION PerfInst )
00080 {
00081   return (PPERF_COUNTER_BLOCK) ( (LPBYTE) PerfInst + PerfInst->ByteLength );
00082 }
00083 
00084 #define GETPID_TOTAL 64 * 1024
00085 #define GETPID_BYTEINCREMENT 1024
00086 #define GETPID_PROCESS_OBJECT_INDEX 230
00087 #define GETPID_PROC_ID_COUNTER 784
00088 
00089 static QString fromWChar( const wchar_t *string, int size = -1 )
00090 {
00091   return ( sizeof(wchar_t) == sizeof(QChar) ) ?
00092     QString::fromUtf16( (ushort *)string, size )
00093     : QString::fromUcs4( (uint *)string, size );
00094 }
00095 
00096 void KPIMUtils::getProcessesIdForName( const QString &processName, QList<int> &pids )
00097 {
00098   qDebug() << "KPIMUtils::getProcessesIdForName" << processName;
00099 #ifndef Q_OS_WINCE
00100   PPERF_OBJECT_TYPE perfObject;
00101   PPERF_INSTANCE_DEFINITION perfInstance;
00102   PPERF_COUNTER_DEFINITION perfCounter, curCounter;
00103   PPERF_COUNTER_BLOCK counterPtr;
00104   DWORD bufSize = GETPID_TOTAL;
00105   PPERF_DATA_BLOCK perfData = (PPERF_DATA_BLOCK) malloc( bufSize );
00106 
00107   char key[64];
00108   sprintf( key,"%d %d", GETPID_PROCESS_OBJECT_INDEX, GETPID_PROC_ID_COUNTER );
00109   LONG lRes;
00110   while ( ( lRes = RegQueryValueExA( HKEY_PERFORMANCE_DATA,
00111                                      key,
00112                                      0,
00113                                      0,
00114                                      (LPBYTE) perfData,
00115                                      &bufSize ) ) == ERROR_MORE_DATA ) {
00116     // get a buffer that is big enough
00117     bufSize += GETPID_BYTEINCREMENT;
00118     perfData = (PPERF_DATA_BLOCK) realloc( perfData, bufSize );
00119   }
00120 
00121   // Get the first object type.
00122   perfObject = FirstObject( perfData );
00123   if ( !perfObject ) {
00124     return;
00125   }
00126 
00127   // Process all objects.
00128   for ( uint i = 0; i < perfData->NumObjectTypes; i++ ) {
00129     if ( perfObject->ObjectNameTitleIndex != GETPID_PROCESS_OBJECT_INDEX ) {
00130       perfObject = NextObject( perfObject );
00131       continue;
00132     }
00133     pids.clear();
00134     perfCounter = FirstCounter( perfObject );
00135     perfInstance = FirstInstance( perfObject );
00136     // retrieve the instances
00137     qDebug() << "INSTANCES: " << perfObject->NumInstances;
00138     for ( int instance = 0; instance < perfObject->NumInstances; instance++ ) {
00139       curCounter = perfCounter;
00140       const QString foundProcessName(
00141         fromWChar( ( wchar_t * )( (PBYTE)perfInstance + perfInstance->NameOffset ) ) );
00142       qDebug() << "foundProcessName: " << foundProcessName;
00143       if ( foundProcessName == processName ) {
00144         // retrieve the counters
00145         for ( uint counter = 0; counter < perfObject->NumCounters; counter++ ) {
00146           if ( curCounter->CounterNameTitleIndex == GETPID_PROC_ID_COUNTER ) {
00147             counterPtr = CounterBlock( perfInstance );
00148             DWORD *value = (DWORD*)( (LPBYTE) counterPtr + curCounter->CounterOffset );
00149             pids.append( int( *value ) );
00150             qDebug() << "found PID: " << int( *value );
00151             break;
00152           }
00153           curCounter = NextCounter( curCounter );
00154         }
00155       }
00156       perfInstance = NextInstance( perfInstance );
00157     }
00158   }
00159   free( perfData );
00160   RegCloseKey( HKEY_PERFORMANCE_DATA );
00161 #else
00162   HANDLE h;
00163   PROCESSENTRY32 pe32;
00164 
00165   h = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
00166   if ( h == INVALID_HANDLE_VALUE ) {
00167     return;
00168   }
00169   pe32.dwSize = sizeof(PROCESSENTRY32);
00170   if ( !Process32First( h, &pe32 ) ) {
00171     return;
00172   }
00173   pids.clear();
00174   do
00175   {
00176     if ( QString::fromWCharArray( pe32.szExeFile ) == processName ) {
00177       pids.append( (int)pe32.th32ProcessID );
00178       qDebug() << "found PID: " << (int)pe32.th32ProcessID;
00179     }
00180 
00181   } while( Process32Next( h, &pe32 ) );
00182   CloseToolhelp32Snapshot(h);
00183 #endif
00184 }
00185 
00186 bool KPIMUtils::otherProcessesExist( const QString &processName )
00187 {
00188   QList<int> pids;
00189   getProcessesIdForName( processName, pids );
00190   int myPid = getpid();
00191   foreach ( int pid, pids ) {
00192     if ( myPid != pid ) {
00193 //      kDebug() << "Process ID is " << pid;
00194       return true;
00195     }
00196   }
00197   return false;
00198 }
00199 
00200 bool KPIMUtils::killProcesses( const QString &processName )
00201 {
00202   QList<int> pids;
00203   getProcessesIdForName( processName, pids );
00204   if ( pids.empty() ) {
00205     return true;
00206   }
00207 
00208   qWarning() << "Killing process \"" << processName << " (pid=" << pids[0] << ")..";
00209   int overallResult = 0;
00210   foreach ( int pid, pids ) {
00211     int result;
00212 #ifndef _WIN32_WCE
00213     result = kill( pid, SIGTERM );
00214     if ( result == 0 ) {
00215       continue;
00216     }
00217 #endif
00218     result = kill( pid, SIGKILL );
00219     if ( result != 0 ) {
00220       overallResult = result;
00221     }
00222   }
00223   return overallResult == 0;
00224 }
00225 
00226 struct EnumWindowsStruct
00227 {
00228   EnumWindowsStruct() : windowId( 0 ) {}
00229   int pid;
00230   HWND windowId;
00231 };
00232 
00233 BOOL CALLBACK EnumWindowsProc( HWND hwnd, LPARAM lParam )
00234 {
00235   if ( GetWindowLong( hwnd, GWL_STYLE ) & WS_VISIBLE ) {
00236 
00237     DWORD pidwin;
00238 
00239     GetWindowThreadProcessId( hwnd, &pidwin );
00240     if ( pidwin == ( (EnumWindowsStruct *)lParam )->pid ) {
00241       ( (EnumWindowsStruct *)lParam )->windowId = hwnd;
00242       return FALSE; //krazy:exclude=captruefalse
00243     }
00244   }
00245   return TRUE; //krazy:exclude=captruefalse
00246 }
00247 
00248 void KPIMUtils::activateWindowForProcess( const QString &executableName )
00249 {
00250   QList<int> pids;
00251   KPIMUtils::getProcessesIdForName( executableName, pids );
00252   int myPid = getpid();
00253   int foundPid = 0;
00254   foreach ( int pid, pids ) {
00255     if ( myPid != pid ) {
00256       qDebug() << "activateWindowForProcess(): PID to activate:" << pid;
00257       foundPid = pid;
00258       break;
00259     }
00260   }
00261   if ( foundPid == 0 ) {
00262     return;
00263   }
00264   EnumWindowsStruct winStruct;
00265   winStruct.pid = foundPid;
00266   EnumWindows( EnumWindowsProc, (LPARAM)&winStruct );
00267   if ( winStruct.windowId == 0 ) {
00268     return;
00269   }
00270   SetForegroundWindow( winStruct.windowId );
00271 }
00272 
00273 #endif // Q_WS_WIN
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon May 14 2012 04:44:53 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kpimutils

Skip menu "kpimutils"
  • Main Page
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • Modules

kdepimlibs-4.8.3 API Reference

Skip menu "kdepimlibs-4.8.3 API Reference"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal