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.

369 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. Thomas J. Dimitri 05/28/93
  12. Revision History:
  13. --*/
  14. //
  15. // include files
  16. //
  17. #include <windows.h>
  18. #include <string.h>
  19. #include <winperf.h>
  20. #include "rasctrs.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. hEventLog = NULL;
  127. }
  128. }
  129. }
  130. DWORD
  131. GetQueryType (
  132. IN LPWSTR lpValue
  133. )
  134. /*++
  135. GetQueryType
  136. returns the type of query described in the lpValue string so that
  137. the appropriate processing method may be used
  138. Arguments
  139. IN lpValue
  140. string passed to PerfRegQuery Value for processing
  141. Return Value
  142. QUERY_GLOBAL
  143. if lpValue == 0 (null pointer)
  144. lpValue == pointer to Null string
  145. lpValue == pointer to "Global" string
  146. QUERY_FOREIGN
  147. if lpValue == pointer to "Foriegn" string
  148. QUERY_COSTLY
  149. if lpValue == pointer to "Costly" string
  150. otherwise:
  151. QUERY_ITEMS
  152. --*/
  153. {
  154. WCHAR *pwcArgChar, *pwcTypeChar;
  155. BOOL bFound;
  156. if (lpValue == 0) {
  157. return QUERY_GLOBAL;
  158. } else if (*lpValue == 0) {
  159. return QUERY_GLOBAL;
  160. }
  161. // check for "Global" request
  162. pwcArgChar = lpValue;
  163. pwcTypeChar = GLOBAL_STRING;
  164. bFound = TRUE; // assume found until contradicted
  165. // check to the length of the shortest string
  166. while ((*pwcArgChar != 0) && (*pwcTypeChar != 0)) {
  167. if (*pwcArgChar++ != *pwcTypeChar++) {
  168. bFound = FALSE; // no match
  169. break; // bail out now
  170. }
  171. }
  172. if (bFound) return QUERY_GLOBAL;
  173. // check for "Foreign" request
  174. pwcArgChar = lpValue;
  175. pwcTypeChar = FOREIGN_STRING;
  176. bFound = TRUE; // assume found until contradicted
  177. // check to the length of the shortest string
  178. while ((*pwcArgChar != 0) && (*pwcTypeChar != 0)) {
  179. if (*pwcArgChar++ != *pwcTypeChar++) {
  180. bFound = FALSE; // no match
  181. break; // bail out now
  182. }
  183. }
  184. if (bFound) return QUERY_FOREIGN;
  185. // check for "Costly" request
  186. pwcArgChar = lpValue;
  187. pwcTypeChar = COSTLY_STRING;
  188. bFound = TRUE; // assume found until contradicted
  189. // check to the length of the shortest string
  190. while ((*pwcArgChar != 0) && (*pwcTypeChar != 0)) {
  191. if (*pwcArgChar++ != *pwcTypeChar++) {
  192. bFound = FALSE; // no match
  193. break; // bail out now
  194. }
  195. }
  196. if (bFound) return QUERY_COSTLY;
  197. // if not Global and not Foreign and not Costly,
  198. // then it must be an item list
  199. return QUERY_ITEMS;
  200. }
  201. BOOL
  202. IsNumberInUnicodeList (
  203. IN DWORD dwNumber,
  204. IN LPWSTR lpwszUnicodeList
  205. )
  206. /*++
  207. IsNumberInUnicodeList
  208. Arguments:
  209. IN dwNumber
  210. DWORD number to find in list
  211. IN lpwszUnicodeList
  212. Null terminated, Space delimited list of decimal numbers
  213. Return Value:
  214. TRUE:
  215. dwNumber was found in the list of unicode number strings
  216. FALSE:
  217. dwNumber was not found in the list.
  218. --*/
  219. {
  220. DWORD dwThisNumber;
  221. WCHAR *pwcThisChar;
  222. BOOL bValidNumber;
  223. BOOL bNewItem;
  224. BOOL bReturnValue;
  225. WCHAR wcDelimiter; // could be an argument to be more flexible
  226. if (lpwszUnicodeList == 0) return FALSE; // null pointer, # not founde
  227. pwcThisChar = lpwszUnicodeList;
  228. dwThisNumber = 0;
  229. wcDelimiter = (WCHAR)' ';
  230. bValidNumber = FALSE;
  231. bNewItem = TRUE;
  232. while (TRUE) {
  233. switch (EvalThisChar (*pwcThisChar, wcDelimiter)) {
  234. case DIGIT:
  235. // if this is the first digit after a delimiter, then
  236. // set flags to start computing the new number
  237. if (bNewItem) {
  238. bNewItem = FALSE;
  239. bValidNumber = TRUE;
  240. }
  241. if (bValidNumber) {
  242. dwThisNumber *= 10;
  243. dwThisNumber += (*pwcThisChar - (WCHAR)'0');
  244. }
  245. break;
  246. case DELIMITER:
  247. // a delimter is either the delimiter character or the
  248. // end of the string ('\0') if when the delimiter has been
  249. // reached a valid number was found, then compare it to the
  250. // number from the argument list. if this is the end of the
  251. // string and no match was found, then return.
  252. //
  253. if (bValidNumber) {
  254. if (dwThisNumber == dwNumber) return TRUE;
  255. bValidNumber = FALSE;
  256. }
  257. if (*pwcThisChar == 0) {
  258. return FALSE;
  259. } else {
  260. bNewItem = TRUE;
  261. dwThisNumber = 0;
  262. }
  263. break;
  264. case INVALID:
  265. // if an invalid character was encountered, ignore all
  266. // characters up to the next delimiter and then start fresh.
  267. // the invalid number is not compared.
  268. bValidNumber = FALSE;
  269. break;
  270. default:
  271. break;
  272. }
  273. pwcThisChar++;
  274. }
  275. } // IsNumberInUnicodeList
  276.