746 lines
21 KiB
C
746 lines
21 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (C) 1995-1999 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
calcfuns.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Counter calculation functions
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include <windows.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <assert.h>
|
||
|
#include <math.h>
|
||
|
#include <pdh.h>
|
||
|
#include "pdhicalc.h"
|
||
|
#include "pdhitype.h"
|
||
|
#include "pdhidef.h"
|
||
|
#include "pdhmsg.h"
|
||
|
|
||
|
BOOL
|
||
|
AssignCalcFunction (
|
||
|
IN DWORD dwCounterType,
|
||
|
IN LPCOUNTERCALC *pCalcFunc,
|
||
|
IN LPCOUNTERSTAT *pStatFunc
|
||
|
)
|
||
|
{
|
||
|
BOOL bReturn = TRUE;
|
||
|
|
||
|
// reset the last error value
|
||
|
SetLastError (ERROR_SUCCESS);
|
||
|
|
||
|
if (pCalcFunc == NULL || pStatFunc == NULL) {
|
||
|
SetLastError(PDH_INVALID_ARGUMENT);
|
||
|
return FALSE;
|
||
|
}
|
||
|
else {
|
||
|
__try {
|
||
|
* pCalcFunc = PdhiCalcNoData;
|
||
|
* pStatFunc = PdhiComputeNoDataStats;
|
||
|
}
|
||
|
except (EXCEPTION_EXECUTE_HANDLER) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
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) {
|
||
|
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) {
|
||
|
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 {
|
||
|
// just return 0 & normal status
|
||
|
}
|
||
|
} 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) {
|
||
|
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 {
|
||
|
// just return 0 and a normal status
|
||
|
}
|
||
|
} 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) {
|
||
|
|
||
|
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) {
|
||
|
dwStatus = PDH_CALC_NEGATIVE_VALUE;
|
||
|
dReturn = (double)0.0;
|
||
|
} else {
|
||
|
dReturn = (double)llNumDiff;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (pdwStatus != NULL) {
|
||
|
*pdwStatus = dwStatus;
|
||
|
}
|
||
|
|
||
|
return dReturn;
|
||
|
}
|
||
|
|
||
|
PDH_STATUS
|
||
|
PdhiComputeFormattedValue (
|
||
|
IN LPCOUNTERCALC pCalcFunc,
|
||
|
IN DWORD dwCounterType,
|
||
|
IN LONG lScale,
|
||
|
IN DWORD dwFormat,
|
||
|
IN PPDH_RAW_COUNTER pRawValue1,
|
||
|
IN PPDH_RAW_COUNTER pRawValue2,
|
||
|
IN PLONGLONG pTimeBase,
|
||
|
IN DWORD dwReserved,
|
||
|
IN 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)) {
|
||
|
// 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;
|
||
|
}
|