Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

perfutil.c

Go to the documentation of this file.
00001 /*++ BUILD Version: 0001 00002 00003 Copyright (c) 1985 - 1999, Microsoft Corporation 00004 00005 Module Name: perfutil.c 00006 00007 Abstract: 00008 This file implements the utility routines used to construct the 00009 common parts of a PERF_INSTANCE_DEFINITION (see winperf.h) and 00010 perform event logging functions. 00011 00012 Revision History: 00013 --*/ 00014 00015 // 00016 // include files 00017 // 00018 00019 #include <windows.h> 00020 #include <string.h> 00021 #include <winperf.h> 00022 #include "userctrs.h" // error message definition 00023 #include "perfmsg.h" 00024 #include "perfutil.h" 00025 #include "userdata.h" 00026 #define INITIAL_SIZE 1024L 00027 #define EXTEND_SIZE 1024L 00028 00029 // 00030 // Global data definitions. 00031 // 00032 00033 ULONG ulInfoBufferSize = 0; 00034 HANDLE hEventLog = NULL; // event log handle for reporting events 00035 // initialized in Open... routines 00036 DWORD dwLogUsers = 0; // count of functions using event log 00037 DWORD MESSAGE_LEVEL = 0; 00038 WCHAR GLOBAL_STRING[] = L"Global"; 00039 WCHAR FOREIGN_STRING[] = L"Foreign"; 00040 WCHAR COSTLY_STRING[] = L"Costly"; 00041 WCHAR NULL_STRING[] = L"\0"; 00042 00043 // 00044 // Global data from userdata.c 00045 // 00046 extern USER_DATA_DEFINITION UserDataDefinition; 00047 extern CS_DATA_DEFINITION CSDataDefinition; 00048 00049 // pointer to null string 00050 // test for delimiter, end of line and non-digit characters 00051 // used by IsNumberInUnicodeList routine 00052 // 00053 00054 #define DIGIT 1 00055 #define DELIMITER 2 00056 #define ENDOFSTRING 3 00057 #define INVALID 4 00058 #define EvalThisChar(c,d) ( \ 00059 (c == d) ? DELIMITER : \ 00060 (c == 0) ? ENDOFSTRING : \ 00061 (c < (WCHAR)'0') ? INVALID : \ 00062 (c > (WCHAR)'9') ? INVALID : \ 00063 DIGIT) 00064 00065 HANDLE MonOpenEventLog () 00066 /*++ 00067 Routine Description: 00068 00069 Reads the level of event logging from the registry and opens the 00070 channel to the event logger for subsequent event log entries. 00071 00072 Arguments: 00073 None 00074 00075 Return Value: 00076 Handle to the event log for reporting events. 00077 NULL if open not successful. 00078 --*/ 00079 { 00080 HKEY hAppKey; 00081 TCHAR LogLevelKeyName[] = "SOFTWARE\\Microsoft\\WindowsNT\\CurrentVersion\\PerfLib"; 00082 TCHAR LogLevelValueName[] = "EventLogLevel"; 00083 LONG lStatus; 00084 DWORD dwLogLevel; 00085 DWORD dwValueType; 00086 DWORD dwValueSize; 00087 00088 // if global value of the logging level not initialized or is disabled, 00089 // check the registry to see if it should be updated. 00090 00091 if (!MESSAGE_LEVEL) { 00092 lStatus = RegOpenKeyEx (HKEY_LOCAL_MACHINE, 00093 LogLevelKeyName, 00094 0, 00095 KEY_READ, 00096 &hAppKey); 00097 dwValueSize = sizeof (dwLogLevel); 00098 if (lStatus == ERROR_SUCCESS) { 00099 lStatus = RegQueryValueEx (hAppKey, 00100 LogLevelValueName, 00101 (LPDWORD)NULL, 00102 &dwValueType, 00103 (LPBYTE)&dwLogLevel, 00104 &dwValueSize); 00105 if (lStatus == ERROR_SUCCESS) { 00106 MESSAGE_LEVEL = dwLogLevel; 00107 } 00108 else { 00109 MESSAGE_LEVEL = MESSAGE_LEVEL_DEFAULT; 00110 } 00111 RegCloseKey (hAppKey); 00112 } 00113 else { 00114 MESSAGE_LEVEL = MESSAGE_LEVEL_DEFAULT; 00115 } 00116 } 00117 if (hEventLog == NULL) { 00118 hEventLog = RegisterEventSource ( 00119 (LPTSTR)NULL, // Use Local Machine 00120 APP_NAME); // event log app name to find in registry 00121 if (hEventLog != NULL) { 00122 REPORT_INFORMATION (UTIL_LOG_OPEN, LOG_DEBUG); 00123 } 00124 } 00125 if (hEventLog != NULL) { 00126 dwLogUsers++; // increment count of perfctr log users 00127 } 00128 return (hEventLog); 00129 } 00130 00131 VOID MonCloseEventLog () 00132 /*++ 00133 Routine Description: 00134 Closes the handle to the event logger if this is the last caller 00135 00136 Arguments: None 00137 00138 Return Value: None 00139 00140 --*/ 00141 { 00142 if (hEventLog != NULL) { 00143 dwLogUsers--; // decrement usage 00144 if (dwLogUsers <= 0) { // and if we're the last, then close up log 00145 REPORT_INFORMATION (UTIL_CLOSING_LOG, LOG_DEBUG); 00146 DeregisterEventSource (hEventLog); 00147 } 00148 } 00149 } 00150 00151 DWORD GetQueryType ( 00152 IN LPWSTR lpValue) 00153 /*++ 00154 Routine Description: 00155 Returns the type of query described in the lpValue string so that 00156 the appropriate processing method may be used 00157 00158 Arguments 00159 IN lpValue 00160 string passed to PerfRegQuery Value for processing 00161 00162 Return Value 00163 00164 QUERY_GLOBAL if lpValue == 0 (null pointer) 00165 lpValue == pointer to Null string 00166 lpValue == pointer to "Global" string 00167 QUERY_FOREIGN 00168 if lpValue == pointer to "Foreign" string 00169 QUERY_COSTLY 00170 if lpValue == pointer to "Costly" string 00171 otherwise: 00172 00173 QUERY_ITEMS 00174 00175 --*/ 00176 00177 { 00178 WCHAR *pwcArgChar, *pwcTypeChar; 00179 BOOL bFound; 00180 if (lpValue == 0) { 00181 return QUERY_GLOBAL; 00182 } 00183 else if (*lpValue == 0) { 00184 return QUERY_GLOBAL; 00185 } 00186 00187 // check for "Global" request 00188 pwcArgChar = lpValue; 00189 pwcTypeChar = GLOBAL_STRING; 00190 bFound = TRUE; // assume found until contradicted 00191 00192 // check to the length of the shortest string 00193 while ((*pwcArgChar != 0) && (*pwcTypeChar != 0)) { 00194 if (*pwcArgChar++ != *pwcTypeChar++) { 00195 bFound = FALSE; // no match 00196 break; // bail out now 00197 } 00198 } 00199 if (bFound) return QUERY_GLOBAL; 00200 00201 // check for "Foreign" request 00202 pwcArgChar = lpValue; 00203 pwcTypeChar = FOREIGN_STRING; 00204 bFound = TRUE; // assume found until contradicted 00205 00206 // check to the length of the shortest string 00207 while ((*pwcArgChar != 0) && (*pwcTypeChar != 0)) { 00208 if (*pwcArgChar++ != *pwcTypeChar++) { 00209 bFound = FALSE; // no match 00210 break; // bail out now 00211 } 00212 } 00213 if (bFound) return QUERY_FOREIGN; 00214 00215 // check for "Costly" request 00216 pwcArgChar = lpValue; 00217 pwcTypeChar = COSTLY_STRING; 00218 bFound = TRUE; // assume found until contradicted 00219 00220 // check to the length of the shortest string 00221 while ((*pwcArgChar != 0) && (*pwcTypeChar != 0)) { 00222 if (*pwcArgChar++ != *pwcTypeChar++) { 00223 bFound = FALSE; // no match 00224 break; // bail out now 00225 } 00226 } 00227 if (bFound) return QUERY_COSTLY; 00228 00229 // if not Global and not Foreign and not Costly, 00230 // then it must be an item list 00231 00232 return QUERY_ITEMS; 00233 } 00234 00235 DWORD 00236 IsNumberInUnicodeList ( 00237 IN LPWSTR lpwszUnicodeList 00238 ) 00239 /*++ 00240 Routine Description: 00241 When querying counters, the collect function receives a list of Unicode strings 00242 representing object indexes. This function parses the string and returns a bit 00243 combination representing the needed objects. 00244 00245 Arguments: 00246 IN lpwszUnicodeList 00247 Null terminated, space delimited list of decimal numbers 00248 00249 Return Value: 00250 The returned DWORD is a combination of QUERY_USER and QUERY_CS 00251 --*/ 00252 { 00253 DWORD dwThisNumber; 00254 DWORD dwReturnValue; 00255 WCHAR *pwcThisChar; 00256 WCHAR wcDelimiter; 00257 BOOL bValidNumber; 00258 BOOL bNewItem; 00259 00260 if (lpwszUnicodeList == 0) return 0; // null pointer, # not found 00261 00262 pwcThisChar = lpwszUnicodeList; 00263 dwThisNumber = 0; 00264 dwReturnValue = 0; 00265 wcDelimiter = (WCHAR)' '; 00266 bValidNumber = FALSE; 00267 bNewItem = TRUE; 00268 00269 while (TRUE) { 00270 switch (EvalThisChar (*pwcThisChar, wcDelimiter)) { 00271 case DIGIT: 00272 // if this is the first digit after a delimiter, then 00273 // set flags to start computing the new number 00274 if (bNewItem) { 00275 bNewItem = FALSE; 00276 bValidNumber = TRUE; 00277 } 00278 if (bValidNumber) { 00279 dwThisNumber *= 10; 00280 dwThisNumber += (*pwcThisChar - (WCHAR)'0'); 00281 } 00282 break; 00283 case ENDOFSTRING: 00284 case DELIMITER: 00285 // a delimiter is either the delimiter character or the 00286 // end of the string ('\0') if when the delimiter has been 00287 // reached a valid number was found, then compare it to the 00288 // number from the argument list. if this is the end of the 00289 // string and no match was found, then return. 00290 // 00291 if (bValidNumber) { 00292 if (dwThisNumber == UserDataDefinition.UserObjectType.ObjectNameTitleIndex) { 00293 dwReturnValue |= QUERY_USER; 00294 } 00295 else if (dwThisNumber == CSDataDefinition.CSObjectType.ObjectNameTitleIndex) { 00296 dwReturnValue |= QUERY_CS; 00297 } 00298 bValidNumber = FALSE; 00299 } 00300 if (*pwcThisChar == 0) { 00301 return dwReturnValue; 00302 } 00303 else { 00304 bNewItem = TRUE; 00305 dwThisNumber = 0; 00306 } 00307 break; 00308 00309 case INVALID: 00310 // if an invalid character was encountered, ignore all 00311 // characters up to the next delimiter and then start fresh. 00312 // the invalid number is not compared. 00313 bValidNumber = FALSE; 00314 break; 00315 00316 default: 00317 break; 00318 00319 } 00320 pwcThisChar++; 00321 } 00322 00323 } // IsNumberInUnicodeList

Generated on Sat May 15 19:41:09 2004 for test by doxygen 1.3.7