www.pudn.com > bxt.zip > PerfCounters.h
#include#include #include // for using bstr_t class #include #define TOTALBYTES 100*1024 #define BYTEINCREMENT 10*1024 template class CPerfCounters { public: CPerfCounters() { } ~CPerfCounters() { } T GetCounterValue(PERF_DATA_BLOCK **pPerfData, DWORD dwObjectIndex, DWORD dwCounterIndex, LPCTSTR pInstanceName = NULL) { QueryPerformanceData(pPerfData, dwObjectIndex, dwCounterIndex); PPERF_OBJECT_TYPE pPerfObj = NULL; T lnValue = {0}; // Get the first object type. pPerfObj = FirstObject( *pPerfData ); // Look for the given object index for( DWORD i=0; i < (*pPerfData)->NumObjectTypes; i++ ) { if (pPerfObj->ObjectNameTitleIndex == dwObjectIndex) { lnValue = GetCounterValue(pPerfObj, dwCounterIndex, pInstanceName); break; } pPerfObj = NextObject( pPerfObj ); } return lnValue; } T GetCounterValueForProcessID(PERF_DATA_BLOCK **pPerfData, DWORD dwObjectIndex, DWORD dwCounterIndex, DWORD dwProcessID) { QueryPerformanceData(pPerfData, dwObjectIndex, dwCounterIndex); PPERF_OBJECT_TYPE pPerfObj = NULL; T lnValue = {0}; // Get the first object type. pPerfObj = FirstObject( *pPerfData ); // Look for the given object index for( DWORD i=0; i < (*pPerfData)->NumObjectTypes; i++ ) { if (pPerfObj->ObjectNameTitleIndex == dwObjectIndex) { lnValue = GetCounterValueForProcessID(pPerfObj, dwCounterIndex, dwProcessID); break; } pPerfObj = NextObject( pPerfObj ); } return lnValue; } protected: class CBuffer { public: CBuffer(UINT Size) { m_Size = Size; m_pBuffer = (LPBYTE) malloc( Size*sizeof(BYTE) ); } ~CBuffer() { free(m_pBuffer); } void *Realloc(UINT Size) { m_Size = Size; m_pBuffer = (LPBYTE) realloc( m_pBuffer, Size ); return m_pBuffer; } void Reset() { memset(m_pBuffer,NULL,m_Size); } operator LPBYTE () { return m_pBuffer; } UINT GetSize() { return m_Size; } public: LPBYTE m_pBuffer; private: UINT m_Size; }; // // The performance data is accessed through the registry key // HKEY_PEFORMANCE_DATA. // However, although we use the registry to collect performance data, // the data is not stored in the registry database. // Instead, calling the registry functions with the HKEY_PEFORMANCE_DATA key // causes the system to collect the data from the appropriate system // object managers. // // QueryPerformanceData allocates memory block for getting the // performance data. // // void QueryPerformanceData(PERF_DATA_BLOCK **pPerfData, DWORD dwObjectIndex, DWORD /*dwCounterIndex */) { // // Since i want to use the same allocated area for each query, // i declare CBuffer as static. // The allocated is changed only when RegQueryValueEx return ERROR_MORE_DATA // static CBuffer Buffer(TOTALBYTES); DWORD BufferSize = Buffer.GetSize(); LONG lRes; char keyName[32]; sprintf(keyName,"%d",dwObjectIndex); Buffer.Reset(); while( (lRes = RegQueryValueEx( HKEY_PERFORMANCE_DATA, keyName, NULL, NULL, Buffer, &BufferSize )) == ERROR_MORE_DATA ) { // Get a buffer that is big enough. BufferSize += BYTEINCREMENT; Buffer.Realloc(BufferSize); } *pPerfData = (PPERF_DATA_BLOCK) Buffer.m_pBuffer; } // // GetCounterValue gets performance object structure // and returns the value of given counter index . // This functions iterates through the counters of the input object // structure and looks for the given counter index. // // For objects that have instances, this function returns the counter value // of the instance pInstanceName. // T GetCounterValue(PPERF_OBJECT_TYPE pPerfObj, DWORD dwCounterIndex, LPCTSTR pInstanceName) { PPERF_COUNTER_DEFINITION pPerfCntr = NULL; PPERF_INSTANCE_DEFINITION pPerfInst = NULL; PPERF_COUNTER_BLOCK pCounterBlock = NULL; // Get the first counter. pPerfCntr = FirstCounter( pPerfObj ); for( DWORD j=0; j < pPerfObj->NumCounters; j++ ) { if (pPerfCntr->CounterNameTitleIndex == dwCounterIndex) break; // Get the next counter. pPerfCntr = NextCounter( pPerfCntr ); } if( pPerfObj->NumInstances == PERF_NO_INSTANCES ) { pCounterBlock = (PPERF_COUNTER_BLOCK) ((LPBYTE) pPerfObj + pPerfObj->DefinitionLength); } else { pPerfInst = FirstInstance( pPerfObj ); // Look for instance pInstanceName _bstr_t bstrInstance; _bstr_t bstrInputInstance = pInstanceName; for( int k=0; k < pPerfObj->NumInstances; k++ ) { bstrInstance = (wchar_t *)((PBYTE)pPerfInst + pPerfInst->NameOffset); if (!stricmp((LPCTSTR)bstrInstance, (LPCTSTR)bstrInputInstance)) { pCounterBlock = (PPERF_COUNTER_BLOCK) ((LPBYTE) pPerfInst + pPerfInst->ByteLength); break; } // Get the next instance. pPerfInst = NextInstance( pPerfInst ); } } if (pCounterBlock) { T *lnValue = NULL; lnValue = (T*)((LPBYTE) pCounterBlock + pPerfCntr->CounterOffset); return *lnValue; } return -1; } T GetCounterValueForProcessID(PPERF_OBJECT_TYPE pPerfObj, DWORD dwCounterIndex, DWORD dwProcessID) { int PROC_ID_COUNTER = 784; BOOL bProcessIDExist = FALSE; PPERF_COUNTER_DEFINITION pPerfCntr = NULL; PPERF_COUNTER_DEFINITION pTheRequestedPerfCntr = NULL; PPERF_COUNTER_DEFINITION pProcIDPerfCntr = NULL; PPERF_INSTANCE_DEFINITION pPerfInst = NULL; PPERF_COUNTER_BLOCK pCounterBlock = NULL; // Get the first counter. pPerfCntr = FirstCounter( pPerfObj ); for( DWORD j=0; j < pPerfObj->NumCounters; j++ ) { if (pPerfCntr->CounterNameTitleIndex == PROC_ID_COUNTER) { pProcIDPerfCntr = pPerfCntr; if (pTheRequestedPerfCntr) break; } if (pPerfCntr->CounterNameTitleIndex == dwCounterIndex) { pTheRequestedPerfCntr = pPerfCntr; if (pProcIDPerfCntr) break; } // Get the next counter. pPerfCntr = NextCounter( pPerfCntr ); } if( pPerfObj->NumInstances == PERF_NO_INSTANCES ) { pCounterBlock = (PPERF_COUNTER_BLOCK) ((LPBYTE) pPerfObj + pPerfObj->DefinitionLength); } else { pPerfInst = FirstInstance( pPerfObj ); for( int k=0; k < pPerfObj->NumInstances; k++ ) { pCounterBlock = (PPERF_COUNTER_BLOCK) ((LPBYTE) pPerfInst + pPerfInst->ByteLength); if (pCounterBlock) { int processID = 0; processID = *(T*)((LPBYTE) pCounterBlock + pProcIDPerfCntr->CounterOffset); if (processID == dwProcessID) { bProcessIDExist = TRUE; break; } } // Get the next instance. pPerfInst = NextInstance( pPerfInst ); } } if (bProcessIDExist && pCounterBlock) { T *lnValue = NULL; lnValue = (T*)((LPBYTE) pCounterBlock + pTheRequestedPerfCntr->CounterOffset); return *lnValue; } return -1; } /***************************************************************** * * * Functions used to navigate through the performance data. * * * *****************************************************************/ PPERF_OBJECT_TYPE FirstObject( PPERF_DATA_BLOCK PerfData ) { return( (PPERF_OBJECT_TYPE)((PBYTE)PerfData + PerfData->HeaderLength) ); } PPERF_OBJECT_TYPE NextObject( PPERF_OBJECT_TYPE PerfObj ) { return( (PPERF_OBJECT_TYPE)((PBYTE)PerfObj + PerfObj->TotalByteLength) ); } PPERF_COUNTER_DEFINITION FirstCounter( PPERF_OBJECT_TYPE PerfObj ) { return( (PPERF_COUNTER_DEFINITION) ((PBYTE)PerfObj + PerfObj->HeaderLength) ); } PPERF_COUNTER_DEFINITION NextCounter( PPERF_COUNTER_DEFINITION PerfCntr ) { return( (PPERF_COUNTER_DEFINITION)((PBYTE)PerfCntr + PerfCntr->ByteLength) ); } PPERF_INSTANCE_DEFINITION FirstInstance( PPERF_OBJECT_TYPE PerfObj ) { return( (PPERF_INSTANCE_DEFINITION)((PBYTE)PerfObj + PerfObj->DefinitionLength) ); } PPERF_INSTANCE_DEFINITION NextInstance( PPERF_INSTANCE_DEFINITION PerfInst ) { PPERF_COUNTER_BLOCK PerfCntrBlk; PerfCntrBlk = (PPERF_COUNTER_BLOCK)((PBYTE)PerfInst + PerfInst->ByteLength); return( (PPERF_INSTANCE_DEFINITION)((PBYTE)PerfCntrBlk + PerfCntrBlk->ByteLength) ); } };