Leaked source code of windows server 2003
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

#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;
}