123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382 |
- #include "pch.h"
- extern CPerfShare gPerfShare;
- extern PSHARE_HEADER gpHeader;
- extern BOOL gbInitialized;
- BOOL HandleNonCases(LPWSTR lpRequestType,
- LPVOID *lppData,
- LPDWORD lpcbTotalBytes,
- LPDWORD lpcObjectTypes,
- PBOOL bMask)
- {
- DWORD dwQueryType, dwIndex;
- BOOL bFound;
- //
- // Make sure we initialized ok.
- //
- if ((NULL == gpHeader) || !gbInitialized)
- {
- *lpcbTotalBytes = (DWORD) 0;
- *lpcObjectTypes = (DWORD) 0;
- return(TRUE);
- }
- //
- // See if this is a non-NT data request.
- //
- dwQueryType = GetQueryType(lpRequestType);
- if (QUERY_FOREIGN == dwQueryType)
- {
- *lpcbTotalBytes = (DWORD) 0;
- *lpcObjectTypes = (DWORD) 0;
- return(TRUE);
- }
- //
- // Make sure we're requesting one of our objects.
- //
- ZeroMemory(bMask, sizeof(BOOL) * MAX_PERF_OBJECTS);
- bFound = FALSE;
- if (QUERY_ITEMS == dwQueryType)
- {
- for(dwIndex = 0; dwIndex < gdwNumberOfPerfObjects; dwIndex++)
- {
- if ((IsNumberInUnicodeList(gPerfObject[dwIndex].mPerfId,
- lpRequestType)) && (gPerfObject[dwIndex].mdwCounters > 0))
- {
- bMask[dwIndex] = TRUE;
- bFound = TRUE;
- }
- }
- if (!bFound)
- {
- *lpcbTotalBytes = (DWORD) 0;
- *lpcObjectTypes = (DWORD) 0;
- return(TRUE);
- }
- } else
- {
- for(dwIndex = 0; dwIndex < gdwNumberOfPerfObjects; dwIndex++)
- bMask[dwIndex] = TRUE;
- }
- return(FALSE);
- }
- DWORD ComputeSpaceNeeded(PBOOL bMask)
- {
- DWORD dwIndex, dwLoop, dwTemp, dwSpaceNeeded[MAX_PERF_OBJECTS];
- PSHARE_INSTANCE pInstance;
- //
- // Go through all the instances and see how much they're taking
- // up. We keep totals for each object type.
- //
- ZeroMemory(dwSpaceNeeded, sizeof(DWORD) * MAX_PERF_OBJECTS);
- pInstance = (PSHARE_INSTANCE) (gpHeader + 1);
- for(dwLoop = gpHeader->dwInstanceHeader; dwLoop != DWORD_NULL;
- dwLoop = pInstance[dwLoop].dwNextInList)
- {
- for(dwIndex = 0; dwIndex < gdwNumberOfPerfObjects; dwIndex++)
- {
- if (gPerfObject[dwIndex].mdwFirstCounter ==
- pInstance[dwLoop].dwFirstCounter)
- {
- if (0 < (dwTemp = wcslen(pInstance[dwLoop].wszInstanceName)))
- dwTemp = (dwTemp + 1) * sizeof(WCHAR);
- dwSpaceNeeded[dwIndex] += (sizeof(PERF_INSTANCE_DEFINITION) +
- DWORD_MULTIPLE(dwTemp) +
- sizeof(PERF_COUNTER_BLOCK) +
- pInstance[dwLoop].dwDataSize);
-
- break;
- }
- }
- }
- //
- // We have running totals for each object. Now tack on the object
- // and counter specific data.
- //
- for(dwIndex = dwTemp = 0; dwIndex < gdwNumberOfPerfObjects; dwIndex++)
- {
- // if (dwSpaceNeeded[dwIndex] > 0)
- if (bMask[dwIndex])
- {
- dwTemp += (dwSpaceNeeded[dwIndex] +
- sizeof(PERF_OBJECT_TYPE) +
- sizeof(PERF_COUNTER_DEFINITION) *
- gPerfObject[dwIndex].mdwCounters);
- if (!dwSpaceNeeded[dwIndex])
- {
- dwTemp += sizeof(PERF_INSTANCE_DEFINITION) +
- sizeof(PERF_COUNTER_BLOCK) +
- MAX_BYTES_FOR_INSTANCE_COUNTERS;
- }
- }
- // else
- // bMask[dwIndex] = FALSE;
- }
- return(dwTemp);
- }
- VOID BuildPerfmonObjectBase(PPERF_OBJECT_MAP pObject,
- PPERF_OBJECT_TYPE_MAP pMap)
- {
- pMap->mObject.DefinitionLength = sizeof(PERF_OBJECT_TYPE) +
- sizeof(PERF_COUNTER_DEFINITION) *
- pObject->mdwCounters;
- pMap->mObject.HeaderLength = sizeof(PERF_OBJECT_TYPE);
- pMap->mObject.ObjectNameTitleIndex = pObject->mPerfId;
- pMap->mObject.ObjectNameTitle = 0;
- pMap->mObject.ObjectHelpTitleIndex = pObject->mPerfId + 1;
- pMap->mObject.ObjectHelpTitle = 0;
- pMap->mObject.DetailLevel = PERF_DETAIL_NOVICE;
- pMap->mObject.NumCounters = pObject->mdwCounters;
- pMap->mObject.NumInstances = 0;
- pMap->mObject.CodePage = 0; // Unicode
- ZeroMemory(&(pMap->mObject.PerfTime), sizeof(LARGE_INTEGER));
- ZeroMemory(&(pMap->mObject.PerfFreq), sizeof(LARGE_INTEGER));
- }
- VOID BuildPerfmonObjectCounters(PPERF_OBJECT_MAP pObject,
- PPERF_OBJECT_TYPE_MAP pMap)
- {
- DWORD dwIndex, dwTotal;
- dwTotal = sizeof(PERF_COUNTER_BLOCK);
- for(dwIndex = 0; dwIndex < pObject->mdwCounters; dwIndex++)
- {
- pMap->mCounter[dwIndex].ByteLength = sizeof(PERF_COUNTER_DEFINITION);
- pMap->mCounter[dwIndex].CounterNameTitleIndex =
- pObject->mCounter[dwIndex].mPerfId;
- pMap->mCounter[dwIndex].CounterNameTitle = 0;
- pMap->mCounter[dwIndex].CounterHelpTitleIndex =
- pObject->mCounter[dwIndex].mPerfId + 1;
- pMap->mCounter[dwIndex].CounterHelpTitle = 0;
- pMap->mCounter[dwIndex].DefaultScale = 0; // 1
- pMap->mCounter[dwIndex].DetailLevel = PERF_DETAIL_NOVICE;
- pMap->mCounter[dwIndex].CounterType =
- pObject->mCounter[dwIndex].mdwCounterType;
- //
- // We need to determine the counter size.
- //
- switch(pObject->mCounter[dwIndex].mdwCounterType &
- PERF_SIZE_VARIABLE_LEN)
- {
- case PERF_SIZE_DWORD:
- pMap->mCounter[dwIndex].CounterSize = sizeof(DWORD);
- break;
- case PERF_SIZE_LARGE:
- pMap->mCounter[dwIndex].CounterSize = sizeof(LARGE_INTEGER);
- break;
- default:
- pMap->mCounter[dwIndex].CounterSize = 0;
- break;
- }
- pMap->mCounter[dwIndex].CounterOffset = dwTotal;
- dwTotal += pMap->mCounter[dwIndex].CounterSize;
- }
- }
- VOID BuildPerfmonObjectInstanceStructure(PERF_INSTANCE_DEFINITION *pInstance,
- PWCHAR wszInstanceName)
- {
- DWORD dwLength;
- if (0 < (dwLength = wcslen(wszInstanceName) * sizeof(WCHAR)))
- dwLength += sizeof(WCHAR);
- pInstance->ByteLength = sizeof(PERF_INSTANCE_DEFINITION) +
- DWORD_MULTIPLE(dwLength);
- pInstance->ParentObjectTitleIndex = 0;
- pInstance->ParentObjectInstance = 0;
- pInstance->UniqueID = (DWORD) PERF_NO_UNIQUE_ID;
- pInstance->NameOffset = sizeof(PERF_INSTANCE_DEFINITION);
- pInstance->NameLength = dwLength;
- if (dwLength > 0)
- wcscpy((PWCHAR) (pInstance + 1), wszInstanceName);
- }
- DWORD BuildPerfmonObjectInstances(PPERF_OBJECT_MAP pObject,
- PPERF_OBJECT_TYPE_MAP pMap,
- PBYTE lpData)
- {
- PERF_INSTANCE_DEFINITION *pInstance;
- PERF_COUNTER_BLOCK *pBlock;
- PSHARE_INSTANCE pList;
- DWORD dwLoop;
- //
- // Go through all the instances and copy our instances over.
- //
- pInstance = (PERF_INSTANCE_DEFINITION *) lpData;
- pList = (PSHARE_INSTANCE) (gpHeader + 1);
- for(dwLoop = gpHeader->dwInstanceHeader; dwLoop != DWORD_NULL;
- dwLoop = pList[dwLoop].dwNextInList)
- {
- if (pObject->mdwFirstCounter == pList[dwLoop].dwFirstCounter)
- {
- //
- // Add the instance structure.
- //
- BuildPerfmonObjectInstanceStructure(pInstance,
- pList[dwLoop].wszInstanceName);
- //
- // Add the counter block.
- //
- pBlock = (PERF_COUNTER_BLOCK *) ((PBYTE) pInstance +
- pInstance->ByteLength);
- pBlock->ByteLength = sizeof(PERF_COUNTER_BLOCK) +
- pList[dwLoop].dwDataSize;
- //
- // Add the data.
- //
- CopyMemory(pBlock + 1,
- pList[dwLoop].Data,
- pList[dwLoop].dwDataSize);
- pMap->mObject.NumInstances++;
- pInstance = (PERF_INSTANCE_DEFINITION *) ((PBYTE) pInstance +
- pInstance->ByteLength +
- pBlock->ByteLength);
- }
- }
- //
- // If there are no instances, we need to include an empty instance.
- //
- if (0 == pMap->mObject.NumInstances)
- {
- BuildPerfmonObjectInstanceStructure(pInstance, L"");
- pBlock = (PERF_COUNTER_BLOCK *) ((PBYTE) pInstance +
- pInstance->ByteLength);
- pBlock->ByteLength = sizeof(PERF_COUNTER_BLOCK) +
- MAX_BYTES_FOR_INSTANCE_COUNTERS;
- ZeroMemory(pBlock + 1, MAX_BYTES_FOR_INSTANCE_COUNTERS);
- pInstance = (PERF_INSTANCE_DEFINITION *) ((PBYTE) pInstance +
- pInstance->ByteLength +
- pBlock->ByteLength);
- }
- return((PBYTE) pInstance - lpData);
- }
- DWORD BuildPerfmonObject(PPERF_OBJECT_MAP pObject, LPBYTE lpData)
- {
- PPERF_OBJECT_TYPE_MAP pMap;
-
- //
- // Set up the PERF_OBJECT_TYPE.
- //
- pMap = (PPERF_OBJECT_TYPE_MAP) lpData;
- BuildPerfmonObjectBase(pObject, pMap);
- BuildPerfmonObjectCounters(pObject, pMap);
- lpData += pMap->mObject.DefinitionLength;
- //
- // Add the instances and their counters.
- //
- lpData += BuildPerfmonObjectInstances(pObject, pMap, lpData);
- pMap->mObject.TotalByteLength = (DWORD) (lpData - (PBYTE) pMap);
- return(pMap->mObject.TotalByteLength);
- }
- DWORD BuildPerfmonBuffer(PBOOL bMask, LPBYTE *lppData, DWORD dwSpaceNeeded)
- {
- DWORD dwIndex, dwCount;
- for(dwIndex = dwCount = 0; dwIndex < gdwNumberOfPerfObjects; dwIndex++)
- {
- if (bMask[dwIndex])
- {
- *lppData += BuildPerfmonObject(&gPerfObject[dwIndex], *lppData);
- dwCount++;
- }
- }
- return(dwCount);
- }
- extern "C" DWORD APIENTRY DwCollectData(LPWSTR lpRequestType,
- LPVOID *lppData,
- LPDWORD lpcbTotalBytes,
- LPDWORD lpcObjectTypes)
- {
- DWORD dwSpaceNeeded;
- BOOL bMask[MAX_PERF_OBJECTS];
- PBYTE pStart;
- if (HandleNonCases(lpRequestType,
- lppData,
- lpcbTotalBytes,
- lpcObjectTypes,
- bMask))
- {
- return(ERROR_SUCCESS);
- }
- //
- // We have one or more objects that we need to report.
- //
- //
- // Lock the shared memory.
- //
- if (!gPerfShare.Lock())
- {
- *lpcbTotalBytes = (DWORD) 0;
- *lpcObjectTypes = (DWORD) 0;
- return(ERROR_SUCCESS);
- }
- //
- // Figure out how much space we need.
- //
- dwSpaceNeeded = ComputeSpaceNeeded(bMask);
- if (*lpcbTotalBytes < dwSpaceNeeded)
- {
- gPerfShare.Unlock();
- *lpcbTotalBytes = (DWORD) 0;
- *lpcObjectTypes = (DWORD) 0;
- return(ERROR_MORE_DATA);
- }
- //
- // Fill the buffer with the objects and their data.
- //
- pStart = (PBYTE) *lppData;
- *lpcObjectTypes = BuildPerfmonBuffer(bMask,
- (LPBYTE *) lppData,
- dwSpaceNeeded);
- *lpcbTotalBytes = ((PBYTE) *lppData) - pStart;
- //
- // We've finished, let's return.
- //
- gPerfShare.Unlock();
- return(ERROR_SUCCESS);
- }
|