mirror of https://github.com/tongzx/nt5src
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.
1793 lines
71 KiB
1793 lines
71 KiB
/*++ BUILD Version: 0001 // Increment this if a change has global effects
|
|
|
|
Copyright (c) 1992-1993 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
counters.c
|
|
|
|
Abstract:
|
|
|
|
This module contains the routines to calculate "DataPoint" values from
|
|
the registry data.
|
|
|
|
The algoritms were lifted from RussBls's "Data.C" in winmeter.
|
|
|
|
All the math is done in floating point to get the correct results, at
|
|
the sacrifice of efficiency on a 386 with not 387. We can always
|
|
revisit these routines later.
|
|
|
|
Revision History:
|
|
|
|
Bob Watson 11/04/92
|
|
-- modified calculations to use more integer math and "early
|
|
exits" to improve efficiency on slower & non-coprocessor
|
|
machines
|
|
--*/
|
|
|
|
//==========================================================================//
|
|
// Includes //
|
|
//==========================================================================//
|
|
#include "perfmon.h" // perfmon include files
|
|
#include "counters.h" // Exported declarations for this file
|
|
#include "perfmsg.h" // message file definitions
|
|
|
|
//==========================================================================//
|
|
// Constants //
|
|
//==========================================================================//
|
|
|
|
#ifdef DBG_COUNTER_DATA
|
|
#undef DBG_COUNTER_DATA
|
|
#endif
|
|
//#define DBG_COUNTER_DATA
|
|
|
|
#define INVERT PERF_COUNTER_TIMER_INV
|
|
#define NS100_INVERT PERF_100NSEC_TIMER_INV
|
|
#define NS100 PERF_100NSEC_TIMER
|
|
#define TIMER_MULTI PERF_COUNTER_MULTI_TIMER
|
|
#define TIMER_MULTI_INVERT PERF_COUNTER_MULTI_TIMER_INV
|
|
#define NS100_MULTI PERF_100NSEC_MULTI_TIMER
|
|
#define NS100_MULTI_INVERT PERF_100NSEC_MULTI_TIMER_INV
|
|
|
|
|
|
#define FRACTION 1
|
|
#define BULK 1
|
|
|
|
#define TOO_BIG (FLOAT)1500000000
|
|
|
|
//==========================================================================//
|
|
// Local Functions //
|
|
//==========================================================================//
|
|
#define eLIntToFloat(LI) (FLOAT)( ((LARGE_INTEGER *)(LI))->QuadPart )
|
|
|
|
static LPTSTR cszSpace = TEXT(" ");
|
|
|
|
|
|
FLOAT
|
|
eGetTimeInterval(
|
|
IN PLARGE_INTEGER pliCurrentTime,
|
|
IN PLARGE_INTEGER pliPreviousTime,
|
|
IN PLARGE_INTEGER pliFreq
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Get the difference between the current and previous time counts,
|
|
then divide by the frequency.
|
|
|
|
Arguments:
|
|
|
|
IN pCurrentTime
|
|
IN pPreviousTime
|
|
used to compute the duration of this sample (the time between
|
|
samples
|
|
|
|
IN pliFreq
|
|
# of counts (clock ticks) per second
|
|
|
|
Return Value:
|
|
|
|
Floating point representation of Time Interval (seconds)
|
|
--*/
|
|
{
|
|
FLOAT eTimeDifference;
|
|
FLOAT eFreq;
|
|
FLOAT eTimeInterval ;
|
|
|
|
LARGE_INTEGER liDifference;
|
|
|
|
// Get the number of counts that have occured since the last sample
|
|
|
|
liDifference.QuadPart = pliCurrentTime->QuadPart -
|
|
pliPreviousTime->QuadPart;
|
|
|
|
if (liDifference.QuadPart <= 0) {
|
|
return (FLOAT) 0.0f;
|
|
} else {
|
|
eTimeDifference = eLIntToFloat(&liDifference);
|
|
|
|
// Get the counts per second
|
|
|
|
eFreq = eLIntToFloat(pliFreq) ;
|
|
if (eFreq <= 0.0f)
|
|
return (FLOAT) 0.0f;
|
|
|
|
// Get the time since the last sample.
|
|
|
|
eTimeInterval = eTimeDifference / eFreq ;
|
|
|
|
return (eTimeInterval) ;
|
|
}
|
|
} // eGetTimeInterval
|
|
|
|
FLOAT
|
|
Counter_Counter_Common(
|
|
IN PLINESTRUCT pLineStruct,
|
|
IN INT iType
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Take the difference between the current and previous counts
|
|
then divide by the time interval
|
|
|
|
Arguments:
|
|
|
|
IN pLineStruct
|
|
Line structure containing data to perform computations on
|
|
|
|
IN iType
|
|
Counter Type
|
|
|
|
|
|
Return Value:
|
|
|
|
Floating point representation of outcome
|
|
--*/
|
|
{
|
|
FLOAT eTimeInterval;
|
|
FLOAT eDifference;
|
|
FLOAT eCount ;
|
|
BOOL bValueDrop = FALSE ;
|
|
|
|
LARGE_INTEGER liDifference;
|
|
|
|
if (iType != BULK) {
|
|
pLineStruct->lnaCounterValue[0].HighPart = 0;
|
|
}
|
|
|
|
liDifference.QuadPart = pLineStruct->lnaCounterValue[0].QuadPart -
|
|
pLineStruct->lnaOldCounterValue[0].QuadPart;
|
|
|
|
if (liDifference.QuadPart <= 0) {
|
|
if (bReportEvents && (liDifference.QuadPart < 0)) {
|
|
wMessageIndex = 0;
|
|
dwMessageDataBytes = 0;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnSystemName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnObjectName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnCounterName;
|
|
if (pLineStruct->lnInstanceName != NULL){
|
|
if (pLineStruct->lnPINName != NULL) {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnPINName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
if (iType != BULK) {
|
|
dwMessageData[dwMessageDataBytes++] = // recent data
|
|
pLineStruct->lnaCounterValue[0].LowPart;
|
|
dwMessageData[dwMessageDataBytes++] = // previous data
|
|
pLineStruct->lnaOldCounterValue[0].LowPart;
|
|
} else { // 8 byte counter values
|
|
dwMessageData[dwMessageDataBytes++] = // recent data
|
|
pLineStruct->lnaCounterValue[0].LowPart;
|
|
dwMessageData[dwMessageDataBytes++] = // recent data
|
|
pLineStruct->lnaCounterValue[0].HighPart;
|
|
dwMessageData[dwMessageDataBytes++] = // previous data
|
|
pLineStruct->lnaOldCounterValue[0].LowPart;
|
|
dwMessageData[dwMessageDataBytes++] = // previous data
|
|
pLineStruct->lnaOldCounterValue[0].HighPart;
|
|
}
|
|
dwMessageDataBytes *= sizeof(DWORD); // convert index to size
|
|
ReportEvent (hEventLog,
|
|
EVENTLOG_WARNING_TYPE, // error type
|
|
0, // category (not used)
|
|
(DWORD)PERFMON_ERROR_NEGATIVE_VALUE, // event,
|
|
NULL, // SID (not used),
|
|
wMessageIndex, // number of strings
|
|
dwMessageDataBytes, // sizeof raw data
|
|
szMessageArray, // message text array
|
|
(LPVOID)&dwMessageData[0]); // raw data
|
|
}
|
|
return (FLOAT) 0.0f;
|
|
} else {
|
|
eTimeInterval = eGetTimeInterval(&pLineStruct->lnNewTime,
|
|
&pLineStruct->lnOldTime,
|
|
&pLineStruct->lnPerfFreq) ;
|
|
if (eTimeInterval <= 0.0f) {
|
|
if ((eTimeInterval < 0.0f) && bReportEvents) {
|
|
wMessageIndex = 0;
|
|
dwMessageDataBytes = 0;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnSystemName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnObjectName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnCounterName;
|
|
if (pLineStruct->lnInstanceName != NULL){
|
|
if (pLineStruct->lnPINName != NULL) {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnPINName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
dwMessageData[dwMessageDataBytes++] = // recent data
|
|
pLineStruct->lnNewTime.LowPart;
|
|
dwMessageData[dwMessageDataBytes++] = // recent data
|
|
pLineStruct->lnNewTime.HighPart;
|
|
dwMessageData[dwMessageDataBytes++] = // previous data
|
|
pLineStruct->lnOldTime.LowPart;
|
|
dwMessageData[dwMessageDataBytes++] = // previous data
|
|
pLineStruct->lnOldTime.HighPart;
|
|
dwMessageDataBytes *= sizeof(DWORD); // convert index to size
|
|
ReportEvent (hEventLog,
|
|
EVENTLOG_ERROR_TYPE, // error type
|
|
0, // category (not used)
|
|
(DWORD)PERFMON_ERROR_NEGATIVE_TIME, // event,
|
|
NULL, // SID (not used),
|
|
wMessageIndex, // number of strings
|
|
dwMessageDataBytes, // sizeof raw data
|
|
szMessageArray, // message text array
|
|
(LPVOID)&dwMessageData[0]); // raw data
|
|
return (FLOAT) 0.0f;
|
|
}
|
|
} else {
|
|
eDifference = eLIntToFloat (&liDifference);
|
|
|
|
eCount = eDifference / eTimeInterval ;
|
|
|
|
if (bValueDrop && (eCount > ((FLOAT)TOO_BIG))) {
|
|
// ignore this bogus data since it is too big for
|
|
// the wrap-around case
|
|
wMessageIndex = 0;
|
|
dwMessageDataBytes = 0;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnSystemName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnObjectName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnCounterName;
|
|
if (pLineStruct->lnInstanceName != NULL){
|
|
if (pLineStruct->lnPINName != NULL) {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnPINName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
dwMessageData[dwMessageDataBytes++] = // recent data
|
|
liDifference.LowPart;
|
|
dwMessageData[dwMessageDataBytes++] = // recent data
|
|
liDifference.HighPart;
|
|
dwMessageDataBytes *= sizeof(DWORD); // convert index to size
|
|
ReportEvent (hEventLog,
|
|
EVENTLOG_WARNING_TYPE, // error type
|
|
0, // category (not used)
|
|
(DWORD)PERFMON_ERROR_VALUE_OUT_OF_BOUNDS, // event
|
|
NULL, // SID (not used),
|
|
wMessageIndex, // number of strings
|
|
dwMessageDataBytes, // sizeof raw data
|
|
szMessageArray, // message text array
|
|
(LPVOID)&dwMessageData[0]); // raw data
|
|
eCount = (FLOAT) 0.0f ;
|
|
}
|
|
return(eCount) ;
|
|
}
|
|
}
|
|
return (FLOAT) 0.0f;
|
|
} // Counter_Counter_Common
|
|
|
|
|
|
FLOAT
|
|
Counter_Average_Timer(
|
|
IN PLINESTRUCT pLineStruct
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Take the differences between the current and previous times and counts
|
|
divide the time interval by the counts multiply by 10,000,000 (convert
|
|
from 100 nsec to sec)
|
|
|
|
Arguments:
|
|
|
|
IN pLineStruct
|
|
Line structure containing data to perform computations on
|
|
|
|
Return Value:
|
|
|
|
Floating point representation of outcome
|
|
--*/
|
|
{
|
|
FLOAT eTimeInterval;
|
|
FLOAT eCount;
|
|
|
|
LARGE_INTEGER liDifference;
|
|
|
|
// Get the current and previous counts.
|
|
|
|
pLineStruct->lnaCounterValue[1].HighPart = 0;
|
|
liDifference.QuadPart = pLineStruct->lnaCounterValue[1].QuadPart -
|
|
pLineStruct->lnaOldCounterValue[1].QuadPart;
|
|
|
|
if ( liDifference.QuadPart <= 0) {
|
|
if ((liDifference.QuadPart < 0) && bReportEvents) {
|
|
wMessageIndex = 0;
|
|
dwMessageDataBytes = 0;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnSystemName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnObjectName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnCounterName;
|
|
if (pLineStruct->lnInstanceName != NULL){
|
|
if (pLineStruct->lnPINName != NULL) {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnPINName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
dwMessageData[dwMessageDataBytes++] = // recent data
|
|
pLineStruct->lnaCounterValue[1].LowPart;
|
|
dwMessageData[dwMessageDataBytes++] = // previous data
|
|
pLineStruct->lnaOldCounterValue[1].LowPart;
|
|
dwMessageDataBytes *= sizeof(DWORD); // convert index to size
|
|
ReportEvent (hEventLog,
|
|
EVENTLOG_WARNING_TYPE, // error type
|
|
0, // category (not used)
|
|
(DWORD)PERFMON_ERROR_NEGATIVE_VALUE, // event,
|
|
NULL, // SID (not used),
|
|
wMessageIndex, // number of strings
|
|
dwMessageDataBytes, // sizeof raw data
|
|
szMessageArray, // message text array
|
|
(LPVOID)&dwMessageData[0]); // raw data
|
|
}
|
|
return (FLOAT) 0.0f;
|
|
} else {
|
|
// Get the amount of time that has passed since the last sample
|
|
eTimeInterval = eGetTimeInterval(&pLineStruct->lnaCounterValue[0],
|
|
&pLineStruct->lnaOldCounterValue[0],
|
|
&pLineStruct->lnPerfFreq) ;
|
|
|
|
if (eTimeInterval <= 0.0f) { // return 0 if negative time has passed
|
|
if ((eTimeInterval < 0.0f) & bReportEvents) {
|
|
wMessageIndex = 0;
|
|
dwMessageDataBytes = 0;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnSystemName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnObjectName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnCounterName;
|
|
if (pLineStruct->lnInstanceName != NULL){
|
|
if (pLineStruct->lnPINName != NULL) {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnPINName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
dwMessageData[dwMessageDataBytes++] = // recent data
|
|
pLineStruct->lnaCounterValue[0].LowPart;
|
|
dwMessageData[dwMessageDataBytes++] = // recent data
|
|
pLineStruct->lnaCounterValue[0].HighPart;
|
|
dwMessageData[dwMessageDataBytes++] = // previous data
|
|
pLineStruct->lnaOldCounterValue[0].LowPart;
|
|
dwMessageData[dwMessageDataBytes++] = // previous data
|
|
pLineStruct->lnaOldCounterValue[0].HighPart;
|
|
dwMessageDataBytes *= sizeof(DWORD); // convert index to size
|
|
ReportEvent (hEventLog,
|
|
EVENTLOG_ERROR_TYPE, // error type
|
|
0, // category (not used)
|
|
(DWORD)PERFMON_ERROR_NEGATIVE_TIME, // event,
|
|
NULL, // SID (not used),
|
|
wMessageIndex, // number of strings
|
|
dwMessageDataBytes, // sizeof raw data
|
|
szMessageArray, // message text array
|
|
(LPVOID)&dwMessageData[0]); // raw data
|
|
}
|
|
return (0.0f);
|
|
} else {
|
|
// Get the number of counts in this time interval.
|
|
eCount = eTimeInterval / eLIntToFloat (&liDifference);
|
|
return(eCount) ;
|
|
}
|
|
}
|
|
} //Counter_Average_Timer
|
|
|
|
|
|
|
|
FLOAT
|
|
Counter_Average_Bulk(
|
|
IN PLINESTRUCT pLineStruct
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Take the differences between the current and previous byte counts and
|
|
operation counts divide the bulk count by the operation counts
|
|
|
|
Arguments:
|
|
|
|
IN pLineStruct
|
|
Line structure containing data to perform computations on
|
|
|
|
Return Value:
|
|
|
|
Floating point representation of outcome
|
|
--*/
|
|
{
|
|
FLOAT eBulkDelta;
|
|
FLOAT eDifference;
|
|
FLOAT eCount;
|
|
|
|
LARGE_INTEGER liDifference;
|
|
LARGE_INTEGER liBulkDelta;
|
|
|
|
// Get the bulk count increment since the last sample
|
|
|
|
liBulkDelta.QuadPart = pLineStruct->lnaCounterValue[0].QuadPart -
|
|
pLineStruct->lnaOldCounterValue[0].QuadPart;
|
|
|
|
if (liBulkDelta.QuadPart <= 0) {
|
|
if ((liBulkDelta.QuadPart < 0) && bReportEvents) {
|
|
wMessageIndex = 0;
|
|
dwMessageDataBytes = 0;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnSystemName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnObjectName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnCounterName;
|
|
if (pLineStruct->lnInstanceName != NULL){
|
|
if (pLineStruct->lnPINName != NULL) {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnPINName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
dwMessageData[dwMessageDataBytes++] = // recent data
|
|
pLineStruct->lnaCounterValue[0].LowPart;
|
|
dwMessageData[dwMessageDataBytes++] = // recent data
|
|
pLineStruct->lnaCounterValue[0].HighPart;
|
|
dwMessageData[dwMessageDataBytes++] = // previous data
|
|
pLineStruct->lnaOldCounterValue[0].LowPart;
|
|
dwMessageData[dwMessageDataBytes++] = // previous data
|
|
pLineStruct->lnaOldCounterValue[0].HighPart;
|
|
dwMessageDataBytes *= sizeof(DWORD); // convert index to size
|
|
ReportEvent (hEventLog,
|
|
EVENTLOG_WARNING_TYPE, // error type
|
|
0, // category (not used)
|
|
(DWORD)PERFMON_ERROR_NEGATIVE_VALUE, // event,
|
|
NULL, // SID (not used),
|
|
wMessageIndex, // number of strings
|
|
dwMessageDataBytes, // sizeof raw data
|
|
szMessageArray, // message text array
|
|
(LPVOID)&dwMessageData[0]); // raw data
|
|
}
|
|
return (FLOAT) 0.0f;
|
|
} else {
|
|
// Get the current and previous counts.
|
|
pLineStruct->lnaCounterValue[1].HighPart = 0;
|
|
liDifference.QuadPart = pLineStruct->lnaCounterValue[1].QuadPart -
|
|
pLineStruct->lnaOldCounterValue[1].QuadPart;
|
|
|
|
// Get the number of counts in this time interval.
|
|
|
|
if ( liDifference.QuadPart <= 0) {
|
|
if ((liDifference.QuadPart < 0) && bReportEvents) {
|
|
// Counter value invalid
|
|
wMessageIndex = 0;
|
|
dwMessageDataBytes = 0;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnSystemName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnObjectName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnCounterName;
|
|
if (pLineStruct->lnInstanceName != NULL){
|
|
if (pLineStruct->lnPINName != NULL) {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnPINName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
dwMessageData[dwMessageDataBytes++] = // recent data
|
|
pLineStruct->lnaCounterValue[1].LowPart;
|
|
dwMessageData[dwMessageDataBytes++] = // recent data
|
|
pLineStruct->lnaCounterValue[1].HighPart;
|
|
dwMessageData[dwMessageDataBytes++] = // previous data
|
|
pLineStruct->lnaOldCounterValue[1].LowPart;
|
|
dwMessageData[dwMessageDataBytes++] = // previous data
|
|
pLineStruct->lnaOldCounterValue[1].HighPart;
|
|
dwMessageDataBytes *= sizeof(DWORD); // convert index to size
|
|
ReportEvent (hEventLog,
|
|
EVENTLOG_WARNING_TYPE, // error type
|
|
0, // category (not used)
|
|
(DWORD)PERFMON_ERROR_NEGATIVE_VALUE, // event,
|
|
NULL, // SID (not used),
|
|
wMessageIndex, // number of strings
|
|
dwMessageDataBytes, // sizeof raw data
|
|
szMessageArray, // message text array
|
|
(LPVOID)&dwMessageData[0]); // raw data
|
|
}
|
|
return (FLOAT) 0.0f;
|
|
} else {
|
|
eBulkDelta = eLIntToFloat (&liBulkDelta);
|
|
eDifference = eLIntToFloat (&liDifference);
|
|
eCount = eBulkDelta / eDifference ;
|
|
|
|
// Scale the value to up to 1 second
|
|
|
|
return(eCount) ;
|
|
}
|
|
}
|
|
} // Counter_Average_Bulk
|
|
|
|
|
|
|
|
FLOAT
|
|
Counter_Timer_Common(
|
|
IN PLINESTRUCT pLineStruct,
|
|
IN INT iType
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Take the difference between the current and previous counts,
|
|
Normalize the count (counts per interval)
|
|
divide by the time interval (count = % of interval)
|
|
if (invert)
|
|
subtract from 1 (the normalized size of an interval)
|
|
multiply by 100 (convert to a percentage)
|
|
this value from 100.
|
|
|
|
Arguments:
|
|
|
|
IN pLineStruct
|
|
Line structure containing data to perform computations on
|
|
|
|
IN iType
|
|
Counter Type
|
|
|
|
Return Value:
|
|
|
|
Floating point representation of outcome
|
|
--*/
|
|
{
|
|
FLOAT eTimeInterval;
|
|
FLOAT eDifference;
|
|
FLOAT eFreq;
|
|
FLOAT eFraction;
|
|
FLOAT eMultiBase;
|
|
FLOAT eCount ;
|
|
|
|
LARGE_INTEGER liTimeInterval;
|
|
LARGE_INTEGER liDifference;
|
|
LARGE_INTEGER liFreq;
|
|
|
|
// test to see if the previous sample was 0, if so, return 0 since
|
|
// the difference between a "valid" value and 0 will likely exceed
|
|
// 100%. It's better to keep the value at 0 until a valid one can
|
|
// be displayed, rather than display a 100% spike, then a valid value.
|
|
|
|
if (pLineStruct->lnaOldCounterValue[0].QuadPart == 0) {
|
|
return (FLOAT)0.0f;
|
|
}
|
|
|
|
// Get the amount of time that has passed since the last sample
|
|
|
|
if (iType == NS100 ||
|
|
iType == NS100_INVERT ||
|
|
iType == NS100_MULTI ||
|
|
iType == NS100_MULTI_INVERT) {
|
|
liTimeInterval.QuadPart = pLineStruct->lnNewTime100Ns.QuadPart -
|
|
pLineStruct->lnOldTime100Ns.QuadPart;
|
|
eTimeInterval = eLIntToFloat (&liTimeInterval);
|
|
} else {
|
|
liTimeInterval.QuadPart = pLineStruct->lnNewTime.QuadPart -
|
|
pLineStruct->lnOldTime.QuadPart;
|
|
eTimeInterval = eGetTimeInterval(&pLineStruct->lnNewTime,
|
|
&pLineStruct->lnOldTime,
|
|
&pLineStruct->lnPerfFreq) ;
|
|
}
|
|
|
|
if (liTimeInterval.QuadPart <= 0) {
|
|
if ((liTimeInterval.QuadPart < 0) && bReportEvents) {
|
|
wMessageIndex = 0;
|
|
dwMessageDataBytes = 0;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnSystemName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnObjectName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnCounterName;
|
|
if (pLineStruct->lnInstanceName != NULL){
|
|
if (pLineStruct->lnPINName != NULL) {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnPINName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
dwMessageData[dwMessageDataBytes++] = // recent data
|
|
pLineStruct->lnNewTime.LowPart;
|
|
dwMessageData[dwMessageDataBytes++] = // recent data
|
|
pLineStruct->lnNewTime.HighPart;
|
|
dwMessageData[dwMessageDataBytes++] = // previous data
|
|
pLineStruct->lnOldTime.LowPart;
|
|
dwMessageData[dwMessageDataBytes++] = // previous data
|
|
pLineStruct->lnOldTime.HighPart;
|
|
dwMessageDataBytes *= sizeof(DWORD); // convert index to size
|
|
ReportEvent (hEventLog,
|
|
EVENTLOG_ERROR_TYPE, // error type
|
|
0, // category (not used)
|
|
(DWORD)PERFMON_ERROR_NEGATIVE_TIME, // event,
|
|
NULL, // SID (not used),
|
|
wMessageIndex, // number of strings
|
|
dwMessageDataBytes, // sizeof raw data
|
|
szMessageArray, // message text array
|
|
(LPVOID)&dwMessageData[0]); // raw data
|
|
}
|
|
return (FLOAT) 0.0f;
|
|
}
|
|
// Get the current and previous counts.
|
|
|
|
liDifference.QuadPart = pLineStruct->lnaCounterValue[0].QuadPart -
|
|
pLineStruct->lnaOldCounterValue[0].QuadPart;
|
|
|
|
// Get the number of counts in this time interval.
|
|
// (1, 2, 3 or any number of seconds could have gone by since
|
|
// the last sample)
|
|
|
|
eDifference = eLIntToFloat (&liDifference) ;
|
|
|
|
if (iType == 0 || iType == INVERT)
|
|
{
|
|
// Get the counts per interval (second)
|
|
liFreq.QuadPart = pLineStruct->lnPerfFreq.QuadPart;
|
|
|
|
if ((liFreq.QuadPart <= 0) && bReportEvents) {
|
|
wMessageIndex = 0;
|
|
dwMessageDataBytes = 0;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnSystemName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnObjectName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnCounterName;
|
|
if (pLineStruct->lnInstanceName != NULL){
|
|
if (pLineStruct->lnPINName != NULL) {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnPINName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
dwMessageData[dwMessageDataBytes++] = liFreq.LowPart;
|
|
dwMessageData[dwMessageDataBytes++] = liFreq.HighPart;
|
|
dwMessageDataBytes *= sizeof(DWORD); // convert index to size
|
|
ReportEvent (hEventLog,
|
|
EVENTLOG_ERROR_TYPE, // error type
|
|
0, // category (not used)
|
|
(DWORD)PERFMON_ERROR_BAD_FREQUENCY, // event,
|
|
NULL, // SID (not used),
|
|
wMessageIndex, // number of strings
|
|
dwMessageDataBytes, // sizeof raw data
|
|
szMessageArray, // message text array
|
|
(LPVOID)&dwMessageData[0]); // raw data
|
|
return (FLOAT) 0.0f;
|
|
} else {
|
|
eFreq = eLIntToFloat(&pLineStruct->lnPerfFreq) ;
|
|
}
|
|
// Calculate the fraction of the counts that are used by whatever
|
|
// we are measuring to convert to units per second
|
|
|
|
eFraction = eDifference / eFreq ;
|
|
}
|
|
else
|
|
{
|
|
// for 100 NS counters, the frequency is not included since it
|
|
// would cancel out since both numerator & denominator are returned
|
|
// in 100 NS units. Non "100 NS" counter types are normalized to
|
|
// seconds.
|
|
eFraction = eDifference ;
|
|
liFreq.QuadPart = 10000000;
|
|
}
|
|
|
|
// Calculate the fraction of time used by what were measuring.
|
|
|
|
if (eTimeInterval > 0.0)
|
|
eCount = eFraction / eTimeInterval ;
|
|
else
|
|
eCount = 0.0;
|
|
|
|
// If this is an inverted count take care of the inversion.
|
|
|
|
if (iType == INVERT || iType == NS100_INVERT)
|
|
eCount = (FLOAT) 1.0 - eCount ;
|
|
|
|
if (eCount <= (FLOAT)0.0f) {
|
|
// the threshold for reporting an error is -.1 since some timers
|
|
// have a small margin of error that should never exceed this value
|
|
// but can fall below 0 at times. Typically this error is no more
|
|
// than -0.01
|
|
if ((eCount < (FLOAT)-0.1f) && bReportEvents) {
|
|
wMessageIndex = 0;
|
|
dwMessageDataBytes = 0;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnSystemName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnObjectName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnCounterName;
|
|
if (pLineStruct->lnInstanceName != NULL){
|
|
if (pLineStruct->lnPINName != NULL) {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnPINName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
dwMessageData[dwMessageDataBytes++] = // recent data
|
|
pLineStruct->lnaCounterValue[0].LowPart;
|
|
dwMessageData[dwMessageDataBytes++] = // recent data
|
|
pLineStruct->lnaCounterValue[0].HighPart;
|
|
dwMessageData[dwMessageDataBytes++] = // previous data
|
|
pLineStruct->lnaOldCounterValue[0].LowPart;
|
|
dwMessageData[dwMessageDataBytes++] = // previous data
|
|
pLineStruct->lnaOldCounterValue[0].HighPart;
|
|
dwMessageDataBytes *= sizeof(DWORD); // convert index to size
|
|
ReportEvent (hEventLog,
|
|
EVENTLOG_WARNING_TYPE, // error type
|
|
0, // category (not used)
|
|
(DWORD)PERFMON_ERROR_NEGATIVE_VALUE, // event,
|
|
NULL, // SID (not used),
|
|
wMessageIndex, // number of strings
|
|
dwMessageDataBytes, // sizeof raw data
|
|
szMessageArray, // message text array
|
|
(LPVOID)&dwMessageData[0]); // raw data
|
|
}
|
|
// don't just return here, since 0 is possibly a valid value
|
|
eCount = (FLOAT)0.0f;
|
|
}
|
|
|
|
// If this is a multi count take care of the base
|
|
if (iType == TIMER_MULTI || iType == NS100_MULTI ||
|
|
iType == TIMER_MULTI_INVERT || iType == NS100_MULTI_INVERT) {
|
|
|
|
if (pLineStruct->lnaCounterValue[1].LowPart <= 0) {
|
|
#if 0
|
|
if ((pLineStruct->lnaCounterValue[1].LowPart < 0) &&
|
|
bReportEvents) {
|
|
wMessageIndex = 0;
|
|
dwMessageDataBytes = 0;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnSystemName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnObjectName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnCounterName;
|
|
if (pLineStruct->lnInstanceName != NULL){
|
|
if (pLineStruct->lnPINName != NULL) {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnPINName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
dwMessageData[dwMessageDataBytes++] = // recent data
|
|
pLineStruct->lnaCounterValue[1].LowPart;
|
|
dwMessageDataBytes *= sizeof (DWORD);
|
|
ReportEvent (hEventLog,
|
|
EVENTLOG_ERROR_TYPE, // error type
|
|
0, // category (not used)
|
|
(DWORD)PERFMON_ERROR_INVALID_BASE, // event,
|
|
NULL, // SID (not used),
|
|
wMessageIndex, // number of strings
|
|
dwMessageDataBytes, // sizeof raw data
|
|
szMessageArray, // message text array
|
|
(LPVOID)&dwMessageData[0]); // raw data
|
|
}
|
|
#endif
|
|
return (FLOAT) 0.0f;
|
|
} else {
|
|
eMultiBase = (FLOAT)pLineStruct->lnaCounterValue[1].LowPart ;
|
|
}
|
|
|
|
// If this is an inverted multi count take care of the inversion.
|
|
if (iType == TIMER_MULTI_INVERT || iType == NS100_MULTI_INVERT) {
|
|
eCount = (FLOAT) eMultiBase - eCount ;
|
|
}
|
|
eCount /= eMultiBase;
|
|
}
|
|
|
|
// Scale the value to up to 100.
|
|
|
|
eCount *= 100.0f ;
|
|
|
|
if (((eCount > 100.0f) && (bCapPercentsAt100)) &&
|
|
iType != NS100_MULTI &&
|
|
iType != NS100_MULTI_INVERT &&
|
|
iType != TIMER_MULTI &&
|
|
iType != TIMER_MULTI_INVERT) {
|
|
if (bReportEvents) {
|
|
wMessageIndex = 0;
|
|
dwMessageDataBytes = 0;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnSystemName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnObjectName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnCounterName;
|
|
if (pLineStruct->lnInstanceName != NULL){
|
|
if (pLineStruct->lnPINName != NULL) {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnPINName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
dwMessageData[dwMessageDataBytes++] =
|
|
pLineStruct->lnaCounterValue[0].LowPart;
|
|
dwMessageData[dwMessageDataBytes++] =
|
|
pLineStruct->lnaCounterValue[0].HighPart;
|
|
dwMessageData[dwMessageDataBytes++] =
|
|
pLineStruct->lnaOldCounterValue[0].LowPart;
|
|
dwMessageData[dwMessageDataBytes++] =
|
|
pLineStruct->lnaOldCounterValue[0].HighPart;
|
|
dwMessageData[dwMessageDataBytes++] = liTimeInterval.LowPart;
|
|
dwMessageData[dwMessageDataBytes++] = liTimeInterval.HighPart;
|
|
dwMessageData[dwMessageDataBytes++] = liFreq.LowPart;
|
|
dwMessageData[dwMessageDataBytes++] = liFreq.HighPart;
|
|
dwMessageDataBytes *= sizeof(DWORD);
|
|
ReportEvent (hEventLog,
|
|
EVENTLOG_WARNING_TYPE, // error type
|
|
0, // category (not used)
|
|
(DWORD)PERFMON_ERROR_VALUE_OUT_OF_RANGE, // event,
|
|
NULL, // SID (not used),
|
|
wMessageIndex, // number of strings
|
|
dwMessageDataBytes, // sizeof raw data
|
|
szMessageArray, // message text array
|
|
(LPVOID)&dwMessageData[0]); // raw data
|
|
}
|
|
eCount = 100.0f; // limit value to 100.0%
|
|
}
|
|
return(eCount) ;
|
|
} // Counter_Timer_Common
|
|
|
|
|
|
FLOAT
|
|
Counter_Raw_Fraction(
|
|
IN PLINESTRUCT pLineStruct,
|
|
IN BOOL bLargeValue
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Evaluate a raw fraction (no time, just two values: Numerator and
|
|
Denominator) and multiply by 100 (to make a percentage;
|
|
|
|
Arguments:
|
|
|
|
IN pLineStruct
|
|
Line structure containing data to perform computations on
|
|
|
|
Return Value:
|
|
|
|
Floating point representation of outcome
|
|
--*/
|
|
{
|
|
FLOAT eCount ;
|
|
|
|
LARGE_INTEGER liNumerator;
|
|
|
|
if (pLineStruct->lnaCounterValue[0].LowPart == 0) {
|
|
// numerator is 0 so just bail here
|
|
return (FLOAT)0.0f;
|
|
} else {
|
|
if (!bLargeValue) {
|
|
liNumerator.QuadPart =
|
|
pLineStruct->lnaCounterValue[0].LowPart * 100L;
|
|
} else {
|
|
liNumerator.QuadPart =
|
|
pLineStruct->lnaCounterValue[0].QuadPart * 100L;
|
|
}
|
|
}
|
|
|
|
// now test and compute base (denominator)
|
|
if (pLineStruct->lnaCounterValue[1].QuadPart == 0 ) {
|
|
// invalid value for denominator
|
|
if (bReportEvents) {
|
|
wMessageIndex = 0;
|
|
dwMessageDataBytes = 0;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnSystemName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnObjectName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnCounterName;
|
|
if (pLineStruct->lnInstanceName != NULL){
|
|
if (pLineStruct->lnPINName != NULL) {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnPINName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
dwMessageData[dwMessageDataBytes++] = // recent data
|
|
pLineStruct->lnaCounterValue[0].LowPart;
|
|
dwMessageData[dwMessageDataBytes++] = // recent data
|
|
pLineStruct->lnaCounterValue[1].LowPart;
|
|
dwMessageDataBytes *= sizeof (DWORD);
|
|
ReportEvent (hEventLog,
|
|
EVENTLOG_ERROR_TYPE, // error type
|
|
0, // category (not used)
|
|
(DWORD)PERFMON_ERROR_INVALID_BASE, // event,
|
|
NULL, // SID (not used),
|
|
wMessageIndex, // number of strings
|
|
dwMessageDataBytes, // sizeof raw data
|
|
szMessageArray, // message text array
|
|
(LPVOID)&dwMessageData[0]); // raw data
|
|
}
|
|
return (0.0f);
|
|
} else {
|
|
// if base is OK, then get fraction
|
|
eCount = eLIntToFloat(&liNumerator) /
|
|
(FLOAT) pLineStruct->lnaCounterValue[1].QuadPart;
|
|
return(eCount) ;
|
|
}
|
|
} // Counter_Raw_Fraction
|
|
|
|
|
|
FLOAT
|
|
eElapsedTime(
|
|
PLINESTRUCT pLineStruct,
|
|
INT iType
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Converts 100NS elapsed time to fractional seconds
|
|
|
|
Arguments:
|
|
|
|
IN pLineStruct
|
|
Line structure containing data to perform computations on
|
|
|
|
IN iType
|
|
Unused.
|
|
|
|
Return Value:
|
|
|
|
Floating point representation of elapsed time in seconds
|
|
--*/
|
|
{
|
|
FLOAT eSeconds ;
|
|
|
|
LARGE_INTEGER liDifference;
|
|
|
|
if (pLineStruct->lnaCounterValue[0].QuadPart <= 0) {
|
|
// no data [start time = 0] so return 0
|
|
// this really doesn't warrant an error message
|
|
return (FLOAT) 0.0f;
|
|
} else {
|
|
// otherwise compute difference between current time and start time
|
|
liDifference.QuadPart =
|
|
pLineStruct->lnNewTime.QuadPart - // sample time in obj. units
|
|
pLineStruct->lnaCounterValue[0].QuadPart; // start time in obj. units
|
|
|
|
if ((liDifference.QuadPart <= 0) ||
|
|
(pLineStruct->lnObject.PerfFreq.QuadPart <= 0)) {
|
|
|
|
if ((bReportEvents) && ((liDifference.QuadPart < 0) ||
|
|
(pLineStruct->lnObject.PerfFreq.QuadPart < 0))) {
|
|
wMessageIndex = 0;
|
|
dwMessageDataBytes = 0;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnSystemName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnObjectName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnCounterName;
|
|
if (pLineStruct->lnInstanceName != NULL){
|
|
if (pLineStruct->lnPINName != NULL) {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnPINName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
if (liDifference.QuadPart < 0) {
|
|
dwMessageData[dwMessageDataBytes++] =
|
|
pLineStruct->lnNewTime.LowPart;
|
|
dwMessageData[dwMessageDataBytes++] =
|
|
pLineStruct->lnNewTime.HighPart;
|
|
dwMessageData[dwMessageDataBytes++] =
|
|
pLineStruct->lnaCounterValue[0].LowPart;
|
|
dwMessageData[dwMessageDataBytes++] =
|
|
pLineStruct->lnaCounterValue[0].HighPart;
|
|
dwMessageDataBytes *= sizeof(DWORD); // convert index to size
|
|
ReportEvent (hEventLog,
|
|
EVENTLOG_ERROR_TYPE, // error type
|
|
0, // category (not used)
|
|
(DWORD)PERFMON_ERROR_NEGATIVE_TIME, // event,
|
|
NULL, // SID (not used),
|
|
wMessageIndex, // number of strings
|
|
dwMessageDataBytes, // sizeof raw data
|
|
szMessageArray, // message text array
|
|
(LPVOID)&dwMessageData[0]); // raw data
|
|
} else {
|
|
dwMessageData[dwMessageDataBytes++] =
|
|
pLineStruct->lnObject.PerfFreq.LowPart;
|
|
dwMessageData[dwMessageDataBytes++] =
|
|
pLineStruct->lnObject.PerfFreq.HighPart;
|
|
dwMessageDataBytes *= sizeof(DWORD); // convert index to size
|
|
ReportEvent (hEventLog,
|
|
EVENTLOG_ERROR_TYPE, // error type
|
|
0, // category (not used)
|
|
(DWORD)PERFMON_ERROR_BAD_FREQUENCY, // event,
|
|
NULL, // SID (not used),
|
|
wMessageIndex, // number of strings
|
|
dwMessageDataBytes, // sizeof raw data
|
|
szMessageArray, // message text array
|
|
(LPVOID)&dwMessageData[0]); // raw data
|
|
}
|
|
}
|
|
return (FLOAT) 0.0f;
|
|
} else {
|
|
// convert to fractional seconds using object counter
|
|
eSeconds = eLIntToFloat (&liDifference);
|
|
eSeconds /= eLIntToFloat (&pLineStruct->lnObject.PerfFreq);
|
|
|
|
return (eSeconds);
|
|
}
|
|
}
|
|
|
|
} // eElapsedTime
|
|
|
|
|
|
FLOAT
|
|
Sample_Common(
|
|
PLINESTRUCT pLineStruct,
|
|
INT iType
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Divites "Top" differenced by Base Difference
|
|
|
|
Arguments:
|
|
|
|
IN pLineStruct
|
|
Line structure containing data to perform computations on
|
|
|
|
IN iType
|
|
Counter Type
|
|
|
|
Return Value:
|
|
|
|
Floating point representation of outcome
|
|
--*/
|
|
{
|
|
double eCount ;
|
|
|
|
LONG lDifference;
|
|
LONG lBaseDifference;
|
|
|
|
double dReturn;
|
|
|
|
lDifference = pLineStruct->lnaCounterValue[0].LowPart -
|
|
pLineStruct->lnaOldCounterValue[0].LowPart ;
|
|
|
|
if (lDifference <= 0) {
|
|
if ((lDifference < 0) && bReportEvents) {
|
|
wMessageIndex = 0;
|
|
dwMessageDataBytes = 0;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnSystemName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnObjectName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnCounterName;
|
|
if (pLineStruct->lnInstanceName != NULL){
|
|
if (pLineStruct->lnPINName != NULL) {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnPINName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
dwMessageData[dwMessageDataBytes++] = // recent data
|
|
pLineStruct->lnaCounterValue[0].LowPart;
|
|
dwMessageData[dwMessageDataBytes++] = // previous data
|
|
pLineStruct->lnaOldCounterValue[0].LowPart;
|
|
dwMessageDataBytes *= sizeof(DWORD); // convert index to size
|
|
ReportEvent (hEventLog,
|
|
EVENTLOG_WARNING_TYPE, // error type
|
|
0, // category (not used)
|
|
(DWORD)PERFMON_ERROR_NEGATIVE_VALUE, // event,
|
|
NULL, // SID (not used),
|
|
wMessageIndex, // number of strings
|
|
dwMessageDataBytes, // sizeof raw data
|
|
szMessageArray, // message text array
|
|
(LPVOID)&dwMessageData[0]); // raw data
|
|
}
|
|
dReturn = (double) 0.0f;
|
|
} else {
|
|
lBaseDifference = pLineStruct->lnaCounterValue[1].LowPart -
|
|
pLineStruct->lnaOldCounterValue[1].LowPart ;
|
|
|
|
if ( lBaseDifference <= 0 ) {
|
|
// invalid value
|
|
if ((lBaseDifference < 0 ) && bReportEvents) {
|
|
wMessageIndex = 0;
|
|
dwMessageDataBytes = 0;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnSystemName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnObjectName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnCounterName;
|
|
if (pLineStruct->lnInstanceName != NULL){
|
|
if (pLineStruct->lnPINName != NULL) {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnPINName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
dwMessageData[dwMessageDataBytes++] = // recent data
|
|
pLineStruct->lnaCounterValue[1].LowPart;
|
|
dwMessageData[dwMessageDataBytes++] = // previous data
|
|
pLineStruct->lnaOldCounterValue[1].LowPart;
|
|
dwMessageDataBytes *= sizeof(DWORD); // convert index to size
|
|
ReportEvent (hEventLog,
|
|
EVENTLOG_ERROR_TYPE, // error type
|
|
0, // category (not used)
|
|
(DWORD)PERFMON_ERROR_INVALID_BASE, // event,
|
|
NULL, // SID (not used),
|
|
wMessageIndex, // number of strings
|
|
dwMessageDataBytes, // sizeof raw data
|
|
szMessageArray, // message text array
|
|
(LPVOID)&dwMessageData[0]); // raw data
|
|
}
|
|
dReturn = (0.0f);
|
|
} else {
|
|
eCount = lDifference / lBaseDifference ;
|
|
|
|
if (iType == FRACTION) {
|
|
eCount *= 100.0f ;
|
|
}
|
|
dReturn = eCount;
|
|
}
|
|
}
|
|
|
|
return (FLOAT)dReturn;
|
|
} // Sample_Common
|
|
|
|
|
|
//==========================================================================//
|
|
// Exported Functions //
|
|
//==========================================================================//
|
|
|
|
|
|
/*****************************************************************************
|
|
* Counter_Counter - Take the difference between the current and previous
|
|
* counts then divide by the time interval
|
|
****************************************************************************/
|
|
#define Counter_Counter(pLineStruct) \
|
|
Counter_Counter_Common(pLineStruct, 0)
|
|
|
|
/*****************************************************************************
|
|
* Counter_Bulk - Take the difference between the current and previous
|
|
* counts then divide by the time interval
|
|
* Same as a Counter_counter except it uses large_ints
|
|
****************************************************************************/
|
|
#define Counter_Bulk(pLineStruct) \
|
|
Counter_Counter_Common(pLineStruct, BULK)
|
|
|
|
|
|
/*****************************************************************************
|
|
* Counter_Timer100Ns -
|
|
*
|
|
* Need to review with RussBl exactly what he is doing here.
|
|
****************************************************************************/
|
|
#define Counter_Timer100Ns(pLineStruct) \
|
|
Counter_Timer_Common(pLineStruct, NS100)
|
|
|
|
/*****************************************************************************
|
|
* Counter_Timer100Ns_Inv -
|
|
*
|
|
* Need to review with RussBl exactly what he is doing here.
|
|
****************************************************************************/
|
|
#define Counter_Timer100Ns_Inv(pLineStruct) \
|
|
Counter_Timer_Common(pLineStruct, NS100_INVERT)
|
|
|
|
/*****************************************************************************
|
|
* Counter_Timer_Multi -
|
|
*
|
|
* Need to review with RussBl exactly what he is doing here.
|
|
****************************************************************************/
|
|
#define Counter_Timer_Multi(pLineStruct) \
|
|
Counter_Timer_Common(pLineStruct, TIMER_MULTI)
|
|
|
|
/*****************************************************************************
|
|
* Counter_Timer_Multi_Inv -
|
|
*
|
|
* Need to review with RussBl exactly what he is doing here.
|
|
****************************************************************************/
|
|
#define Counter_Timer_Multi_Inv(pLineStruct) \
|
|
Counter_Timer_Common(pLineStruct, TIMER_MULTI_INVERT)
|
|
|
|
/*****************************************************************************
|
|
* Counter_Timer100Ns_Multi -
|
|
*
|
|
* Need to review with RussBl exactly what he is doing here.
|
|
****************************************************************************/
|
|
#define Counter_Timer100Ns_Multi(pLineStruct) \
|
|
Counter_Timer_Common(pLineStruct, NS100_MULTI)
|
|
|
|
/*****************************************************************************
|
|
* Counter_Timer100Ns_Multi_Inv -
|
|
*
|
|
* Need to review with RussBl exactly what he is doing here.
|
|
****************************************************************************/
|
|
#define Counter_Timer100Ns_Multi_Inv(pLineStruct) \
|
|
Counter_Timer_Common(pLineStruct, NS100_MULTI_INVERT)
|
|
|
|
/*****************************************************************************
|
|
* Counter_Timer - Take the difference between the current and previous
|
|
* counts,
|
|
* Normalize the count (counts per interval)
|
|
* divide by the time interval (count = % of interval)
|
|
* multiply by 100 (convert to a percentage)
|
|
* this value from 100.
|
|
****************************************************************************/
|
|
#define Counter_Timer(pLineStruct) \
|
|
Counter_Timer_Common(pLineStruct, 0)
|
|
|
|
/*****************************************************************************
|
|
* Counter_Timer_Inv - Take the difference between the current and previous
|
|
* counts,
|
|
* Normalize the count (counts per interval)
|
|
* divide by the time interval (count = % of interval)
|
|
* subtract from 1 (the normalized size of an interval)
|
|
* multiply by 100 (convert to a percentage)
|
|
* this value from 100.
|
|
****************************************************************************/
|
|
#define Counter_Timer_Inv(pLineStruct) \
|
|
Counter_Timer_Common(pLineStruct, INVERT)
|
|
|
|
/*****************************************************************************
|
|
* Sample_Counter -
|
|
****************************************************************************/
|
|
#define Sample_Counter(pLineStruct) \
|
|
Sample_Common(pLineStruct, 0)
|
|
|
|
/*****************************************************************************
|
|
* Sample_Fraction -
|
|
****************************************************************************/
|
|
#define Sample_Fraction(pLineStruct) \
|
|
Sample_Common(pLineStruct, FRACTION)
|
|
|
|
/*****************************************************************************
|
|
* Counter_Rawcount - This is just a raw count.
|
|
****************************************************************************/
|
|
#define Counter_Rawcount(pLineStruct) \
|
|
((FLOAT) (pLineStruct->lnaCounterValue[0].LowPart))
|
|
|
|
/*****************************************************************************
|
|
* Counter_Large_Rawcount - This is just a raw count.
|
|
****************************************************************************/
|
|
#define Counter_Large_Rawcount(pLineStruct) \
|
|
((FLOAT) eLIntToFloat(&(pLineStruct->lnaCounterValue[0])))
|
|
|
|
/*****************************************************************************
|
|
* Counter_Elapsed_Time -
|
|
****************************************************************************/
|
|
#define Counter_Elapsed_Time(pLineStruct) \
|
|
eElapsedTime (pLineStruct, 0)
|
|
|
|
#define CQLFLAGS_LARGE ((DWORD)0x00000001)
|
|
#define CQLFLAGS_100NS ((DWORD)0x00000002)
|
|
|
|
FLOAT Counter_Queuelen(PLINESTRUCT pLineStruct, DWORD dwFlags)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Take the difference between the current and previous counts,
|
|
divide by the time interval (count = decimal fraction of interval)
|
|
Value can exceed 1.00.
|
|
|
|
Arguments:
|
|
|
|
IN pLineStruct
|
|
Line structure containing data to perform computations on
|
|
|
|
IN iType
|
|
Counter Type
|
|
|
|
Return Value:
|
|
|
|
Floating point representation of outcome
|
|
--*/
|
|
{
|
|
FLOAT eTimeDiff;
|
|
FLOAT eDifference;
|
|
FLOAT eCount;
|
|
|
|
LONGLONG llDifference;
|
|
LONGLONG llTimeDiff;
|
|
|
|
// Get the amount of time that has passed since the last sample
|
|
|
|
if (dwFlags & CQLFLAGS_100NS) {
|
|
llTimeDiff = pLineStruct->lnNewTime100Ns.QuadPart -
|
|
pLineStruct->lnOldTime100Ns.QuadPart;
|
|
} else {
|
|
llTimeDiff = pLineStruct->lnNewTime.QuadPart -
|
|
pLineStruct->lnOldTime.QuadPart;
|
|
}
|
|
|
|
if (llTimeDiff <= 0) {
|
|
if ((llTimeDiff < 0 ) && bReportEvents) {
|
|
wMessageIndex = 0;
|
|
dwMessageDataBytes = 0;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnSystemName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnObjectName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnCounterName;
|
|
if (pLineStruct->lnInstanceName != NULL){
|
|
if (pLineStruct->lnPINName != NULL) {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnPINName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
dwMessageData[dwMessageDataBytes++] = // recent data
|
|
pLineStruct->lnNewTime.LowPart;
|
|
dwMessageData[dwMessageDataBytes++] = // recent data
|
|
pLineStruct->lnNewTime.HighPart;
|
|
dwMessageData[dwMessageDataBytes++] = // previous data
|
|
pLineStruct->lnOldTime.LowPart;
|
|
dwMessageData[dwMessageDataBytes++] = // previous data
|
|
pLineStruct->lnOldTime.HighPart;
|
|
dwMessageDataBytes *= sizeof(DWORD); // convert index to size
|
|
ReportEvent (hEventLog,
|
|
EVENTLOG_ERROR_TYPE, // error type
|
|
0, // category (not used)
|
|
(DWORD)PERFMON_ERROR_NEGATIVE_TIME, // event,
|
|
NULL, // SID (not used),
|
|
wMessageIndex, // number of strings
|
|
dwMessageDataBytes, // sizeof raw data
|
|
szMessageArray, // message text array
|
|
(LPVOID)&dwMessageData[0]); // raw data
|
|
}
|
|
return (FLOAT)0.0f;
|
|
} else {
|
|
eTimeDiff = (FLOAT)llTimeDiff;
|
|
}
|
|
|
|
// Get the current and previous counts.
|
|
|
|
if (dwFlags & CQLFLAGS_LARGE) {
|
|
llDifference = pLineStruct->lnaCounterValue[0].QuadPart -
|
|
pLineStruct->lnaOldCounterValue[0].QuadPart;
|
|
} else {
|
|
llDifference = (LONGLONG)(pLineStruct->lnaCounterValue[0].LowPart -
|
|
pLineStruct->lnaOldCounterValue[0].LowPart);
|
|
}
|
|
|
|
eDifference = (FLOAT)llDifference;
|
|
|
|
if (eDifference < 0.0f) {
|
|
if (bReportEvents) {
|
|
wMessageIndex = 0;
|
|
dwMessageDataBytes = 0;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnSystemName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnObjectName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnCounterName;
|
|
if (pLineStruct->lnInstanceName != NULL){
|
|
if (pLineStruct->lnPINName != NULL) {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnPINName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
if (!(dwFlags & CQLFLAGS_LARGE)) {
|
|
dwMessageData[dwMessageDataBytes++] = // recent data
|
|
pLineStruct->lnaCounterValue[0].LowPart;
|
|
dwMessageData[dwMessageDataBytes++] = // previous data
|
|
pLineStruct->lnaOldCounterValue[0].LowPart;
|
|
} else { // 8 byte counter values
|
|
dwMessageData[dwMessageDataBytes++] = // recent data
|
|
pLineStruct->lnaCounterValue[0].LowPart;
|
|
dwMessageData[dwMessageDataBytes++] = // recent data
|
|
pLineStruct->lnaCounterValue[0].HighPart;
|
|
dwMessageData[dwMessageDataBytes++] = // previous data
|
|
pLineStruct->lnaOldCounterValue[0].LowPart;
|
|
dwMessageData[dwMessageDataBytes++] = // previous data
|
|
pLineStruct->lnaOldCounterValue[0].HighPart;
|
|
}
|
|
dwMessageDataBytes *= sizeof(DWORD); // convert index to size
|
|
ReportEvent (hEventLog,
|
|
EVENTLOG_WARNING_TYPE, // error type
|
|
0, // category (not used)
|
|
(DWORD)PERFMON_ERROR_NEGATIVE_VALUE, // event,
|
|
NULL, // SID (not used),
|
|
wMessageIndex, // number of strings
|
|
dwMessageDataBytes, // sizeof raw data
|
|
szMessageArray, // message text array
|
|
(LPVOID)&dwMessageData[0]); // raw data
|
|
}
|
|
eCount = 0.0f ;
|
|
} else {
|
|
eCount = eDifference / eTimeDiff;
|
|
}
|
|
|
|
return(eCount) ;
|
|
|
|
}
|
|
|
|
FLOAT Counter_Delta(PLINESTRUCT pLineStruct, BOOL bLargeData)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Take the difference between the current and previous counts,
|
|
|
|
Arguments:
|
|
|
|
IN pLineStruct
|
|
Line structure containing data to perform computations on
|
|
|
|
Return Value:
|
|
|
|
Floating point representation of outcome
|
|
--*/
|
|
{
|
|
FLOAT eDifference;
|
|
LONGLONG llDifference;
|
|
ULONGLONG ullThisValue, ullPrevValue;
|
|
|
|
// Get the current and previous counts.
|
|
|
|
if (!bLargeData) {
|
|
// then clear the high part of the word
|
|
ullThisValue = (ULONGLONG)pLineStruct->lnaCounterValue[0].LowPart;
|
|
ullPrevValue = (ULONGLONG)pLineStruct->lnaOldCounterValue[0].LowPart;
|
|
} else {
|
|
ullThisValue = (ULONGLONG)pLineStruct->lnaCounterValue[0].QuadPart;
|
|
ullPrevValue = (ULONGLONG)pLineStruct->lnaOldCounterValue[0].QuadPart;
|
|
}
|
|
|
|
if (ullThisValue > ullPrevValue) {
|
|
llDifference = (LONGLONG)(ullThisValue - ullPrevValue);
|
|
eDifference = (FLOAT)llDifference;
|
|
} else {
|
|
// the new value is smaller than or equal to the old value
|
|
// and negative numbers are not allowed.
|
|
if ((ullThisValue < ullPrevValue) && bReportEvents) {
|
|
wMessageIndex = 0;
|
|
dwMessageDataBytes = 0;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnSystemName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnObjectName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnCounterName;
|
|
if (pLineStruct->lnInstanceName != NULL){
|
|
if (pLineStruct->lnPINName != NULL) {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnPINName;
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = pLineStruct->lnInstanceName;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
} else {
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
szMessageArray[wMessageIndex++] = cszSpace;
|
|
}
|
|
if (!bLargeData) {
|
|
dwMessageData[dwMessageDataBytes++] = // recent data
|
|
pLineStruct->lnaCounterValue[0].LowPart;
|
|
dwMessageData[dwMessageDataBytes++] = // previous data
|
|
pLineStruct->lnaOldCounterValue[0].LowPart;
|
|
} else { // 8 byte counter values
|
|
dwMessageData[dwMessageDataBytes++] = // recent data
|
|
pLineStruct->lnaCounterValue[0].LowPart;
|
|
dwMessageData[dwMessageDataBytes++] = // recent data
|
|
pLineStruct->lnaCounterValue[0].HighPart;
|
|
dwMessageData[dwMessageDataBytes++] = // previous data
|
|
pLineStruct->lnaOldCounterValue[0].LowPart;
|
|
dwMessageData[dwMessageDataBytes++] = // previous data
|
|
pLineStruct->lnaOldCounterValue[0].HighPart;
|
|
}
|
|
dwMessageDataBytes *= sizeof(DWORD); // convert index to size
|
|
ReportEvent (hEventLog,
|
|
EVENTLOG_WARNING_TYPE, // error type
|
|
0, // category (not used)
|
|
(DWORD)PERFMON_ERROR_NEGATIVE_VALUE, // event,
|
|
NULL, // SID (not used),
|
|
wMessageIndex, // number of strings
|
|
dwMessageDataBytes, // sizeof raw data
|
|
szMessageArray, // message text array
|
|
(LPVOID)&dwMessageData[0]); // raw data
|
|
}
|
|
eDifference = 0.0f;
|
|
}
|
|
|
|
return(eDifference) ;
|
|
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Counter_Null - The counters that return nothing go here.
|
|
****************************************************************************/
|
|
#define Counter_Null(pline) \
|
|
((FLOAT) 0.0)
|
|
|
|
|
|
FLOAT
|
|
CounterEntry (
|
|
PLINESTRUCT pLine
|
|
)
|
|
{
|
|
FLOAT fReturn;
|
|
|
|
#ifdef DBG_COUNTER_DATA
|
|
PLINESTRUCT pLineStruct = pLine;
|
|
WCHAR szBuffer[512];
|
|
WCHAR szBuffer2[512];
|
|
|
|
swprintf (szBuffer2, L"\nPERFMON:CALC\t%s\\%s",
|
|
pLineStruct->lnSystemName,
|
|
pLineStruct->lnObjectName);
|
|
lstrcpyW (szBuffer, szBuffer2);
|
|
|
|
if (pLineStruct->lnInstanceName != NULL){
|
|
if (pLineStruct->lnPINName != NULL) {
|
|
swprintf (szBuffer2, L"\\(%s/%s)",
|
|
pLineStruct->lnPINName,
|
|
pLineStruct->lnInstanceName);
|
|
} else {
|
|
swprintf (szBuffer2, L"\\(%s)",
|
|
pLineStruct->lnInstanceName);
|
|
}
|
|
lstrcatW (szBuffer, szBuffer2);
|
|
}
|
|
|
|
swprintf (szBuffer2, L"\\%s\t%u\t%I64u\t%I64u\t%I64u",
|
|
pLineStruct->lnCounterName,
|
|
pLineStruct->lnCounterType,
|
|
pLineStruct->lnNewTime100Ns,
|
|
pLineStruct->lnaCounterValue[0].QuadPart,
|
|
pLineStruct->lnaCounterValue[1].QuadPart);
|
|
lstrcatW (szBuffer, szBuffer2);
|
|
|
|
#endif
|
|
|
|
switch (pLine->lnCounterType) {
|
|
case PERF_COUNTER_COUNTER:
|
|
fReturn = Counter_Counter (pLine);
|
|
break;
|
|
|
|
case PERF_COUNTER_TIMER:
|
|
case PERF_PRECISION_SYSTEM_TIMER: // precision value is not used
|
|
fReturn = Counter_Timer (pLine);
|
|
break;
|
|
|
|
case PERF_COUNTER_QUEUELEN_TYPE:
|
|
fReturn = Counter_Queuelen(pLine, 0);
|
|
break;
|
|
|
|
case PERF_COUNTER_LARGE_QUEUELEN_TYPE:
|
|
fReturn = Counter_Queuelen(pLine, CQLFLAGS_LARGE);
|
|
break;
|
|
|
|
case PERF_COUNTER_100NS_QUEUELEN_TYPE:
|
|
fReturn = Counter_Queuelen(pLine, CQLFLAGS_LARGE | CQLFLAGS_100NS);
|
|
break;
|
|
|
|
case PERF_COUNTER_BULK_COUNT:
|
|
fReturn = Counter_Bulk (pLine);
|
|
break;
|
|
|
|
case PERF_COUNTER_RAWCOUNT:
|
|
case PERF_COUNTER_RAWCOUNT_HEX:
|
|
fReturn = Counter_Rawcount(pLine);
|
|
break;
|
|
|
|
case PERF_COUNTER_LARGE_RAWCOUNT:
|
|
case PERF_COUNTER_LARGE_RAWCOUNT_HEX:
|
|
fReturn = Counter_Large_Rawcount(pLine);
|
|
break;
|
|
|
|
case PERF_SAMPLE_FRACTION:
|
|
fReturn = Sample_Fraction(pLine);
|
|
break;
|
|
|
|
case PERF_SAMPLE_COUNTER:
|
|
fReturn = Sample_Counter (pLine);
|
|
break;
|
|
|
|
case PERF_COUNTER_TIMER_INV:
|
|
fReturn = Counter_Timer_Inv (pLine);
|
|
break;
|
|
|
|
case PERF_AVERAGE_TIMER:
|
|
fReturn = Counter_Average_Timer (pLine);
|
|
break;
|
|
|
|
case PERF_AVERAGE_BULK:
|
|
fReturn = Counter_Average_Bulk (pLine);
|
|
break;
|
|
|
|
case PERF_100NSEC_TIMER:
|
|
case PERF_PRECISION_100NS_TIMER: // precision value is not used
|
|
fReturn = Counter_Timer100Ns (pLine);
|
|
break;
|
|
|
|
case PERF_100NSEC_TIMER_INV:
|
|
fReturn = Counter_Timer100Ns_Inv (pLine);
|
|
break;
|
|
|
|
case PERF_COUNTER_MULTI_TIMER:
|
|
fReturn = Counter_Timer_Multi (pLine);
|
|
break;
|
|
|
|
case PERF_COUNTER_MULTI_TIMER_INV:
|
|
fReturn = Counter_Timer_Multi_Inv (pLine);
|
|
break;
|
|
|
|
case PERF_100NSEC_MULTI_TIMER:
|
|
fReturn = Counter_Timer100Ns_Multi (pLine);
|
|
break;
|
|
|
|
case PERF_100NSEC_MULTI_TIMER_INV:
|
|
fReturn = Counter_Timer100Ns_Multi_Inv (pLine);
|
|
break;
|
|
|
|
case PERF_RAW_FRACTION:
|
|
fReturn = Counter_Raw_Fraction (pLine, FALSE);
|
|
break;
|
|
|
|
case PERF_LARGE_RAW_FRACTION:
|
|
fReturn = Counter_Raw_Fraction (pLine, TRUE);
|
|
break;
|
|
|
|
case PERF_ELAPSED_TIME:
|
|
fReturn = Counter_Elapsed_Time (pLine);
|
|
break;
|
|
|
|
case PERF_COUNTER_DELTA:
|
|
fReturn = Counter_Delta(pLine, FALSE);
|
|
break;
|
|
|
|
case PERF_COUNTER_LARGE_DELTA:
|
|
fReturn = Counter_Delta(pLine, TRUE);
|
|
break;
|
|
|
|
case PERF_COUNTER_TEXT:
|
|
case PERF_COUNTER_NODATA:
|
|
case PERF_RAW_BASE:
|
|
case PERF_LARGE_RAW_BASE:
|
|
case PERF_COUNTER_MULTI_BASE:
|
|
// case PERF_SAMPLE_BASE:
|
|
// case PERF_AVERAGE_BASE:
|
|
default:
|
|
fReturn = Counter_Null (pLine);
|
|
break;
|
|
}
|
|
|
|
#ifdef DBG_COUNTER_DATA
|
|
swprintf (szBuffer2, L"\t%g", fReturn);
|
|
lstrcatW (szBuffer, szBuffer2);
|
|
OutputDebugStringW(szBuffer);
|
|
#endif
|
|
|
|
return fReturn;
|
|
}
|
|
|
|
|
|
BOOL
|
|
IsCounterSupported (
|
|
DWORD dwCounterType
|
|
)
|
|
{
|
|
switch (dwCounterType) {
|
|
// supported counters
|
|
case PERF_COUNTER_COUNTER:
|
|
case PERF_COUNTER_TIMER:
|
|
case PERF_COUNTER_QUEUELEN_TYPE:
|
|
case PERF_COUNTER_LARGE_QUEUELEN_TYPE:
|
|
case PERF_COUNTER_100NS_QUEUELEN_TYPE:
|
|
case PERF_COUNTER_BULK_COUNT:
|
|
case PERF_COUNTER_RAWCOUNT:
|
|
case PERF_COUNTER_RAWCOUNT_HEX:
|
|
case PERF_COUNTER_LARGE_RAWCOUNT:
|
|
case PERF_COUNTER_LARGE_RAWCOUNT_HEX:
|
|
case PERF_SAMPLE_FRACTION:
|
|
case PERF_SAMPLE_COUNTER:
|
|
case PERF_COUNTER_TIMER_INV:
|
|
case PERF_AVERAGE_TIMER:
|
|
case PERF_AVERAGE_BULK:
|
|
case PERF_100NSEC_TIMER:
|
|
case PERF_100NSEC_TIMER_INV:
|
|
case PERF_COUNTER_MULTI_TIMER:
|
|
case PERF_COUNTER_MULTI_TIMER_INV:
|
|
case PERF_100NSEC_MULTI_TIMER:
|
|
case PERF_100NSEC_MULTI_TIMER_INV:
|
|
case PERF_RAW_FRACTION:
|
|
case PERF_ELAPSED_TIME:
|
|
case PERF_COUNTER_DELTA:
|
|
case PERF_COUNTER_LARGE_DELTA:
|
|
case PERF_PRECISION_100NS_TIMER:
|
|
case PERF_PRECISION_SYSTEM_TIMER:
|
|
case PERF_LARGE_RAW_FRACTION:
|
|
return TRUE;
|
|
|
|
// unsupported counters
|
|
case PERF_COUNTER_TEXT:
|
|
case PERF_COUNTER_NODATA:
|
|
case PERF_RAW_BASE:
|
|
case PERF_LARGE_RAW_BASE:
|
|
// case PERF_SAMPLE_BASE:
|
|
// case PERF_AVERAGE_BASE:
|
|
case PERF_COUNTER_MULTI_BASE:
|
|
// case PERF_PRECISION_TIMESTAMP:
|
|
default:
|
|
return FALSE;
|
|
|
|
}
|
|
}
|