• Skip to content
  • Skip to link menu
KDE 4.4 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • Sitemap
  • 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 #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     // get a buffer that is big enough
00112     bufSize += GETPID_BYTEINCREMENT;
00113     perfData = (PPERF_DATA_BLOCK) realloc( perfData, bufSize );
00114   }
00115 
00116   // Get the first object type.
00117   perfObject = FirstObject( perfData );
00118   if ( !perfObject ) {
00119     return;
00120   }
00121 
00122   // Process all objects.
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     // retrieve the instances
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         // retrieve the counters
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 //      kDebug() << "Process ID is " << pid;
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; //krazy:exclude=captruefalse
00212     }
00213   }
00214   return TRUE; //krazy:exclude=captruefalse
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

kpimutils

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

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kblog
  • kcal
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.6.2-20100208
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal