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.

338 lines
9.2 KiB

  1. /*++ BUILD Version: 0001 // Increment this if a change has global effects
  2. Copyright (c) Microsoft Corporation. All rights reserved.
  3. Module Name:
  4. utils.c
  5. Abstract:
  6. Utility functions used by the performance library functions
  7. Author:
  8. Russ Blake 11/15/91
  9. Revision History:
  10. 8-Jun-98 bobw revised for use with WBEM functions
  11. --*/
  12. #define UNICODE
  13. //
  14. // Include files
  15. //
  16. #include <nt.h>
  17. #include <ntrtl.h>
  18. #include <nturtl.h>
  19. #include <windows.h>
  20. #include <winperf.h>
  21. #include <strsafe.h>
  22. //#include <prflbmsg.h>
  23. //#include <regrpc.h>
  24. #include "PerfAcc.h"
  25. #include "strings.h"
  26. #include "utils.h"
  27. #include "wbprfmsg.h"
  28. // test for delimiter, end of line and non-digit characters
  29. // used by IsNumberInUnicodeList routine
  30. //
  31. #define DIGIT 1
  32. #define DELIMITER 2
  33. #define INVALID 3
  34. #define EvalThisChar(c,d) ( \
  35. (c == d) ? DELIMITER : \
  36. (c == 0) ? DELIMITER : \
  37. (c < '0') ? INVALID : \
  38. (c > '9') ? INVALID : \
  39. DIGIT)
  40. // the length of "ADDEXPLAIN" in chars
  41. #define MAX_KEYWORD_LEN 10
  42. // minimum length to hold a value name understood by Perflib
  43. // "foreign" is the longest "string" value understood
  44. const DWORD VALUE_NAME_LENGTH = ((7 + 1) * sizeof(WCHAR));
  45. HANDLE hEventLog = NULL;
  46. static WCHAR LocalComputerName[WBEMPERF_STRING_SIZE];
  47. static LPWSTR pComputerName = &LocalComputerName[0];
  48. static DWORD ComputerNameLength = 0;
  49. BOOL
  50. MonBuildPerfDataBlock(
  51. PERF_DATA_BLOCK *pBuffer,
  52. PVOID *pBufferNext,
  53. DWORD NumObjectTypes,
  54. DWORD DefaultObject
  55. )
  56. /*++
  57. MonBuildPerfDataBlock - build the PERF_DATA_BLOCK structure
  58. Inputs:
  59. pBuffer - where the data block should be placed
  60. pBufferNext - where pointer to next byte of data block
  61. is to begin; DWORD aligned
  62. NumObjectTypes - number of types of objects being reported
  63. DefaultObject - object to display by default when
  64. this system is selected; this is the
  65. object type title index
  66. --*/
  67. {
  68. LARGE_INTEGER Time, TimeX10000;
  69. // Initialize Signature and version ID for this data structure
  70. pBuffer->Signature[0] = wc_P;
  71. pBuffer->Signature[1] = wc_E;
  72. pBuffer->Signature[2] = wc_R;
  73. pBuffer->Signature[3] = wc_F;
  74. pBuffer->LittleEndian = 1;
  75. pBuffer->Version = PERF_DATA_VERSION;
  76. pBuffer->Revision = PERF_DATA_REVISION;
  77. //
  78. // The next field will be filled in at the end when the length
  79. // of the return data is known
  80. //
  81. pBuffer->TotalByteLength = 0;
  82. pBuffer->NumObjectTypes = NumObjectTypes;
  83. pBuffer->DefaultObject = DefaultObject;
  84. GetSystemTime(&pBuffer->SystemTime);
  85. NtQueryPerformanceCounter(&pBuffer->PerfTime,&pBuffer->PerfFreq);
  86. TimeX10000.QuadPart = pBuffer->PerfTime.QuadPart * 10000L;
  87. Time.QuadPart = TimeX10000.QuadPart / pBuffer->PerfFreq.LowPart;
  88. pBuffer->PerfTime100nSec.QuadPart = Time.QuadPart * 1000L;
  89. if ( ComputerNameLength == 0) {
  90. // load the name
  91. ComputerNameLength = sizeof (LocalComputerName) / sizeof(LocalComputerName[0]);
  92. if (!GetComputerNameW(pComputerName, &ComputerNameLength)) {
  93. // name look up failed so reset length
  94. ComputerNameLength = 0;
  95. }
  96. assert (ComputerNameLength > 0);
  97. }
  98. // There is a Computer name: i.e., the network is installed
  99. pBuffer->SystemNameLength = ComputerNameLength;
  100. pBuffer->SystemNameOffset = sizeof(PERF_DATA_BLOCK);
  101. RtlMoveMemory(&pBuffer[1],
  102. pComputerName,
  103. ComputerNameLength);
  104. *pBufferNext = (PVOID) ((PCHAR) &pBuffer[1] +
  105. QWORD_MULTIPLE(ComputerNameLength));
  106. pBuffer->HeaderLength = (DWORD)((PCHAR) *pBufferNext - (PCHAR) pBuffer);
  107. return 0;
  108. }
  109. #pragma warning ( disable : 4127) // while (TRUE) error
  110. BOOL
  111. MatchString (
  112. IN LPCWSTR lpValueArg,
  113. IN LPCWSTR lpNameArg
  114. )
  115. /*++
  116. MatchString
  117. return TRUE if lpName is in lpValue. Otherwise return FALSE
  118. Arguments
  119. IN lpValue
  120. string passed to PerfRegQuery Value for processing
  121. IN lpName
  122. string for one of the keyword names
  123. Return TRUE | FALSE
  124. --*/
  125. {
  126. BOOL bFound = TRUE; // assume found until contradicted
  127. LPWSTR lpValue = (LPWSTR)lpValueArg;
  128. LPWSTR lpName = (LPWSTR)lpNameArg;
  129. // check to the length of the shortest string
  130. while (1) {
  131. if (*lpValue != 0) {
  132. if (*lpName != 0) {
  133. if (*lpValue++ != *lpName++) {
  134. bFound = FALSE; // no match
  135. break; // bail out now
  136. }
  137. } else {
  138. // the value still has characters, but the name is out
  139. // so this is no match
  140. bFound = FALSE;
  141. break;
  142. }
  143. } else {
  144. if (*lpName != 0) {
  145. // then the value is out of characters, but the name
  146. // is out so no match
  147. bFound = FALSE;
  148. break;
  149. } else {
  150. // both strings are at the end so it must be a match
  151. }
  152. }
  153. }
  154. return (bFound);
  155. }
  156. #pragma warning ( default : 4127) // while (TRUE) error
  157. #pragma warning ( disable : 4127) // while (TRUE) error
  158. DWORD
  159. GetNextNumberFromList (
  160. IN LPWSTR szStartChar,
  161. IN LPWSTR *szNextChar
  162. )
  163. /*++
  164. Reads a character string from the szStartChar to the next
  165. delimiting space character or the end of the string and returns
  166. the value of the decimal number found. If no valid number is found
  167. then 0 is returned. The pointer to the next character in the
  168. string is returned in the szNextChar parameter. If the character
  169. referenced by this pointer is 0, then the end of the string has
  170. been reached.
  171. --*/
  172. {
  173. DWORD dwThisNumber = 0;
  174. WCHAR *pwcThisChar = szStartChar;
  175. WCHAR wcDelimiter = wcSpace;
  176. BOOL bValidNumber = FALSE;
  177. if (szStartChar != 0) {
  178. while (TRUE) {
  179. switch (EvalThisChar (*pwcThisChar, wcDelimiter)) {
  180. case DIGIT:
  181. // if this is the first digit after a delimiter, then
  182. // set flags to start computing the new number
  183. bValidNumber = TRUE;
  184. dwThisNumber *= 10;
  185. dwThisNumber += (*pwcThisChar - wc_0);
  186. break;
  187. case DELIMITER:
  188. // a delimter is either the delimiter character or the
  189. // end of the string ('\0') if when the delimiter has been
  190. // reached a valid number was found, then return it
  191. //
  192. if (bValidNumber || (*pwcThisChar == 0)) {
  193. *szNextChar = pwcThisChar;
  194. return dwThisNumber;
  195. } else {
  196. // continue until a non-delimiter char or the
  197. // end of the file is found
  198. }
  199. break;
  200. case INVALID:
  201. // if an invalid character was encountered, ignore all
  202. // characters up to the next delimiter and then start fresh.
  203. // the invalid number is not compared.
  204. bValidNumber = FALSE;
  205. break;
  206. default:
  207. break;
  208. }
  209. pwcThisChar++;
  210. }
  211. } else {
  212. *szNextChar = szStartChar;
  213. return 0;
  214. }
  215. }
  216. #pragma warning ( default : 4127) // while (TRUE) error
  217. BOOL
  218. IsNumberInUnicodeList (
  219. IN DWORD dwNumber,
  220. IN LPWSTR lpwszUnicodeList
  221. )
  222. /*++
  223. IsNumberInUnicodeList
  224. Arguments:
  225. IN dwNumber
  226. DWORD number to find in list
  227. IN lpwszUnicodeList
  228. Null terminated, Space delimited list of decimal numbers
  229. Return Value:
  230. TRUE:
  231. dwNumber was found in the list of unicode number strings
  232. FALSE:
  233. dwNumber was not found in the list.
  234. --*/
  235. {
  236. DWORD dwThisNumber;
  237. WCHAR *pwcThisChar;
  238. if (lpwszUnicodeList == 0) return FALSE; // null pointer, # not founde
  239. pwcThisChar = lpwszUnicodeList;
  240. dwThisNumber = 0;
  241. while (*pwcThisChar != 0) {
  242. dwThisNumber = GetNextNumberFromList (
  243. pwcThisChar, &pwcThisChar);
  244. if (dwNumber == dwThisNumber) return TRUE;
  245. }
  246. // if here, then the number wasn't found
  247. return FALSE;
  248. } // IsNumberInUnicodeList
  249. LPWSTR
  250. ConvertProcName(LPSTR strProcName, LPWSTR buffer, DWORD cchBuffer )
  251. {
  252. ULONG lenProcName = (strProcName == NULL) ? (0) : (lstrlenA(strProcName));
  253. ULONG i;
  254. PUCHAR AnsiChar;
  255. if ((lenProcName == 0) || (lenProcName >= cchBuffer)) {
  256. return (LPWSTR) cszSpace;
  257. }
  258. for (i = 0; i < lenProcName; i ++) {
  259. AnsiChar = (PUCHAR) & strProcName[i];
  260. buffer[i] = (WCHAR) RtlAnsiCharToUnicodeChar(& AnsiChar);
  261. }
  262. buffer[lenProcName] = L'\0';
  263. return buffer;
  264. }