821 lines
23 KiB
C
821 lines
23 KiB
C
/*++
|
|
|
|
Copyright (C) 1995-1999 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
calcfuns.c
|
|
|
|
Abstract:
|
|
|
|
Counter calculation functions
|
|
WMICOOKER.DLL depends on this file also. \nt\admin\wmi\wbem\winmgmt\wmicooker
|
|
|
|
--*/
|
|
|
|
#include <windows.h>
|
|
#include <math.h>
|
|
#include "strsafe.h"
|
|
#include <pdh.h>
|
|
#include "pdhitype.h"
|
|
#include "pdhidef.h"
|
|
#include "pdhicalc.h"
|
|
#include "pdhmsg.h"
|
|
|
|
BOOL
|
|
AssignCalcFunction(
|
|
DWORD dwCounterType,
|
|
LPCOUNTERCALC * pCalcFunc,
|
|
LPCOUNTERSTAT * pStatFunc
|
|
)
|
|
{
|
|
BOOL bReturn = TRUE;
|
|
|
|
// reset the last error value
|
|
SetLastError(ERROR_SUCCESS);
|
|
|
|
if (pCalcFunc == NULL || pStatFunc == NULL) {
|
|
SetLastError(PDH_INVALID_ARGUMENT);
|
|
bReturn = FALSE;
|
|
}
|
|
else {
|
|
__try {
|
|
* pCalcFunc = PdhiCalcNoData;
|
|
* pStatFunc = PdhiComputeNoDataStats;
|
|
}
|
|
except (EXCEPTION_EXECUTE_HANDLER) {
|
|
bReturn = FALSE;
|
|
}
|
|
}
|
|
if (bReturn) {
|
|
switch (dwCounterType) {
|
|
case PERF_DOUBLE_RAW:
|
|
* pCalcFunc = PdhiCalcDouble;
|
|
* pStatFunc = PdhiComputeRawCountStats;
|
|
break;
|
|
|
|
case PERF_AVERAGE_TIMER:
|
|
* pCalcFunc = PdhiCalcAverage;
|
|
* pStatFunc = PdhiComputeFirstLastStats;
|
|
break;
|
|
|
|
case PERF_ELAPSED_TIME:
|
|
* pCalcFunc = PdhiCalcElapsedTime;
|
|
* pStatFunc = PdhiComputeRawCountStats;
|
|
break;
|
|
|
|
case PERF_RAW_FRACTION:
|
|
case PERF_LARGE_RAW_FRACTION:
|
|
* pCalcFunc = PdhiCalcRawFraction;
|
|
* pStatFunc = PdhiComputeRawCountStats;
|
|
break;
|
|
|
|
case PERF_COUNTER_COUNTER:
|
|
case PERF_COUNTER_BULK_COUNT:
|
|
case PERF_SAMPLE_COUNTER:
|
|
* pCalcFunc = PdhiCalcCounter;
|
|
* pStatFunc = PdhiComputeFirstLastStats;
|
|
break;
|
|
|
|
case PERF_AVERAGE_BULK:
|
|
case PERF_COUNTER_TIMER:
|
|
case PERF_100NSEC_TIMER:
|
|
case PERF_OBJ_TIME_TIMER:
|
|
case PERF_COUNTER_QUEUELEN_TYPE:
|
|
case PERF_COUNTER_LARGE_QUEUELEN_TYPE:
|
|
case PERF_COUNTER_100NS_QUEUELEN_TYPE:
|
|
case PERF_COUNTER_OBJ_TIME_QUEUELEN_TYPE:
|
|
case PERF_SAMPLE_FRACTION:
|
|
case PERF_COUNTER_MULTI_TIMER:
|
|
case PERF_100NSEC_MULTI_TIMER:
|
|
case PERF_PRECISION_SYSTEM_TIMER:
|
|
case PERF_PRECISION_100NS_TIMER:
|
|
case PERF_PRECISION_OBJECT_TIMER:
|
|
* pCalcFunc = PdhiCalcTimer;
|
|
* pStatFunc = PdhiComputeFirstLastStats;
|
|
break;
|
|
|
|
case PERF_COUNTER_TIMER_INV:
|
|
case PERF_100NSEC_TIMER_INV:
|
|
case PERF_COUNTER_MULTI_TIMER_INV:
|
|
case PERF_100NSEC_MULTI_TIMER_INV:
|
|
* pCalcFunc = PdhiCalcInverseTimer;
|
|
* pStatFunc = PdhiComputeFirstLastStats;
|
|
break;
|
|
|
|
case PERF_COUNTER_RAWCOUNT:
|
|
case PERF_COUNTER_LARGE_RAWCOUNT:
|
|
case PERF_COUNTER_RAWCOUNT_HEX:
|
|
case PERF_COUNTER_LARGE_RAWCOUNT_HEX:
|
|
* pCalcFunc = PdhiCalcRawCounter;
|
|
* pStatFunc = PdhiComputeRawCountStats;
|
|
break;
|
|
|
|
case PERF_COUNTER_DELTA:
|
|
case PERF_COUNTER_LARGE_DELTA:
|
|
* pCalcFunc = PdhiCalcDelta;
|
|
* pStatFunc = PdhiComputeRawCountStats;
|
|
break;
|
|
|
|
case PERF_COUNTER_TEXT:
|
|
case PERF_SAMPLE_BASE:
|
|
case PERF_AVERAGE_BASE:
|
|
case PERF_COUNTER_MULTI_BASE:
|
|
case PERF_RAW_BASE:
|
|
//case PERF_LARGE_RAW_BASE:
|
|
case PERF_COUNTER_HISTOGRAM_TYPE:
|
|
case PERF_COUNTER_NODATA:
|
|
case PERF_PRECISION_TIMESTAMP:
|
|
* pCalcFunc = PdhiCalcNoData;
|
|
* pStatFunc = PdhiComputeNoDataStats;
|
|
break;
|
|
|
|
default:
|
|
// an unrecognized counter type. Define the function, but
|
|
// return false.
|
|
* pCalcFunc = PdhiCalcNoData;
|
|
* pStatFunc = PdhiComputeNoDataStats;
|
|
SetLastError(PDH_FUNCTION_NOT_FOUND);
|
|
bReturn = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
return bReturn;
|
|
}
|
|
|
|
BOOL
|
|
PdhiCounterNeedLastValue(
|
|
DWORD dwCounterType
|
|
)
|
|
{
|
|
BOOL bReturn = TRUE;
|
|
switch (dwCounterType) {
|
|
case PERF_DOUBLE_RAW:
|
|
case PERF_ELAPSED_TIME:
|
|
case PERF_RAW_FRACTION:
|
|
case PERF_LARGE_RAW_FRACTION:
|
|
case PERF_COUNTER_RAWCOUNT:
|
|
case PERF_COUNTER_LARGE_RAWCOUNT:
|
|
case PERF_COUNTER_RAWCOUNT_HEX:
|
|
case PERF_COUNTER_LARGE_RAWCOUNT_HEX:
|
|
case PERF_COUNTER_TEXT:
|
|
case PERF_SAMPLE_BASE:
|
|
case PERF_AVERAGE_BASE:
|
|
case PERF_COUNTER_MULTI_BASE:
|
|
case PERF_RAW_BASE:
|
|
//case PERF_LARGE_RAW_BASE:
|
|
case PERF_COUNTER_HISTOGRAM_TYPE:
|
|
case PERF_COUNTER_NODATA:
|
|
case PERF_PRECISION_TIMESTAMP:
|
|
bReturn = FALSE;
|
|
break;
|
|
|
|
case PERF_AVERAGE_TIMER:
|
|
case PERF_COUNTER_COUNTER:
|
|
case PERF_COUNTER_BULK_COUNT:
|
|
case PERF_SAMPLE_COUNTER:
|
|
case PERF_AVERAGE_BULK:
|
|
case PERF_COUNTER_TIMER:
|
|
case PERF_100NSEC_TIMER:
|
|
case PERF_OBJ_TIME_TIMER:
|
|
case PERF_COUNTER_QUEUELEN_TYPE:
|
|
case PERF_COUNTER_LARGE_QUEUELEN_TYPE:
|
|
case PERF_COUNTER_100NS_QUEUELEN_TYPE:
|
|
case PERF_COUNTER_OBJ_TIME_QUEUELEN_TYPE:
|
|
case PERF_SAMPLE_FRACTION:
|
|
case PERF_COUNTER_MULTI_TIMER:
|
|
case PERF_100NSEC_MULTI_TIMER:
|
|
case PERF_PRECISION_SYSTEM_TIMER:
|
|
case PERF_PRECISION_100NS_TIMER:
|
|
case PERF_PRECISION_OBJECT_TIMER:
|
|
case PERF_COUNTER_TIMER_INV:
|
|
case PERF_100NSEC_TIMER_INV:
|
|
case PERF_COUNTER_MULTI_TIMER_INV:
|
|
case PERF_100NSEC_MULTI_TIMER_INV:
|
|
case PERF_COUNTER_DELTA:
|
|
case PERF_COUNTER_LARGE_DELTA:
|
|
|
|
default:
|
|
bReturn = TRUE;
|
|
break;
|
|
}
|
|
|
|
return bReturn;
|
|
}
|
|
|
|
double
|
|
APIENTRY
|
|
PdhiCalcDouble(
|
|
PPDH_RAW_COUNTER pThisValue,
|
|
PPDH_RAW_COUNTER pLastValue,
|
|
LONGLONG * pllTimeBase,
|
|
LPDWORD pdwStatus
|
|
)
|
|
{
|
|
double dReturn;
|
|
DWORD dwStatus;
|
|
|
|
UNREFERENCED_PARAMETER(pLastValue);
|
|
UNREFERENCED_PARAMETER(pllTimeBase);
|
|
|
|
dReturn = * (DOUBLE *) & pThisValue->FirstValue;
|
|
|
|
if (dReturn < 0) {
|
|
dReturn = 0.0f;
|
|
dwStatus = PDH_CSTATUS_INVALID_DATA;
|
|
}
|
|
else {
|
|
dwStatus = pThisValue->CStatus;
|
|
}
|
|
if (pdwStatus != NULL) {
|
|
* pdwStatus = dwStatus;
|
|
}
|
|
return dReturn;
|
|
}
|
|
|
|
double
|
|
APIENTRY
|
|
PdhiCalcAverage(
|
|
PPDH_RAW_COUNTER pThisValue,
|
|
PPDH_RAW_COUNTER pLastValue,
|
|
LONGLONG * pllTimeBase,
|
|
LPDWORD pdwStatus
|
|
)
|
|
{
|
|
LONGLONG llNumDiff;
|
|
LONGLONG llDenDiff = 0;
|
|
double dNum;
|
|
double dDen;
|
|
double dReturn = 0.0f;
|
|
DWORD dwStatus = PDH_CSTATUS_VALID_DATA;
|
|
|
|
// test access to the required second parameter (lastValue)
|
|
__try {
|
|
if (pLastValue != NULL) {
|
|
if (IsSuccessSeverity(pLastValue->CStatus)) {
|
|
llDenDiff = pThisValue->SecondValue - pLastValue->SecondValue;
|
|
}
|
|
else {
|
|
dwStatus = pLastValue->CStatus;
|
|
}
|
|
}
|
|
else {
|
|
dwStatus = PDH_CSTATUS_INVALID_DATA;
|
|
}
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER) {
|
|
dwStatus = PDH_INVALID_ARGUMENT;
|
|
}
|
|
|
|
if (dwStatus == PDH_CSTATUS_VALID_DATA) {
|
|
if ((llDenDiff > 0) && (* pllTimeBase > 0)) {
|
|
llNumDiff = pThisValue->FirstValue - pLastValue->FirstValue;
|
|
if (llNumDiff < 0) {
|
|
llNumDiff += MAXDWORD;
|
|
}
|
|
if (llNumDiff > 0) {
|
|
dNum = (double) llNumDiff;
|
|
dNum /= (double) * pllTimeBase;
|
|
dDen = (double) llDenDiff;
|
|
dReturn = (dNum / dDen);
|
|
}
|
|
else if (llNumDiff < 0) {
|
|
dwStatus = PDH_CALC_NEGATIVE_VALUE;
|
|
}
|
|
}
|
|
else {
|
|
if (llDenDiff < 0) {
|
|
dwStatus = PDH_CALC_NEGATIVE_DENOMINATOR;
|
|
}
|
|
else if (* pllTimeBase < 0) {
|
|
dwStatus = PDH_CALC_NEGATIVE_TIMEBASE;
|
|
}
|
|
}
|
|
}
|
|
if (pdwStatus != NULL) {
|
|
* pdwStatus = dwStatus;
|
|
}
|
|
return dReturn;
|
|
}
|
|
|
|
double
|
|
APIENTRY
|
|
PdhiCalcElapsedTime(
|
|
PPDH_RAW_COUNTER pThisValue,
|
|
PPDH_RAW_COUNTER pLastValue,
|
|
LONGLONG * pllTimeBase,
|
|
LPDWORD pdwStatus
|
|
)
|
|
{
|
|
LONGLONG llDiff;
|
|
double dReturn = 0.0f;
|
|
DWORD dwStatus = PDH_CSTATUS_VALID_DATA;
|
|
|
|
UNREFERENCED_PARAMETER(pLastValue);
|
|
// test access to the required second parameter (lastValue)
|
|
__try {
|
|
if (IsSuccessSeverity(pThisValue->CStatus)) {
|
|
llDiff = pThisValue->SecondValue - pThisValue->FirstValue;
|
|
}
|
|
else {
|
|
dwStatus = pThisValue->CStatus;
|
|
}
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER) {
|
|
dwStatus = PDH_INVALID_ARGUMENT;
|
|
}
|
|
|
|
if (dwStatus == PDH_CSTATUS_VALID_DATA) {
|
|
if (* pllTimeBase > 0) {
|
|
llDiff = pThisValue->SecondValue - pThisValue->FirstValue;
|
|
if (llDiff > 0) {
|
|
dReturn = (double) llDiff;
|
|
dReturn /= (double) * pllTimeBase;
|
|
}
|
|
else {
|
|
if (llDiff < 0) {
|
|
dwStatus = PDH_CALC_NEGATIVE_DENOMINATOR;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
if (* pllTimeBase < 0) {
|
|
dwStatus = PDH_CALC_NEGATIVE_TIMEBASE;
|
|
}
|
|
}
|
|
}
|
|
if (pdwStatus != NULL) {
|
|
* pdwStatus = dwStatus;
|
|
}
|
|
return dReturn;
|
|
}
|
|
|
|
double
|
|
APIENTRY
|
|
PdhiCalcRawFraction(
|
|
PPDH_RAW_COUNTER pThisValue,
|
|
PPDH_RAW_COUNTER pLastValue,
|
|
LONGLONG * pllTimeBase,
|
|
LPDWORD pdwStatus
|
|
)
|
|
{
|
|
LONGLONG llDen;
|
|
double dReturn = 0.0f;
|
|
DWORD dwStatus = PDH_CSTATUS_VALID_DATA;
|
|
|
|
UNREFERENCED_PARAMETER(pLastValue);
|
|
UNREFERENCED_PARAMETER(pllTimeBase);
|
|
|
|
if ((llDen = pThisValue->SecondValue) > 0) {
|
|
dReturn = (double)(pThisValue->FirstValue);
|
|
dReturn /= (double)llDen;
|
|
}
|
|
else {
|
|
if (llDen < 0) {
|
|
dwStatus = PDH_CALC_NEGATIVE_DENOMINATOR;
|
|
}
|
|
dReturn = (double)0.0;
|
|
}
|
|
if (pdwStatus != NULL) {
|
|
* pdwStatus = dwStatus;
|
|
}
|
|
return dReturn;
|
|
}
|
|
|
|
double
|
|
APIENTRY
|
|
PdhiCalcCounter(
|
|
PPDH_RAW_COUNTER pThisValue,
|
|
PPDH_RAW_COUNTER pLastValue,
|
|
LONGLONG * pllTimeBase,
|
|
LPDWORD pdwStatus
|
|
)
|
|
{
|
|
LONGLONG llNumDiff;
|
|
LONGLONG llDenDiff = 0;
|
|
double dNum;
|
|
double dDen;
|
|
double dReturn = 0.0f;
|
|
double dMulti;
|
|
DWORD dwStatus = PDH_CSTATUS_VALID_DATA;
|
|
|
|
// test access to the required second parameter (lastValue)
|
|
__try {
|
|
if (pLastValue != NULL) {
|
|
if (IsSuccessSeverity(pLastValue->CStatus)) {
|
|
llDenDiff = pThisValue->SecondValue - pLastValue->SecondValue;
|
|
}
|
|
else {
|
|
dwStatus = pLastValue->CStatus;
|
|
}
|
|
}
|
|
else {
|
|
dwStatus = PDH_CSTATUS_INVALID_DATA;
|
|
}
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER) {
|
|
dwStatus = PDH_INVALID_ARGUMENT;
|
|
}
|
|
|
|
if (dwStatus == PDH_CSTATUS_VALID_DATA) {
|
|
if ((llDenDiff > 0) && (* pllTimeBase)) {
|
|
llNumDiff = pThisValue->FirstValue - pLastValue->FirstValue;
|
|
if (llNumDiff < 0) {
|
|
llNumDiff += MAXDWORD;
|
|
}
|
|
if (llNumDiff > 0) {
|
|
dNum = (double) llNumDiff;
|
|
dDen = (double) llDenDiff;
|
|
dDen /= (double) * pllTimeBase;
|
|
dReturn = (dNum / dDen);
|
|
if (pThisValue->MultiCount > 1) {
|
|
// don't do this if the count is <= 1
|
|
dMulti = (double) pThisValue->FirstValue;
|
|
dReturn /= dMulti;
|
|
}
|
|
}
|
|
else if (llNumDiff < 0) {
|
|
dwStatus = PDH_CALC_NEGATIVE_VALUE;
|
|
}
|
|
}
|
|
else {
|
|
if (llDenDiff < 0) {
|
|
dwStatus = PDH_CALC_NEGATIVE_DENOMINATOR;
|
|
}
|
|
else if (* pllTimeBase < 0) {
|
|
dwStatus = PDH_CALC_NEGATIVE_TIMEBASE;
|
|
}
|
|
}
|
|
}
|
|
if (pdwStatus != NULL) {
|
|
* pdwStatus = dwStatus;
|
|
}
|
|
return dReturn;
|
|
}
|
|
|
|
double
|
|
APIENTRY
|
|
PdhiCalcTimer(
|
|
PPDH_RAW_COUNTER pThisValue,
|
|
PPDH_RAW_COUNTER pLastValue,
|
|
LONGLONG * pllTimeBase,
|
|
LPDWORD pdwStatus
|
|
)
|
|
{
|
|
LONGLONG llNumDiff;
|
|
LONGLONG llDenDiff = 0;
|
|
double dReturn = 0.0f;
|
|
DWORD dwStatus = PDH_CSTATUS_VALID_DATA;
|
|
|
|
UNREFERENCED_PARAMETER(pllTimeBase);
|
|
|
|
// test access to the required second parameter (lastValue)
|
|
__try {
|
|
if (pLastValue != NULL) {
|
|
if (IsSuccessSeverity(pLastValue->CStatus)) {
|
|
llDenDiff = pThisValue->SecondValue - pLastValue->SecondValue;
|
|
}
|
|
else {
|
|
dwStatus = pLastValue->CStatus;
|
|
}
|
|
}
|
|
else {
|
|
// the last value wasn't passed in
|
|
dwStatus = PDH_CSTATUS_INVALID_DATA;
|
|
}
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER) {
|
|
dwStatus = PDH_INVALID_ARGUMENT;
|
|
}
|
|
|
|
if (dwStatus == PDH_CSTATUS_VALID_DATA) {
|
|
if (llDenDiff > 0) {
|
|
llNumDiff = pThisValue->FirstValue - pLastValue->FirstValue;
|
|
if (llNumDiff < 0) {
|
|
llNumDiff += MAXDWORD;
|
|
}
|
|
if (llNumDiff > 0) {
|
|
dReturn = (double) llNumDiff;
|
|
dReturn /= (double) llDenDiff;
|
|
if (pThisValue->MultiCount > 1) {
|
|
// don't do this if the count is <= 1
|
|
dReturn /= (double)pThisValue->MultiCount;
|
|
}
|
|
}
|
|
else if (llNumDiff < 0) {
|
|
dwStatus = PDH_CALC_NEGATIVE_VALUE;
|
|
}
|
|
}
|
|
else {
|
|
if (llDenDiff < 0) {
|
|
dwStatus = PDH_CALC_NEGATIVE_DENOMINATOR;
|
|
}
|
|
}
|
|
}
|
|
if (pdwStatus != NULL) {
|
|
* pdwStatus = dwStatus;
|
|
}
|
|
return dReturn;
|
|
}
|
|
|
|
double
|
|
APIENTRY
|
|
PdhiCalcInverseTimer(
|
|
PPDH_RAW_COUNTER pThisValue,
|
|
PPDH_RAW_COUNTER pLastValue,
|
|
LONGLONG * pllTimeBase,
|
|
LPDWORD pdwStatus
|
|
)
|
|
{
|
|
LONGLONG llNumDiff;
|
|
LONGLONG llDenDiff = 0;
|
|
double dReturn = 0.0f;
|
|
double dNumDiff, dDenDiff;
|
|
double dRatio;
|
|
DWORD dwStatus = PDH_CSTATUS_VALID_DATA;
|
|
|
|
UNREFERENCED_PARAMETER(pllTimeBase);
|
|
// test access to the required second parameter (lastValue)
|
|
__try {
|
|
if (pLastValue != NULL) {
|
|
if (IsSuccessSeverity(pLastValue->CStatus)) {
|
|
llDenDiff = pThisValue->SecondValue - pLastValue->SecondValue;
|
|
}
|
|
else {
|
|
dwStatus = pLastValue->CStatus;
|
|
}
|
|
}
|
|
else {
|
|
dwStatus = PDH_CSTATUS_INVALID_DATA;
|
|
}
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER) {
|
|
dwStatus = PDH_INVALID_ARGUMENT;
|
|
}
|
|
if (dwStatus == PDH_CSTATUS_VALID_DATA) {
|
|
if (llDenDiff > 0) {
|
|
llNumDiff = pThisValue->FirstValue - pLastValue->FirstValue;
|
|
if (llNumDiff < 0) {
|
|
llNumDiff += MAXDWORD;
|
|
}
|
|
if (llNumDiff >= 0) {
|
|
dNumDiff = (double)llNumDiff;
|
|
dDenDiff = (double)llDenDiff;
|
|
dRatio = dNumDiff;
|
|
dRatio /= dDenDiff;
|
|
if (pThisValue->MultiCount <= 1) {
|
|
dReturn = (double) 1.0;
|
|
}
|
|
else {
|
|
dReturn = (double) pThisValue->MultiCount;
|
|
}
|
|
// subtract the result from the multi count to get the
|
|
// "inverse" time
|
|
dReturn -= dRatio;
|
|
|
|
if (dReturn < (double) 0.0) {
|
|
// allow a "fudge" factor before reporting errors
|
|
if (dReturn < (double) (-0.1)) {
|
|
dwStatus = PDH_CALC_NEGATIVE_DENOMINATOR;
|
|
}
|
|
dReturn = (double) 0.0;
|
|
}
|
|
}
|
|
else if (llNumDiff < 0) {
|
|
dwStatus = PDH_CALC_NEGATIVE_VALUE;
|
|
}
|
|
}
|
|
else {
|
|
if (llDenDiff < 0) {
|
|
dwStatus = PDH_CALC_NEGATIVE_DENOMINATOR;
|
|
}
|
|
dReturn = (double) 0.0;
|
|
}
|
|
}
|
|
if (pdwStatus != NULL) {
|
|
* pdwStatus = dwStatus;
|
|
}
|
|
return dReturn;
|
|
}
|
|
|
|
double
|
|
APIENTRY
|
|
PdhiCalcRawCounter(
|
|
PPDH_RAW_COUNTER pThisValue,
|
|
PPDH_RAW_COUNTER pLastValue,
|
|
LONGLONG * pllTimeBase,
|
|
LPDWORD pdwStatus
|
|
)
|
|
{
|
|
UNREFERENCED_PARAMETER(pLastValue);
|
|
UNREFERENCED_PARAMETER(pllTimeBase);
|
|
if (pdwStatus != NULL) {
|
|
* pdwStatus = pThisValue->CStatus;
|
|
}
|
|
return (double) pThisValue->FirstValue;
|
|
}
|
|
|
|
double
|
|
APIENTRY
|
|
PdhiCalcNoData(
|
|
PPDH_RAW_COUNTER pThisValue,
|
|
PPDH_RAW_COUNTER pLastValue,
|
|
LONGLONG * pllTimeBase,
|
|
LPDWORD pdwStatus
|
|
)
|
|
{
|
|
UNREFERENCED_PARAMETER(pThisValue);
|
|
UNREFERENCED_PARAMETER(pLastValue);
|
|
UNREFERENCED_PARAMETER(pllTimeBase);
|
|
if (pdwStatus != NULL) {
|
|
* pdwStatus = PDH_NO_DATA;
|
|
}
|
|
return (double) 0.0;
|
|
}
|
|
|
|
double
|
|
APIENTRY
|
|
PdhiCalcDelta(
|
|
PPDH_RAW_COUNTER pThisValue,
|
|
PPDH_RAW_COUNTER pLastValue,
|
|
LONGLONG * pllTimeBase,
|
|
LPDWORD pdwStatus
|
|
)
|
|
{
|
|
LONGLONG llNumDiff = 0;
|
|
double dReturn = 0.0f;
|
|
DWORD dwStatus = PDH_CSTATUS_VALID_DATA;
|
|
|
|
UNREFERENCED_PARAMETER(pllTimeBase);
|
|
// test access to the required second parameter (lastValue)
|
|
__try {
|
|
if (pLastValue != NULL) {
|
|
if (IsSuccessSeverity(pLastValue->CStatus)) {
|
|
llNumDiff = pThisValue->FirstValue - pLastValue->FirstValue;
|
|
}
|
|
else {
|
|
dwStatus = pLastValue->CStatus;
|
|
}
|
|
}
|
|
else {
|
|
dwStatus = PDH_CSTATUS_INVALID_DATA;
|
|
}
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER) {
|
|
dwStatus = PDH_INVALID_ARGUMENT;
|
|
}
|
|
|
|
if (dwStatus == PDH_CSTATUS_VALID_DATA) {
|
|
if (llNumDiff < 0) {
|
|
llNumDiff += MAXDWORD;
|
|
}
|
|
if (llNumDiff < 0) {
|
|
dwStatus = PDH_CALC_NEGATIVE_VALUE;
|
|
dReturn = (double) 0.0;
|
|
}
|
|
else {
|
|
dReturn = (double)llNumDiff;
|
|
}
|
|
}
|
|
if (pdwStatus != NULL) {
|
|
* pdwStatus = dwStatus;
|
|
}
|
|
return dReturn;
|
|
}
|
|
|
|
PDH_STATUS
|
|
PdhiComputeFormattedValue(
|
|
LPCOUNTERCALC pCalcFunc,
|
|
DWORD dwCounterType,
|
|
LONG lScale,
|
|
DWORD dwFormat,
|
|
PPDH_RAW_COUNTER pRawValue1,
|
|
PPDH_RAW_COUNTER pRawValue2,
|
|
PLONGLONG pTimeBase,
|
|
DWORD dwReserved,
|
|
PPDH_FMT_COUNTERVALUE pValue
|
|
)
|
|
{
|
|
double dResult = (double)0.0;
|
|
double dScale;
|
|
PDH_STATUS lStatus = ERROR_SUCCESS;
|
|
DWORD dwValueStatus = PDH_CSTATUS_VALID_DATA;
|
|
|
|
UNREFERENCED_PARAMETER(dwReserved);
|
|
|
|
__try {
|
|
// make sure the counter values are valid before continuing
|
|
if (pRawValue1 != NULL) {
|
|
if ((pRawValue1->CStatus != PDH_CSTATUS_NEW_DATA) &&
|
|
(pRawValue1->CStatus != PDH_CSTATUS_VALID_DATA)) {
|
|
dwValueStatus = pRawValue1->CStatus;
|
|
lStatus = PDH_INVALID_DATA;
|
|
}
|
|
}
|
|
else {
|
|
// this is a required parameter
|
|
dwValueStatus = PDH_CSTATUS_INVALID_DATA;
|
|
lStatus = PDH_INVALID_ARGUMENT;
|
|
}
|
|
|
|
if ((lStatus == ERROR_SUCCESS) && (pRawValue2 != NULL)) {
|
|
if (PdhiCounterNeedLastValue(dwCounterType) == TRUE) {
|
|
// this is an optional parameter, but if present, it must be valid
|
|
if ((pRawValue2->CStatus != PDH_CSTATUS_NEW_DATA) &&
|
|
(pRawValue2->CStatus != PDH_CSTATUS_VALID_DATA)) {
|
|
dwValueStatus = pRawValue2->CStatus;
|
|
lStatus = PDH_INVALID_DATA;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (((dwFormat & PDH_FMT_LONG) != 0) && ((dwFormat & PDH_FMT_LARGE) != 0)) {
|
|
dwValueStatus = PDH_CSTATUS_INVALID_DATA;
|
|
lStatus = PDH_INVALID_ARGUMENT;
|
|
}
|
|
else if (((dwFormat & PDH_FMT_LONG) != 0) || ((dwFormat & PDH_FMT_LARGE) != 0)) {
|
|
if (dwFormat & PDH_FMT_DOUBLE) {
|
|
dwValueStatus = PDH_CSTATUS_INVALID_DATA;
|
|
lStatus = PDH_INVALID_ARGUMENT;
|
|
}
|
|
}
|
|
|
|
if (lScale > PDH_MAX_SCALE || lScale < PDH_MIN_SCALE) {
|
|
dwValueStatus = PDH_CSTATUS_INVALID_DATA;
|
|
lStatus = PDH_INVALID_ARGUMENT;
|
|
}
|
|
if (pTimeBase == NULL) {
|
|
dwValueStatus = PDH_CSTATUS_INVALID_DATA;
|
|
lStatus = PDH_INVALID_ARGUMENT;
|
|
}
|
|
else {
|
|
LONGLONG tmpTimeBase = * pTimeBase;
|
|
* pTimeBase = tmpTimeBase;
|
|
}
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER) {
|
|
dwValueStatus = PDH_CSTATUS_INVALID_DATA;
|
|
lStatus = PDH_INVALID_ARGUMENT;
|
|
}
|
|
if (lStatus == ERROR_SUCCESS) {
|
|
// call the counter's calculation function if the raw value is valid
|
|
if (IsSuccessSeverity(pRawValue1->CStatus)) {
|
|
__try {
|
|
dResult = (* pCalcFunc)(pRawValue1, pRawValue2, pTimeBase, & dwValueStatus);
|
|
// format returned value
|
|
|
|
if ((dwCounterType & 0xF0000000) == PERF_DISPLAY_PERCENT) {
|
|
// scale to show percent
|
|
dResult *= (double) 100.0;
|
|
// this should probably be controlled by a registry
|
|
// value as is the case with PERFMON
|
|
if (! (dwFormat & PDH_FMT_NOCAP100)) {
|
|
if (dResult > (double) 100.0) dResult = (double) 100.0;
|
|
}
|
|
}
|
|
if (!(dwFormat & PDH_FMT_NOSCALE)) {
|
|
//now scale
|
|
dScale = pow(10.0, (double)lScale);
|
|
dResult *= dScale;
|
|
}
|
|
|
|
if (dwFormat & PDH_FMT_1000) {
|
|
//now scale
|
|
dResult *= (double) 1000.0;
|
|
}
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER) {
|
|
// something failed
|
|
dResult = (double) 0.0;
|
|
dwValueStatus = PDH_INVALID_ARGUMENT;
|
|
}
|
|
}
|
|
else {
|
|
dwValueStatus = pRawValue1->CStatus;
|
|
}
|
|
if (!IsSuccessSeverity(dwValueStatus)) {
|
|
// an error occured so pass that on to the caller
|
|
lStatus = dwValueStatus;
|
|
}
|
|
} //end if valid counter data
|
|
|
|
// now format
|
|
__try {
|
|
if (dwFormat & PDH_FMT_LONG) {
|
|
pValue->longValue = (LONG) dResult;
|
|
}
|
|
else if (dwFormat & PDH_FMT_LARGE) {
|
|
pValue->largeValue = (LONGLONG) dResult;
|
|
}
|
|
else {
|
|
// double is the default
|
|
pValue->doubleValue = dResult;
|
|
}
|
|
pValue->CStatus = dwValueStatus;
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER) {
|
|
lStatus = PDH_INVALID_ARGUMENT;
|
|
}
|
|
return lStatus;
|
|
}
|