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.

2053 lines
66 KiB

  1. //+-------------------------------------------------------------------------
  2. // Microsoft Windows
  3. //
  4. // Copyright (C) Microsoft Corporation, 1999 - 1999
  5. //
  6. // File: certperf.cpp
  7. //
  8. // Contents: Certificate Performance Counter Functions
  9. //
  10. // Functions:
  11. // OpenCertPerformanceData
  12. // CollectCertPerformanceData
  13. // CloseCertPerformanceData
  14. // CertPerfDllMain
  15. //
  16. // CertPerfGetCertificateChainBefore
  17. // CertPerfGetCertificateChainAfter
  18. //
  19. // History: 04-May-99 philh created
  20. //--------------------------------------------------------------------------
  21. #include "global.hxx"
  22. #include <dbgdef.h>
  23. #ifdef STATIC
  24. #undef STATIC
  25. #endif
  26. #define STATIC
  27. #define DWORD_MULTIPLE(x) (((x+sizeof(DWORD)-1)/sizeof(DWORD))*sizeof(DWORD))
  28. #define CERT_PERF_REGPATH \
  29. L"SYSTEM\\CurrentControlSet\\Services\\crypt32\\Performance"
  30. #define CERT_PERF_SHARED_MEMORY_FILE_NAME \
  31. L"crypt32CertPerfFile"
  32. #define CERT_PERF_SHARED_MEMORY_MUTEX_NAME \
  33. L"crypt32CertPerfMutex"
  34. #define CERT_PERF_TS_GLOBAL_PREFIX \
  35. L"Global\\"
  36. #define CERT_PERF_TS_SHARED_MEMORY_FILE_NAME \
  37. CERT_PERF_TS_GLOBAL_PREFIX CERT_PERF_SHARED_MEMORY_FILE_NAME
  38. #define CERT_PERF_TS_SHARED_MEMORY_MUTEX_NAME \
  39. CERT_PERF_TS_GLOBAL_PREFIX CERT_PERF_SHARED_MEMORY_MUTEX_NAME
  40. #define CERT_PERF_SHARED_MEMORY_MUTEX_TIMEOUT ((DWORD) 5000L)
  41. #define CERT_PERF_MAX_PROCESS_NAME_LEN 32
  42. #define CERT_PERF_MAX_PROCESS_CNT 50
  43. #include <pshpack8.h>
  44. // Note, a dwIndex >= CERT_PERF_MAX_PROCESS_CNT indicates an empty or
  45. // the end of a list
  46. typedef struct _CERT_PERF_PROCESS_DATA {
  47. DWORD dwNextIndex;
  48. DWORD dwPrevIndex;
  49. DWORD dwProcessId;
  50. DWORD dwReserved;
  51. WCHAR wcszProcessName[CERT_PERF_MAX_PROCESS_NAME_LEN];
  52. CERT_PERF_PROCESS_COUNTERS Counters;
  53. } CERT_PERF_PROCESS_DATA, *PCERT_PERF_PROCESS_DATA;
  54. typedef struct _CERT_PERF_SHARED_MEMORY {
  55. DWORD dwProcessCnt;
  56. DWORD dwFirstInUseIndex;
  57. DWORD dwFirstFreeIndex;
  58. DWORD dwReserved;
  59. CERT_PERF_PROCESS_DATA rgProcessData[CERT_PERF_MAX_PROCESS_CNT];
  60. } CERT_PERF_SHARED_MEMORY, *PCERT_PERF_SHARED_MEMORY;
  61. // Certificate performance counters
  62. typedef struct _CERT_PERF_DATA_DEFINITION {
  63. PERF_OBJECT_TYPE ObjectType;
  64. PERF_COUNTER_DEFINITION ChainCnt;
  65. PERF_COUNTER_DEFINITION ChainElementCnt;
  66. PERF_COUNTER_DEFINITION ChainEngineCurrentCnt;
  67. PERF_COUNTER_DEFINITION ChainEngineTotalCnt;
  68. PERF_COUNTER_DEFINITION ChainEngineResyncCnt;
  69. PERF_COUNTER_DEFINITION ChainCertCacheCnt;
  70. PERF_COUNTER_DEFINITION ChainCtlCacheCnt;
  71. PERF_COUNTER_DEFINITION ChainEndCertInCacheCnt;
  72. PERF_COUNTER_DEFINITION ChainCacheEndCertCnt;
  73. PERF_COUNTER_DEFINITION ChainRevocationCnt;
  74. PERF_COUNTER_DEFINITION ChainRevokedCnt;
  75. PERF_COUNTER_DEFINITION ChainRevocationOfflineCnt;
  76. PERF_COUNTER_DEFINITION ChainNoRevocationCheckCnt;
  77. PERF_COUNTER_DEFINITION ChainVerifyCertSignatureCnt;
  78. PERF_COUNTER_DEFINITION ChainCompareIssuerPublicKeyCnt;
  79. PERF_COUNTER_DEFINITION ChainVerifyCtlSignatureCnt;
  80. PERF_COUNTER_DEFINITION ChainBeenVerifiedCtlSignatureCnt;
  81. PERF_COUNTER_DEFINITION ChainUrlIssuerCnt;
  82. PERF_COUNTER_DEFINITION ChainCacheOnlyUrlIssuerCnt;
  83. PERF_COUNTER_DEFINITION ChainRequestedEngineResyncCnt;
  84. PERF_COUNTER_DEFINITION ChangeNotifyCnt;
  85. PERF_COUNTER_DEFINITION ChangeNotifyLmGpCnt;
  86. PERF_COUNTER_DEFINITION ChangeNotifyCuGpCnt;
  87. PERF_COUNTER_DEFINITION ChangeNotifyCuMyCnt;
  88. PERF_COUNTER_DEFINITION ChangeNotifyRegCnt;
  89. PERF_COUNTER_DEFINITION StoreCurrentCnt;
  90. PERF_COUNTER_DEFINITION StoreTotalCnt;
  91. PERF_COUNTER_DEFINITION StoreRegCurrentCnt;
  92. PERF_COUNTER_DEFINITION StoreRegTotalCnt;
  93. PERF_COUNTER_DEFINITION RegElementReadCnt;
  94. PERF_COUNTER_DEFINITION RegElementWriteCnt;
  95. PERF_COUNTER_DEFINITION RegElementDeleteCnt;
  96. PERF_COUNTER_DEFINITION CertElementCurrentCnt;
  97. PERF_COUNTER_DEFINITION CertElementTotalCnt;
  98. PERF_COUNTER_DEFINITION CrlElementCurrentCnt;
  99. PERF_COUNTER_DEFINITION CrlElementTotalCnt;
  100. PERF_COUNTER_DEFINITION CtlElementCurrentCnt;
  101. PERF_COUNTER_DEFINITION CtlElementTotalCnt;
  102. //--### Add New Counters ###--
  103. } CERT_PERF_DATA_DEFINITION, *PCERT_PERF_DATA_DEFINITION;
  104. typedef struct _CERT_PERF_COUNTERS {
  105. PERF_COUNTER_BLOCK CounterBlock;
  106. DWORD dwChainCnt;
  107. DWORD dwChainElementCnt;
  108. DWORD dwChainEngineCurrentCnt;
  109. DWORD dwChainEngineTotalCnt;
  110. DWORD dwChainEngineResyncCnt;
  111. DWORD dwChainCertCacheCnt;
  112. DWORD dwChainCtlCacheCnt;
  113. DWORD dwChainEndCertInCacheCnt;
  114. DWORD dwChainCacheEndCertCnt;
  115. DWORD dwChainRevocationCnt;
  116. DWORD dwChainRevokedCnt;
  117. DWORD dwChainRevocationOfflineCnt;
  118. DWORD dwChainNoRevocationCheckCnt;
  119. DWORD dwChainVerifyCertSignatureCnt;
  120. DWORD dwChainCompareIssuerPublicKeyCnt;
  121. DWORD dwChainVerifyCtlSignatureCnt;
  122. DWORD dwChainBeenVerifiedCtlSignatureCnt;
  123. DWORD dwChainUrlIssuerCnt;
  124. DWORD dwChainCacheOnlyUrlIssuerCnt;
  125. DWORD dwChainRequestedEngineResyncCnt;
  126. DWORD dwChangeNotifyCnt;
  127. DWORD dwChangeNotifyLmGpCnt;
  128. DWORD dwChangeNotifyCuGpCnt;
  129. DWORD dwChangeNotifyCuMyCnt;
  130. DWORD dwChangeNotifyRegCnt;
  131. DWORD dwStoreCurrentCnt;
  132. DWORD dwStoreTotalCnt;
  133. DWORD dwStoreRegCurrentCnt;
  134. DWORD dwStoreRegTotalCnt;
  135. DWORD dwRegElementReadCnt;
  136. DWORD dwRegElementWriteCnt;
  137. DWORD dwRegElementDeleteCnt;
  138. DWORD dwCertElementCurrentCnt;
  139. DWORD dwCertElementTotalCnt;
  140. DWORD dwCrlElementCurrentCnt;
  141. DWORD dwCrlElementTotalCnt;
  142. DWORD dwCtlElementCurrentCnt;
  143. DWORD dwCtlElementTotalCnt;
  144. //--### Add New Counters ###--
  145. } CERT_PERF_COUNTERS, *PCERT_PERF_COUNTERS;
  146. #include <poppack.h>
  147. //+----------------------------------------------------------------------
  148. // The following are set at DLL_PROCESS_ATTACH if certperf.reg has been
  149. // regedit'ed and certperf.ini has been lodctr'ed. Otherwise, they remain
  150. // NULL.
  151. //-----------------------------------------------------------------------
  152. HANDLE hCertPerfSharedMemoryMutex;
  153. HANDLE hCertPerfSharedMemoryFile;
  154. PCERT_PERF_SHARED_MEMORY pCertPerfSharedMemory;
  155. PCERT_PERF_PROCESS_DATA pCertPerfProcessData;
  156. PCERT_PERF_PROCESS_COUNTERS pCertPerfProcessCounters;
  157. // Always initialized
  158. CRITICAL_SECTION CertPerfProcessCriticalSection;
  159. #define IMPURE 0
  160. CERT_PERF_DATA_DEFINITION CertPerfDataDefinition = {
  161. // PERF_OBJECT_TYPE ObjectType
  162. {
  163. IMPURE, // TotalByteLength
  164. sizeof(CERT_PERF_DATA_DEFINITION),
  165. sizeof(PERF_OBJECT_TYPE),
  166. IMPURE, // ObjectNameTitleIndex: dwFirstCounter + CERT_OBJ
  167. 0,
  168. IMPURE, // ObjectHelpTitleIndex: dwFirstHelp + CERT_OBJ
  169. 0,
  170. PERF_DETAIL_NOVICE,
  171. (sizeof(CERT_PERF_DATA_DEFINITION) - sizeof(PERF_OBJECT_TYPE))/
  172. sizeof(PERF_COUNTER_DEFINITION),
  173. 0, // ChainCnt is the default counter
  174. IMPURE, // NumInstances
  175. 0, // unicode instance names
  176. {0,0},
  177. {0,0}
  178. },
  179. // 0 - PERF_COUNTER_DEFINITION ChainCnt
  180. {
  181. sizeof(PERF_COUNTER_DEFINITION),
  182. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  183. 0,
  184. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  185. 0,
  186. -2,
  187. PERF_DETAIL_NOVICE,
  188. PERF_COUNTER_RAWCOUNT,
  189. sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainCnt),
  190. offsetof(CERT_PERF_COUNTERS, dwChainCnt),
  191. },
  192. // 1 - PERF_COUNTER_DEFINITION ChainElementCnt
  193. {
  194. sizeof(PERF_COUNTER_DEFINITION),
  195. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  196. 0,
  197. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  198. 0,
  199. -2,
  200. PERF_DETAIL_NOVICE,
  201. PERF_COUNTER_RAWCOUNT,
  202. sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainElementCnt),
  203. offsetof(CERT_PERF_COUNTERS, dwChainElementCnt),
  204. },
  205. // 2 - PERF_COUNTER_DEFINITION ChainEngineCurrentCnt
  206. {
  207. sizeof(PERF_COUNTER_DEFINITION),
  208. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  209. 0,
  210. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  211. 0,
  212. -2,
  213. PERF_DETAIL_NOVICE,
  214. PERF_COUNTER_RAWCOUNT,
  215. sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainEngineCurrentCnt),
  216. offsetof(CERT_PERF_COUNTERS, dwChainEngineCurrentCnt),
  217. },
  218. // 3 - PERF_COUNTER_DEFINITION ChainEngineTotalCnt
  219. {
  220. sizeof(PERF_COUNTER_DEFINITION),
  221. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  222. 0,
  223. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  224. 0,
  225. -2,
  226. PERF_DETAIL_NOVICE,
  227. PERF_COUNTER_RAWCOUNT,
  228. sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainEngineTotalCnt),
  229. offsetof(CERT_PERF_COUNTERS, dwChainEngineTotalCnt),
  230. },
  231. // 4 - PERF_COUNTER_DEFINITION ChainEngineResyncCnt
  232. {
  233. sizeof(PERF_COUNTER_DEFINITION),
  234. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  235. 0,
  236. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  237. 0,
  238. -2,
  239. PERF_DETAIL_NOVICE,
  240. PERF_COUNTER_RAWCOUNT,
  241. sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainEngineResyncCnt),
  242. offsetof(CERT_PERF_COUNTERS, dwChainEngineResyncCnt),
  243. },
  244. // 5 - PERF_COUNTER_DEFINITION ChainCertCacheCnt
  245. {
  246. sizeof(PERF_COUNTER_DEFINITION),
  247. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  248. 0,
  249. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  250. 0,
  251. -2,
  252. PERF_DETAIL_NOVICE,
  253. PERF_COUNTER_RAWCOUNT,
  254. sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainCertCacheCnt),
  255. offsetof(CERT_PERF_COUNTERS, dwChainCertCacheCnt),
  256. },
  257. // 6 - PERF_COUNTER_DEFINITION ChainCtlCacheCnt
  258. {
  259. sizeof(PERF_COUNTER_DEFINITION),
  260. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  261. 0,
  262. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  263. 0,
  264. -2,
  265. PERF_DETAIL_NOVICE,
  266. PERF_COUNTER_RAWCOUNT,
  267. sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainCtlCacheCnt),
  268. offsetof(CERT_PERF_COUNTERS, dwChainCtlCacheCnt),
  269. },
  270. // 7 - PERF_COUNTER_DEFINITION ChainEndCertInCacheCnt
  271. {
  272. sizeof(PERF_COUNTER_DEFINITION),
  273. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  274. 0,
  275. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  276. 0,
  277. -2,
  278. PERF_DETAIL_NOVICE,
  279. PERF_COUNTER_RAWCOUNT,
  280. sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainEndCertInCacheCnt),
  281. offsetof(CERT_PERF_COUNTERS, dwChainEndCertInCacheCnt),
  282. },
  283. // 8 - PERF_COUNTER_DEFINITION ChainCacheEndCertCnt
  284. {
  285. sizeof(PERF_COUNTER_DEFINITION),
  286. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  287. 0,
  288. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  289. 0,
  290. -2,
  291. PERF_DETAIL_NOVICE,
  292. PERF_COUNTER_RAWCOUNT,
  293. sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainCacheEndCertCnt),
  294. offsetof(CERT_PERF_COUNTERS, dwChainCacheEndCertCnt),
  295. },
  296. // 9 - PERF_COUNTER_DEFINITION ChainRevocationCnt
  297. {
  298. sizeof(PERF_COUNTER_DEFINITION),
  299. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  300. 0,
  301. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  302. 0,
  303. -2,
  304. PERF_DETAIL_NOVICE,
  305. PERF_COUNTER_RAWCOUNT,
  306. sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainRevocationCnt),
  307. offsetof(CERT_PERF_COUNTERS, dwChainRevocationCnt),
  308. },
  309. // 10 - PERF_COUNTER_DEFINITION ChainRevokedCnt
  310. {
  311. sizeof(PERF_COUNTER_DEFINITION),
  312. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  313. 0,
  314. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  315. 0,
  316. -2,
  317. PERF_DETAIL_NOVICE,
  318. PERF_COUNTER_RAWCOUNT,
  319. sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainRevokedCnt),
  320. offsetof(CERT_PERF_COUNTERS, dwChainRevokedCnt),
  321. },
  322. // 11 - PERF_COUNTER_DEFINITION ChainRevocationOfflineCnt
  323. {
  324. sizeof(PERF_COUNTER_DEFINITION),
  325. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  326. 0,
  327. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  328. 0,
  329. -2,
  330. PERF_DETAIL_NOVICE,
  331. PERF_COUNTER_RAWCOUNT,
  332. sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainRevocationOfflineCnt),
  333. offsetof(CERT_PERF_COUNTERS, dwChainRevocationOfflineCnt),
  334. },
  335. // 12 - PERF_COUNTER_DEFINITION ChainNoRevocationCheckCnt
  336. {
  337. sizeof(PERF_COUNTER_DEFINITION),
  338. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  339. 0,
  340. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  341. 0,
  342. -2,
  343. PERF_DETAIL_NOVICE,
  344. PERF_COUNTER_RAWCOUNT,
  345. sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainNoRevocationCheckCnt),
  346. offsetof(CERT_PERF_COUNTERS, dwChainNoRevocationCheckCnt),
  347. },
  348. // 13 - PERF_COUNTER_DEFINITION ChainVerifyCertSignatureCnt
  349. {
  350. sizeof(PERF_COUNTER_DEFINITION),
  351. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  352. 0,
  353. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  354. 0,
  355. -2,
  356. PERF_DETAIL_NOVICE,
  357. PERF_COUNTER_RAWCOUNT,
  358. sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainVerifyCertSignatureCnt),
  359. offsetof(CERT_PERF_COUNTERS, dwChainVerifyCertSignatureCnt),
  360. },
  361. // 14 - PERF_COUNTER_DEFINITION ChainCompareIssuerPublicKeyCnt
  362. {
  363. sizeof(PERF_COUNTER_DEFINITION),
  364. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  365. 0,
  366. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  367. 0,
  368. -2,
  369. PERF_DETAIL_NOVICE,
  370. PERF_COUNTER_RAWCOUNT,
  371. sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainCompareIssuerPublicKeyCnt),
  372. offsetof(CERT_PERF_COUNTERS, dwChainCompareIssuerPublicKeyCnt),
  373. },
  374. // 15 - PERF_COUNTER_DEFINITION ChainVerifyCtlSignatureCnt
  375. {
  376. sizeof(PERF_COUNTER_DEFINITION),
  377. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  378. 0,
  379. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  380. 0,
  381. -2,
  382. PERF_DETAIL_NOVICE,
  383. PERF_COUNTER_RAWCOUNT,
  384. sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainVerifyCtlSignatureCnt),
  385. offsetof(CERT_PERF_COUNTERS, dwChainVerifyCtlSignatureCnt),
  386. },
  387. // 16 - PERF_COUNTER_DEFINITION ChainBeenVerifiedCtlSignatureCnt
  388. {
  389. sizeof(PERF_COUNTER_DEFINITION),
  390. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  391. 0,
  392. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  393. 0,
  394. -2,
  395. PERF_DETAIL_NOVICE,
  396. PERF_COUNTER_RAWCOUNT,
  397. sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainBeenVerifiedCtlSignatureCnt),
  398. offsetof(CERT_PERF_COUNTERS, dwChainBeenVerifiedCtlSignatureCnt),
  399. },
  400. // 17 - PERF_COUNTER_DEFINITION ChainUrlIssuerCnt
  401. {
  402. sizeof(PERF_COUNTER_DEFINITION),
  403. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  404. 0,
  405. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  406. 0,
  407. -2,
  408. PERF_DETAIL_NOVICE,
  409. PERF_COUNTER_RAWCOUNT,
  410. sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainUrlIssuerCnt),
  411. offsetof(CERT_PERF_COUNTERS, dwChainUrlIssuerCnt),
  412. },
  413. // 18 - PERF_COUNTER_DEFINITION ChainCacheOnlyUrlIssuerCnt
  414. {
  415. sizeof(PERF_COUNTER_DEFINITION),
  416. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  417. 0,
  418. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  419. 0,
  420. -2,
  421. PERF_DETAIL_NOVICE,
  422. PERF_COUNTER_RAWCOUNT,
  423. sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainCacheOnlyUrlIssuerCnt),
  424. offsetof(CERT_PERF_COUNTERS, dwChainCacheOnlyUrlIssuerCnt),
  425. },
  426. // 19 - PERF_COUNTER_DEFINITION ChainRequestedEngineResyncCnt
  427. {
  428. sizeof(PERF_COUNTER_DEFINITION),
  429. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  430. 0,
  431. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  432. 0,
  433. -2,
  434. PERF_DETAIL_NOVICE,
  435. PERF_COUNTER_RAWCOUNT,
  436. sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainRequestedEngineResyncCnt),
  437. offsetof(CERT_PERF_COUNTERS, dwChainRequestedEngineResyncCnt),
  438. },
  439. // 20 - PERF_COUNTER_DEFINITION ChangeNotifyCnt
  440. {
  441. sizeof(PERF_COUNTER_DEFINITION),
  442. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  443. 0,
  444. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  445. 0,
  446. -2,
  447. PERF_DETAIL_NOVICE,
  448. PERF_COUNTER_RAWCOUNT,
  449. sizeof(((PCERT_PERF_COUNTERS) 0)->dwChangeNotifyCnt),
  450. offsetof(CERT_PERF_COUNTERS, dwChangeNotifyCnt),
  451. },
  452. // 21 - PERF_COUNTER_DEFINITION ChangeNotifyLmGpCnt
  453. {
  454. sizeof(PERF_COUNTER_DEFINITION),
  455. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  456. 0,
  457. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  458. 0,
  459. -2,
  460. PERF_DETAIL_NOVICE,
  461. PERF_COUNTER_RAWCOUNT,
  462. sizeof(((PCERT_PERF_COUNTERS) 0)->dwChangeNotifyLmGpCnt),
  463. offsetof(CERT_PERF_COUNTERS, dwChangeNotifyLmGpCnt),
  464. },
  465. // 22 - PERF_COUNTER_DEFINITION ChangeNotifyCuGpCnt
  466. {
  467. sizeof(PERF_COUNTER_DEFINITION),
  468. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  469. 0,
  470. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  471. 0,
  472. -2,
  473. PERF_DETAIL_NOVICE,
  474. PERF_COUNTER_RAWCOUNT,
  475. sizeof(((PCERT_PERF_COUNTERS) 0)->dwChangeNotifyCuGpCnt),
  476. offsetof(CERT_PERF_COUNTERS, dwChangeNotifyCuGpCnt),
  477. },
  478. // 23 - PERF_COUNTER_DEFINITION ChangeNotifyCuMyCnt
  479. {
  480. sizeof(PERF_COUNTER_DEFINITION),
  481. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  482. 0,
  483. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  484. 0,
  485. -2,
  486. PERF_DETAIL_NOVICE,
  487. PERF_COUNTER_RAWCOUNT,
  488. sizeof(((PCERT_PERF_COUNTERS) 0)->dwChangeNotifyCuMyCnt),
  489. offsetof(CERT_PERF_COUNTERS, dwChangeNotifyCuMyCnt),
  490. },
  491. // 24 - PERF_COUNTER_DEFINITION ChangeNotifyRegCnt
  492. {
  493. sizeof(PERF_COUNTER_DEFINITION),
  494. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  495. 0,
  496. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  497. 0,
  498. -2,
  499. PERF_DETAIL_NOVICE,
  500. PERF_COUNTER_RAWCOUNT,
  501. sizeof(((PCERT_PERF_COUNTERS) 0)->dwChangeNotifyRegCnt),
  502. offsetof(CERT_PERF_COUNTERS, dwChangeNotifyRegCnt),
  503. },
  504. // 25 - PERF_COUNTER_DEFINITION StoreCurrentCnt
  505. {
  506. sizeof(PERF_COUNTER_DEFINITION),
  507. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  508. 0,
  509. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  510. 0,
  511. -2,
  512. PERF_DETAIL_NOVICE,
  513. PERF_COUNTER_RAWCOUNT,
  514. sizeof(((PCERT_PERF_COUNTERS) 0)->dwStoreCurrentCnt),
  515. offsetof(CERT_PERF_COUNTERS, dwStoreCurrentCnt),
  516. },
  517. // 26 - PERF_COUNTER_DEFINITION StoreTotalCnt
  518. {
  519. sizeof(PERF_COUNTER_DEFINITION),
  520. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  521. 0,
  522. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  523. 0,
  524. -2,
  525. PERF_DETAIL_NOVICE,
  526. PERF_COUNTER_RAWCOUNT,
  527. sizeof(((PCERT_PERF_COUNTERS) 0)->dwStoreTotalCnt),
  528. offsetof(CERT_PERF_COUNTERS, dwStoreTotalCnt),
  529. },
  530. // 27 - PERF_COUNTER_DEFINITION StoreRegCurrentCnt
  531. {
  532. sizeof(PERF_COUNTER_DEFINITION),
  533. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  534. 0,
  535. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  536. 0,
  537. -2,
  538. PERF_DETAIL_NOVICE,
  539. PERF_COUNTER_RAWCOUNT,
  540. sizeof(((PCERT_PERF_COUNTERS) 0)->dwStoreRegCurrentCnt),
  541. offsetof(CERT_PERF_COUNTERS, dwStoreRegCurrentCnt),
  542. },
  543. // 28 - PERF_COUNTER_DEFINITION StoreRegTotalCnt
  544. {
  545. sizeof(PERF_COUNTER_DEFINITION),
  546. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  547. 0,
  548. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  549. 0,
  550. -2,
  551. PERF_DETAIL_NOVICE,
  552. PERF_COUNTER_RAWCOUNT,
  553. sizeof(((PCERT_PERF_COUNTERS) 0)->dwStoreRegTotalCnt),
  554. offsetof(CERT_PERF_COUNTERS, dwStoreRegTotalCnt),
  555. },
  556. // 29 - PERF_COUNTER_DEFINITION RegElementReadCnt
  557. {
  558. sizeof(PERF_COUNTER_DEFINITION),
  559. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  560. 0,
  561. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  562. 0,
  563. -2,
  564. PERF_DETAIL_NOVICE,
  565. PERF_COUNTER_RAWCOUNT,
  566. sizeof(((PCERT_PERF_COUNTERS) 0)->dwRegElementReadCnt),
  567. offsetof(CERT_PERF_COUNTERS, dwRegElementReadCnt),
  568. },
  569. // 30 - PERF_COUNTER_DEFINITION RegElementWriteCnt
  570. {
  571. sizeof(PERF_COUNTER_DEFINITION),
  572. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  573. 0,
  574. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  575. 0,
  576. -2,
  577. PERF_DETAIL_NOVICE,
  578. PERF_COUNTER_RAWCOUNT,
  579. sizeof(((PCERT_PERF_COUNTERS) 0)->dwRegElementWriteCnt),
  580. offsetof(CERT_PERF_COUNTERS, dwRegElementWriteCnt),
  581. },
  582. // 31 - PERF_COUNTER_DEFINITION RegElementDeleteCnt
  583. {
  584. sizeof(PERF_COUNTER_DEFINITION),
  585. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  586. 0,
  587. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  588. 0,
  589. -2,
  590. PERF_DETAIL_NOVICE,
  591. PERF_COUNTER_RAWCOUNT,
  592. sizeof(((PCERT_PERF_COUNTERS) 0)->dwRegElementDeleteCnt),
  593. offsetof(CERT_PERF_COUNTERS, dwRegElementDeleteCnt),
  594. },
  595. // 32 - PERF_COUNTER_DEFINITION CertElementCurrentCnt
  596. {
  597. sizeof(PERF_COUNTER_DEFINITION),
  598. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  599. 0,
  600. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  601. 0,
  602. -2,
  603. PERF_DETAIL_NOVICE,
  604. PERF_COUNTER_RAWCOUNT,
  605. sizeof(((PCERT_PERF_COUNTERS) 0)->dwCertElementCurrentCnt),
  606. offsetof(CERT_PERF_COUNTERS, dwCertElementCurrentCnt),
  607. },
  608. // 33 - PERF_COUNTER_DEFINITION CertElementTotalCnt
  609. {
  610. sizeof(PERF_COUNTER_DEFINITION),
  611. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  612. 0,
  613. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  614. 0,
  615. -2,
  616. PERF_DETAIL_NOVICE,
  617. PERF_COUNTER_RAWCOUNT,
  618. sizeof(((PCERT_PERF_COUNTERS) 0)->dwCertElementTotalCnt),
  619. offsetof(CERT_PERF_COUNTERS, dwCertElementTotalCnt),
  620. },
  621. // 34 - PERF_COUNTER_DEFINITION CrlElementCurrentCnt
  622. {
  623. sizeof(PERF_COUNTER_DEFINITION),
  624. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  625. 0,
  626. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  627. 0,
  628. -2,
  629. PERF_DETAIL_NOVICE,
  630. PERF_COUNTER_RAWCOUNT,
  631. sizeof(((PCERT_PERF_COUNTERS) 0)->dwCrlElementCurrentCnt),
  632. offsetof(CERT_PERF_COUNTERS, dwCrlElementCurrentCnt),
  633. },
  634. // 35 - PERF_COUNTER_DEFINITION CrlElementTotalCnt
  635. {
  636. sizeof(PERF_COUNTER_DEFINITION),
  637. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  638. 0,
  639. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  640. 0,
  641. -2,
  642. PERF_DETAIL_NOVICE,
  643. PERF_COUNTER_RAWCOUNT,
  644. sizeof(((PCERT_PERF_COUNTERS) 0)->dwCrlElementTotalCnt),
  645. offsetof(CERT_PERF_COUNTERS, dwCrlElementTotalCnt),
  646. },
  647. // 36 - PERF_COUNTER_DEFINITION CtlElementCurrentCnt
  648. {
  649. sizeof(PERF_COUNTER_DEFINITION),
  650. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  651. 0,
  652. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  653. 0,
  654. -2,
  655. PERF_DETAIL_NOVICE,
  656. PERF_COUNTER_RAWCOUNT,
  657. sizeof(((PCERT_PERF_COUNTERS) 0)->dwCtlElementCurrentCnt),
  658. offsetof(CERT_PERF_COUNTERS, dwCtlElementCurrentCnt),
  659. },
  660. // 37 - PERF_COUNTER_DEFINITION CtlElementTotalCnt
  661. {
  662. sizeof(PERF_COUNTER_DEFINITION),
  663. IMPURE, // CounterNameTitleIndex: dwFirstCounter +
  664. 0,
  665. IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
  666. 0,
  667. -2,
  668. PERF_DETAIL_NOVICE,
  669. PERF_COUNTER_RAWCOUNT,
  670. sizeof(((PCERT_PERF_COUNTERS) 0)->dwCtlElementTotalCnt),
  671. offsetof(CERT_PERF_COUNTERS, dwCtlElementTotalCnt),
  672. },
  673. //--### Add New Counters ###--
  674. };
  675. STATIC
  676. BOOL
  677. I_CertPerfSetNameAndHelpIndices()
  678. {
  679. BOOL fResult;
  680. HKEY hKey = NULL;
  681. DWORD dwType;
  682. DWORD cbValue;
  683. DWORD dwFirstCounter;
  684. DWORD dwFirstHelp;
  685. if (!FIsWinNT())
  686. return FALSE;
  687. if (ERROR_SUCCESS != RegOpenKeyExW(
  688. HKEY_LOCAL_MACHINE,
  689. CERT_PERF_REGPATH,
  690. 0, // dwReserved
  691. KEY_READ,
  692. &hKey))
  693. goto ErrorReturn;
  694. cbValue = sizeof(DWORD);
  695. if (ERROR_SUCCESS != RegQueryValueExW(
  696. hKey,
  697. L"First Counter",
  698. NULL, // pdwReserved
  699. &dwType,
  700. (PBYTE) &dwFirstCounter,
  701. &cbValue))
  702. goto ErrorReturn;
  703. cbValue = sizeof(DWORD);
  704. if (ERROR_SUCCESS != RegQueryValueExW(
  705. hKey,
  706. L"First Help",
  707. NULL, // pdwReserved
  708. &dwType,
  709. (PBYTE) &dwFirstHelp,
  710. &cbValue))
  711. goto ErrorReturn;
  712. // Update CertPerfDataDefinitions' counter and help name indices
  713. CertPerfDataDefinition.ObjectType.ObjectNameTitleIndex =
  714. dwFirstCounter + CERT_OBJ;
  715. CertPerfDataDefinition.ObjectType.ObjectHelpTitleIndex =
  716. dwFirstHelp + CERT_OBJ;
  717. CertPerfDataDefinition.ChainCnt.CounterNameTitleIndex =
  718. dwFirstCounter + CERT_CHAIN_CNT;
  719. CertPerfDataDefinition.ChainCnt.CounterHelpTitleIndex =
  720. dwFirstHelp + CERT_CHAIN_CNT;
  721. CertPerfDataDefinition.ChainElementCnt.CounterNameTitleIndex =
  722. dwFirstCounter + CERT_CHAIN_ELEMENT_CNT;
  723. CertPerfDataDefinition.ChainElementCnt.CounterHelpTitleIndex =
  724. dwFirstHelp + CERT_CHAIN_ELEMENT_CNT;
  725. CertPerfDataDefinition.ChainEngineCurrentCnt.CounterNameTitleIndex =
  726. dwFirstCounter + CERT_CHAIN_ENGINE_CURRENT_CNT;
  727. CertPerfDataDefinition.ChainEngineCurrentCnt.CounterHelpTitleIndex =
  728. dwFirstHelp + CERT_CHAIN_ENGINE_CURRENT_CNT;
  729. CertPerfDataDefinition.ChainEngineTotalCnt.CounterNameTitleIndex =
  730. dwFirstCounter + CERT_CHAIN_ENGINE_TOTAL_CNT;
  731. CertPerfDataDefinition.ChainEngineTotalCnt.CounterHelpTitleIndex =
  732. dwFirstHelp + CERT_CHAIN_ENGINE_TOTAL_CNT;
  733. CertPerfDataDefinition.ChainEngineResyncCnt.CounterNameTitleIndex =
  734. dwFirstCounter + CERT_CHAIN_ENGINE_RESYNC_CNT;
  735. CertPerfDataDefinition.ChainEngineResyncCnt.CounterHelpTitleIndex =
  736. dwFirstHelp + CERT_CHAIN_ENGINE_RESYNC_CNT;
  737. CertPerfDataDefinition.ChainCertCacheCnt.CounterNameTitleIndex =
  738. dwFirstCounter + CERT_CHAIN_CERT_CACHE_CNT;
  739. CertPerfDataDefinition.ChainCertCacheCnt.CounterHelpTitleIndex =
  740. dwFirstHelp + CERT_CHAIN_CERT_CACHE_CNT;
  741. CertPerfDataDefinition.ChainCtlCacheCnt.CounterNameTitleIndex =
  742. dwFirstCounter + CERT_CHAIN_CTL_CACHE_CNT;
  743. CertPerfDataDefinition.ChainCtlCacheCnt.CounterHelpTitleIndex =
  744. dwFirstHelp + CERT_CHAIN_CTL_CACHE_CNT;
  745. CertPerfDataDefinition.ChainEndCertInCacheCnt.CounterNameTitleIndex =
  746. dwFirstCounter + CERT_CHAIN_END_CERT_IN_CACHE_CNT;
  747. CertPerfDataDefinition.ChainEndCertInCacheCnt.CounterHelpTitleIndex =
  748. dwFirstHelp + CERT_CHAIN_END_CERT_IN_CACHE_CNT;
  749. CertPerfDataDefinition.ChainCacheEndCertCnt.CounterNameTitleIndex =
  750. dwFirstCounter + CERT_CHAIN_CACHE_END_CERT_CNT;
  751. CertPerfDataDefinition.ChainCacheEndCertCnt.CounterHelpTitleIndex =
  752. dwFirstHelp + CERT_CHAIN_CACHE_END_CERT_CNT;
  753. CertPerfDataDefinition.ChainRevocationCnt.CounterNameTitleIndex =
  754. dwFirstCounter + CERT_CHAIN_REVOCATION_CNT;
  755. CertPerfDataDefinition.ChainRevocationCnt.CounterHelpTitleIndex =
  756. dwFirstHelp + CERT_CHAIN_REVOCATION_CNT;
  757. CertPerfDataDefinition.ChainRevokedCnt.CounterNameTitleIndex =
  758. dwFirstCounter + CERT_CHAIN_REVOKED_CNT;
  759. CertPerfDataDefinition.ChainRevokedCnt.CounterHelpTitleIndex =
  760. dwFirstHelp + CERT_CHAIN_REVOKED_CNT;
  761. CertPerfDataDefinition.ChainRevocationOfflineCnt.CounterNameTitleIndex =
  762. dwFirstCounter + CERT_CHAIN_REVOCATION_OFFLINE_CNT;
  763. CertPerfDataDefinition.ChainRevocationOfflineCnt.CounterHelpTitleIndex =
  764. dwFirstHelp + CERT_CHAIN_REVOCATION_OFFLINE_CNT;
  765. CertPerfDataDefinition.ChainNoRevocationCheckCnt.CounterNameTitleIndex =
  766. dwFirstCounter + CERT_CHAIN_NO_REVOCATION_CHECK_CNT;
  767. CertPerfDataDefinition.ChainNoRevocationCheckCnt.CounterHelpTitleIndex =
  768. dwFirstHelp + CERT_CHAIN_NO_REVOCATION_CHECK_CNT;
  769. CertPerfDataDefinition.ChainVerifyCertSignatureCnt.CounterNameTitleIndex =
  770. dwFirstCounter + CERT_CHAIN_VERIFY_CERT_SIGNATURE_CNT;
  771. CertPerfDataDefinition.ChainVerifyCertSignatureCnt.CounterHelpTitleIndex =
  772. dwFirstHelp + CERT_CHAIN_VERIFY_CERT_SIGNATURE_CNT;
  773. CertPerfDataDefinition.ChainCompareIssuerPublicKeyCnt.CounterNameTitleIndex =
  774. dwFirstCounter + CERT_CHAIN_COMPARE_ISSUER_PUBLIC_KEY_CNT;
  775. CertPerfDataDefinition.ChainCompareIssuerPublicKeyCnt.CounterHelpTitleIndex =
  776. dwFirstHelp + CERT_CHAIN_COMPARE_ISSUER_PUBLIC_KEY_CNT;
  777. CertPerfDataDefinition.ChainVerifyCtlSignatureCnt.CounterNameTitleIndex =
  778. dwFirstCounter + CERT_CHAIN_VERIFY_CTL_SIGNATURE_CNT;
  779. CertPerfDataDefinition.ChainVerifyCtlSignatureCnt.CounterHelpTitleIndex =
  780. dwFirstHelp + CERT_CHAIN_VERIFY_CTL_SIGNATURE_CNT;
  781. CertPerfDataDefinition.ChainBeenVerifiedCtlSignatureCnt.CounterNameTitleIndex =
  782. dwFirstCounter + CERT_CHAIN_BEEN_VERIFIED_CTL_SIGNATURE_CNT;
  783. CertPerfDataDefinition.ChainBeenVerifiedCtlSignatureCnt.CounterHelpTitleIndex =
  784. dwFirstHelp + CERT_CHAIN_BEEN_VERIFIED_CTL_SIGNATURE_CNT;
  785. CertPerfDataDefinition.ChainUrlIssuerCnt.CounterNameTitleIndex =
  786. dwFirstCounter + CERT_CHAIN_URL_ISSUER_CNT;
  787. CertPerfDataDefinition.ChainUrlIssuerCnt.CounterHelpTitleIndex =
  788. dwFirstHelp + CERT_CHAIN_URL_ISSUER_CNT;
  789. CertPerfDataDefinition.ChainCacheOnlyUrlIssuerCnt.CounterNameTitleIndex =
  790. dwFirstCounter + CERT_CHAIN_CACHE_ONLY_URL_ISSUER_CNT;
  791. CertPerfDataDefinition.ChainCacheOnlyUrlIssuerCnt.CounterHelpTitleIndex =
  792. dwFirstHelp + CERT_CHAIN_CACHE_ONLY_URL_ISSUER_CNT;
  793. CertPerfDataDefinition.ChainRequestedEngineResyncCnt.CounterNameTitleIndex =
  794. dwFirstCounter + CERT_CHAIN_REQUESTED_ENGINE_RESYNC_CNT;
  795. CertPerfDataDefinition.ChainRequestedEngineResyncCnt.CounterHelpTitleIndex =
  796. dwFirstHelp + CERT_CHAIN_REQUESTED_ENGINE_RESYNC_CNT;
  797. CertPerfDataDefinition.ChangeNotifyCnt.CounterNameTitleIndex =
  798. dwFirstCounter + CERT_CHANGE_NOTIFY_CNT;
  799. CertPerfDataDefinition.ChangeNotifyCnt.CounterHelpTitleIndex =
  800. dwFirstHelp + CERT_CHANGE_NOTIFY_CNT;
  801. CertPerfDataDefinition.ChangeNotifyLmGpCnt.CounterNameTitleIndex =
  802. dwFirstCounter + CERT_CHANGE_NOTIFY_LM_GP_CNT;
  803. CertPerfDataDefinition.ChangeNotifyLmGpCnt.CounterHelpTitleIndex =
  804. dwFirstHelp + CERT_CHANGE_NOTIFY_LM_GP_CNT;
  805. CertPerfDataDefinition.ChangeNotifyCuGpCnt.CounterNameTitleIndex =
  806. dwFirstCounter + CERT_CHANGE_NOTIFY_CU_GP_CNT;
  807. CertPerfDataDefinition.ChangeNotifyCuGpCnt.CounterHelpTitleIndex =
  808. dwFirstHelp + CERT_CHANGE_NOTIFY_CU_GP_CNT;
  809. CertPerfDataDefinition.ChangeNotifyCuMyCnt.CounterNameTitleIndex =
  810. dwFirstCounter + CERT_CHANGE_NOTIFY_CU_MY_CNT;
  811. CertPerfDataDefinition.ChangeNotifyCuMyCnt.CounterHelpTitleIndex =
  812. dwFirstHelp + CERT_CHANGE_NOTIFY_CU_MY_CNT;
  813. CertPerfDataDefinition.ChangeNotifyRegCnt.CounterNameTitleIndex =
  814. dwFirstCounter + CERT_CHANGE_NOTIFY_REG_CNT;
  815. CertPerfDataDefinition.ChangeNotifyRegCnt.CounterHelpTitleIndex =
  816. dwFirstHelp + CERT_CHANGE_NOTIFY_REG_CNT;
  817. CertPerfDataDefinition.StoreCurrentCnt.CounterNameTitleIndex =
  818. dwFirstCounter + CERT_STORE_CURRENT_CNT;
  819. CertPerfDataDefinition.StoreCurrentCnt.CounterHelpTitleIndex =
  820. dwFirstHelp + CERT_STORE_CURRENT_CNT;
  821. CertPerfDataDefinition.StoreTotalCnt.CounterNameTitleIndex =
  822. dwFirstCounter + CERT_STORE_TOTAL_CNT;
  823. CertPerfDataDefinition.StoreTotalCnt.CounterHelpTitleIndex =
  824. dwFirstHelp + CERT_STORE_TOTAL_CNT;
  825. CertPerfDataDefinition.StoreRegCurrentCnt.CounterNameTitleIndex =
  826. dwFirstCounter + CERT_STORE_REG_CURRENT_CNT;
  827. CertPerfDataDefinition.StoreRegCurrentCnt.CounterHelpTitleIndex =
  828. dwFirstHelp + CERT_STORE_REG_CURRENT_CNT;
  829. CertPerfDataDefinition.StoreRegTotalCnt.CounterNameTitleIndex =
  830. dwFirstCounter + CERT_STORE_REG_TOTAL_CNT;
  831. CertPerfDataDefinition.StoreRegTotalCnt.CounterHelpTitleIndex =
  832. dwFirstHelp + CERT_STORE_REG_TOTAL_CNT;
  833. CertPerfDataDefinition.RegElementReadCnt.CounterNameTitleIndex =
  834. dwFirstCounter + CERT_REG_ELEMENT_READ_CNT;
  835. CertPerfDataDefinition.RegElementReadCnt.CounterHelpTitleIndex =
  836. dwFirstHelp + CERT_REG_ELEMENT_READ_CNT;
  837. CertPerfDataDefinition.RegElementWriteCnt.CounterNameTitleIndex =
  838. dwFirstCounter + CERT_REG_ELEMENT_WRITE_CNT;
  839. CertPerfDataDefinition.RegElementWriteCnt.CounterHelpTitleIndex =
  840. dwFirstHelp + CERT_REG_ELEMENT_WRITE_CNT;
  841. CertPerfDataDefinition.RegElementDeleteCnt.CounterNameTitleIndex =
  842. dwFirstCounter + CERT_REG_ELEMENT_DELETE_CNT;
  843. CertPerfDataDefinition.RegElementDeleteCnt.CounterHelpTitleIndex =
  844. dwFirstHelp + CERT_REG_ELEMENT_DELETE_CNT;
  845. CertPerfDataDefinition.CertElementCurrentCnt.CounterNameTitleIndex =
  846. dwFirstCounter + CERT_CERT_ELEMENT_CURRENT_CNT;
  847. CertPerfDataDefinition.CertElementCurrentCnt.CounterHelpTitleIndex =
  848. dwFirstHelp + CERT_CERT_ELEMENT_CURRENT_CNT;
  849. CertPerfDataDefinition.CertElementTotalCnt.CounterNameTitleIndex =
  850. dwFirstCounter + CERT_CERT_ELEMENT_TOTAL_CNT;
  851. CertPerfDataDefinition.CertElementTotalCnt.CounterHelpTitleIndex =
  852. dwFirstHelp + CERT_CERT_ELEMENT_TOTAL_CNT;
  853. CertPerfDataDefinition.CrlElementCurrentCnt.CounterNameTitleIndex =
  854. dwFirstCounter + CERT_CRL_ELEMENT_CURRENT_CNT;
  855. CertPerfDataDefinition.CrlElementCurrentCnt.CounterHelpTitleIndex =
  856. dwFirstHelp + CERT_CRL_ELEMENT_CURRENT_CNT;
  857. CertPerfDataDefinition.CrlElementTotalCnt.CounterNameTitleIndex =
  858. dwFirstCounter + CERT_CRL_ELEMENT_TOTAL_CNT;
  859. CertPerfDataDefinition.CrlElementTotalCnt.CounterHelpTitleIndex =
  860. dwFirstHelp + CERT_CRL_ELEMENT_TOTAL_CNT;
  861. CertPerfDataDefinition.CtlElementCurrentCnt.CounterNameTitleIndex =
  862. dwFirstCounter + CERT_CTL_ELEMENT_CURRENT_CNT;
  863. CertPerfDataDefinition.CtlElementCurrentCnt.CounterHelpTitleIndex =
  864. dwFirstHelp + CERT_CTL_ELEMENT_CURRENT_CNT;
  865. CertPerfDataDefinition.CtlElementTotalCnt.CounterNameTitleIndex =
  866. dwFirstCounter + CERT_CTL_ELEMENT_TOTAL_CNT;
  867. CertPerfDataDefinition.CtlElementTotalCnt.CounterHelpTitleIndex =
  868. dwFirstHelp + CERT_CTL_ELEMENT_TOTAL_CNT;
  869. //--### Add New Counters ###--
  870. fResult = TRUE;
  871. CommonReturn:
  872. if (hKey)
  873. RegCloseKey(hKey);
  874. return fResult;
  875. ErrorReturn:
  876. fResult = FALSE;
  877. goto CommonReturn;
  878. }
  879. STATIC
  880. void
  881. I_CertPerfGetProcessName(
  882. OUT WCHAR wcszProcessName[CERT_PERF_MAX_PROCESS_NAME_LEN]
  883. )
  884. {
  885. WCHAR wszModule[MAX_PATH + 1];
  886. LPWSTR pwsz;
  887. LPWSTR pwszSlash;
  888. LPWSTR pwszPeriod;
  889. WCHAR wc;
  890. DWORD cchProcessName;
  891. wszModule[MAX_PATH] = L'\0';
  892. if (0 == GetModuleFileNameW(NULL, wszModule, MAX_PATH))
  893. goto GetModuleFileNameError;
  894. // Go from beginning to end and find last backslash and
  895. // last period in name
  896. pwszPeriod = NULL;
  897. pwszSlash = NULL;
  898. for (pwsz = wszModule; L'\0' != (wc = *pwsz); pwsz++) {
  899. if (L'\\' == wc)
  900. pwszSlash = pwsz;
  901. else if (L'.' == wc)
  902. pwszPeriod = pwsz;
  903. }
  904. // If present, the process name is between the last \ and the last period.
  905. // Otherwise, between beginning and/or end of entire module name
  906. if (pwszSlash)
  907. pwszSlash++;
  908. else
  909. pwszSlash = wszModule;
  910. if (NULL == pwszPeriod)
  911. pwszPeriod = pwsz;
  912. if (pwszSlash >= pwszPeriod)
  913. goto InvalidModuleName;
  914. cchProcessName = (DWORD) (pwszPeriod - pwszSlash);
  915. if (cchProcessName > (CERT_PERF_MAX_PROCESS_NAME_LEN - 1))
  916. cchProcessName = CERT_PERF_MAX_PROCESS_NAME_LEN - 1;
  917. memcpy(wcszProcessName, pwszSlash, cchProcessName * sizeof(WCHAR));
  918. wcszProcessName[cchProcessName] = L'\0';
  919. CommonReturn:
  920. return;
  921. ErrorReturn:
  922. wcscpy(wcszProcessName, L"???");
  923. goto CommonReturn;
  924. TRACE_ERROR(GetModuleFileNameError)
  925. TRACE_ERROR(InvalidModuleName)
  926. }
  927. // The returnd ACL must be freed via PkiFree()
  928. STATIC
  929. PACL
  930. CreateEveryoneAcl(
  931. IN DWORD dwAccessMask
  932. )
  933. {
  934. DWORD dwLastErr = 0;
  935. PACL pEveryoneAcl = NULL;
  936. PSID psidEveryone = NULL;
  937. DWORD dwAclSize;
  938. SID_IDENTIFIER_AUTHORITY siaWorldSidAuthority =
  939. SECURITY_WORLD_SID_AUTHORITY;
  940. if (!AllocateAndInitializeSid(
  941. &siaWorldSidAuthority,
  942. 1,
  943. SECURITY_WORLD_RID,
  944. 0, 0, 0, 0, 0, 0, 0,
  945. &psidEveryone
  946. ))
  947. goto AllocateAndInitializeSidError;
  948. //
  949. // compute size of ACL
  950. //
  951. dwAclSize =
  952. sizeof(ACL) +
  953. ( sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) ) +
  954. GetLengthSid(psidEveryone);
  955. //
  956. // allocate storage for Acl
  957. //
  958. if (NULL == (pEveryoneAcl = (PACL) PkiNonzeroAlloc(dwAclSize)))
  959. goto OutOfMemory;
  960. if (!InitializeAcl(pEveryoneAcl, dwAclSize, ACL_REVISION))
  961. goto InitializeAclError;
  962. if (!AddAccessAllowedAce(
  963. pEveryoneAcl,
  964. ACL_REVISION,
  965. dwAccessMask,
  966. psidEveryone
  967. ))
  968. goto AddAceError;
  969. CommonReturn:
  970. if (psidEveryone)
  971. FreeSid(psidEveryone);
  972. if (dwLastErr)
  973. SetLastError(dwLastErr);
  974. return pEveryoneAcl;
  975. ErrorReturn:
  976. dwLastErr = GetLastError();
  977. if (pEveryoneAcl) {
  978. PkiFree(pEveryoneAcl);
  979. pEveryoneAcl = NULL;
  980. }
  981. goto CommonReturn;
  982. TRACE_ERROR(AllocateAndInitializeSidError)
  983. TRACE_ERROR(OutOfMemory)
  984. TRACE_ERROR(InitializeAclError)
  985. TRACE_ERROR(AddAceError)
  986. }
  987. STATIC
  988. BOOL
  989. InitializeSecurityDescriptorAndAttributes(
  990. IN PACL pAcl,
  991. OUT SECURITY_DESCRIPTOR *psd,
  992. OUT SECURITY_ATTRIBUTES *psa
  993. )
  994. {
  995. BOOL fResult;
  996. if (!InitializeSecurityDescriptor(psd, SECURITY_DESCRIPTOR_REVISION))
  997. goto InitializeSecurityDescriptorError;
  998. if (!SetSecurityDescriptorDacl(psd, TRUE, pAcl, FALSE))
  999. goto SetSecurityDescriptorDaclError;
  1000. psa->nLength = sizeof(SECURITY_ATTRIBUTES);
  1001. psa->lpSecurityDescriptor = psd;
  1002. psa->bInheritHandle = FALSE;
  1003. fResult = TRUE;
  1004. CommonReturn:
  1005. return fResult;
  1006. ErrorReturn:
  1007. fResult = FALSE;
  1008. goto CommonReturn;
  1009. TRACE_ERROR(InitializeSecurityDescriptorError)
  1010. TRACE_ERROR(SetSecurityDescriptorDaclError)
  1011. }
  1012. STATIC
  1013. HANDLE
  1014. CreateMutexWithSynchronizeAccess(
  1015. IN LPWSTR pwszMutexName
  1016. )
  1017. {
  1018. HANDLE hMutex = NULL;
  1019. PACL pEveryoneAcl = NULL;
  1020. SECURITY_DESCRIPTOR sd;
  1021. SECURITY_ATTRIBUTES sa;
  1022. DWORD i;
  1023. if (NULL == (pEveryoneAcl = CreateEveryoneAcl(SYNCHRONIZE)))
  1024. goto CreateEveryoneAclError;
  1025. if (!InitializeSecurityDescriptorAndAttributes(pEveryoneAcl, &sd, &sa))
  1026. goto InitializeSecurityDescriptorAndAttributesError;
  1027. // Retry a couple of times. There is a small window between the
  1028. // CreateMutex and OpenMutex where the mutex is deleted.
  1029. for (i = 0; i < 5; i++) {
  1030. hMutex = CreateMutexU(
  1031. &sa,
  1032. FALSE, // fInitialOwner
  1033. pwszMutexName
  1034. );
  1035. if (NULL != hMutex)
  1036. goto CommonReturn;
  1037. hMutex = OpenMutexU(
  1038. SYNCHRONIZE,
  1039. FALSE, // bInheritHandle
  1040. pwszMutexName
  1041. );
  1042. if (NULL != hMutex) {
  1043. SetLastError(ERROR_ALREADY_EXISTS);
  1044. goto CommonReturn;
  1045. }
  1046. if (ERROR_FILE_NOT_FOUND != GetLastError())
  1047. break;
  1048. }
  1049. assert(NULL == hMutex);
  1050. goto OpenMutexError;
  1051. CommonReturn:
  1052. if (pEveryoneAcl)
  1053. PkiFree(pEveryoneAcl);
  1054. return hMutex;
  1055. ErrorReturn:
  1056. assert(NULL == hMutex);
  1057. goto CommonReturn;
  1058. TRACE_ERROR(CreateEveryoneAclError)
  1059. TRACE_ERROR(InitializeSecurityDescriptorAndAttributesError)
  1060. TRACE_ERROR(OpenMutexError)
  1061. }
  1062. STATIC
  1063. HANDLE
  1064. CreateFileMappingWithWriteAccess(
  1065. IN DWORD dwMaximumSizeLow,
  1066. IN LPWSTR pwszFileName
  1067. )
  1068. {
  1069. HANDLE hFile = NULL;
  1070. PACL pEveryoneAcl = NULL;
  1071. SECURITY_DESCRIPTOR sd;
  1072. SECURITY_ATTRIBUTES sa;
  1073. DWORD i;
  1074. if (NULL == (pEveryoneAcl = CreateEveryoneAcl(FILE_MAP_WRITE)))
  1075. goto CreateEveryoneAclError;
  1076. if (!InitializeSecurityDescriptorAndAttributes(pEveryoneAcl, &sd, &sa))
  1077. goto InitializeSecurityDescriptorAndAttributesError;
  1078. // Retry a couple of times. There is a small window between the
  1079. // CreateFileMapping and OpenFileMapping where the file is closed.
  1080. for (i = 0; i < 5; i++) {
  1081. hFile = CreateFileMappingW(
  1082. INVALID_HANDLE_VALUE,
  1083. &sa,
  1084. PAGE_READWRITE,
  1085. 0, // dwMaximumSizeHigh
  1086. dwMaximumSizeLow,
  1087. pwszFileName
  1088. );
  1089. if (NULL != hFile)
  1090. goto CommonReturn;
  1091. hFile = OpenFileMappingW(
  1092. FILE_MAP_WRITE,
  1093. FALSE, // bInheritHandle
  1094. pwszFileName
  1095. );
  1096. if (NULL != hFile) {
  1097. SetLastError(ERROR_ALREADY_EXISTS);
  1098. goto CommonReturn;
  1099. }
  1100. if (ERROR_FILE_NOT_FOUND != GetLastError())
  1101. break;
  1102. }
  1103. assert(NULL == hFile);
  1104. goto OpenFileError;
  1105. CommonReturn:
  1106. if (pEveryoneAcl)
  1107. PkiFree(pEveryoneAcl);
  1108. return hFile;
  1109. ErrorReturn:
  1110. assert(NULL == hFile);
  1111. goto CommonReturn;
  1112. TRACE_ERROR(CreateEveryoneAclError)
  1113. TRACE_ERROR(InitializeSecurityDescriptorAndAttributesError)
  1114. TRACE_ERROR(OpenFileError)
  1115. }
  1116. STATIC
  1117. void
  1118. I_CertPerfGetSharedMemory()
  1119. {
  1120. DWORD dwFileMappingStatus;
  1121. BOOL fReleaseMutex = FALSE;
  1122. DWORD dwIndex;
  1123. DWORD dwNextIndex;
  1124. BOOL fTerminalServerGlobalName;
  1125. if (!I_CertPerfSetNameAndHelpIndices())
  1126. return;
  1127. // First try with W2K Terminal Server "Global\" prefix
  1128. if (NULL == (hCertPerfSharedMemoryMutex = CreateMutexWithSynchronizeAccess(
  1129. CERT_PERF_TS_SHARED_MEMORY_MUTEX_NAME
  1130. ))) {
  1131. if (NULL == (hCertPerfSharedMemoryMutex =
  1132. CreateMutexWithSynchronizeAccess(
  1133. CERT_PERF_SHARED_MEMORY_MUTEX_NAME
  1134. )))
  1135. goto CreateMutexError;
  1136. else
  1137. fTerminalServerGlobalName = FALSE;
  1138. } else
  1139. fTerminalServerGlobalName = TRUE;
  1140. if (WAIT_OBJECT_0 != WaitForSingleObject(
  1141. hCertPerfSharedMemoryMutex,
  1142. CERT_PERF_SHARED_MEMORY_MUTEX_TIMEOUT
  1143. ))
  1144. goto WaitForMutexError;
  1145. else
  1146. fReleaseMutex = TRUE;
  1147. if (NULL == (hCertPerfSharedMemoryFile = CreateFileMappingWithWriteAccess(
  1148. sizeof(CERT_PERF_SHARED_MEMORY),
  1149. fTerminalServerGlobalName ?
  1150. CERT_PERF_TS_SHARED_MEMORY_FILE_NAME :
  1151. CERT_PERF_SHARED_MEMORY_FILE_NAME
  1152. )))
  1153. goto CreateFileMappingError;
  1154. dwFileMappingStatus = GetLastError();
  1155. if (NULL == (pCertPerfSharedMemory =
  1156. (PCERT_PERF_SHARED_MEMORY) MapViewOfFile(
  1157. hCertPerfSharedMemoryFile,
  1158. FILE_MAP_WRITE,
  1159. 0, // dwOffsetHigh
  1160. 0, // dwOffsetLow
  1161. sizeof(CERT_PERF_SHARED_MEMORY)
  1162. )))
  1163. goto MapViewOfFileError;
  1164. if (ERROR_ALREADY_EXISTS != dwFileMappingStatus) {
  1165. DWORD i;
  1166. assert(ERROR_SUCCESS == dwFileMappingStatus);
  1167. // Need to initialize the shared memory
  1168. memset(pCertPerfSharedMemory, 0, sizeof(CERT_PERF_SHARED_MEMORY));
  1169. // Create linked list of process free elements.
  1170. //
  1171. // Only need forward indices for the free list
  1172. for (i = 0; i < CERT_PERF_MAX_PROCESS_CNT; i++) {
  1173. // An index >= CERT_PERF_MAX_PROCESS_CNT indicates end of list
  1174. pCertPerfSharedMemory->rgProcessData[i].dwNextIndex = i + 1;
  1175. }
  1176. pCertPerfSharedMemory->dwFirstFreeIndex = 0;
  1177. // An index >= CERT_PERF_MAX_PROCESS_CNT indicates an empty list
  1178. pCertPerfSharedMemory->dwFirstInUseIndex = CERT_PERF_MAX_PROCESS_CNT;
  1179. }
  1180. if (CERT_PERF_MAX_PROCESS_CNT <=
  1181. (dwIndex = pCertPerfSharedMemory->dwFirstFreeIndex))
  1182. goto OutOfSharedMemoryProcessData;
  1183. pCertPerfProcessData = &pCertPerfSharedMemory->rgProcessData[dwIndex];
  1184. // Remove process data element from the free list
  1185. pCertPerfSharedMemory->dwFirstFreeIndex =
  1186. pCertPerfProcessData->dwNextIndex;
  1187. // Add process data element to the in use list
  1188. dwNextIndex = pCertPerfSharedMemory->dwFirstInUseIndex;
  1189. if (CERT_PERF_MAX_PROCESS_CNT > dwNextIndex)
  1190. pCertPerfSharedMemory->rgProcessData[dwNextIndex].dwPrevIndex =
  1191. dwIndex;
  1192. pCertPerfProcessData->dwNextIndex = dwNextIndex;
  1193. pCertPerfProcessData->dwPrevIndex = CERT_PERF_MAX_PROCESS_CNT;
  1194. pCertPerfSharedMemory->dwFirstInUseIndex = dwIndex;
  1195. pCertPerfSharedMemory->dwProcessCnt++;
  1196. pCertPerfProcessData->dwProcessId = GetCurrentProcessId();
  1197. I_CertPerfGetProcessName(pCertPerfProcessData->wcszProcessName);
  1198. memset(&pCertPerfProcessData->Counters, 0,
  1199. sizeof(pCertPerfProcessData->Counters));
  1200. ReleaseMutex(hCertPerfSharedMemoryMutex);
  1201. pCertPerfProcessCounters = &pCertPerfProcessData->Counters;
  1202. CommonReturn:
  1203. return;
  1204. ErrorReturn:
  1205. assert(NULL == pCertPerfProcessData);
  1206. if (pCertPerfSharedMemory) {
  1207. UnmapViewOfFile(pCertPerfSharedMemory);
  1208. pCertPerfSharedMemory = NULL;
  1209. }
  1210. if (hCertPerfSharedMemoryFile) {
  1211. CloseHandle(hCertPerfSharedMemoryFile);
  1212. hCertPerfSharedMemoryFile = NULL;
  1213. }
  1214. if (hCertPerfSharedMemoryMutex) {
  1215. if (fReleaseMutex)
  1216. ReleaseMutex(hCertPerfSharedMemoryMutex);
  1217. CloseHandle(hCertPerfSharedMemoryMutex);
  1218. hCertPerfSharedMemoryMutex = NULL;
  1219. }
  1220. goto CommonReturn;
  1221. TRACE_ERROR(CreateMutexError)
  1222. TRACE_ERROR(WaitForMutexError)
  1223. TRACE_ERROR(CreateFileMappingError)
  1224. TRACE_ERROR(MapViewOfFileError)
  1225. TRACE_ERROR(OutOfSharedMemoryProcessData)
  1226. }
  1227. STATIC
  1228. void
  1229. I_CertPerfFreeSharedMemory()
  1230. {
  1231. if (NULL == pCertPerfProcessData)
  1232. return;
  1233. pCertPerfProcessData->dwProcessId = 0;
  1234. if (WAIT_OBJECT_0 == WaitForSingleObject(
  1235. hCertPerfSharedMemoryMutex,
  1236. CERT_PERF_SHARED_MEMORY_MUTEX_TIMEOUT
  1237. )) {
  1238. DWORD dwIndex;
  1239. DWORD dwPrevIndex;
  1240. DWORD dwNextIndex;
  1241. // Remove process data element from the in use list
  1242. dwIndex = (DWORD)(pCertPerfProcessData -
  1243. pCertPerfSharedMemory->rgProcessData);
  1244. assert(CERT_PERF_MAX_PROCESS_CNT > dwIndex);
  1245. dwPrevIndex = pCertPerfProcessData->dwPrevIndex;
  1246. dwNextIndex = pCertPerfProcessData->dwNextIndex;
  1247. if (CERT_PERF_MAX_PROCESS_CNT > dwNextIndex)
  1248. pCertPerfSharedMemory->rgProcessData[dwNextIndex].dwPrevIndex =
  1249. dwPrevIndex;
  1250. if (CERT_PERF_MAX_PROCESS_CNT > dwPrevIndex)
  1251. pCertPerfSharedMemory->rgProcessData[dwPrevIndex].dwNextIndex =
  1252. dwNextIndex;
  1253. else
  1254. pCertPerfSharedMemory->dwFirstInUseIndex = dwNextIndex;
  1255. if (pCertPerfSharedMemory->dwProcessCnt)
  1256. pCertPerfSharedMemory->dwProcessCnt--;
  1257. // Add to the free list
  1258. pCertPerfProcessData->dwNextIndex =
  1259. pCertPerfSharedMemory->dwFirstFreeIndex;
  1260. pCertPerfSharedMemory->dwFirstFreeIndex = dwIndex;
  1261. ReleaseMutex(hCertPerfSharedMemoryMutex);
  1262. }
  1263. assert(pCertPerfSharedMemory);
  1264. UnmapViewOfFile(pCertPerfSharedMemory);
  1265. pCertPerfSharedMemory = NULL;
  1266. assert(hCertPerfSharedMemoryFile);
  1267. CloseHandle(hCertPerfSharedMemoryFile);
  1268. hCertPerfSharedMemoryFile = NULL;
  1269. assert(hCertPerfSharedMemoryMutex);
  1270. CloseHandle(hCertPerfSharedMemoryMutex);
  1271. hCertPerfSharedMemoryMutex = NULL;
  1272. pCertPerfProcessCounters = NULL;
  1273. pCertPerfProcessData = NULL;
  1274. }
  1275. BOOL
  1276. WINAPI
  1277. CertPerfDllMain(
  1278. HMODULE hInst,
  1279. ULONG ulReason,
  1280. LPVOID lpReserved
  1281. )
  1282. {
  1283. BOOL fRet = TRUE;
  1284. switch (ulReason) {
  1285. case DLL_PROCESS_ATTACH:
  1286. fRet = Pki_InitializeCriticalSection(&CertPerfProcessCriticalSection);
  1287. if (fRet)
  1288. I_CertPerfGetSharedMemory();
  1289. break;
  1290. case DLL_PROCESS_DETACH:
  1291. I_CertPerfFreeSharedMemory();
  1292. DeleteCriticalSection(&CertPerfProcessCriticalSection);
  1293. break;
  1294. case DLL_THREAD_DETACH:
  1295. default:
  1296. break;
  1297. }
  1298. return fRet;
  1299. }
  1300. //
  1301. // Function Prototypes
  1302. //
  1303. // these are used to insure that the data collection functions
  1304. // accessed by Perflib will have the correct calling format.
  1305. //
  1306. PM_OPEN_PROC OpenCertPerformanceData;
  1307. PM_COLLECT_PROC CollectCertPerformanceData;
  1308. PM_CLOSE_PROC CloseCertPerformanceData;
  1309. DWORD
  1310. APIENTRY
  1311. OpenCertPerformanceData(
  1312. IN LPWSTR lpDeviceNames
  1313. )
  1314. {
  1315. if (NULL == pCertPerfProcessData)
  1316. return ERROR_FILE_NOT_FOUND;
  1317. return ERROR_SUCCESS;
  1318. }
  1319. #define QUERY_GLOBAL 1
  1320. #define QUERY_ITEMS 2
  1321. #define QUERY_FOREIGN 3
  1322. #define QUERY_COSTLY 4
  1323. #define GLOBAL_STRING L"Global"
  1324. #define FOREIGN_STRING L"Foreign"
  1325. #define COSTLY_STRING L"Costly"
  1326. // test for delimiter, end of line and non-digit characters
  1327. // used by I_CertPerfIsNumberInUnicodeList routine
  1328. //
  1329. #define DIGIT 1
  1330. #define DELIMITER 2
  1331. #define INVALID 3
  1332. #define EvalThisChar(c,d) ( \
  1333. (c == d) ? DELIMITER : \
  1334. (c == 0) ? DELIMITER : \
  1335. (c < (WCHAR)'0') ? INVALID : \
  1336. (c > (WCHAR)'9') ? INVALID : \
  1337. DIGIT)
  1338. DWORD
  1339. I_CertPerfGetQueryType(
  1340. IN LPWSTR pwszValue
  1341. )
  1342. /*++
  1343. returns the type of query described in the lpValue string so that
  1344. the appropriate processing method may be used
  1345. Arguments
  1346. IN pwszValue
  1347. string passed to PerfRegQuery Value for processing
  1348. Return Value
  1349. QUERY_GLOBAL
  1350. if pwszValue == 0 (null pointer)
  1351. pwszValue == pointer to Null string
  1352. pwszValue == pointer to "Global" string
  1353. QUERY_FOREIGN
  1354. if pwszValue == pointer to "Foreign" string
  1355. QUERY_COSTLY
  1356. if pwszValue == pointer to "Costly" string
  1357. otherwise:
  1358. QUERY_ITEMS
  1359. --*/
  1360. {
  1361. DWORD dwQueryType;
  1362. if (NULL == pwszValue || L'\0' == *pwszValue ||
  1363. 0 == _wcsnicmp(pwszValue, GLOBAL_STRING, wcslen(GLOBAL_STRING)))
  1364. dwQueryType = QUERY_GLOBAL;
  1365. else if (0 == _wcsnicmp(pwszValue, COSTLY_STRING, wcslen(COSTLY_STRING)))
  1366. dwQueryType = QUERY_COSTLY;
  1367. else if (0 == _wcsnicmp(pwszValue, FOREIGN_STRING, wcslen(FOREIGN_STRING)))
  1368. dwQueryType = QUERY_FOREIGN;
  1369. else
  1370. dwQueryType = QUERY_ITEMS;
  1371. return dwQueryType;
  1372. }
  1373. BOOL
  1374. I_CertPerfIsNumberInUnicodeList (
  1375. IN DWORD dwNumber,
  1376. IN LPWSTR lpwszUnicodeList
  1377. )
  1378. /*++
  1379. Arguments:
  1380. IN dwNumber
  1381. DWORD number to find in list
  1382. IN lpwszUnicodeList
  1383. Null terminated, Space delimited list of decimal numbers
  1384. Return Value:
  1385. TRUE:
  1386. dwNumber was found in the list of unicode number strings
  1387. FALSE:
  1388. dwNumber was not found in the list.
  1389. --*/
  1390. {
  1391. DWORD dwThisNumber;
  1392. WCHAR *pwcThisChar;
  1393. BOOL bValidNumber;
  1394. BOOL bNewItem;
  1395. WCHAR wcDelimiter; // could be an argument to be more flexible
  1396. if (lpwszUnicodeList == 0) return FALSE; // null pointer, # not found
  1397. pwcThisChar = lpwszUnicodeList;
  1398. dwThisNumber = 0;
  1399. wcDelimiter = (WCHAR)' ';
  1400. bValidNumber = FALSE;
  1401. bNewItem = TRUE;
  1402. while (TRUE)
  1403. {
  1404. switch (EvalThisChar (*pwcThisChar, wcDelimiter))
  1405. {
  1406. case DIGIT:
  1407. // if this is the first digit after a delimiter, then
  1408. // set flags to start computing the new number
  1409. if (bNewItem)
  1410. {
  1411. bNewItem = FALSE;
  1412. bValidNumber = TRUE;
  1413. }
  1414. if (bValidNumber)
  1415. {
  1416. dwThisNumber *= 10;
  1417. dwThisNumber += (*pwcThisChar - (WCHAR)'0');
  1418. }
  1419. break;
  1420. case DELIMITER:
  1421. // a delimter is either the delimiter character or the
  1422. // end of the string ('\0') if when the delimiter has been
  1423. // reached a valid number was found, then compare it to the
  1424. // number from the argument list. if this is the end of the
  1425. // string and no match was found, then return.
  1426. //
  1427. if (bValidNumber)
  1428. {
  1429. if (dwThisNumber == dwNumber) return TRUE;
  1430. bValidNumber = FALSE;
  1431. }
  1432. if (*pwcThisChar == 0)
  1433. {
  1434. return FALSE;
  1435. }
  1436. else
  1437. {
  1438. bNewItem = TRUE;
  1439. dwThisNumber = 0;
  1440. }
  1441. break;
  1442. case INVALID:
  1443. // if an invalid character was encountered, ignore all
  1444. // characters up to the next delimiter and then start fresh.
  1445. // the invalid number is not compared.
  1446. bValidNumber = FALSE;
  1447. break;
  1448. default:
  1449. break;
  1450. }
  1451. pwcThisChar++;
  1452. }
  1453. return FALSE;
  1454. }
  1455. DWORD
  1456. APIENTRY
  1457. CollectCertPerformanceData(
  1458. IN LPWSTR pwszValueName,
  1459. IN OUT LPVOID *ppvData,
  1460. IN OUT LPDWORD pcbTotalBytes,
  1461. IN OUT LPDWORD pNumObjectTypes
  1462. )
  1463. {
  1464. DWORD dwErr = ERROR_SUCCESS;
  1465. BOOL fReleaseMutex = FALSE;
  1466. PCERT_PERF_DATA_DEFINITION pDataDef;
  1467. PERF_INSTANCE_DEFINITION *pInstanceDef;
  1468. DWORD cbNeededBytes;
  1469. DWORD dwProcessCnt;
  1470. DWORD dwInUseIndex;
  1471. LONG NumInstances;
  1472. DWORD dwQueryType;
  1473. if (NULL == pCertPerfProcessData)
  1474. goto NoProcessDataError;
  1475. dwQueryType = I_CertPerfGetQueryType(pwszValueName);
  1476. if (QUERY_FOREIGN == dwQueryType)
  1477. goto ForeignQueryNotSupported;
  1478. if (QUERY_ITEMS == dwQueryType) {
  1479. if (!(I_CertPerfIsNumberInUnicodeList(
  1480. CertPerfDataDefinition.ObjectType.ObjectNameTitleIndex,
  1481. pwszValueName)))
  1482. goto ObjectTypeQueryNotSupported;
  1483. }
  1484. if (WAIT_OBJECT_0 != WaitForSingleObject(
  1485. hCertPerfSharedMemoryMutex,
  1486. CERT_PERF_SHARED_MEMORY_MUTEX_TIMEOUT
  1487. ))
  1488. goto WaitForMutexError;
  1489. else
  1490. fReleaseMutex = TRUE;
  1491. pDataDef = (PCERT_PERF_DATA_DEFINITION) *ppvData;
  1492. // always return an "instance sized" buffer after the definition blocks
  1493. // to prevent perfmon from reading bogus data. This is strictly a hack
  1494. // to accomodate how PERFMON handles the "0" instance case.
  1495. // By doing this, perfmon won't choke when there are no instances
  1496. // and the counter object & counters will be displayed in the
  1497. // list boxes, even though no instances will be listed.
  1498. dwProcessCnt = pCertPerfSharedMemory->dwProcessCnt;
  1499. if (CERT_PERF_MAX_PROCESS_CNT < dwProcessCnt)
  1500. goto InvalidProcessData;
  1501. cbNeededBytes = sizeof(CERT_PERF_DATA_DEFINITION) +
  1502. (dwProcessCnt > 0 ? dwProcessCnt : 1 ) * (
  1503. sizeof(PERF_INSTANCE_DEFINITION) +
  1504. CERT_PERF_MAX_PROCESS_NAME_LEN +
  1505. sizeof(CERT_PERF_COUNTERS));
  1506. if (*pcbTotalBytes < cbNeededBytes) {
  1507. dwErr = ERROR_MORE_DATA;
  1508. goto MoreDataError;
  1509. }
  1510. // copy the object & counter definition information
  1511. memcpy(pDataDef, &CertPerfDataDefinition,
  1512. sizeof(CERT_PERF_DATA_DEFINITION));
  1513. // Update the instance data for each InUse process.
  1514. pInstanceDef = (PERF_INSTANCE_DEFINITION *) &pDataDef[1];
  1515. dwInUseIndex = pCertPerfSharedMemory->dwFirstInUseIndex;
  1516. NumInstances = 0;
  1517. while (NumInstances < (LONG) dwProcessCnt &&
  1518. CERT_PERF_MAX_PROCESS_CNT > dwInUseIndex) {
  1519. PCERT_PERF_PROCESS_DATA pInUseData;
  1520. PCERT_PERF_COUNTERS pCtr;
  1521. DWORD cchProcessName;
  1522. DWORD NameLength;
  1523. DWORD ByteLength;
  1524. pInUseData = &pCertPerfSharedMemory->rgProcessData[dwInUseIndex];
  1525. dwInUseIndex = pInUseData->dwNextIndex;
  1526. if (0 == pInUseData->dwProcessId)
  1527. continue;
  1528. // The following is updated for each InUse process:
  1529. // - PERF_INSTANCE_DEFINITION
  1530. // - wcszProcessName
  1531. // - optional padding for DWORD alignment
  1532. // - CERT_PERF_COUNTERS
  1533. // Get process name and instance definition byte lengths
  1534. for (cchProcessName = 0;
  1535. cchProcessName < CERT_PERF_MAX_PROCESS_NAME_LEN &&
  1536. L'\0' != pInUseData->wcszProcessName[cchProcessName];
  1537. cchProcessName++)
  1538. ;
  1539. if (CERT_PERF_MAX_PROCESS_NAME_LEN <= cchProcessName)
  1540. goto InvalidProcessData;
  1541. // Include trailing null in name length
  1542. NameLength = cchProcessName * sizeof(WCHAR) + sizeof(WCHAR);
  1543. ByteLength = sizeof(PERF_INSTANCE_DEFINITION) +
  1544. DWORD_MULTIPLE(NameLength);
  1545. // Update the instance definition fields
  1546. pInstanceDef->ByteLength = ByteLength;
  1547. pInstanceDef->ParentObjectTitleIndex = 0; // no parent
  1548. pInstanceDef->ParentObjectInstance = 0; // " "
  1549. pInstanceDef->UniqueID = PERF_NO_UNIQUE_ID;
  1550. pInstanceDef->NameOffset = sizeof(PERF_INSTANCE_DEFINITION);
  1551. pInstanceDef->NameLength = NameLength;
  1552. // Update the process name that immediately follows the
  1553. // instance definition
  1554. memcpy(&pInstanceDef[1], pInUseData->wcszProcessName,
  1555. NameLength);
  1556. // Update the performance counters immediately following the
  1557. // above process name. Note, start of counters is DWORD aligned
  1558. pCtr = (PCERT_PERF_COUNTERS) (((PBYTE) pInstanceDef) + ByteLength);
  1559. pCtr->CounterBlock.ByteLength = sizeof(CERT_PERF_COUNTERS);
  1560. pCtr->dwChainCnt = (DWORD) pInUseData->Counters.lChainCnt;
  1561. pCtr->dwChainElementCnt = (DWORD) pInUseData->Counters.lChainElementCnt;
  1562. pCtr->dwChainEngineCurrentCnt =
  1563. (DWORD) pInUseData->Counters.lChainEngineCurrentCnt;
  1564. pCtr->dwChainEngineTotalCnt =
  1565. (DWORD) pInUseData->Counters.lChainEngineTotalCnt;
  1566. pCtr->dwChainEngineResyncCnt =
  1567. (DWORD) pInUseData->Counters.lChainEngineResyncCnt;
  1568. pCtr->dwChainCertCacheCnt =
  1569. (DWORD) pInUseData->Counters.lChainCertCacheCnt;
  1570. pCtr->dwChainCtlCacheCnt =
  1571. (DWORD) pInUseData->Counters.lChainCtlCacheCnt;
  1572. pCtr->dwChainEndCertInCacheCnt =
  1573. (DWORD) pInUseData->Counters.lChainEndCertInCacheCnt;
  1574. pCtr->dwChainCacheEndCertCnt =
  1575. (DWORD) pInUseData->Counters.lChainCacheEndCertCnt;
  1576. pCtr->dwChainRevocationCnt =
  1577. (DWORD) pInUseData->Counters.lChainRevocationCnt;
  1578. pCtr->dwChainRevokedCnt =
  1579. (DWORD) pInUseData->Counters.lChainRevokedCnt;
  1580. pCtr->dwChainRevocationOfflineCnt =
  1581. (DWORD) pInUseData->Counters.lChainRevocationOfflineCnt;
  1582. pCtr->dwChainNoRevocationCheckCnt =
  1583. (DWORD) pInUseData->Counters.lChainNoRevocationCheckCnt;
  1584. pCtr->dwChainVerifyCertSignatureCnt =
  1585. (DWORD) pInUseData->Counters.lChainVerifyCertSignatureCnt;
  1586. pCtr->dwChainCompareIssuerPublicKeyCnt =
  1587. (DWORD) pInUseData->Counters.lChainCompareIssuerPublicKeyCnt;
  1588. pCtr->dwChainVerifyCtlSignatureCnt =
  1589. (DWORD) pInUseData->Counters.lChainVerifyCtlSignatureCnt;
  1590. pCtr->dwChainBeenVerifiedCtlSignatureCnt =
  1591. (DWORD) pInUseData->Counters.lChainBeenVerifiedCtlSignatureCnt;
  1592. pCtr->dwChainUrlIssuerCnt =
  1593. (DWORD) pInUseData->Counters.lChainUrlIssuerCnt;
  1594. pCtr->dwChainCacheOnlyUrlIssuerCnt =
  1595. (DWORD) pInUseData->Counters.lChainCacheOnlyUrlIssuerCnt;
  1596. pCtr->dwChainRequestedEngineResyncCnt =
  1597. (DWORD) pInUseData->Counters.lChainRequestedEngineResyncCnt;
  1598. pCtr->dwChangeNotifyCnt =
  1599. (DWORD) pInUseData->Counters.lChangeNotifyCnt;
  1600. pCtr->dwChangeNotifyLmGpCnt =
  1601. (DWORD) pInUseData->Counters.lChangeNotifyLmGpCnt;
  1602. pCtr->dwChangeNotifyCuGpCnt =
  1603. (DWORD) pInUseData->Counters.lChangeNotifyCuGpCnt;
  1604. pCtr->dwChangeNotifyCuMyCnt =
  1605. (DWORD) pInUseData->Counters.lChangeNotifyCuMyCnt;
  1606. pCtr->dwChangeNotifyRegCnt =
  1607. (DWORD) pInUseData->Counters.lChangeNotifyRegCnt;
  1608. pCtr->dwStoreCurrentCnt =
  1609. (DWORD) pInUseData->Counters.lStoreCurrentCnt;
  1610. pCtr->dwStoreTotalCnt =
  1611. (DWORD) pInUseData->Counters.lStoreTotalCnt;
  1612. pCtr->dwStoreRegCurrentCnt =
  1613. (DWORD) pInUseData->Counters.lStoreRegCurrentCnt;
  1614. pCtr->dwStoreRegTotalCnt =
  1615. (DWORD) pInUseData->Counters.lStoreRegTotalCnt;
  1616. pCtr->dwRegElementReadCnt =
  1617. (DWORD) pInUseData->Counters.lRegElementReadCnt;
  1618. pCtr->dwRegElementWriteCnt =
  1619. (DWORD) pInUseData->Counters.lRegElementWriteCnt;
  1620. pCtr->dwRegElementDeleteCnt =
  1621. (DWORD) pInUseData->Counters.lRegElementDeleteCnt;
  1622. pCtr->dwCertElementCurrentCnt =
  1623. (DWORD) pInUseData->Counters.lCertElementCurrentCnt;
  1624. pCtr->dwCertElementTotalCnt =
  1625. (DWORD) pInUseData->Counters.lCertElementTotalCnt;
  1626. pCtr->dwCrlElementCurrentCnt =
  1627. (DWORD) pInUseData->Counters.lCrlElementCurrentCnt;
  1628. pCtr->dwCrlElementTotalCnt =
  1629. (DWORD) pInUseData->Counters.lCrlElementTotalCnt;
  1630. pCtr->dwCtlElementCurrentCnt =
  1631. (DWORD) pInUseData->Counters.lCtlElementCurrentCnt;
  1632. pCtr->dwCtlElementTotalCnt =
  1633. (DWORD) pInUseData->Counters.lCtlElementTotalCnt;
  1634. //--### Add New Counters ###--
  1635. NumInstances++;
  1636. // setup for the next instance
  1637. // Next instance starts immediately after the counters
  1638. pInstanceDef = (PERF_INSTANCE_DEFINITION *) &pCtr[1];
  1639. }
  1640. if (0 == NumInstances) {
  1641. // zero fill one instance sized block of data if there are no
  1642. // data instances
  1643. memset(pInstanceDef, 0, sizeof(PERF_INSTANCE_DEFINITION) +
  1644. CERT_PERF_MAX_PROCESS_NAME_LEN +
  1645. sizeof(CERT_PERF_COUNTERS));
  1646. // Advance past the zero'ed instance
  1647. pInstanceDef = (PERF_INSTANCE_DEFINITION *) ((PBYTE) pInstanceDef +
  1648. sizeof(PERF_INSTANCE_DEFINITION) +
  1649. CERT_PERF_MAX_PROCESS_NAME_LEN +
  1650. sizeof(CERT_PERF_COUNTERS));
  1651. }
  1652. // update arguments for return
  1653. *ppvData = (LPVOID) pInstanceDef;
  1654. *pNumObjectTypes = 1;
  1655. pDataDef->ObjectType.NumInstances = NumInstances;
  1656. pDataDef->ObjectType.TotalByteLength = *pcbTotalBytes =
  1657. (DWORD)((PBYTE) pInstanceDef - (PBYTE) pDataDef);
  1658. assert(*pcbTotalBytes <= cbNeededBytes);
  1659. CommonReturn:
  1660. if (fReleaseMutex)
  1661. ReleaseMutex(hCertPerfSharedMemoryMutex);
  1662. return dwErr;
  1663. ErrorReturn:
  1664. *pcbTotalBytes = 0;
  1665. *pNumObjectTypes = 0;
  1666. goto CommonReturn;
  1667. TRACE_ERROR(NoProcessDataError)
  1668. TRACE_ERROR(ForeignQueryNotSupported)
  1669. TRACE_ERROR(ObjectTypeQueryNotSupported)
  1670. TRACE_ERROR(WaitForMutexError)
  1671. TRACE_ERROR(InvalidProcessData)
  1672. TRACE_ERROR(MoreDataError)
  1673. }
  1674. DWORD
  1675. APIENTRY
  1676. CloseCertPerformanceData()
  1677. {
  1678. return ERROR_SUCCESS;
  1679. }
  1680. #if 0
  1681. // Example of timing the CertGetCertificateChain API
  1682. typedef struct _CERT_PERF_CHAIN_DATA {
  1683. union {
  1684. SYSTEMTIME stBefore;
  1685. LARGE_INTEGER liBefore;
  1686. };
  1687. } CERT_PERF_CHAIN_DATA, *PCERT_PERF_CHAIN_DATA;
  1688. void
  1689. WINAPI
  1690. CertPerfGetCertificateChainBefore(
  1691. OUT PCERT_PERF_CHAIN_DATA pData
  1692. )
  1693. {
  1694. if (pCertPerfProcessData) {
  1695. if (fCertPerfHighFreq)
  1696. QueryPerformanceCounter(&pData->liBefore);
  1697. else
  1698. GetSystemTime(&pData->stBefore);
  1699. }
  1700. }
  1701. void
  1702. WINAPI
  1703. CertPerfGetCertificateChainAfter(
  1704. IN PCERT_PERF_CHAIN_DATA pData,
  1705. IN PCCERT_CHAIN_CONTEXT pChainContext
  1706. )
  1707. {
  1708. if (pCertPerfProcessData) {
  1709. if (fCertPerfHighFreq) {
  1710. LARGE_INTEGER liAfter;
  1711. _int64 i64DeltaTime;
  1712. QueryPerformanceCounter(&liAfter);
  1713. i64DeltaTime = liAfter.QuadPart - pData->liBefore.QuadPart;
  1714. EnterCriticalSection(&CertPerfProcessCriticalSection);
  1715. pCertPerfProcessData->Counters.dwChainCnt++;
  1716. pCertPerfProcessData->Counters.i64TotalChainTime =
  1717. pCertPerfProcessData->Counters.i64TotalChainTime +
  1718. i64DeltaTime;
  1719. if (0 == pCertPerfProcessData->Counters.i64MinChainTime ||
  1720. i64DeltaTime <
  1721. pCertPerfProcessData->Counters.i64MinChainTime)
  1722. pCertPerfProcessData->Counters.i64MinChainTime =
  1723. i64DeltaTime;
  1724. if (i64DeltaTime > pCertPerfProcessData->Counters.i64MaxChainTime)
  1725. pCertPerfProcessData->Counters.i64MaxChainTime =
  1726. i64DeltaTime;
  1727. LeaveCriticalSection(&CertPerfProcessCriticalSection);
  1728. } else {
  1729. SYSTEMTIME stAfter;
  1730. FILETIME ftBefore;
  1731. FILETIME ftAfter;
  1732. _int64 i64DeltaTime;
  1733. GetSystemTime(&stAfter);
  1734. SystemTimeToFileTime(&pData->stBefore, &ftBefore);
  1735. SystemTimeToFileTime(&stAfter, &ftAfter);
  1736. i64DeltaTime = *((_int64 *) &ftAfter) - *((_int64 *) &ftBefore);
  1737. EnterCriticalSection(&CertPerfProcessCriticalSection);
  1738. pCertPerfProcessData->Counters.dwChainCnt++;
  1739. pCertPerfProcessData->Counters.i64TotalChainTime =
  1740. pCertPerfProcessData->Counters.i64TotalChainTime +
  1741. i64DeltaTime;
  1742. if (0 == pCertPerfProcessData->Counters.i64MinChainTime ||
  1743. i64DeltaTime <
  1744. pCertPerfProcessData->Counters.i64MinChainTime)
  1745. pCertPerfProcessData->Counters.i64MinChainTime =
  1746. i64DeltaTime;
  1747. if (i64DeltaTime > pCertPerfProcessData->Counters.i64MaxChainTime)
  1748. pCertPerfProcessData->Counters.i64MaxChainTime =
  1749. i64DeltaTime;
  1750. LeaveCriticalSection(&CertPerfProcessCriticalSection);
  1751. }
  1752. }
  1753. }
  1754. #endif