|
|
#define _PassportExport_
#include "PassportExport.h"
#include "PerfSharedMemory.h"
#include "PerfUtils.h"
#include "PassportPerf.h"
#include "PassportPerfInterface.h"
#include <crtdbg.h>
//-------------------------------------------------------------
//
// PerfSharedMemory
//
//-------------------------------------------------------------
PerfSharedMemory::PerfSharedMemory() : PassportSharedMemory() { m_dwNumCounters = 0; }
//-------------------------------------------------------------
//
// PerfSharedMemory
//
//-------------------------------------------------------------
PerfSharedMemory::~PerfSharedMemory() {
}
//-------------------------------------------------------------
//
// initialize
//
//-------------------------------------------------------------
BOOL PerfSharedMemory::initialize( const DWORD &dwNumCounters, const DWORD &dwFirstCounter, const DWORD &dwFirstHelp) { if ( dwNumCounters <= 0 || dwNumCounters >= PassportPerfInterface::MAX_COUNTERS) return FALSE;
m_dwNumCounters = dwNumCounters;
// 2. initialize the PERF_OBJECT_TYPE
m_Object.NumInstances = PassportPerfInterface::MAX_INSTANCES; m_Object.TotalByteLength = 0; m_Object.DefinitionLength = sizeof(PERF_OBJECT_TYPE) + (dwNumCounters * sizeof(PERF_COUNTER_DEFINITION)); m_Object.HeaderLength = sizeof(PERF_OBJECT_TYPE); m_Object.ObjectNameTitleIndex = dwFirstCounter; m_Object.ObjectNameTitle = 0; m_Object.ObjectHelpTitleIndex = dwFirstHelp; m_Object.ObjectHelpTitle = 0; m_Object.DetailLevel = PERF_DETAIL_NOVICE; m_Object.NumCounters = dwNumCounters; m_Object.DefaultCounter = 0; m_Object.CodePage = 0;
// 3. initialize each counter
for (DWORD i = 0; i < dwNumCounters; i++) { m_Counter[i].ByteLength = sizeof(PERF_COUNTER_DEFINITION); m_Counter[i].CounterNameTitleIndex = dwFirstCounter + ((i+1) * 2); m_Counter[i].CounterNameTitle = 0; m_Counter[i].CounterHelpTitleIndex = dwFirstHelp + ((i+1) * 2); m_Counter[i].CounterHelpTitle = 0; m_Counter[i].DefaultScale = 0; m_Counter[i].DetailLevel = PERF_DETAIL_NOVICE; m_Counter[i].CounterType = PERF_COUNTER_RAWCOUNT; // PERF_COUNTER_COUNTER;
m_Counter[i].CounterSize = sizeof(DWORD); m_Counter[i].CounterOffset = sizeof(PERF_COUNTER_BLOCK) + (i * sizeof(DWORD)); }
return TRUE; }
//-------------------------------------------------------------
//
// setDefaultCounterType
//
//-------------------------------------------------------------
VOID PerfSharedMemory::setDefaultCounterType ( const DWORD dwIndex, const DWORD dwType ) { _ASSERT( (dwIndex >= 0) && (dwIndex < PassportPerfInterface::MAX_COUNTERS));
// indexes start at one in SHM, but in this object they start at 0
DWORD dwRealIndex = ((dwIndex == 0) ? 0 : (DWORD)(dwIndex/2)-1); m_Counter[dwRealIndex].CounterType = dwType; return; }
//-------------------------------------------------------------
//
// checkQuery
//
//-------------------------------------------------------------
BOOL PerfSharedMemory::checkQuery ( const LPWSTR lpValueName ) { DWORD dwQueryType = 0;
dwQueryType = GetQueryType (lpValueName); if (dwQueryType == QUERY_FOREIGN) { // this routine does not service requests for data from
// Non-NT computers
return FALSE; }
if (dwQueryType == QUERY_ITEMS) { if ( !(IsNumberInUnicodeList (m_Object.ObjectNameTitleIndex, lpValueName))) { // request received for data object not provided by this routine
return FALSE; } } return TRUE; }
//-------------------------------------------------------------
//
// spaceNeeded
//
//-------------------------------------------------------------
ULONG PerfSharedMemory::spaceNeeded ( void ) { DWORD dwTotalInstanceLength = 0; m_Object.NumInstances = 0;
// --------------------------------
// count the instances
if (m_pbShMem != NULL) { BYTE* pShm = (BYTE *)m_pbShMem; if (pShm != NULL) { pShm += PassportPerfInterface::MAX_COUNTERS * sizeof(DWORD); if (!m_bUseMutex || WaitForSingleObject(m_hMutex,INFINITE) == WAIT_OBJECT_0) { for (DWORD i = 0; i < PassportPerfInterface::MAX_INSTANCES; i++) { INSTANCE_DATA * pInst = (INSTANCE_DATA *)pShm; _ASSERT(pInst); if (pInst->active) { m_Object.NumInstances++; dwTotalInstanceLength += (strlen(pInst->szInstanceName)+1) * sizeof(WCHAR); } pShm += sizeof(INSTANCE_DATA) + (PassportPerfInterface::MAX_COUNTERS * sizeof(DWORD)); } if (m_bUseMutex) ReleaseMutex(m_hMutex); } else { //
// The return value is ULONG not FALSE.
// Is 0 correct here? At least same value as the old FALSE.
//
ReleaseMutex(m_hMutex); return 0; } } } // --------------------------------
// calculate the ByteLength in the Object structure
if (m_Object.NumInstances == 0) { m_Object.NumInstances = PERF_NO_INSTANCES; m_Object.TotalByteLength = sizeof(PERF_OBJECT_TYPE) + (m_dwNumCounters * sizeof(PERF_COUNTER_DEFINITION)) + sizeof(PERF_COUNTER_BLOCK) + (m_dwNumCounters * sizeof(DWORD)); } else { m_Object.TotalByteLength = sizeof(PERF_OBJECT_TYPE) + (m_dwNumCounters * sizeof(PERF_COUNTER_DEFINITION)) + (m_Object.NumInstances * (sizeof(PERF_INSTANCE_DEFINITION) + // note: INSTANCENAME is next in the SHM
sizeof(PERF_COUNTER_BLOCK) + (m_dwNumCounters * sizeof(DWORD)) )) + dwTotalInstanceLength;
}
// align on 8 bytes boundary ...
if (m_Object.TotalByteLength & 7) { m_Object.TotalByteLength += 8; m_Object.TotalByteLength &= ~7; }
return m_Object.TotalByteLength; }
//-------------------------------------------------------------
//
// writeData
//
//-------------------------------------------------------------
BOOL PerfSharedMemory::writeData ( LPVOID *lppData, LPDWORD lpcbTotalBytes ) { BYTE* pb = NULL; DWORD dwBytes = 0; // --------------------------------
// 1. find the active number of instances
// (may have been done already)
if (m_Object.TotalByteLength == 0) spaceNeeded(); pb = (BYTE*) *lppData; // --------------------------------
// 2. copy the Object structure
CopyMemory( pb, &m_Object, sizeof(PERF_OBJECT_TYPE) ); pb += sizeof(PERF_OBJECT_TYPE); dwBytes += sizeof(PERF_OBJECT_TYPE); if (!m_bUseMutex || WaitForSingleObject(m_hMutex,INFINITE) == WAIT_OBJECT_0) { // --------------------------------
// 3. read the counter types from SHM
if ( m_pbShMem != NULL ) { DWORD dwPerfType = 0; BYTE * pShm = (BYTE*)m_pbShMem; _ASSERT(pShm); for (DWORD j = 0; j < m_dwNumCounters; j++) { PDWORD pdwCounter = ((PDWORD) pShm) + j; _ASSERT(pdwCounter); // only reset the counter if it has a defined value
// or if it has changed
if (*pdwCounter != PERF_TYPE_ZERO && m_Counter[j].CounterType != *pdwCounter) m_Counter[j].CounterType = (*pdwCounter); } } // --------------------------------
// 4. copy the counters
for (DWORD i = 0; i < m_dwNumCounters; i++) { CopyMemory( pb, &(m_Counter[i]),sizeof(PERF_COUNTER_DEFINITION)); pb += sizeof(PERF_COUNTER_DEFINITION); dwBytes += sizeof(PERF_COUNTER_DEFINITION); } // --------------------------------
// 5. if SHM if null, then just dump out all
// zeroes for the counters
if ( m_pbShMem == NULL ) { // copy the number of counters in the counter block
PERF_COUNTER_BLOCK counterBlock; counterBlock.ByteLength = sizeof(PERF_COUNTER_BLOCK) + (m_dwNumCounters * sizeof(DWORD)); CopyMemory( pb, &counterBlock, sizeof(PERF_COUNTER_BLOCK)); pb += sizeof(PERF_COUNTER_BLOCK); dwBytes += sizeof(PERF_COUNTER_BLOCK); for (DWORD j = 1; j <= m_dwNumCounters; j++) { DWORD val = 0; CopyMemory( pb, &val, sizeof(DWORD)); pb += sizeof(DWORD); dwBytes += sizeof(DWORD); } } // --------------------------------
// 6. if object has no instances, then read just the first
// section of data,
else if (m_Object.NumInstances == PERF_NO_INSTANCES) { _ASSERT(m_pbShMem); BYTE * pShm = (BYTE*)m_pbShMem; _ASSERT(pShm); pShm += (PassportPerfInterface::MAX_COUNTERS * sizeof(DWORD)); pShm += sizeof(INSTANCE_DATA); _ASSERT(pShm); // copy the number of counters in the counter block
PERF_COUNTER_BLOCK counterBlock; counterBlock.ByteLength = sizeof(PERF_COUNTER_BLOCK) + (m_dwNumCounters * sizeof(DWORD)); CopyMemory( pb, &counterBlock, sizeof(PERF_COUNTER_BLOCK)); pb += sizeof(PERF_COUNTER_BLOCK); dwBytes += sizeof(PERF_COUNTER_BLOCK); PPERF_COUNTER_BLOCK pCounterBlock = (PPERF_COUNTER_BLOCK)pShm; _ASSERT(pCounterBlock); for (DWORD j = 1; j <= m_dwNumCounters; j++) { PDWORD pdwCounter = ((PDWORD) pCounterBlock) + j; _ASSERT(pdwCounter); DWORD val = *pdwCounter; CopyMemory( pb, &val, sizeof(DWORD)); pb += sizeof(DWORD); dwBytes += sizeof(DWORD); } } // --------------------------------
// 7. get and write all instance data
else { _ASSERT(m_pbShMem); BYTE * pShm = (BYTE*)m_pbShMem; _ASSERT(pShm); pShm += (PassportPerfInterface::MAX_COUNTERS * sizeof(DWORD)); DWORD dwInstanceIndex = 0; for (i = 0; i < (DWORD)m_Object.NumInstances; i++) { PERF_INSTANCE_DEFINITION instDef; PERF_COUNTER_BLOCK perfCounterBlock; BOOL gotInstance = FALSE; INSTANCE_DATA * pInst = NULL; WCHAR wszName[MAX_PATH]; // 7a. get the instance name from the next active instance
// in SHM
for (DWORD i = dwInstanceIndex; i < PassportPerfInterface::MAX_INSTANCES && !gotInstance; i++) { pInst = (INSTANCE_DATA *)pShm; _ASSERT(pInst); pShm += sizeof(INSTANCE_DATA); if (pInst->active) { dwInstanceIndex = i + 1; gotInstance = TRUE; } else { pShm += (PassportPerfInterface::MAX_COUNTERS * sizeof(DWORD)); } } if (!gotInstance || pInst == NULL) return FALSE; // 7b. create the instace Definition and
// copy it (also get the instance name)
instDef.ParentObjectTitleIndex = 0;//m_Object.ObjectNameTitleIndex + 2*i;
instDef.ParentObjectInstance = 0; // ????
instDef.UniqueID = PERF_NO_UNIQUE_ID; instDef.NameOffset = sizeof(PERF_INSTANCE_DEFINITION); // Build UNICODE instance name
if (!MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, pInst->szInstanceName, strlen(pInst->szInstanceName)+1, wszName, MAX_PATH)) { wszName[0] = 0; } instDef.NameLength = (lstrlenW( wszName ) + 1) * sizeof(WCHAR); instDef.ByteLength = sizeof(PERF_INSTANCE_DEFINITION) + instDef.NameLength; CopyMemory( pb, &instDef, sizeof(PERF_INSTANCE_DEFINITION) ); pb += sizeof(PERF_INSTANCE_DEFINITION); dwBytes += sizeof(PERF_INSTANCE_DEFINITION); // 7c. copy the instance name
CopyMemory(pb, wszName, instDef.NameLength); pb += instDef.NameLength; dwBytes += instDef.NameLength; // 7d. copy the counterblock
perfCounterBlock.ByteLength = sizeof(PERF_COUNTER_BLOCK) + (m_dwNumCounters * sizeof(DWORD)); CopyMemory( pb, &perfCounterBlock, sizeof(PERF_COUNTER_BLOCK)); pb += sizeof(PERF_COUNTER_BLOCK); dwBytes += sizeof(PERF_COUNTER_BLOCK); // 7e. copy the DWORDs themselves
PPERF_COUNTER_BLOCK pCounterBlock = (PPERF_COUNTER_BLOCK)pShm; DWORD val = 0; for (DWORD j = 1; j <= m_dwNumCounters; j++) { if (m_pbShMem != NULL) { PDWORD pdwCounter = ((PDWORD) pCounterBlock) + j; val = *pdwCounter; } CopyMemory( pb, &val, sizeof(DWORD)); pb += sizeof(DWORD); dwBytes += sizeof(DWORD); } pShm += (PassportPerfInterface::MAX_COUNTERS * sizeof(DWORD)); } // end for ( i = ...)
} // end else (instances exist)
if (m_bUseMutex) ReleaseMutex(m_hMutex); } else { ReleaseMutex(m_hMutex); return FALSE; } //
// 8 byte alignment
while (dwBytes%8 != 0) { (dwBytes)++; pb++; }
*lppData = (void*) pb;//++pb;
*lpcbTotalBytes = dwBytes; return TRUE; }
|