Source code of Windows XP (NT5)
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.

365 lines
8.6 KiB

  1. /*++
  2. Copyright (c) 2000-2001 Microsoft Corporation
  3. Module Name:
  4. perfutil.c
  5. Abstract:
  6. This file implements various utility routines.
  7. Created:
  8. davj 17-May-2000
  9. Revision History:
  10. --*/
  11. //
  12. // include files
  13. //
  14. #include <windows.h>
  15. #include <string.h>
  16. #include <winperf.h>
  17. #include "genctrs.h" // error message definition
  18. #include "perfmsg.h"
  19. #include "perfutil.h"
  20. //
  21. // Global data definitions.
  22. //
  23. HANDLE hEventLog = NULL; // event log handle for reporting events
  24. // initialized in Open... routines
  25. DWORD dwLogUsers = 0; // count of functions using event log
  26. DWORD MESSAGE_LEVEL = 0;
  27. WCHAR GLOBAL_STRING[] = L"Global";
  28. WCHAR FOREIGN_STRING[] = L"Foreign";
  29. WCHAR COSTLY_STRING[] = L"Costly";
  30. WCHAR NULL_STRING[] = L"\0"; // pointer to null string
  31. // test for delimiter, end of line and non-digit characters
  32. // used by IsNumberInUnicodeList routine
  33. //
  34. #define DIGIT 1
  35. #define DELIMITER 2
  36. #define INVALID 3
  37. #define EvalThisChar(c,d) ( \
  38. (c == d) ? DELIMITER : \
  39. (c == 0) ? DELIMITER : \
  40. (c < (WCHAR)'0') ? INVALID : \
  41. (c > (WCHAR)'9') ? INVALID : \
  42. DIGIT)
  43. HANDLE
  44. MonOpenEventLog (
  45. )
  46. /*++
  47. Routine Description:
  48. Reads the level of event logging from the registry and opens the
  49. channel to the event logger for subsequent event log entries.
  50. Arguments:
  51. None
  52. Return Value:
  53. Handle to the event log for reporting events.
  54. NULL if open not successful.
  55. --*/
  56. {
  57. HKEY hAppKey;
  58. LONG lStatus;
  59. DWORD dwLogLevel;
  60. DWORD dwValueType;
  61. DWORD dwValueSize;
  62. // if global value of the logging level not initialized or is disabled,
  63. // check the registry to see if it should be updated.
  64. if (!MESSAGE_LEVEL) {
  65. lStatus = RegOpenKeyEx (HKEY_LOCAL_MACHINE,
  66. "SOFTWARE\\Microsoft\\wbem\\cimom",
  67. 0,
  68. KEY_READ,
  69. &hAppKey);
  70. dwValueSize = sizeof (dwLogLevel);
  71. if (lStatus == ERROR_SUCCESS) {
  72. BYTE bArray[8];
  73. dwValueSize = 8;
  74. lStatus = RegQueryValueEx (hAppKey,
  75. "Logging",
  76. (LPDWORD)NULL,
  77. &dwValueType,
  78. (LPBYTE)bArray,
  79. &dwValueSize);
  80. if (lStatus == ERROR_SUCCESS) {
  81. if(bArray[0] == '2' && bArray[1] == 0)
  82. MESSAGE_LEVEL = LOG_VERBOSE;
  83. else if(bArray[0] == '0' && bArray[1] == 0)
  84. MESSAGE_LEVEL = LOG_NONE;
  85. else
  86. MESSAGE_LEVEL = LOG_ERROR;
  87. } else {
  88. MESSAGE_LEVEL = MESSAGE_LEVEL_DEFAULT;
  89. }
  90. RegCloseKey (hAppKey);
  91. } else {
  92. MESSAGE_LEVEL = MESSAGE_LEVEL_DEFAULT;
  93. }
  94. }
  95. if (hEventLog == NULL){
  96. hEventLog = RegisterEventSource (
  97. (LPTSTR)NULL, // Use Local Machine
  98. "WMIPerf"); // event log app name to find in registry
  99. if (hEventLog != NULL) {
  100. REPORT_INFORMATION (UTIL_LOG_OPEN, LOG_VERBOSE);
  101. }
  102. }
  103. if (hEventLog != NULL) {
  104. dwLogUsers++; // increment count of perfctr log users
  105. }
  106. return (hEventLog);
  107. }
  108. VOID
  109. MonCloseEventLog (
  110. )
  111. /*++
  112. Routine Description:
  113. Closes the handle to the event logger if this is the last caller
  114. Arguments:
  115. None
  116. Return Value:
  117. None
  118. --*/
  119. {
  120. if (hEventLog != NULL) {
  121. dwLogUsers--; // decrement usage
  122. if (dwLogUsers <= 0) { // and if we're the last, then close up log
  123. REPORT_INFORMATION (UTIL_CLOSING_LOG, LOG_VERBOSE);
  124. DeregisterEventSource (hEventLog);
  125. }
  126. }
  127. }
  128. DWORD
  129. GetQueryType (
  130. IN LPWSTR lpValue
  131. )
  132. /*++
  133. GetQueryType
  134. returns the type of query described in the lpValue string so that
  135. the appropriate processing method may be used
  136. Arguments
  137. IN lpValue
  138. string passed to PerfRegQuery Value for processing
  139. Return Value
  140. QUERY_GLOBAL
  141. if lpValue == 0 (null pointer)
  142. lpValue == pointer to Null string
  143. lpValue == pointer to "Global" string
  144. QUERY_FOREIGN
  145. if lpValue == pointer to "Foriegn" string
  146. QUERY_COSTLY
  147. if lpValue == pointer to "Costly" string
  148. otherwise:
  149. QUERY_ITEMS
  150. --*/
  151. {
  152. WCHAR *pwcArgChar, *pwcTypeChar;
  153. BOOL bFound;
  154. if (lpValue == 0) {
  155. return QUERY_GLOBAL;
  156. } else if (*lpValue == 0) {
  157. return QUERY_GLOBAL;
  158. }
  159. // check for "Global" request
  160. pwcArgChar = lpValue;
  161. pwcTypeChar = GLOBAL_STRING;
  162. bFound = TRUE; // assume found until contradicted
  163. // check to the length of the shortest string
  164. while ((*pwcArgChar != 0) && (*pwcTypeChar != 0)) {
  165. if (*pwcArgChar++ != *pwcTypeChar++) {
  166. bFound = FALSE; // no match
  167. break; // bail out now
  168. }
  169. }
  170. if (bFound) return QUERY_GLOBAL;
  171. // check for "Foreign" request
  172. pwcArgChar = lpValue;
  173. pwcTypeChar = FOREIGN_STRING;
  174. bFound = TRUE; // assume found until contradicted
  175. // check to the length of the shortest string
  176. while ((*pwcArgChar != 0) && (*pwcTypeChar != 0)) {
  177. if (*pwcArgChar++ != *pwcTypeChar++) {
  178. bFound = FALSE; // no match
  179. break; // bail out now
  180. }
  181. }
  182. if (bFound) return QUERY_FOREIGN;
  183. // check for "Costly" request
  184. pwcArgChar = lpValue;
  185. pwcTypeChar = COSTLY_STRING;
  186. bFound = TRUE; // assume found until contradicted
  187. // check to the length of the shortest string
  188. while ((*pwcArgChar != 0) && (*pwcTypeChar != 0)) {
  189. if (*pwcArgChar++ != *pwcTypeChar++) {
  190. bFound = FALSE; // no match
  191. break; // bail out now
  192. }
  193. }
  194. if (bFound) return QUERY_COSTLY;
  195. // if not Global and not Foreign and not Costly,
  196. // then it must be an item list
  197. return QUERY_ITEMS;
  198. }
  199. BOOL
  200. IsNumberInUnicodeList (
  201. IN DWORD dwNumber,
  202. IN LPWSTR lpwszUnicodeList
  203. )
  204. /*++
  205. IsNumberInUnicodeList
  206. Arguments:
  207. IN dwNumber
  208. DWORD number to find in list
  209. IN lpwszUnicodeList
  210. Null terminated, Space delimited list of decimal numbers
  211. Return Value:
  212. TRUE:
  213. dwNumber was found in the list of unicode number strings
  214. FALSE:
  215. dwNumber was not found in the list.
  216. --*/
  217. {
  218. DWORD dwThisNumber;
  219. WCHAR *pwcThisChar;
  220. BOOL bValidNumber;
  221. BOOL bNewItem;
  222. WCHAR wcDelimiter; // could be an argument to be more flexible
  223. if (lpwszUnicodeList == 0) return FALSE; // null pointer, # not founde
  224. pwcThisChar = lpwszUnicodeList;
  225. dwThisNumber = 0;
  226. wcDelimiter = (WCHAR)' ';
  227. bValidNumber = FALSE;
  228. bNewItem = TRUE;
  229. while (TRUE) {
  230. switch (EvalThisChar (*pwcThisChar, wcDelimiter)) {
  231. case DIGIT:
  232. // if this is the first digit after a delimiter, then
  233. // set flags to start computing the new number
  234. if (bNewItem) {
  235. bNewItem = FALSE;
  236. bValidNumber = TRUE;
  237. }
  238. if (bValidNumber) {
  239. dwThisNumber *= 10;
  240. dwThisNumber += (*pwcThisChar - (WCHAR)'0');
  241. }
  242. break;
  243. case DELIMITER:
  244. // a delimter is either the delimiter character or the
  245. // end of the string ('\0') if when the delimiter has been
  246. // reached a valid number was found, then compare it to the
  247. // number from the argument list. if this is the end of the
  248. // string and no match was found, then return.
  249. //
  250. if (bValidNumber) {
  251. if (dwThisNumber == dwNumber) return TRUE;
  252. bValidNumber = FALSE;
  253. }
  254. if (*pwcThisChar == 0) {
  255. return FALSE;
  256. } else {
  257. bNewItem = TRUE;
  258. dwThisNumber = 0;
  259. }
  260. break;
  261. case INVALID:
  262. // if an invalid character was encountered, ignore all
  263. // characters up to the next delimiter and then start fresh.
  264. // the invalid number is not compared.
  265. bValidNumber = FALSE;
  266. break;
  267. default:
  268. break;
  269. }
  270. pwcThisChar++;
  271. }
  272. return FALSE;
  273. } // IsNumberInUnicodeList