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.

428 lines
12 KiB

  1. /********************************************************************/
  2. /** Copyright(c) 1985-1998 Microsoft Corporation. **/
  3. /********************************************************************/
  4. //***
  5. //
  6. // Filename: perfmon.c
  7. //
  8. // Description:
  9. //
  10. // History: Feb 11,1998 NarenG Created original version.
  11. //
  12. #include <nt.h>
  13. #include <ntrtl.h>
  14. #include <nturtl.h>
  15. #include <windows.h>
  16. #include <winperf.h>
  17. #include <lmcons.h>
  18. #include <lmapibuf.h>
  19. #include <lmaccess.h>
  20. #include <raserror.h>
  21. #include <time.h>
  22. #include <string.h>
  23. #include <rasauth.h>
  24. #include <stdlib.h>
  25. #include <stdio.h>
  26. #include <rtutils.h>
  27. #include <mprlog.h>
  28. #include <mprerror.h>
  29. #define INCL_RASAUTHATTRIBUTES
  30. #include <ppputil.h>
  31. #include "radclnt.h"
  32. #include "md5.h"
  33. #include "perfmon.h"
  34. // ADD
  35. #define PERFORMANCEKEY TEXT("SYSTEM\\CurrentControlSet\\Services\\Rasrad\\Performance")
  36. #define FIRSTCOUNTER TEXT("First Counter")
  37. #define FIRSTHELP TEXT("First Help")
  38. #define QUERY_GLOBAL 1
  39. #define QUERY_FOREIGN 2
  40. #define QUERY_COSTLY 3
  41. #define QUERY_ITEMS 4
  42. #define DELIMITER 1
  43. #define DIGIT 2
  44. #define INVALID 3
  45. #pragma pack(4)
  46. // ADD
  47. #define NUMBER_COUNTERS 9
  48. #define AUTHREQSENT_OFFSET sizeof(DWORD)
  49. #define AUTHREQFAILED_OFFSET (AUTHREQSENT_OFFSET + sizeof(DWORD))
  50. #define AUTHREQSUCCEDED_OFFSET (AUTHREQFAILED_OFFSET + sizeof(DWORD))
  51. #define AUTHREQTIMEOUT_OFFSET (AUTHREQSUCCEDED_OFFSET + sizeof(DWORD))
  52. #define ACCTREQSENT_OFFSET (AUTHREQTIMEOUT_OFFSET + sizeof(DWORD))
  53. #define ACCTBADPACK_OFFSET (ACCTREQSENT_OFFSET + sizeof(DWORD))
  54. #define ACCTREQSUCCEDED_OFFSET (ACCTBADPACK_OFFSET + sizeof(DWORD))
  55. #define ACCTREQTIMEOUT_OFFSET (ACCTREQSUCCEDED_OFFSET + sizeof(DWORD))
  56. #define AUTHBADPACK_OFFSET (ACCTREQTIMEOUT_OFFSET + sizeof(DWORD))
  57. #define CB_PERF_DATA (sizeof(PERF_COUNTER_BLOCK) + (NUMBER_COUNTERS * sizeof(DWORD)))
  58. typedef struct
  59. {
  60. PERF_OBJECT_TYPE PerfObjectType;
  61. // ADD
  62. PERF_COUNTER_DEFINITION cAuthReqSent;
  63. PERF_COUNTER_DEFINITION cAuthReqFailed;
  64. PERF_COUNTER_DEFINITION cAuthReqSucceded;
  65. PERF_COUNTER_DEFINITION cAuthReqTimeout;
  66. PERF_COUNTER_DEFINITION cAcctReqSent;
  67. PERF_COUNTER_DEFINITION cAcctBadPack;
  68. PERF_COUNTER_DEFINITION cAcctReqSucceded;
  69. PERF_COUNTER_DEFINITION cAcctReqTimeout;
  70. PERF_COUNTER_DEFINITION cAuthBadPack;
  71. } PERF_DATA;
  72. #pragma pack()
  73. DWORD GetQueryType(LPWSTR pwszQuery);
  74. BOOL IsNumberInUnicodeList(DWORD dwNumber, WCHAR UNALIGNED *pwszUnicodeList);
  75. DWORD g_cRef = 0;
  76. CONST WCHAR g_wszGlobal[] = L"Global";
  77. CONST WCHAR g_wszForeign[] = L"Foreign";
  78. CONST WCHAR g_wszCostly[] = L"Costly";
  79. PERF_DATA g_PerfData =
  80. {
  81. {
  82. sizeof(PERF_DATA) + CB_PERF_DATA, sizeof(PERF_DATA), sizeof(PERF_OBJECT_TYPE),
  83. RADIUS_CLIENT_COUNTER_OBJECT, 0, RADIUS_CLIENT_COUNTER_OBJECT, 0, PERF_DETAIL_NOVICE, (sizeof(PERF_DATA) - sizeof(PERF_OBJECT_TYPE)) / sizeof(PERF_COUNTER_DEFINITION),
  84. 0, 0, 0
  85. },
  86. // ADD
  87. {
  88. sizeof(PERF_COUNTER_DEFINITION), AUTHREQSENT, 0, AUTHREQSENT, 0, 0, PERF_DETAIL_NOVICE, PERF_COUNTER_RAWCOUNT,
  89. sizeof(DWORD), AUTHREQSENT_OFFSET
  90. },
  91. {
  92. sizeof(PERF_COUNTER_DEFINITION), AUTHREQFAILED, 0, AUTHREQFAILED, 0, 0, PERF_DETAIL_NOVICE, PERF_COUNTER_RAWCOUNT,
  93. sizeof(DWORD), AUTHREQFAILED_OFFSET
  94. },
  95. {
  96. sizeof(PERF_COUNTER_DEFINITION), AUTHREQSUCCEDED, 0, AUTHREQSUCCEDED, 0, 0, PERF_DETAIL_NOVICE, PERF_COUNTER_RAWCOUNT,
  97. sizeof(DWORD), AUTHREQSUCCEDED_OFFSET
  98. },
  99. {
  100. sizeof(PERF_COUNTER_DEFINITION), AUTHREQTIMEOUT, 0, AUTHREQTIMEOUT, 0, 0, PERF_DETAIL_NOVICE, PERF_COUNTER_RAWCOUNT,
  101. sizeof(DWORD), AUTHREQTIMEOUT_OFFSET
  102. },
  103. {
  104. sizeof(PERF_COUNTER_DEFINITION), ACCTREQSENT, 0, ACCTREQSENT, 0, 0, PERF_DETAIL_NOVICE, PERF_COUNTER_RAWCOUNT,
  105. sizeof(DWORD), ACCTREQSENT_OFFSET
  106. },
  107. {
  108. sizeof(PERF_COUNTER_DEFINITION), ACCTBADPACK, 0, ACCTBADPACK, 0, 0, PERF_DETAIL_NOVICE, PERF_COUNTER_RAWCOUNT,
  109. sizeof(DWORD), ACCTBADPACK_OFFSET
  110. },
  111. {
  112. sizeof(PERF_COUNTER_DEFINITION), ACCTREQSUCCEDED, 0, ACCTREQSUCCEDED, 0, 0, PERF_DETAIL_NOVICE, PERF_COUNTER_RAWCOUNT,
  113. sizeof(DWORD), ACCTREQSUCCEDED_OFFSET
  114. },
  115. {
  116. sizeof(PERF_COUNTER_DEFINITION), ACCTREQTIMEOUT, 0, ACCTREQTIMEOUT, 0, 0, PERF_DETAIL_NOVICE, PERF_COUNTER_RAWCOUNT,
  117. sizeof(DWORD), ACCTREQTIMEOUT_OFFSET
  118. },
  119. {
  120. sizeof(PERF_COUNTER_DEFINITION), AUTHBADPACK, 0, AUTHBADPACK, 0, 0, PERF_DETAIL_NOVICE, PERF_COUNTER_RAWCOUNT,
  121. sizeof(DWORD), AUTHBADPACK_OFFSET
  122. },
  123. };
  124. // ============================= EvalChar ==========================================
  125. DWORD EvalChar(WCHAR wch, WCHAR wchDelimiter)
  126. {
  127. if (wch == wchDelimiter || wch == 0)
  128. return (DELIMITER);
  129. if (wch >= (WCHAR) '0' && wch <= (WCHAR) '9')
  130. return (DIGIT);
  131. return (INVALID);
  132. } // EvalChar()
  133. // ================================== CompareQuery ===================================
  134. BOOL CompareQuery(WCHAR UNALIGNED *pwszFirst, WCHAR UNALIGNED *pwszSecond)
  135. {
  136. BOOL fFound = TRUE;
  137. while ((*pwszFirst != 0) && (*pwszSecond != 0))
  138. {
  139. if (*pwszFirst++ != *pwszSecond++)
  140. {
  141. fFound = FALSE;
  142. break;
  143. }
  144. }
  145. return (fFound);
  146. } // CompareQuery()
  147. // ================================ Open ===========================================
  148. DWORD APIENTRY Open(LPWSTR *pwszDeviceName)
  149. {
  150. DWORD Status = ERROR_SUCCESS;
  151. if (g_cRef == 0)
  152. {
  153. HKEY hKey = NULL;
  154. DWORD Size, Type, dwFirstCounter, dwFirstHelp;
  155. __try
  156. {
  157. Status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, PERFORMANCEKEY, 0, KEY_ALL_ACCESS, &hKey);
  158. if (Status != ERROR_SUCCESS)
  159. __leave;
  160. Size = sizeof(DWORD);
  161. Status = RegQueryValueEx(hKey, FIRSTCOUNTER, 0, &Type, (PBYTE) &dwFirstCounter, &Size);
  162. if (Status != ERROR_SUCCESS)
  163. __leave;
  164. Size = sizeof(DWORD);
  165. Status = RegQueryValueEx(hKey, FIRSTHELP, 0, &Type, (PBYTE) &dwFirstHelp, &Size);
  166. if (Status != ERROR_SUCCESS)
  167. __leave;
  168. g_PerfData.PerfObjectType.ObjectNameTitleIndex += dwFirstCounter;
  169. g_PerfData.PerfObjectType.ObjectHelpTitleIndex += dwFirstHelp;
  170. // ADD
  171. g_PerfData.cAuthReqSent.CounterNameTitleIndex += dwFirstCounter;
  172. g_PerfData.cAuthReqSent.CounterHelpTitleIndex += dwFirstHelp;
  173. g_PerfData.cAuthReqFailed.CounterNameTitleIndex += dwFirstCounter;
  174. g_PerfData.cAuthReqFailed.CounterHelpTitleIndex += dwFirstHelp;
  175. g_PerfData.cAuthReqSucceded.CounterNameTitleIndex += dwFirstCounter;
  176. g_PerfData.cAuthReqSucceded.CounterHelpTitleIndex += dwFirstHelp;
  177. g_PerfData.cAuthReqTimeout.CounterNameTitleIndex += dwFirstCounter;
  178. g_PerfData.cAuthReqTimeout.CounterHelpTitleIndex += dwFirstHelp;
  179. g_PerfData.cAcctReqSent.CounterNameTitleIndex += dwFirstCounter;
  180. g_PerfData.cAcctReqSent.CounterHelpTitleIndex += dwFirstHelp;
  181. g_PerfData.cAcctBadPack.CounterNameTitleIndex += dwFirstCounter;
  182. g_PerfData.cAcctBadPack.CounterHelpTitleIndex += dwFirstHelp;
  183. g_PerfData.cAcctReqSucceded.CounterNameTitleIndex += dwFirstCounter;
  184. g_PerfData.cAcctReqSucceded.CounterHelpTitleIndex += dwFirstHelp;
  185. g_PerfData.cAcctReqTimeout.CounterNameTitleIndex += dwFirstCounter;
  186. g_PerfData.cAcctReqTimeout.CounterHelpTitleIndex += dwFirstHelp;
  187. g_PerfData.cAuthBadPack.CounterNameTitleIndex += dwFirstCounter;
  188. g_PerfData.cAuthBadPack.CounterHelpTitleIndex += dwFirstHelp;
  189. } // __try
  190. __finally
  191. {
  192. RegCloseKey(hKey);
  193. } // __finally
  194. } // g_cRef == 0
  195. g_cRef ++;
  196. return (Status);
  197. } // Open()
  198. // ================================ Collect ========================================
  199. DWORD APIENTRY Collect(LPWSTR pwszValue, LPVOID *ppvData, LPDWORD pcbData, LPDWORD pcObjectTypes)
  200. {
  201. DWORD dwQueryType, *pdwCounter, dwSpaceNeeded;
  202. PERF_DATA UNALIGNED *pPerfData;
  203. PERF_COUNTER_BLOCK UNALIGNED *pPerfCounter;
  204. dwQueryType = GetQueryType(pwszValue);
  205. if (dwQueryType == QUERY_FOREIGN)
  206. {
  207. *pcbData = 0;
  208. *pcObjectTypes = 0;
  209. return (ERROR_SUCCESS);
  210. }
  211. if (dwQueryType == QUERY_ITEMS)
  212. {
  213. if (IsNumberInUnicodeList(g_PerfData.PerfObjectType.ObjectNameTitleIndex, pwszValue) == FALSE)
  214. {
  215. *pcbData = 0;
  216. *pcObjectTypes = 0;
  217. return (ERROR_SUCCESS);
  218. }
  219. } // QUERY_ITEMS
  220. pPerfData = (PERF_DATA *) *ppvData;
  221. dwSpaceNeeded = sizeof(PERF_DATA) + CB_PERF_DATA;
  222. if (*pcbData < dwSpaceNeeded)
  223. {
  224. *pcbData = 0;
  225. *pcObjectTypes = 0;
  226. return (ERROR_MORE_DATA);
  227. }
  228. CopyMemory(pPerfData, &g_PerfData, sizeof(PERF_DATA));
  229. pPerfCounter = (PERF_COUNTER_BLOCK *) &pPerfData[1];
  230. pPerfCounter->ByteLength = CB_PERF_DATA;
  231. pdwCounter = (DWORD *) &pPerfCounter[1];
  232. // ADD
  233. *pdwCounter = g_cAuthReqSent;
  234. pdwCounter += 1;
  235. *pdwCounter = g_cAuthReqFailed;
  236. pdwCounter += 1;
  237. *pdwCounter = g_cAuthReqSucceded;
  238. pdwCounter += 1;
  239. *pdwCounter = g_cAuthReqTimeout;
  240. pdwCounter += 1;
  241. *pdwCounter = g_cAcctReqSent;
  242. pdwCounter += 1;
  243. *pdwCounter = g_cAcctBadPack;
  244. pdwCounter += 1;
  245. *pdwCounter = g_cAcctReqSucceded;
  246. pdwCounter += 1;
  247. *pdwCounter = g_cAcctReqTimeout;
  248. pdwCounter += 1;
  249. *pdwCounter = g_cAuthBadPack;
  250. pdwCounter += 1;
  251. *ppvData = (PVOID) pdwCounter;
  252. *pcObjectTypes = 1;
  253. *pcbData = (DWORD) ((PBYTE) pdwCounter - (PBYTE) pPerfData);
  254. return (ERROR_SUCCESS);
  255. } // Collect()
  256. // ================================= Close ==========================================
  257. DWORD APIENTRY Close(VOID)
  258. {
  259. g_cRef --;
  260. if (g_cRef == 0)
  261. {
  262. }
  263. return (ERROR_SUCCESS);
  264. } // Close()
  265. // ================================== GetQueryType ==================================
  266. DWORD GetQueryType(LPWSTR pwszQuery)
  267. {
  268. if (pwszQuery == NULL || *pwszQuery == 0)
  269. {
  270. return (QUERY_GLOBAL);
  271. }
  272. if (CompareQuery(pwszQuery, (WCHAR *) g_wszGlobal))
  273. return (QUERY_GLOBAL);
  274. if (CompareQuery(pwszQuery, (WCHAR *) g_wszForeign))
  275. return (QUERY_FOREIGN);
  276. if (CompareQuery(pwszQuery, (WCHAR *) g_wszCostly))
  277. return (QUERY_COSTLY);
  278. return (QUERY_ITEMS);
  279. } // GetQueryType()
  280. // ============================== IsNumberInUnicodeList ===============================
  281. BOOL IsNumberInUnicodeList(DWORD dwNumber, WCHAR UNALIGNED *pwszUnicodeList)
  282. {
  283. BOOL fInList = FALSE;
  284. __try
  285. {
  286. WCHAR UNALIGNED *pwszCh = pwszUnicodeList;
  287. BOOL fNewItem = TRUE;
  288. BOOL fValidNumber = FALSE;
  289. DWORD dwThisNumber = 0;
  290. if (pwszUnicodeList == NULL)
  291. __leave;
  292. while (TRUE)
  293. {
  294. switch (EvalChar(*pwszCh, (WCHAR) ' '))
  295. {
  296. case DIGIT:
  297. if (fNewItem == TRUE)
  298. {
  299. fNewItem = FALSE;
  300. fValidNumber = TRUE;
  301. }
  302. if (fValidNumber == TRUE)
  303. {
  304. dwThisNumber *= 10;
  305. dwThisNumber += (*pwszCh - (WCHAR) '0');
  306. }
  307. break;
  308. case DELIMITER:
  309. if (fValidNumber)
  310. {
  311. if (dwThisNumber == dwNumber)
  312. {
  313. fInList = TRUE;
  314. __leave;
  315. // Fixed because of PREFAST warning
  316. //
  317. // return (TRUE);
  318. //
  319. }
  320. fValidNumber = FALSE;
  321. }
  322. if (*pwszCh == 0)
  323. {
  324. fInList = FALSE;
  325. __leave;
  326. // Fixed because of PREFAST warning
  327. //
  328. // return (FALSE);
  329. //
  330. }
  331. else
  332. {
  333. fNewItem = TRUE;
  334. dwThisNumber = 0;
  335. }
  336. break;
  337. case INVALID:
  338. fValidNumber = FALSE;
  339. break;
  340. default:
  341. break;
  342. } // EvalChar
  343. pwszCh++;
  344. } // TRUE
  345. } // __try
  346. __finally
  347. {
  348. } // __finally
  349. return (fInList);
  350. } // IsNumberInUnicodeList()