home *** CD-ROM | disk | FTP | other *** search
- /*++
-
- Copyright (c) 1995-6 Microsoft Corporation
-
- Module Name:
-
- perfutil.c
-
- Abstract:
-
- This file implements the utility routines used to construct the
- common parts of a PERF_INSTANCE_DEFINITION (see winperf.h) and
- perform event logging functions.
-
- Created:
-
- Bob Watson 28-Jul-1995
-
- Revision History:
-
- --*/
- //
- // include files
- //
- #include <windows.h>
- #include <string.h>
- #include <winperf.h>
- #include "genctrs.h" // error message definition
- #include "perfmsg.h"
- #include "perfutil.h"
-
- //
- // Global data definitions.
- //
-
- ULONG ulInfoBufferSize = 0;
-
- HANDLE hEventLog = NULL; // event log handle for reporting events
- // initialized in Open... routines
- DWORD dwLogUsers = 0; // count of functions using event log
-
- DWORD MESSAGE_LEVEL = 0;
-
- 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)
-
-
- HANDLE
- MonOpenEventLog (
- )
- /*++
-
- Routine Description:
-
- Reads the level of event logging from the registry and opens the
- channel to the event logger for subsequent event log entries.
-
- Arguments:
-
- None
-
- Return Value:
-
- Handle to the event log for reporting events.
- NULL if open not successful.
-
- --*/
- {
- HKEY hAppKey;
- TCHAR LogLevelKeyName[] = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib";
- TCHAR LogLevelValueName[] = "EventLogLevel";
-
- LONG lStatus;
-
- DWORD dwLogLevel;
- DWORD dwValueType;
- DWORD dwValueSize;
-
- // if global value of the logging level not initialized or is disabled,
- // check the registry to see if it should be updated.
-
- if (!MESSAGE_LEVEL) {
-
- lStatus = RegOpenKeyEx (HKEY_LOCAL_MACHINE,
- LogLevelKeyName,
- 0,
- KEY_READ,
- &hAppKey);
-
- dwValueSize = sizeof (dwLogLevel);
-
- if (lStatus == ERROR_SUCCESS) {
- lStatus = RegQueryValueEx (hAppKey,
- LogLevelValueName,
- (LPDWORD)NULL,
- &dwValueType,
- (LPBYTE)&dwLogLevel,
- &dwValueSize);
-
- if (lStatus == ERROR_SUCCESS) {
- MESSAGE_LEVEL = dwLogLevel;
- } else {
- MESSAGE_LEVEL = MESSAGE_LEVEL_DEFAULT;
- }
- RegCloseKey (hAppKey);
- } else {
- MESSAGE_LEVEL = MESSAGE_LEVEL_DEFAULT;
- }
- }
-
- if (hEventLog == NULL){
- hEventLog = RegisterEventSource (
- (LPTSTR)NULL, // Use Local Machine
- APP_NAME); // event log app name to find in registry
-
- if (hEventLog != NULL) {
- REPORT_INFORMATION (UTIL_LOG_OPEN, LOG_DEBUG);
- }
- }
-
- if (hEventLog != NULL) {
- dwLogUsers++; // increment count of perfctr log users
- }
- return (hEventLog);
- }
-
-
- VOID
- MonCloseEventLog (
- )
- /*++
-
- Routine Description:
-
- Closes the handle to the event logger if this is the last caller
-
- Arguments:
-
- None
-
- Return Value:
-
- None
-
- --*/
- {
- if (hEventLog != NULL) {
- dwLogUsers--; // decrement usage
- if (dwLogUsers <= 0) { // and if we're the last, then close up log
- REPORT_INFORMATION (UTIL_CLOSING_LOG, LOG_DEBUG);
- DeregisterEventSource (hEventLog);
- }
- }
- }
-
- 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 "Foriegn" 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;
- WCHAR wcDelimiter; // could be an argument to be more flexible
-
- if (lpwszUnicodeList == 0) return FALSE; // null pointer, # not founde
-
- 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 delimter 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++;
- }
- return FALSE;
- } // IsNumberInUnicodeList
-
-
- BOOL
- MonBuildInstanceDefinition(
- PERF_INSTANCE_DEFINITION *pBuffer,
- PVOID *pBufferNext,
- DWORD ParentObjectTitleIndex,
- DWORD ParentObjectInstance,
- DWORD UniqueID,
- LPWSTR Name
- )
- /*++
-
- MonBuildInstanceDefinition - Build an instance of an object
-
- Inputs:
-
- pBuffer - pointer to buffer where instance is to
- be constructed
-
- pBufferNext - pointer to a pointer which will contain
- next available location, DWORD aligned
-
- ParentObjectTitleIndex
- - Title Index of parent object type; 0 if
- no parent object
-
- ParentObjectInstance
- - Index into instances of parent object
- type, starting at 0, for this instances
- parent object instance
-
- UniqueID - a unique identifier which should be used
- instead of the Name for identifying
- this instance
-
- Name - Name of this instance
- --*/
- {
- DWORD NameLength;
- LPWSTR pName;
- //
- // Include trailing null in name size
- //
-
- NameLength = (lstrlenW(Name) + 1) * sizeof(WCHAR);
-
- pBuffer->ByteLength = sizeof(PERF_INSTANCE_DEFINITION) +
- DWORD_MULTIPLE(NameLength);
-
- pBuffer->ParentObjectTitleIndex = ParentObjectTitleIndex;
- pBuffer->ParentObjectInstance = ParentObjectInstance;
- pBuffer->UniqueID = UniqueID;
- pBuffer->NameOffset = sizeof(PERF_INSTANCE_DEFINITION);
- pBuffer->NameLength = NameLength;
-
- // copy name to name buffer
- pName = (LPWSTR)&pBuffer[1];
- RtlMoveMemory(pName,Name,NameLength);
-
- // update "next byte" pointer
- *pBufferNext = (PVOID) ((PCHAR) pBuffer + pBuffer->ByteLength);
-
- return 0;
- }