Leaked source code of windows server 2003
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.

367 lines
9.0 KiB

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