279 lines
6.9 KiB
C
279 lines
6.9 KiB
C
|
/*++ BUILD Version: 0001 // Increment this if a change has global effects
|
||
|
|
||
|
Copyright (c) 1998-1999 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
PerfUtil.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This file implements utility functions for performance monitoring functions
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Eliot Gillum (t-eliotg) - July 5, 1998
|
||
|
|
||
|
Revision History
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include <windows.h>
|
||
|
#include <winperf.h>
|
||
|
#include "PerfUtil.h"
|
||
|
|
||
|
|
||
|
WCHAR GLOBAL_STRING[] = L"Global";
|
||
|
WCHAR FOREIGN_STRING[] = L"Foreign";
|
||
|
WCHAR COSTLY_STRING[] = L"Costly";
|
||
|
WCHAR NULL_STRING[] = L"\0"; // pointer to null string
|
||
|
|
||
|
|
||
|
// test for delimiter, end of line and non-digit characters
|
||
|
// used by IsNumberInUnicodeList routine
|
||
|
//
|
||
|
#define DIGIT 1
|
||
|
#define DELIMITER 2
|
||
|
#define INVALID 3
|
||
|
|
||
|
#define EvalThisChar(c,d) ( \
|
||
|
(c == d) ? DELIMITER : \
|
||
|
(c == 0) ? DELIMITER : \
|
||
|
(c < (WCHAR)'0') ? INVALID : \
|
||
|
(c > (WCHAR)'9') ? INVALID : \
|
||
|
DIGIT)
|
||
|
|
||
|
|
||
|
// convertIndices()
|
||
|
// Takes a pointer to an array of PERF_COUNTER_DEFINITIONs and converts their indices
|
||
|
// to be absolute by adding the appropriate value (dwFirstCounter/dwFirstHelp)
|
||
|
//
|
||
|
// BYTE *buf Pointer to an array of PERF_COUNTER_DEFINITIONs
|
||
|
// int numCounters The number of PERF_COUNTER_DEFINITIONs to convert
|
||
|
// DWORD dwFirstCounter Absolute index of the first counter in the series
|
||
|
// DWORD dwFirstHelp Absolute index of the first help index in the series
|
||
|
void convertIndices(BYTE *buf, int numCounters, DWORD dwFirstCounter, DWORD dwFirstHelp)
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
// then the counter indices
|
||
|
for (i=0; i<numCounters; i++) {
|
||
|
((PERF_COUNTER_DEFINITION *)buf)->CounterNameTitleIndex += dwFirstCounter;
|
||
|
((PERF_COUNTER_DEFINITION *)buf)->CounterHelpTitleIndex += dwFirstHelp;
|
||
|
buf += sizeof(PERF_COUNTER_DEFINITION);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
DWORD
|
||
|
GetQueryType (
|
||
|
IN LPWSTR lpValue
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
GetQueryType
|
||
|
|
||
|
returns the type of query described in the lpValue string so that
|
||
|
the appropriate processing method may be used
|
||
|
|
||
|
Arguments
|
||
|
|
||
|
IN lpValue
|
||
|
string passed to PerfRegQuery Value for processing
|
||
|
|
||
|
Return Value
|
||
|
|
||
|
QUERY_GLOBAL
|
||
|
if lpValue == 0 (null pointer)
|
||
|
lpValue == pointer to Null string
|
||
|
lpValue == pointer to "Global" string
|
||
|
|
||
|
QUERY_FOREIGN
|
||
|
if lpValue == pointer to "Foreign" string
|
||
|
|
||
|
QUERY_COSTLY
|
||
|
if lpValue == pointer to "Costly" string
|
||
|
|
||
|
otherwise:
|
||
|
|
||
|
QUERY_ITEMS
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
WCHAR *pwcArgChar, *pwcTypeChar;
|
||
|
BOOL bFound;
|
||
|
|
||
|
if (lpValue == 0) {
|
||
|
return QUERY_GLOBAL;
|
||
|
} else if (*lpValue == 0) {
|
||
|
return QUERY_GLOBAL;
|
||
|
}
|
||
|
|
||
|
// check for "Global" request
|
||
|
|
||
|
pwcArgChar = lpValue;
|
||
|
pwcTypeChar = GLOBAL_STRING;
|
||
|
bFound = TRUE; // assume found until contradicted
|
||
|
|
||
|
// check to the length of the shortest string
|
||
|
|
||
|
while ((*pwcArgChar != 0) && (*pwcTypeChar != 0)) {
|
||
|
if (*pwcArgChar++ != *pwcTypeChar++) {
|
||
|
bFound = FALSE; // no match
|
||
|
break; // bail out now
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (bFound) return QUERY_GLOBAL;
|
||
|
|
||
|
// check for "Foreign" request
|
||
|
|
||
|
pwcArgChar = lpValue;
|
||
|
pwcTypeChar = FOREIGN_STRING;
|
||
|
bFound = TRUE; // assume found until contradicted
|
||
|
|
||
|
// check to the length of the shortest string
|
||
|
|
||
|
while ((*pwcArgChar != 0) && (*pwcTypeChar != 0)) {
|
||
|
if (*pwcArgChar++ != *pwcTypeChar++) {
|
||
|
bFound = FALSE; // no match
|
||
|
break; // bail out now
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (bFound) return QUERY_FOREIGN;
|
||
|
|
||
|
// check for "Costly" request
|
||
|
|
||
|
pwcArgChar = lpValue;
|
||
|
pwcTypeChar = COSTLY_STRING;
|
||
|
bFound = TRUE; // assume found until contradicted
|
||
|
|
||
|
// check to the length of the shortest string
|
||
|
|
||
|
while ((*pwcArgChar != 0) && (*pwcTypeChar != 0)) {
|
||
|
if (*pwcArgChar++ != *pwcTypeChar++) {
|
||
|
bFound = FALSE; // no match
|
||
|
break; // bail out now
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (bFound) return QUERY_COSTLY;
|
||
|
|
||
|
// if not Global and not Foreign and not Costly,
|
||
|
// then it must be an item list
|
||
|
|
||
|
return QUERY_ITEMS;
|
||
|
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
IsNumberInUnicodeList (
|
||
|
IN DWORD dwNumber,
|
||
|
IN LPWSTR lpwszUnicodeList
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
IsNumberInUnicodeList
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
IN dwNumber
|
||
|
DWORD number to find in list
|
||
|
|
||
|
IN lpwszUnicodeList
|
||
|
Null terminated, Space delimited list of decimal numbers
|
||
|
|
||
|
Return Value:
|
||
|
TRUE: dwNumber was found in the list of unicode number strings
|
||
|
FALSE: dwNumber was not found in the list.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
DWORD dwThisNumber;
|
||
|
WCHAR *pwcThisChar;
|
||
|
BOOL bValidNumber;
|
||
|
BOOL bNewItem;
|
||
|
BOOL bReturnValue;
|
||
|
WCHAR wcDelimiter; // could be an argument to be more flexible
|
||
|
|
||
|
if (lpwszUnicodeList == 0) return FALSE; // null pointer, # not found
|
||
|
|
||
|
pwcThisChar = lpwszUnicodeList;
|
||
|
dwThisNumber = 0;
|
||
|
wcDelimiter = (WCHAR)' ';
|
||
|
bValidNumber = FALSE;
|
||
|
bNewItem = TRUE;
|
||
|
|
||
|
while (TRUE) {
|
||
|
switch (EvalThisChar (*pwcThisChar, wcDelimiter)) {
|
||
|
case DIGIT:
|
||
|
// if this is the first digit after a delimiter, then
|
||
|
// set flags to start computing the new number
|
||
|
if (bNewItem) {
|
||
|
bNewItem = FALSE;
|
||
|
bValidNumber = TRUE;
|
||
|
}
|
||
|
if (bValidNumber) {
|
||
|
dwThisNumber *= 10;
|
||
|
dwThisNumber += (*pwcThisChar - (WCHAR)'0');
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case DELIMITER:
|
||
|
// a delimiter is either the delimiter character or the
|
||
|
// end of the string ('\0') if when the delimiter has been
|
||
|
// reached a valid number was found, then compare it to the
|
||
|
// number from the argument list. if this is the end of the
|
||
|
// string and no match was found, then return.
|
||
|
//
|
||
|
if (bValidNumber) {
|
||
|
if (dwThisNumber == dwNumber) return TRUE;
|
||
|
bValidNumber = FALSE;
|
||
|
}
|
||
|
if (*pwcThisChar == 0) {
|
||
|
return FALSE;
|
||
|
} else {
|
||
|
bNewItem = TRUE;
|
||
|
dwThisNumber = 0;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case INVALID:
|
||
|
// if an invalid character was encountered, ignore all
|
||
|
// characters up to the next delimiter and then start fresh.
|
||
|
// the invalid number is not compared.
|
||
|
bValidNumber = FALSE;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
pwcThisChar++;
|
||
|
}
|
||
|
|
||
|
} // IsNumberInUnicodeList
|
||
|
|
||
|
VOID
|
||
|
CorrectInstanceName(PWCHAR IfcName)
|
||
|
{
|
||
|
WCHAR SpecialChars[] = L")(#\\/";
|
||
|
int k;
|
||
|
int r;
|
||
|
WCHAR *p;
|
||
|
|
||
|
//
|
||
|
// perfmon does not allow the following characters in the name. We need to munge the name
|
||
|
// and replace them with some other character.
|
||
|
//
|
||
|
for(r=0; SpecialChars[r]; r++)
|
||
|
{
|
||
|
p = IfcName;
|
||
|
while((p = wcschr(p, SpecialChars[r])))
|
||
|
{
|
||
|
*p = L'-';
|
||
|
}
|
||
|
}
|
||
|
}
|