|
|
1.1 ! root 1: /*++ BUILD Version: 0001 // Increment this if a change has global effects ! 2: ! 3: Copyright (c) 1992 Microsoft Corporation ! 4: ! 5: Module Name: ! 6: ! 7: perfutil.c ! 8: ! 9: Abstract: ! 10: ! 11: This file implements the utility routines used to construct the ! 12: common parts of a PERF_INSTANCE_DEFINITION (see winperf.h) and ! 13: perform event logging functions. ! 14: ! 15: Created: ! 16: ! 17: Russ Blake 07/30/92 ! 18: ! 19: Revision History: ! 20: ! 21: --*/ ! 22: // ! 23: // include files ! 24: // ! 25: #include <windows.h> ! 26: #include <string.h> ! 27: #include <winperf.h> ! 28: #include "vgactrs.h" // error message definition ! 29: #include "perfmsg.h" ! 30: #include "perfutil.h" ! 31: ! 32: #define INITIAL_SIZE 1024L ! 33: #define EXTEND_SIZE 1024L ! 34: ! 35: // ! 36: // Global data definitions. ! 37: // ! 38: ! 39: ULONG ulInfoBufferSize = 0; ! 40: ! 41: HANDLE hEventLog = NULL; // event log handle for reporting events ! 42: // initialized in Open... routines ! 43: DWORD dwLogUsers = 0; // count of functions using event log ! 44: ! 45: DWORD MESSAGE_LEVEL = 0; ! 46: ! 47: WCHAR GLOBAL_STRING[] = L"Global"; ! 48: WCHAR FOREIGN_STRING[] = L"Foreign"; ! 49: WCHAR COSTLY_STRING[] = L"Costly"; ! 50: ! 51: WCHAR NULL_STRING[] = L"\0"; // pointer to null string ! 52: ! 53: // test for delimiter, end of line and non-digit characters ! 54: // used by IsNumberInUnicodeList routine ! 55: // ! 56: #define DIGIT 1 ! 57: #define DELIMITER 2 ! 58: #define INVALID 3 ! 59: ! 60: #define EvalThisChar(c,d) ( \ ! 61: (c == d) ? DELIMITER : \ ! 62: (c == 0) ? DELIMITER : \ ! 63: (c < (WCHAR)'0') ? INVALID : \ ! 64: (c > (WCHAR)'9') ? INVALID : \ ! 65: DIGIT) ! 66: ! 67: ! 68: HANDLE ! 69: MonOpenEventLog ( ! 70: ) ! 71: /*++ ! 72: ! 73: Routine Description: ! 74: ! 75: Reads the level of event logging from the registry and opens the ! 76: channel to the event logger for subsequent event log entries. ! 77: ! 78: Arguments: ! 79: ! 80: None ! 81: ! 82: Return Value: ! 83: ! 84: Handle to the event log for reporting events. ! 85: NULL if open not successful. ! 86: ! 87: --*/ ! 88: { ! 89: HKEY hAppKey; ! 90: TCHAR LogLevelKeyName[] = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib"; ! 91: TCHAR LogLevelValueName[] = "EventLogLevel"; ! 92: ! 93: LONG lStatus; ! 94: ! 95: DWORD dwLogLevel; ! 96: DWORD dwValueType; ! 97: DWORD dwValueSize; ! 98: ! 99: // if global value of the logging level not initialized or is disabled, ! 100: // check the registry to see if it should be updated. ! 101: ! 102: if (!MESSAGE_LEVEL) { ! 103: ! 104: lStatus = RegOpenKeyEx (HKEY_LOCAL_MACHINE, ! 105: LogLevelKeyName, ! 106: 0, ! 107: KEY_READ, ! 108: &hAppKey); ! 109: ! 110: dwValueSize = sizeof (dwLogLevel); ! 111: ! 112: if (lStatus == ERROR_SUCCESS) { ! 113: lStatus = RegQueryValueEx (hAppKey, ! 114: LogLevelValueName, ! 115: (LPDWORD)NULL, ! 116: &dwValueType, ! 117: (LPBYTE)&dwLogLevel, ! 118: &dwValueSize); ! 119: ! 120: if (lStatus == ERROR_SUCCESS) { ! 121: MESSAGE_LEVEL = dwLogLevel; ! 122: } else { ! 123: MESSAGE_LEVEL = MESSAGE_LEVEL_DEFAULT; ! 124: } ! 125: RegCloseKey (hAppKey); ! 126: } else { ! 127: MESSAGE_LEVEL = MESSAGE_LEVEL_DEFAULT; ! 128: } ! 129: } ! 130: ! 131: if (hEventLog == NULL){ ! 132: hEventLog = RegisterEventSource ( ! 133: (LPTSTR)NULL, // Use Local Machine ! 134: APP_NAME); // event log app name to find in registry ! 135: ! 136: if (hEventLog != NULL) { ! 137: REPORT_INFORMATION (UTIL_LOG_OPEN, LOG_DEBUG); ! 138: } ! 139: } ! 140: ! 141: if (hEventLog != NULL) { ! 142: dwLogUsers++; // increment count of perfctr log users ! 143: } ! 144: return (hEventLog); ! 145: } ! 146: ! 147: ! 148: VOID ! 149: MonCloseEventLog ( ! 150: ) ! 151: /*++ ! 152: ! 153: Routine Description: ! 154: ! 155: Closes the handle to the event logger if this is the last caller ! 156: ! 157: Arguments: ! 158: ! 159: None ! 160: ! 161: Return Value: ! 162: ! 163: None ! 164: ! 165: --*/ ! 166: { ! 167: if (hEventLog != NULL) { ! 168: dwLogUsers--; // decrement usage ! 169: if (dwLogUsers <= 0) { // and if we're the last, then close up log ! 170: REPORT_INFORMATION (UTIL_CLOSING_LOG, LOG_DEBUG); ! 171: DeregisterEventSource (hEventLog); ! 172: } ! 173: } ! 174: } ! 175: ! 176: DWORD ! 177: GetQueryType ( ! 178: IN LPWSTR lpValue ! 179: ) ! 180: /*++ ! 181: ! 182: GetQueryType ! 183: ! 184: returns the type of query described in the lpValue string so that ! 185: the appropriate processing method may be used ! 186: ! 187: Arguments ! 188: ! 189: IN lpValue ! 190: string passed to PerfRegQuery Value for processing ! 191: ! 192: Return Value ! 193: ! 194: QUERY_GLOBAL ! 195: if lpValue == 0 (null pointer) ! 196: lpValue == pointer to Null string ! 197: lpValue == pointer to "Global" string ! 198: ! 199: QUERY_FOREIGN ! 200: if lpValue == pointer to "Foriegn" string ! 201: ! 202: QUERY_COSTLY ! 203: if lpValue == pointer to "Costly" string ! 204: ! 205: otherwise: ! 206: ! 207: QUERY_ITEMS ! 208: ! 209: --*/ ! 210: { ! 211: WCHAR *pwcArgChar, *pwcTypeChar; ! 212: BOOL bFound; ! 213: ! 214: if (lpValue == 0) { ! 215: return QUERY_GLOBAL; ! 216: } else if (*lpValue == 0) { ! 217: return QUERY_GLOBAL; ! 218: } ! 219: ! 220: // check for "Global" request ! 221: ! 222: pwcArgChar = lpValue; ! 223: pwcTypeChar = GLOBAL_STRING; ! 224: bFound = TRUE; // assume found until contradicted ! 225: ! 226: // check to the length of the shortest string ! 227: ! 228: while ((*pwcArgChar != 0) && (*pwcTypeChar != 0)) { ! 229: if (*pwcArgChar++ != *pwcTypeChar++) { ! 230: bFound = FALSE; // no match ! 231: break; // bail out now ! 232: } ! 233: } ! 234: ! 235: if (bFound) return QUERY_GLOBAL; ! 236: ! 237: // check for "Foreign" request ! 238: ! 239: pwcArgChar = lpValue; ! 240: pwcTypeChar = FOREIGN_STRING; ! 241: bFound = TRUE; // assume found until contradicted ! 242: ! 243: // check to the length of the shortest string ! 244: ! 245: while ((*pwcArgChar != 0) && (*pwcTypeChar != 0)) { ! 246: if (*pwcArgChar++ != *pwcTypeChar++) { ! 247: bFound = FALSE; // no match ! 248: break; // bail out now ! 249: } ! 250: } ! 251: ! 252: if (bFound) return QUERY_FOREIGN; ! 253: ! 254: // check for "Costly" request ! 255: ! 256: pwcArgChar = lpValue; ! 257: pwcTypeChar = COSTLY_STRING; ! 258: bFound = TRUE; // assume found until contradicted ! 259: ! 260: // check to the length of the shortest string ! 261: ! 262: while ((*pwcArgChar != 0) && (*pwcTypeChar != 0)) { ! 263: if (*pwcArgChar++ != *pwcTypeChar++) { ! 264: bFound = FALSE; // no match ! 265: break; // bail out now ! 266: } ! 267: } ! 268: ! 269: if (bFound) return QUERY_COSTLY; ! 270: ! 271: // if not Global and not Foreign and not Costly, ! 272: // then it must be an item list ! 273: ! 274: return QUERY_ITEMS; ! 275: ! 276: } ! 277: ! 278: BOOL ! 279: IsNumberInUnicodeList ( ! 280: IN DWORD dwNumber, ! 281: IN LPWSTR lpwszUnicodeList ! 282: ) ! 283: /*++ ! 284: ! 285: IsNumberInUnicodeList ! 286: ! 287: Arguments: ! 288: ! 289: IN dwNumber ! 290: DWORD number to find in list ! 291: ! 292: IN lpwszUnicodeList ! 293: Null terminated, Space delimited list of decimal numbers ! 294: ! 295: Return Value: ! 296: ! 297: TRUE: ! 298: dwNumber was found in the list of unicode number strings ! 299: ! 300: FALSE: ! 301: dwNumber was not found in the list. ! 302: ! 303: --*/ ! 304: { ! 305: DWORD dwThisNumber; ! 306: WCHAR *pwcThisChar; ! 307: BOOL bValidNumber; ! 308: BOOL bNewItem; ! 309: BOOL bReturnValue; ! 310: WCHAR wcDelimiter; // could be an argument to be more flexible ! 311: ! 312: if (lpwszUnicodeList == 0) return FALSE; // null pointer, # not founde ! 313: ! 314: pwcThisChar = lpwszUnicodeList; ! 315: dwThisNumber = 0; ! 316: wcDelimiter = (WCHAR)' '; ! 317: bValidNumber = FALSE; ! 318: bNewItem = TRUE; ! 319: ! 320: while (TRUE) { ! 321: switch (EvalThisChar (*pwcThisChar, wcDelimiter)) { ! 322: case DIGIT: ! 323: // if this is the first digit after a delimiter, then ! 324: // set flags to start computing the new number ! 325: if (bNewItem) { ! 326: bNewItem = FALSE; ! 327: bValidNumber = TRUE; ! 328: } ! 329: if (bValidNumber) { ! 330: dwThisNumber *= 10; ! 331: dwThisNumber += (*pwcThisChar - (WCHAR)'0'); ! 332: } ! 333: break; ! 334: ! 335: case DELIMITER: ! 336: // a delimter is either the delimiter character or the ! 337: // end of the string ('\0') if when the delimiter has been ! 338: // reached a valid number was found, then compare it to the ! 339: // number from the argument list. if this is the end of the ! 340: // string and no match was found, then return. ! 341: // ! 342: if (bValidNumber) { ! 343: if (dwThisNumber == dwNumber) return TRUE; ! 344: bValidNumber = FALSE; ! 345: } ! 346: if (*pwcThisChar == 0) { ! 347: return FALSE; ! 348: } else { ! 349: bNewItem = TRUE; ! 350: dwThisNumber = 0; ! 351: } ! 352: break; ! 353: ! 354: case INVALID: ! 355: // if an invalid character was encountered, ignore all ! 356: // characters up to the next delimiter and then start fresh. ! 357: // the invalid number is not compared. ! 358: bValidNumber = FALSE; ! 359: break; ! 360: ! 361: default: ! 362: break; ! 363: ! 364: } ! 365: pwcThisChar++; ! 366: } ! 367: ! 368: } // IsNumberInUnicodeList
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.