You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
449 lines
16 KiB
449 lines
16 KiB
|
|
#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;
|
|
}
|
|
|