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
68 KiB
2053 lines
68 KiB
//+-------------------------------------------------------------------------
|
|
// Microsoft Windows
|
|
//
|
|
// Copyright (C) Microsoft Corporation, 1999 - 1999
|
|
//
|
|
// File: certperf.cpp
|
|
//
|
|
// Contents: Certificate Performance Counter Functions
|
|
//
|
|
// Functions:
|
|
// OpenCertPerformanceData
|
|
// CollectCertPerformanceData
|
|
// CloseCertPerformanceData
|
|
// CertPerfDllMain
|
|
//
|
|
// CertPerfGetCertificateChainBefore
|
|
// CertPerfGetCertificateChainAfter
|
|
//
|
|
// History: 04-May-99 philh created
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
#include "global.hxx"
|
|
#include <dbgdef.h>
|
|
|
|
#ifdef STATIC
|
|
#undef STATIC
|
|
#endif
|
|
#define STATIC
|
|
|
|
#define DWORD_MULTIPLE(x) (((x+sizeof(DWORD)-1)/sizeof(DWORD))*sizeof(DWORD))
|
|
|
|
|
|
#define CERT_PERF_REGPATH \
|
|
L"SYSTEM\\CurrentControlSet\\Services\\crypt32\\Performance"
|
|
|
|
#define CERT_PERF_SHARED_MEMORY_FILE_NAME \
|
|
L"crypt32CertPerfFile"
|
|
#define CERT_PERF_SHARED_MEMORY_MUTEX_NAME \
|
|
L"crypt32CertPerfMutex"
|
|
|
|
#define CERT_PERF_TS_GLOBAL_PREFIX \
|
|
L"Global\\"
|
|
#define CERT_PERF_TS_SHARED_MEMORY_FILE_NAME \
|
|
CERT_PERF_TS_GLOBAL_PREFIX CERT_PERF_SHARED_MEMORY_FILE_NAME
|
|
#define CERT_PERF_TS_SHARED_MEMORY_MUTEX_NAME \
|
|
CERT_PERF_TS_GLOBAL_PREFIX CERT_PERF_SHARED_MEMORY_MUTEX_NAME
|
|
|
|
|
|
|
|
#define CERT_PERF_SHARED_MEMORY_MUTEX_TIMEOUT ((DWORD) 5000L)
|
|
#define CERT_PERF_MAX_PROCESS_NAME_LEN 32
|
|
#define CERT_PERF_MAX_PROCESS_CNT 50
|
|
|
|
#include <pshpack8.h>
|
|
|
|
|
|
// Note, a dwIndex >= CERT_PERF_MAX_PROCESS_CNT indicates an empty or
|
|
// the end of a list
|
|
typedef struct _CERT_PERF_PROCESS_DATA {
|
|
DWORD dwNextIndex;
|
|
DWORD dwPrevIndex;
|
|
DWORD dwProcessId;
|
|
DWORD dwReserved;
|
|
WCHAR wcszProcessName[CERT_PERF_MAX_PROCESS_NAME_LEN];
|
|
CERT_PERF_PROCESS_COUNTERS Counters;
|
|
} CERT_PERF_PROCESS_DATA, *PCERT_PERF_PROCESS_DATA;
|
|
|
|
typedef struct _CERT_PERF_SHARED_MEMORY {
|
|
DWORD dwProcessCnt;
|
|
DWORD dwFirstInUseIndex;
|
|
DWORD dwFirstFreeIndex;
|
|
DWORD dwReserved;
|
|
CERT_PERF_PROCESS_DATA rgProcessData[CERT_PERF_MAX_PROCESS_CNT];
|
|
} CERT_PERF_SHARED_MEMORY, *PCERT_PERF_SHARED_MEMORY;
|
|
|
|
|
|
// Certificate performance counters
|
|
typedef struct _CERT_PERF_DATA_DEFINITION {
|
|
PERF_OBJECT_TYPE ObjectType;
|
|
PERF_COUNTER_DEFINITION ChainCnt;
|
|
PERF_COUNTER_DEFINITION ChainElementCnt;
|
|
PERF_COUNTER_DEFINITION ChainEngineCurrentCnt;
|
|
PERF_COUNTER_DEFINITION ChainEngineTotalCnt;
|
|
PERF_COUNTER_DEFINITION ChainEngineResyncCnt;
|
|
PERF_COUNTER_DEFINITION ChainCertCacheCnt;
|
|
PERF_COUNTER_DEFINITION ChainCtlCacheCnt;
|
|
PERF_COUNTER_DEFINITION ChainEndCertInCacheCnt;
|
|
PERF_COUNTER_DEFINITION ChainCacheEndCertCnt;
|
|
PERF_COUNTER_DEFINITION ChainRevocationCnt;
|
|
PERF_COUNTER_DEFINITION ChainRevokedCnt;
|
|
PERF_COUNTER_DEFINITION ChainRevocationOfflineCnt;
|
|
PERF_COUNTER_DEFINITION ChainNoRevocationCheckCnt;
|
|
PERF_COUNTER_DEFINITION ChainVerifyCertSignatureCnt;
|
|
PERF_COUNTER_DEFINITION ChainCompareIssuerPublicKeyCnt;
|
|
PERF_COUNTER_DEFINITION ChainVerifyCtlSignatureCnt;
|
|
PERF_COUNTER_DEFINITION ChainBeenVerifiedCtlSignatureCnt;
|
|
PERF_COUNTER_DEFINITION ChainUrlIssuerCnt;
|
|
PERF_COUNTER_DEFINITION ChainCacheOnlyUrlIssuerCnt;
|
|
PERF_COUNTER_DEFINITION ChainRequestedEngineResyncCnt;
|
|
PERF_COUNTER_DEFINITION ChangeNotifyCnt;
|
|
PERF_COUNTER_DEFINITION ChangeNotifyLmGpCnt;
|
|
PERF_COUNTER_DEFINITION ChangeNotifyCuGpCnt;
|
|
PERF_COUNTER_DEFINITION ChangeNotifyCuMyCnt;
|
|
PERF_COUNTER_DEFINITION ChangeNotifyRegCnt;
|
|
PERF_COUNTER_DEFINITION StoreCurrentCnt;
|
|
PERF_COUNTER_DEFINITION StoreTotalCnt;
|
|
PERF_COUNTER_DEFINITION StoreRegCurrentCnt;
|
|
PERF_COUNTER_DEFINITION StoreRegTotalCnt;
|
|
PERF_COUNTER_DEFINITION RegElementReadCnt;
|
|
PERF_COUNTER_DEFINITION RegElementWriteCnt;
|
|
PERF_COUNTER_DEFINITION RegElementDeleteCnt;
|
|
PERF_COUNTER_DEFINITION CertElementCurrentCnt;
|
|
PERF_COUNTER_DEFINITION CertElementTotalCnt;
|
|
PERF_COUNTER_DEFINITION CrlElementCurrentCnt;
|
|
PERF_COUNTER_DEFINITION CrlElementTotalCnt;
|
|
PERF_COUNTER_DEFINITION CtlElementCurrentCnt;
|
|
PERF_COUNTER_DEFINITION CtlElementTotalCnt;
|
|
|
|
|
|
//--### Add New Counters ###--
|
|
} CERT_PERF_DATA_DEFINITION, *PCERT_PERF_DATA_DEFINITION;
|
|
|
|
typedef struct _CERT_PERF_COUNTERS {
|
|
PERF_COUNTER_BLOCK CounterBlock;
|
|
DWORD dwChainCnt;
|
|
DWORD dwChainElementCnt;
|
|
DWORD dwChainEngineCurrentCnt;
|
|
DWORD dwChainEngineTotalCnt;
|
|
DWORD dwChainEngineResyncCnt;
|
|
DWORD dwChainCertCacheCnt;
|
|
DWORD dwChainCtlCacheCnt;
|
|
DWORD dwChainEndCertInCacheCnt;
|
|
DWORD dwChainCacheEndCertCnt;
|
|
DWORD dwChainRevocationCnt;
|
|
DWORD dwChainRevokedCnt;
|
|
DWORD dwChainRevocationOfflineCnt;
|
|
DWORD dwChainNoRevocationCheckCnt;
|
|
DWORD dwChainVerifyCertSignatureCnt;
|
|
DWORD dwChainCompareIssuerPublicKeyCnt;
|
|
DWORD dwChainVerifyCtlSignatureCnt;
|
|
DWORD dwChainBeenVerifiedCtlSignatureCnt;
|
|
DWORD dwChainUrlIssuerCnt;
|
|
DWORD dwChainCacheOnlyUrlIssuerCnt;
|
|
DWORD dwChainRequestedEngineResyncCnt;
|
|
DWORD dwChangeNotifyCnt;
|
|
DWORD dwChangeNotifyLmGpCnt;
|
|
DWORD dwChangeNotifyCuGpCnt;
|
|
DWORD dwChangeNotifyCuMyCnt;
|
|
DWORD dwChangeNotifyRegCnt;
|
|
DWORD dwStoreCurrentCnt;
|
|
DWORD dwStoreTotalCnt;
|
|
DWORD dwStoreRegCurrentCnt;
|
|
DWORD dwStoreRegTotalCnt;
|
|
DWORD dwRegElementReadCnt;
|
|
DWORD dwRegElementWriteCnt;
|
|
DWORD dwRegElementDeleteCnt;
|
|
DWORD dwCertElementCurrentCnt;
|
|
DWORD dwCertElementTotalCnt;
|
|
DWORD dwCrlElementCurrentCnt;
|
|
DWORD dwCrlElementTotalCnt;
|
|
DWORD dwCtlElementCurrentCnt;
|
|
DWORD dwCtlElementTotalCnt;
|
|
|
|
//--### Add New Counters ###--
|
|
} CERT_PERF_COUNTERS, *PCERT_PERF_COUNTERS;
|
|
|
|
#include <poppack.h>
|
|
|
|
|
|
//+----------------------------------------------------------------------
|
|
// The following are set at DLL_PROCESS_ATTACH if certperf.reg has been
|
|
// regedit'ed and certperf.ini has been lodctr'ed. Otherwise, they remain
|
|
// NULL.
|
|
//-----------------------------------------------------------------------
|
|
HANDLE hCertPerfSharedMemoryMutex;
|
|
HANDLE hCertPerfSharedMemoryFile;
|
|
PCERT_PERF_SHARED_MEMORY pCertPerfSharedMemory;
|
|
PCERT_PERF_PROCESS_DATA pCertPerfProcessData;
|
|
PCERT_PERF_PROCESS_COUNTERS pCertPerfProcessCounters;
|
|
|
|
// Always initialized
|
|
CRITICAL_SECTION CertPerfProcessCriticalSection;
|
|
|
|
#define IMPURE 0
|
|
|
|
CERT_PERF_DATA_DEFINITION CertPerfDataDefinition = {
|
|
// PERF_OBJECT_TYPE ObjectType
|
|
{
|
|
IMPURE, // TotalByteLength
|
|
sizeof(CERT_PERF_DATA_DEFINITION),
|
|
sizeof(PERF_OBJECT_TYPE),
|
|
IMPURE, // ObjectNameTitleIndex: dwFirstCounter + CERT_OBJ
|
|
0,
|
|
IMPURE, // ObjectHelpTitleIndex: dwFirstHelp + CERT_OBJ
|
|
0,
|
|
PERF_DETAIL_NOVICE,
|
|
(sizeof(CERT_PERF_DATA_DEFINITION) - sizeof(PERF_OBJECT_TYPE))/
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
0, // ChainCnt is the default counter
|
|
IMPURE, // NumInstances
|
|
0, // unicode instance names
|
|
{0,0},
|
|
{0,0}
|
|
},
|
|
|
|
// 0 - PERF_COUNTER_DEFINITION ChainCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwChainCnt),
|
|
},
|
|
|
|
// 1 - PERF_COUNTER_DEFINITION ChainElementCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainElementCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwChainElementCnt),
|
|
},
|
|
|
|
// 2 - PERF_COUNTER_DEFINITION ChainEngineCurrentCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainEngineCurrentCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwChainEngineCurrentCnt),
|
|
},
|
|
|
|
// 3 - PERF_COUNTER_DEFINITION ChainEngineTotalCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainEngineTotalCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwChainEngineTotalCnt),
|
|
},
|
|
|
|
// 4 - PERF_COUNTER_DEFINITION ChainEngineResyncCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainEngineResyncCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwChainEngineResyncCnt),
|
|
},
|
|
|
|
// 5 - PERF_COUNTER_DEFINITION ChainCertCacheCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainCertCacheCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwChainCertCacheCnt),
|
|
},
|
|
|
|
// 6 - PERF_COUNTER_DEFINITION ChainCtlCacheCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainCtlCacheCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwChainCtlCacheCnt),
|
|
},
|
|
|
|
// 7 - PERF_COUNTER_DEFINITION ChainEndCertInCacheCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainEndCertInCacheCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwChainEndCertInCacheCnt),
|
|
},
|
|
|
|
// 8 - PERF_COUNTER_DEFINITION ChainCacheEndCertCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainCacheEndCertCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwChainCacheEndCertCnt),
|
|
},
|
|
|
|
// 9 - PERF_COUNTER_DEFINITION ChainRevocationCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainRevocationCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwChainRevocationCnt),
|
|
},
|
|
|
|
// 10 - PERF_COUNTER_DEFINITION ChainRevokedCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainRevokedCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwChainRevokedCnt),
|
|
},
|
|
|
|
// 11 - PERF_COUNTER_DEFINITION ChainRevocationOfflineCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainRevocationOfflineCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwChainRevocationOfflineCnt),
|
|
},
|
|
|
|
// 12 - PERF_COUNTER_DEFINITION ChainNoRevocationCheckCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainNoRevocationCheckCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwChainNoRevocationCheckCnt),
|
|
},
|
|
|
|
// 13 - PERF_COUNTER_DEFINITION ChainVerifyCertSignatureCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainVerifyCertSignatureCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwChainVerifyCertSignatureCnt),
|
|
},
|
|
|
|
// 14 - PERF_COUNTER_DEFINITION ChainCompareIssuerPublicKeyCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainCompareIssuerPublicKeyCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwChainCompareIssuerPublicKeyCnt),
|
|
},
|
|
|
|
// 15 - PERF_COUNTER_DEFINITION ChainVerifyCtlSignatureCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainVerifyCtlSignatureCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwChainVerifyCtlSignatureCnt),
|
|
},
|
|
|
|
// 16 - PERF_COUNTER_DEFINITION ChainBeenVerifiedCtlSignatureCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainBeenVerifiedCtlSignatureCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwChainBeenVerifiedCtlSignatureCnt),
|
|
},
|
|
|
|
// 17 - PERF_COUNTER_DEFINITION ChainUrlIssuerCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainUrlIssuerCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwChainUrlIssuerCnt),
|
|
},
|
|
|
|
// 18 - PERF_COUNTER_DEFINITION ChainCacheOnlyUrlIssuerCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainCacheOnlyUrlIssuerCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwChainCacheOnlyUrlIssuerCnt),
|
|
},
|
|
|
|
// 19 - PERF_COUNTER_DEFINITION ChainRequestedEngineResyncCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwChainRequestedEngineResyncCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwChainRequestedEngineResyncCnt),
|
|
},
|
|
|
|
// 20 - PERF_COUNTER_DEFINITION ChangeNotifyCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwChangeNotifyCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwChangeNotifyCnt),
|
|
},
|
|
|
|
// 21 - PERF_COUNTER_DEFINITION ChangeNotifyLmGpCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwChangeNotifyLmGpCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwChangeNotifyLmGpCnt),
|
|
},
|
|
|
|
// 22 - PERF_COUNTER_DEFINITION ChangeNotifyCuGpCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwChangeNotifyCuGpCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwChangeNotifyCuGpCnt),
|
|
},
|
|
|
|
// 23 - PERF_COUNTER_DEFINITION ChangeNotifyCuMyCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwChangeNotifyCuMyCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwChangeNotifyCuMyCnt),
|
|
},
|
|
|
|
// 24 - PERF_COUNTER_DEFINITION ChangeNotifyRegCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwChangeNotifyRegCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwChangeNotifyRegCnt),
|
|
},
|
|
|
|
// 25 - PERF_COUNTER_DEFINITION StoreCurrentCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwStoreCurrentCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwStoreCurrentCnt),
|
|
},
|
|
|
|
// 26 - PERF_COUNTER_DEFINITION StoreTotalCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwStoreTotalCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwStoreTotalCnt),
|
|
},
|
|
|
|
// 27 - PERF_COUNTER_DEFINITION StoreRegCurrentCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwStoreRegCurrentCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwStoreRegCurrentCnt),
|
|
},
|
|
|
|
// 28 - PERF_COUNTER_DEFINITION StoreRegTotalCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwStoreRegTotalCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwStoreRegTotalCnt),
|
|
},
|
|
|
|
// 29 - PERF_COUNTER_DEFINITION RegElementReadCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwRegElementReadCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwRegElementReadCnt),
|
|
},
|
|
|
|
// 30 - PERF_COUNTER_DEFINITION RegElementWriteCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwRegElementWriteCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwRegElementWriteCnt),
|
|
},
|
|
|
|
// 31 - PERF_COUNTER_DEFINITION RegElementDeleteCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwRegElementDeleteCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwRegElementDeleteCnt),
|
|
},
|
|
|
|
// 32 - PERF_COUNTER_DEFINITION CertElementCurrentCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwCertElementCurrentCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwCertElementCurrentCnt),
|
|
},
|
|
|
|
// 33 - PERF_COUNTER_DEFINITION CertElementTotalCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwCertElementTotalCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwCertElementTotalCnt),
|
|
},
|
|
|
|
// 34 - PERF_COUNTER_DEFINITION CrlElementCurrentCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwCrlElementCurrentCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwCrlElementCurrentCnt),
|
|
},
|
|
|
|
// 35 - PERF_COUNTER_DEFINITION CrlElementTotalCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwCrlElementTotalCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwCrlElementTotalCnt),
|
|
},
|
|
|
|
// 36 - PERF_COUNTER_DEFINITION CtlElementCurrentCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwCtlElementCurrentCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwCtlElementCurrentCnt),
|
|
},
|
|
|
|
// 37 - PERF_COUNTER_DEFINITION CtlElementTotalCnt
|
|
{
|
|
sizeof(PERF_COUNTER_DEFINITION),
|
|
IMPURE, // CounterNameTitleIndex: dwFirstCounter +
|
|
0,
|
|
IMPURE, // CounterHelpTitleIndex: dwFirstHelp +
|
|
0,
|
|
-2,
|
|
PERF_DETAIL_NOVICE,
|
|
PERF_COUNTER_RAWCOUNT,
|
|
sizeof(((PCERT_PERF_COUNTERS) 0)->dwCtlElementTotalCnt),
|
|
offsetof(CERT_PERF_COUNTERS, dwCtlElementTotalCnt),
|
|
},
|
|
|
|
|
|
//--### Add New Counters ###--
|
|
};
|
|
|
|
|
|
STATIC
|
|
BOOL
|
|
I_CertPerfSetNameAndHelpIndices()
|
|
{
|
|
BOOL fResult;
|
|
HKEY hKey = NULL;
|
|
DWORD dwType;
|
|
DWORD cbValue;
|
|
DWORD dwFirstCounter;
|
|
DWORD dwFirstHelp;
|
|
|
|
if (!FIsWinNT())
|
|
return FALSE;
|
|
|
|
if (ERROR_SUCCESS != RegOpenKeyExW(
|
|
HKEY_LOCAL_MACHINE,
|
|
CERT_PERF_REGPATH,
|
|
0, // dwReserved
|
|
KEY_READ,
|
|
&hKey))
|
|
goto ErrorReturn;
|
|
|
|
cbValue = sizeof(DWORD);
|
|
if (ERROR_SUCCESS != RegQueryValueExW(
|
|
hKey,
|
|
L"First Counter",
|
|
NULL, // pdwReserved
|
|
&dwType,
|
|
(PBYTE) &dwFirstCounter,
|
|
&cbValue))
|
|
goto ErrorReturn;
|
|
cbValue = sizeof(DWORD);
|
|
if (ERROR_SUCCESS != RegQueryValueExW(
|
|
hKey,
|
|
L"First Help",
|
|
NULL, // pdwReserved
|
|
&dwType,
|
|
(PBYTE) &dwFirstHelp,
|
|
&cbValue))
|
|
goto ErrorReturn;
|
|
|
|
|
|
// Update CertPerfDataDefinitions' counter and help name indices
|
|
CertPerfDataDefinition.ObjectType.ObjectNameTitleIndex =
|
|
dwFirstCounter + CERT_OBJ;
|
|
CertPerfDataDefinition.ObjectType.ObjectHelpTitleIndex =
|
|
dwFirstHelp + CERT_OBJ;
|
|
|
|
CertPerfDataDefinition.ChainCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_CHAIN_CNT;
|
|
CertPerfDataDefinition.ChainCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_CHAIN_CNT;
|
|
|
|
CertPerfDataDefinition.ChainElementCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_CHAIN_ELEMENT_CNT;
|
|
CertPerfDataDefinition.ChainElementCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_CHAIN_ELEMENT_CNT;
|
|
|
|
CertPerfDataDefinition.ChainEngineCurrentCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_CHAIN_ENGINE_CURRENT_CNT;
|
|
CertPerfDataDefinition.ChainEngineCurrentCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_CHAIN_ENGINE_CURRENT_CNT;
|
|
|
|
CertPerfDataDefinition.ChainEngineTotalCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_CHAIN_ENGINE_TOTAL_CNT;
|
|
CertPerfDataDefinition.ChainEngineTotalCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_CHAIN_ENGINE_TOTAL_CNT;
|
|
|
|
CertPerfDataDefinition.ChainEngineResyncCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_CHAIN_ENGINE_RESYNC_CNT;
|
|
CertPerfDataDefinition.ChainEngineResyncCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_CHAIN_ENGINE_RESYNC_CNT;
|
|
|
|
CertPerfDataDefinition.ChainCertCacheCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_CHAIN_CERT_CACHE_CNT;
|
|
CertPerfDataDefinition.ChainCertCacheCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_CHAIN_CERT_CACHE_CNT;
|
|
|
|
CertPerfDataDefinition.ChainCtlCacheCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_CHAIN_CTL_CACHE_CNT;
|
|
CertPerfDataDefinition.ChainCtlCacheCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_CHAIN_CTL_CACHE_CNT;
|
|
|
|
CertPerfDataDefinition.ChainEndCertInCacheCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_CHAIN_END_CERT_IN_CACHE_CNT;
|
|
CertPerfDataDefinition.ChainEndCertInCacheCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_CHAIN_END_CERT_IN_CACHE_CNT;
|
|
|
|
CertPerfDataDefinition.ChainCacheEndCertCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_CHAIN_CACHE_END_CERT_CNT;
|
|
CertPerfDataDefinition.ChainCacheEndCertCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_CHAIN_CACHE_END_CERT_CNT;
|
|
|
|
CertPerfDataDefinition.ChainRevocationCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_CHAIN_REVOCATION_CNT;
|
|
CertPerfDataDefinition.ChainRevocationCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_CHAIN_REVOCATION_CNT;
|
|
|
|
CertPerfDataDefinition.ChainRevokedCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_CHAIN_REVOKED_CNT;
|
|
CertPerfDataDefinition.ChainRevokedCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_CHAIN_REVOKED_CNT;
|
|
|
|
CertPerfDataDefinition.ChainRevocationOfflineCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_CHAIN_REVOCATION_OFFLINE_CNT;
|
|
CertPerfDataDefinition.ChainRevocationOfflineCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_CHAIN_REVOCATION_OFFLINE_CNT;
|
|
|
|
CertPerfDataDefinition.ChainNoRevocationCheckCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_CHAIN_NO_REVOCATION_CHECK_CNT;
|
|
CertPerfDataDefinition.ChainNoRevocationCheckCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_CHAIN_NO_REVOCATION_CHECK_CNT;
|
|
|
|
CertPerfDataDefinition.ChainVerifyCertSignatureCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_CHAIN_VERIFY_CERT_SIGNATURE_CNT;
|
|
CertPerfDataDefinition.ChainVerifyCertSignatureCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_CHAIN_VERIFY_CERT_SIGNATURE_CNT;
|
|
|
|
CertPerfDataDefinition.ChainCompareIssuerPublicKeyCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_CHAIN_COMPARE_ISSUER_PUBLIC_KEY_CNT;
|
|
CertPerfDataDefinition.ChainCompareIssuerPublicKeyCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_CHAIN_COMPARE_ISSUER_PUBLIC_KEY_CNT;
|
|
|
|
CertPerfDataDefinition.ChainVerifyCtlSignatureCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_CHAIN_VERIFY_CTL_SIGNATURE_CNT;
|
|
CertPerfDataDefinition.ChainVerifyCtlSignatureCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_CHAIN_VERIFY_CTL_SIGNATURE_CNT;
|
|
|
|
CertPerfDataDefinition.ChainBeenVerifiedCtlSignatureCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_CHAIN_BEEN_VERIFIED_CTL_SIGNATURE_CNT;
|
|
CertPerfDataDefinition.ChainBeenVerifiedCtlSignatureCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_CHAIN_BEEN_VERIFIED_CTL_SIGNATURE_CNT;
|
|
|
|
CertPerfDataDefinition.ChainUrlIssuerCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_CHAIN_URL_ISSUER_CNT;
|
|
CertPerfDataDefinition.ChainUrlIssuerCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_CHAIN_URL_ISSUER_CNT;
|
|
|
|
CertPerfDataDefinition.ChainCacheOnlyUrlIssuerCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_CHAIN_CACHE_ONLY_URL_ISSUER_CNT;
|
|
CertPerfDataDefinition.ChainCacheOnlyUrlIssuerCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_CHAIN_CACHE_ONLY_URL_ISSUER_CNT;
|
|
|
|
CertPerfDataDefinition.ChainRequestedEngineResyncCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_CHAIN_REQUESTED_ENGINE_RESYNC_CNT;
|
|
CertPerfDataDefinition.ChainRequestedEngineResyncCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_CHAIN_REQUESTED_ENGINE_RESYNC_CNT;
|
|
|
|
CertPerfDataDefinition.ChangeNotifyCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_CHANGE_NOTIFY_CNT;
|
|
CertPerfDataDefinition.ChangeNotifyCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_CHANGE_NOTIFY_CNT;
|
|
|
|
CertPerfDataDefinition.ChangeNotifyLmGpCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_CHANGE_NOTIFY_LM_GP_CNT;
|
|
CertPerfDataDefinition.ChangeNotifyLmGpCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_CHANGE_NOTIFY_LM_GP_CNT;
|
|
|
|
CertPerfDataDefinition.ChangeNotifyCuGpCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_CHANGE_NOTIFY_CU_GP_CNT;
|
|
CertPerfDataDefinition.ChangeNotifyCuGpCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_CHANGE_NOTIFY_CU_GP_CNT;
|
|
|
|
CertPerfDataDefinition.ChangeNotifyCuMyCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_CHANGE_NOTIFY_CU_MY_CNT;
|
|
CertPerfDataDefinition.ChangeNotifyCuMyCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_CHANGE_NOTIFY_CU_MY_CNT;
|
|
|
|
CertPerfDataDefinition.ChangeNotifyRegCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_CHANGE_NOTIFY_REG_CNT;
|
|
CertPerfDataDefinition.ChangeNotifyRegCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_CHANGE_NOTIFY_REG_CNT;
|
|
|
|
CertPerfDataDefinition.StoreCurrentCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_STORE_CURRENT_CNT;
|
|
CertPerfDataDefinition.StoreCurrentCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_STORE_CURRENT_CNT;
|
|
|
|
CertPerfDataDefinition.StoreTotalCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_STORE_TOTAL_CNT;
|
|
CertPerfDataDefinition.StoreTotalCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_STORE_TOTAL_CNT;
|
|
|
|
CertPerfDataDefinition.StoreRegCurrentCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_STORE_REG_CURRENT_CNT;
|
|
CertPerfDataDefinition.StoreRegCurrentCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_STORE_REG_CURRENT_CNT;
|
|
|
|
CertPerfDataDefinition.StoreRegTotalCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_STORE_REG_TOTAL_CNT;
|
|
CertPerfDataDefinition.StoreRegTotalCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_STORE_REG_TOTAL_CNT;
|
|
|
|
CertPerfDataDefinition.RegElementReadCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_REG_ELEMENT_READ_CNT;
|
|
CertPerfDataDefinition.RegElementReadCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_REG_ELEMENT_READ_CNT;
|
|
|
|
CertPerfDataDefinition.RegElementWriteCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_REG_ELEMENT_WRITE_CNT;
|
|
CertPerfDataDefinition.RegElementWriteCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_REG_ELEMENT_WRITE_CNT;
|
|
|
|
CertPerfDataDefinition.RegElementDeleteCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_REG_ELEMENT_DELETE_CNT;
|
|
CertPerfDataDefinition.RegElementDeleteCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_REG_ELEMENT_DELETE_CNT;
|
|
|
|
CertPerfDataDefinition.CertElementCurrentCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_CERT_ELEMENT_CURRENT_CNT;
|
|
CertPerfDataDefinition.CertElementCurrentCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_CERT_ELEMENT_CURRENT_CNT;
|
|
|
|
CertPerfDataDefinition.CertElementTotalCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_CERT_ELEMENT_TOTAL_CNT;
|
|
CertPerfDataDefinition.CertElementTotalCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_CERT_ELEMENT_TOTAL_CNT;
|
|
|
|
CertPerfDataDefinition.CrlElementCurrentCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_CRL_ELEMENT_CURRENT_CNT;
|
|
CertPerfDataDefinition.CrlElementCurrentCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_CRL_ELEMENT_CURRENT_CNT;
|
|
|
|
CertPerfDataDefinition.CrlElementTotalCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_CRL_ELEMENT_TOTAL_CNT;
|
|
CertPerfDataDefinition.CrlElementTotalCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_CRL_ELEMENT_TOTAL_CNT;
|
|
|
|
CertPerfDataDefinition.CtlElementCurrentCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_CTL_ELEMENT_CURRENT_CNT;
|
|
CertPerfDataDefinition.CtlElementCurrentCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_CTL_ELEMENT_CURRENT_CNT;
|
|
|
|
CertPerfDataDefinition.CtlElementTotalCnt.CounterNameTitleIndex =
|
|
dwFirstCounter + CERT_CTL_ELEMENT_TOTAL_CNT;
|
|
CertPerfDataDefinition.CtlElementTotalCnt.CounterHelpTitleIndex =
|
|
dwFirstHelp + CERT_CTL_ELEMENT_TOTAL_CNT;
|
|
|
|
//--### Add New Counters ###--
|
|
|
|
fResult = TRUE;
|
|
|
|
CommonReturn:
|
|
if (hKey)
|
|
RegCloseKey(hKey);
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
}
|
|
|
|
STATIC
|
|
void
|
|
I_CertPerfGetProcessName(
|
|
OUT WCHAR wcszProcessName[CERT_PERF_MAX_PROCESS_NAME_LEN]
|
|
)
|
|
{
|
|
WCHAR wszModule[MAX_PATH + 1];
|
|
LPWSTR pwsz;
|
|
LPWSTR pwszSlash;
|
|
LPWSTR pwszPeriod;
|
|
WCHAR wc;
|
|
DWORD cchProcessName;
|
|
|
|
wszModule[MAX_PATH] = L'\0';
|
|
if (0 == GetModuleFileNameW(NULL, wszModule, MAX_PATH))
|
|
goto GetModuleFileNameError;
|
|
|
|
// Go from beginning to end and find last backslash and
|
|
// last period in name
|
|
pwszPeriod = NULL;
|
|
pwszSlash = NULL;
|
|
for (pwsz = wszModule; L'\0' != (wc = *pwsz); pwsz++) {
|
|
if (L'\\' == wc)
|
|
pwszSlash = pwsz;
|
|
else if (L'.' == wc)
|
|
pwszPeriod = pwsz;
|
|
}
|
|
|
|
// If present, the process name is between the last \ and the last period.
|
|
// Otherwise, between beginning and/or end of entire module name
|
|
if (pwszSlash)
|
|
pwszSlash++;
|
|
else
|
|
pwszSlash = wszModule;
|
|
|
|
if (NULL == pwszPeriod)
|
|
pwszPeriod = pwsz;
|
|
|
|
if (pwszSlash >= pwszPeriod)
|
|
goto InvalidModuleName;
|
|
cchProcessName = (DWORD) (pwszPeriod - pwszSlash);
|
|
if (cchProcessName > (CERT_PERF_MAX_PROCESS_NAME_LEN - 1))
|
|
cchProcessName = CERT_PERF_MAX_PROCESS_NAME_LEN - 1;
|
|
|
|
memcpy(wcszProcessName, pwszSlash, cchProcessName * sizeof(WCHAR));
|
|
wcszProcessName[cchProcessName] = L'\0';
|
|
|
|
CommonReturn:
|
|
return;
|
|
ErrorReturn:
|
|
wcscpy(wcszProcessName, L"???");
|
|
goto CommonReturn;
|
|
TRACE_ERROR(GetModuleFileNameError)
|
|
TRACE_ERROR(InvalidModuleName)
|
|
}
|
|
|
|
// The returnd ACL must be freed via PkiFree()
|
|
STATIC
|
|
PACL
|
|
CreateEveryoneAcl(
|
|
IN DWORD dwAccessMask
|
|
)
|
|
{
|
|
DWORD dwLastErr = 0;
|
|
PACL pEveryoneAcl = NULL;
|
|
PSID psidEveryone = NULL;
|
|
DWORD dwAclSize;
|
|
|
|
SID_IDENTIFIER_AUTHORITY siaWorldSidAuthority =
|
|
SECURITY_WORLD_SID_AUTHORITY;
|
|
|
|
if (!AllocateAndInitializeSid(
|
|
&siaWorldSidAuthority,
|
|
1,
|
|
SECURITY_WORLD_RID,
|
|
0, 0, 0, 0, 0, 0, 0,
|
|
&psidEveryone
|
|
))
|
|
goto AllocateAndInitializeSidError;
|
|
|
|
//
|
|
// compute size of ACL
|
|
//
|
|
dwAclSize =
|
|
sizeof(ACL) +
|
|
( sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) ) +
|
|
GetLengthSid(psidEveryone);
|
|
|
|
//
|
|
// allocate storage for Acl
|
|
//
|
|
if (NULL == (pEveryoneAcl = (PACL) PkiNonzeroAlloc(dwAclSize)))
|
|
goto OutOfMemory;
|
|
|
|
if (!InitializeAcl(pEveryoneAcl, dwAclSize, ACL_REVISION))
|
|
goto InitializeAclError;
|
|
|
|
if (!AddAccessAllowedAce(
|
|
pEveryoneAcl,
|
|
ACL_REVISION,
|
|
dwAccessMask,
|
|
psidEveryone
|
|
))
|
|
goto AddAceError;
|
|
|
|
CommonReturn:
|
|
if (psidEveryone)
|
|
FreeSid(psidEveryone);
|
|
if (dwLastErr)
|
|
SetLastError(dwLastErr);
|
|
|
|
return pEveryoneAcl;
|
|
|
|
ErrorReturn:
|
|
dwLastErr = GetLastError();
|
|
if (pEveryoneAcl) {
|
|
PkiFree(pEveryoneAcl);
|
|
pEveryoneAcl = NULL;
|
|
}
|
|
goto CommonReturn;
|
|
|
|
TRACE_ERROR(AllocateAndInitializeSidError)
|
|
TRACE_ERROR(OutOfMemory)
|
|
TRACE_ERROR(InitializeAclError)
|
|
TRACE_ERROR(AddAceError)
|
|
}
|
|
|
|
STATIC
|
|
BOOL
|
|
InitializeSecurityDescriptorAndAttributes(
|
|
IN PACL pAcl,
|
|
OUT SECURITY_DESCRIPTOR *psd,
|
|
OUT SECURITY_ATTRIBUTES *psa
|
|
)
|
|
{
|
|
BOOL fResult;
|
|
|
|
if (!InitializeSecurityDescriptor(psd, SECURITY_DESCRIPTOR_REVISION))
|
|
goto InitializeSecurityDescriptorError;
|
|
if (!SetSecurityDescriptorDacl(psd, TRUE, pAcl, FALSE))
|
|
goto SetSecurityDescriptorDaclError;
|
|
|
|
psa->nLength = sizeof(SECURITY_ATTRIBUTES);
|
|
psa->lpSecurityDescriptor = psd;
|
|
psa->bInheritHandle = FALSE;
|
|
|
|
fResult = TRUE;
|
|
CommonReturn:
|
|
return fResult;
|
|
|
|
ErrorReturn:
|
|
fResult = FALSE;
|
|
goto CommonReturn;
|
|
|
|
TRACE_ERROR(InitializeSecurityDescriptorError)
|
|
TRACE_ERROR(SetSecurityDescriptorDaclError)
|
|
}
|
|
|
|
STATIC
|
|
HANDLE
|
|
CreateMutexWithSynchronizeAccess(
|
|
IN LPWSTR pwszMutexName
|
|
)
|
|
{
|
|
HANDLE hMutex = NULL;
|
|
PACL pEveryoneAcl = NULL;
|
|
SECURITY_DESCRIPTOR sd;
|
|
SECURITY_ATTRIBUTES sa;
|
|
DWORD i;
|
|
|
|
if (NULL == (pEveryoneAcl = CreateEveryoneAcl(SYNCHRONIZE)))
|
|
goto CreateEveryoneAclError;
|
|
if (!InitializeSecurityDescriptorAndAttributes(pEveryoneAcl, &sd, &sa))
|
|
goto InitializeSecurityDescriptorAndAttributesError;
|
|
|
|
// Retry a couple of times. There is a small window between the
|
|
// CreateMutex and OpenMutex where the mutex is deleted.
|
|
for (i = 0; i < 5; i++) {
|
|
hMutex = CreateMutexU(
|
|
&sa,
|
|
FALSE, // fInitialOwner
|
|
pwszMutexName
|
|
);
|
|
if (NULL != hMutex)
|
|
goto CommonReturn;
|
|
|
|
hMutex = OpenMutexU(
|
|
SYNCHRONIZE,
|
|
FALSE, // bInheritHandle
|
|
pwszMutexName
|
|
);
|
|
if (NULL != hMutex) {
|
|
SetLastError(ERROR_ALREADY_EXISTS);
|
|
goto CommonReturn;
|
|
}
|
|
|
|
if (ERROR_FILE_NOT_FOUND != GetLastError())
|
|
break;
|
|
}
|
|
|
|
assert(NULL == hMutex);
|
|
goto OpenMutexError;
|
|
|
|
CommonReturn:
|
|
if (pEveryoneAcl)
|
|
PkiFree(pEveryoneAcl);
|
|
|
|
return hMutex;
|
|
|
|
ErrorReturn:
|
|
assert(NULL == hMutex);
|
|
goto CommonReturn;
|
|
|
|
TRACE_ERROR(CreateEveryoneAclError)
|
|
TRACE_ERROR(InitializeSecurityDescriptorAndAttributesError)
|
|
TRACE_ERROR(OpenMutexError)
|
|
}
|
|
|
|
STATIC
|
|
HANDLE
|
|
CreateFileMappingWithWriteAccess(
|
|
IN DWORD dwMaximumSizeLow,
|
|
IN LPWSTR pwszFileName
|
|
)
|
|
{
|
|
HANDLE hFile = NULL;
|
|
PACL pEveryoneAcl = NULL;
|
|
SECURITY_DESCRIPTOR sd;
|
|
SECURITY_ATTRIBUTES sa;
|
|
DWORD i;
|
|
|
|
if (NULL == (pEveryoneAcl = CreateEveryoneAcl(FILE_MAP_WRITE)))
|
|
goto CreateEveryoneAclError;
|
|
if (!InitializeSecurityDescriptorAndAttributes(pEveryoneAcl, &sd, &sa))
|
|
goto InitializeSecurityDescriptorAndAttributesError;
|
|
|
|
// Retry a couple of times. There is a small window between the
|
|
// CreateFileMapping and OpenFileMapping where the file is closed.
|
|
for (i = 0; i < 5; i++) {
|
|
hFile = CreateFileMappingW(
|
|
INVALID_HANDLE_VALUE,
|
|
&sa,
|
|
PAGE_READWRITE,
|
|
0, // dwMaximumSizeHigh
|
|
dwMaximumSizeLow,
|
|
pwszFileName
|
|
);
|
|
|
|
if (NULL != hFile)
|
|
goto CommonReturn;
|
|
|
|
hFile = OpenFileMappingW(
|
|
FILE_MAP_WRITE,
|
|
FALSE, // bInheritHandle
|
|
pwszFileName
|
|
);
|
|
if (NULL != hFile) {
|
|
SetLastError(ERROR_ALREADY_EXISTS);
|
|
goto CommonReturn;
|
|
}
|
|
|
|
if (ERROR_FILE_NOT_FOUND != GetLastError())
|
|
break;
|
|
}
|
|
|
|
assert(NULL == hFile);
|
|
goto OpenFileError;
|
|
|
|
CommonReturn:
|
|
if (pEveryoneAcl)
|
|
PkiFree(pEveryoneAcl);
|
|
|
|
return hFile;
|
|
|
|
ErrorReturn:
|
|
assert(NULL == hFile);
|
|
goto CommonReturn;
|
|
|
|
TRACE_ERROR(CreateEveryoneAclError)
|
|
TRACE_ERROR(InitializeSecurityDescriptorAndAttributesError)
|
|
TRACE_ERROR(OpenFileError)
|
|
}
|
|
|
|
STATIC
|
|
void
|
|
I_CertPerfGetSharedMemory()
|
|
{
|
|
DWORD dwFileMappingStatus;
|
|
BOOL fReleaseMutex = FALSE;
|
|
DWORD dwIndex;
|
|
DWORD dwNextIndex;
|
|
BOOL fTerminalServerGlobalName;
|
|
|
|
if (!I_CertPerfSetNameAndHelpIndices())
|
|
return;
|
|
|
|
// First try with W2K Terminal Server "Global\" prefix
|
|
if (NULL == (hCertPerfSharedMemoryMutex = CreateMutexWithSynchronizeAccess(
|
|
CERT_PERF_TS_SHARED_MEMORY_MUTEX_NAME
|
|
))) {
|
|
if (NULL == (hCertPerfSharedMemoryMutex =
|
|
CreateMutexWithSynchronizeAccess(
|
|
CERT_PERF_SHARED_MEMORY_MUTEX_NAME
|
|
)))
|
|
goto CreateMutexError;
|
|
else
|
|
fTerminalServerGlobalName = FALSE;
|
|
} else
|
|
fTerminalServerGlobalName = TRUE;
|
|
if (WAIT_OBJECT_0 != WaitForSingleObject(
|
|
hCertPerfSharedMemoryMutex,
|
|
CERT_PERF_SHARED_MEMORY_MUTEX_TIMEOUT
|
|
))
|
|
goto WaitForMutexError;
|
|
else
|
|
fReleaseMutex = TRUE;
|
|
|
|
if (NULL == (hCertPerfSharedMemoryFile = CreateFileMappingWithWriteAccess(
|
|
sizeof(CERT_PERF_SHARED_MEMORY),
|
|
fTerminalServerGlobalName ?
|
|
CERT_PERF_TS_SHARED_MEMORY_FILE_NAME :
|
|
CERT_PERF_SHARED_MEMORY_FILE_NAME
|
|
)))
|
|
goto CreateFileMappingError;
|
|
dwFileMappingStatus = GetLastError();
|
|
|
|
if (NULL == (pCertPerfSharedMemory =
|
|
(PCERT_PERF_SHARED_MEMORY) MapViewOfFile(
|
|
hCertPerfSharedMemoryFile,
|
|
FILE_MAP_WRITE,
|
|
0, // dwOffsetHigh
|
|
0, // dwOffsetLow
|
|
sizeof(CERT_PERF_SHARED_MEMORY)
|
|
)))
|
|
goto MapViewOfFileError;
|
|
|
|
if (ERROR_ALREADY_EXISTS != dwFileMappingStatus) {
|
|
DWORD i;
|
|
|
|
assert(ERROR_SUCCESS == dwFileMappingStatus);
|
|
|
|
// Need to initialize the shared memory
|
|
memset(pCertPerfSharedMemory, 0, sizeof(CERT_PERF_SHARED_MEMORY));
|
|
|
|
// Create linked list of process free elements.
|
|
//
|
|
// Only need forward indices for the free list
|
|
for (i = 0; i < CERT_PERF_MAX_PROCESS_CNT; i++) {
|
|
// An index >= CERT_PERF_MAX_PROCESS_CNT indicates end of list
|
|
pCertPerfSharedMemory->rgProcessData[i].dwNextIndex = i + 1;
|
|
|
|
}
|
|
pCertPerfSharedMemory->dwFirstFreeIndex = 0;
|
|
|
|
// An index >= CERT_PERF_MAX_PROCESS_CNT indicates an empty list
|
|
pCertPerfSharedMemory->dwFirstInUseIndex = CERT_PERF_MAX_PROCESS_CNT;
|
|
}
|
|
|
|
if (CERT_PERF_MAX_PROCESS_CNT <=
|
|
(dwIndex = pCertPerfSharedMemory->dwFirstFreeIndex))
|
|
goto OutOfSharedMemoryProcessData;
|
|
pCertPerfProcessData = &pCertPerfSharedMemory->rgProcessData[dwIndex];
|
|
|
|
// Remove process data element from the free list
|
|
pCertPerfSharedMemory->dwFirstFreeIndex =
|
|
pCertPerfProcessData->dwNextIndex;
|
|
|
|
// Add process data element to the in use list
|
|
dwNextIndex = pCertPerfSharedMemory->dwFirstInUseIndex;
|
|
if (CERT_PERF_MAX_PROCESS_CNT > dwNextIndex)
|
|
pCertPerfSharedMemory->rgProcessData[dwNextIndex].dwPrevIndex =
|
|
dwIndex;
|
|
pCertPerfProcessData->dwNextIndex = dwNextIndex;
|
|
pCertPerfProcessData->dwPrevIndex = CERT_PERF_MAX_PROCESS_CNT;
|
|
pCertPerfSharedMemory->dwFirstInUseIndex = dwIndex;
|
|
pCertPerfSharedMemory->dwProcessCnt++;
|
|
|
|
pCertPerfProcessData->dwProcessId = GetCurrentProcessId();
|
|
I_CertPerfGetProcessName(pCertPerfProcessData->wcszProcessName);
|
|
memset(&pCertPerfProcessData->Counters, 0,
|
|
sizeof(pCertPerfProcessData->Counters));
|
|
|
|
ReleaseMutex(hCertPerfSharedMemoryMutex);
|
|
|
|
pCertPerfProcessCounters = &pCertPerfProcessData->Counters;
|
|
|
|
CommonReturn:
|
|
return;
|
|
|
|
ErrorReturn:
|
|
assert(NULL == pCertPerfProcessData);
|
|
|
|
if (pCertPerfSharedMemory) {
|
|
UnmapViewOfFile(pCertPerfSharedMemory);
|
|
pCertPerfSharedMemory = NULL;
|
|
}
|
|
|
|
if (hCertPerfSharedMemoryFile) {
|
|
CloseHandle(hCertPerfSharedMemoryFile);
|
|
hCertPerfSharedMemoryFile = NULL;
|
|
}
|
|
|
|
if (hCertPerfSharedMemoryMutex) {
|
|
if (fReleaseMutex)
|
|
ReleaseMutex(hCertPerfSharedMemoryMutex);
|
|
|
|
CloseHandle(hCertPerfSharedMemoryMutex);
|
|
hCertPerfSharedMemoryMutex = NULL;
|
|
}
|
|
goto CommonReturn;
|
|
|
|
TRACE_ERROR(CreateMutexError)
|
|
TRACE_ERROR(WaitForMutexError)
|
|
TRACE_ERROR(CreateFileMappingError)
|
|
TRACE_ERROR(MapViewOfFileError)
|
|
TRACE_ERROR(OutOfSharedMemoryProcessData)
|
|
}
|
|
|
|
|
|
STATIC
|
|
void
|
|
I_CertPerfFreeSharedMemory()
|
|
{
|
|
if (NULL == pCertPerfProcessData)
|
|
return;
|
|
|
|
pCertPerfProcessData->dwProcessId = 0;
|
|
if (WAIT_OBJECT_0 == WaitForSingleObject(
|
|
hCertPerfSharedMemoryMutex,
|
|
CERT_PERF_SHARED_MEMORY_MUTEX_TIMEOUT
|
|
)) {
|
|
DWORD dwIndex;
|
|
DWORD dwPrevIndex;
|
|
DWORD dwNextIndex;
|
|
|
|
// Remove process data element from the in use list
|
|
dwIndex = (DWORD)(pCertPerfProcessData -
|
|
pCertPerfSharedMemory->rgProcessData);
|
|
assert(CERT_PERF_MAX_PROCESS_CNT > dwIndex);
|
|
|
|
dwPrevIndex = pCertPerfProcessData->dwPrevIndex;
|
|
dwNextIndex = pCertPerfProcessData->dwNextIndex;
|
|
|
|
if (CERT_PERF_MAX_PROCESS_CNT > dwNextIndex)
|
|
pCertPerfSharedMemory->rgProcessData[dwNextIndex].dwPrevIndex =
|
|
dwPrevIndex;
|
|
if (CERT_PERF_MAX_PROCESS_CNT > dwPrevIndex)
|
|
pCertPerfSharedMemory->rgProcessData[dwPrevIndex].dwNextIndex =
|
|
dwNextIndex;
|
|
else
|
|
pCertPerfSharedMemory->dwFirstInUseIndex = dwNextIndex;
|
|
|
|
|
|
if (pCertPerfSharedMemory->dwProcessCnt)
|
|
pCertPerfSharedMemory->dwProcessCnt--;
|
|
|
|
// Add to the free list
|
|
pCertPerfProcessData->dwNextIndex =
|
|
pCertPerfSharedMemory->dwFirstFreeIndex;
|
|
pCertPerfSharedMemory->dwFirstFreeIndex = dwIndex;
|
|
|
|
ReleaseMutex(hCertPerfSharedMemoryMutex);
|
|
}
|
|
|
|
assert(pCertPerfSharedMemory);
|
|
UnmapViewOfFile(pCertPerfSharedMemory);
|
|
pCertPerfSharedMemory = NULL;
|
|
|
|
assert(hCertPerfSharedMemoryFile);
|
|
CloseHandle(hCertPerfSharedMemoryFile);
|
|
hCertPerfSharedMemoryFile = NULL;
|
|
|
|
assert(hCertPerfSharedMemoryMutex);
|
|
CloseHandle(hCertPerfSharedMemoryMutex);
|
|
hCertPerfSharedMemoryMutex = NULL;
|
|
|
|
pCertPerfProcessCounters = NULL;
|
|
pCertPerfProcessData = NULL;
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
WINAPI
|
|
CertPerfDllMain(
|
|
HMODULE hInst,
|
|
ULONG ulReason,
|
|
LPVOID lpReserved
|
|
)
|
|
{
|
|
BOOL fRet = TRUE;
|
|
|
|
switch (ulReason) {
|
|
case DLL_PROCESS_ATTACH:
|
|
fRet = Pki_InitializeCriticalSection(&CertPerfProcessCriticalSection);
|
|
if (fRet)
|
|
I_CertPerfGetSharedMemory();
|
|
break;
|
|
case DLL_PROCESS_DETACH:
|
|
I_CertPerfFreeSharedMemory();
|
|
DeleteCriticalSection(&CertPerfProcessCriticalSection);
|
|
break;
|
|
case DLL_THREAD_DETACH:
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return fRet;
|
|
}
|
|
|
|
|
|
//
|
|
// Function Prototypes
|
|
//
|
|
// these are used to insure that the data collection functions
|
|
// accessed by Perflib will have the correct calling format.
|
|
//
|
|
|
|
PM_OPEN_PROC OpenCertPerformanceData;
|
|
PM_COLLECT_PROC CollectCertPerformanceData;
|
|
PM_CLOSE_PROC CloseCertPerformanceData;
|
|
|
|
DWORD
|
|
APIENTRY
|
|
OpenCertPerformanceData(
|
|
IN LPWSTR lpDeviceNames
|
|
)
|
|
{
|
|
if (NULL == pCertPerfProcessData)
|
|
return ERROR_FILE_NOT_FOUND;
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
#define QUERY_GLOBAL 1
|
|
#define QUERY_ITEMS 2
|
|
#define QUERY_FOREIGN 3
|
|
#define QUERY_COSTLY 4
|
|
|
|
#define GLOBAL_STRING L"Global"
|
|
#define FOREIGN_STRING L"Foreign"
|
|
#define COSTLY_STRING L"Costly"
|
|
|
|
// test for delimiter, end of line and non-digit characters
|
|
// used by I_CertPerfIsNumberInUnicodeList routine
|
|
//
|
|
#define DIGIT 1
|
|
#define DELIMITER 2
|
|
#define INVALID 3
|
|
|
|
#define EvalThisChar(c,d) ( \
|
|
(c == d) ? DELIMITER : \
|
|
(c == 0) ? DELIMITER : \
|
|
(c < (WCHAR)'0') ? INVALID : \
|
|
(c > (WCHAR)'9') ? INVALID : \
|
|
DIGIT)
|
|
|
|
|
|
DWORD
|
|
I_CertPerfGetQueryType(
|
|
IN LPWSTR pwszValue
|
|
)
|
|
/*++
|
|
|
|
returns the type of query described in the lpValue string so that
|
|
the appropriate processing method may be used
|
|
|
|
Arguments
|
|
|
|
IN pwszValue
|
|
string passed to PerfRegQuery Value for processing
|
|
|
|
Return Value
|
|
|
|
QUERY_GLOBAL
|
|
if pwszValue == 0 (null pointer)
|
|
pwszValue == pointer to Null string
|
|
pwszValue == pointer to "Global" string
|
|
|
|
QUERY_FOREIGN
|
|
if pwszValue == pointer to "Foreign" string
|
|
|
|
QUERY_COSTLY
|
|
if pwszValue == pointer to "Costly" string
|
|
|
|
otherwise:
|
|
|
|
QUERY_ITEMS
|
|
|
|
--*/
|
|
{
|
|
DWORD dwQueryType;
|
|
if (NULL == pwszValue || L'\0' == *pwszValue ||
|
|
0 == _wcsnicmp(pwszValue, GLOBAL_STRING, wcslen(GLOBAL_STRING)))
|
|
dwQueryType = QUERY_GLOBAL;
|
|
else if (0 == _wcsnicmp(pwszValue, COSTLY_STRING, wcslen(COSTLY_STRING)))
|
|
dwQueryType = QUERY_COSTLY;
|
|
else if (0 == _wcsnicmp(pwszValue, FOREIGN_STRING, wcslen(FOREIGN_STRING)))
|
|
dwQueryType = QUERY_FOREIGN;
|
|
else
|
|
dwQueryType = QUERY_ITEMS;
|
|
|
|
return dwQueryType;
|
|
}
|
|
|
|
BOOL
|
|
I_CertPerfIsNumberInUnicodeList (
|
|
IN DWORD dwNumber,
|
|
IN LPWSTR lpwszUnicodeList
|
|
)
|
|
/*++
|
|
|
|
Arguments:
|
|
|
|
IN dwNumber
|
|
DWORD number to find in list
|
|
|
|
IN lpwszUnicodeList
|
|
Null terminated, Space delimited list of decimal numbers
|
|
|
|
Return Value:
|
|
|
|
TRUE:
|
|
dwNumber was found in the list of unicode number strings
|
|
|
|
FALSE:
|
|
dwNumber was not found in the list.
|
|
|
|
--*/
|
|
{
|
|
DWORD dwThisNumber;
|
|
WCHAR *pwcThisChar;
|
|
BOOL bValidNumber;
|
|
BOOL bNewItem;
|
|
WCHAR wcDelimiter; // could be an argument to be more flexible
|
|
|
|
if (lpwszUnicodeList == 0) return FALSE; // null pointer, # not found
|
|
|
|
pwcThisChar = lpwszUnicodeList;
|
|
dwThisNumber = 0;
|
|
wcDelimiter = (WCHAR)' ';
|
|
bValidNumber = FALSE;
|
|
bNewItem = TRUE;
|
|
|
|
while (TRUE)
|
|
{
|
|
switch (EvalThisChar (*pwcThisChar, wcDelimiter))
|
|
{
|
|
case DIGIT:
|
|
// if this is the first digit after a delimiter, then
|
|
// set flags to start computing the new number
|
|
if (bNewItem)
|
|
{
|
|
bNewItem = FALSE;
|
|
bValidNumber = TRUE;
|
|
}
|
|
if (bValidNumber)
|
|
{
|
|
dwThisNumber *= 10;
|
|
dwThisNumber += (*pwcThisChar - (WCHAR)'0');
|
|
}
|
|
break;
|
|
|
|
case DELIMITER:
|
|
// a delimter is either the delimiter character or the
|
|
// end of the string ('\0') if when the delimiter has been
|
|
// reached a valid number was found, then compare it to the
|
|
// number from the argument list. if this is the end of the
|
|
// string and no match was found, then return.
|
|
//
|
|
if (bValidNumber)
|
|
{
|
|
if (dwThisNumber == dwNumber) return TRUE;
|
|
bValidNumber = FALSE;
|
|
}
|
|
if (*pwcThisChar == 0)
|
|
{
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
bNewItem = TRUE;
|
|
dwThisNumber = 0;
|
|
}
|
|
break;
|
|
|
|
case INVALID:
|
|
// if an invalid character was encountered, ignore all
|
|
// characters up to the next delimiter and then start fresh.
|
|
// the invalid number is not compared.
|
|
bValidNumber = FALSE;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
|
|
}
|
|
pwcThisChar++;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
DWORD
|
|
APIENTRY
|
|
CollectCertPerformanceData(
|
|
IN LPWSTR pwszValueName,
|
|
IN OUT LPVOID *ppvData,
|
|
IN OUT LPDWORD pcbTotalBytes,
|
|
IN OUT LPDWORD pNumObjectTypes
|
|
)
|
|
{
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
BOOL fReleaseMutex = FALSE;
|
|
PCERT_PERF_DATA_DEFINITION pDataDef;
|
|
PERF_INSTANCE_DEFINITION *pInstanceDef;
|
|
DWORD cbNeededBytes;
|
|
DWORD dwProcessCnt;
|
|
DWORD dwInUseIndex;
|
|
LONG NumInstances;
|
|
DWORD dwQueryType;
|
|
|
|
if (NULL == pCertPerfProcessData)
|
|
goto NoProcessDataError;
|
|
|
|
dwQueryType = I_CertPerfGetQueryType(pwszValueName);
|
|
if (QUERY_FOREIGN == dwQueryType)
|
|
goto ForeignQueryNotSupported;
|
|
|
|
if (QUERY_ITEMS == dwQueryType) {
|
|
if (!(I_CertPerfIsNumberInUnicodeList(
|
|
CertPerfDataDefinition.ObjectType.ObjectNameTitleIndex,
|
|
pwszValueName)))
|
|
goto ObjectTypeQueryNotSupported;
|
|
}
|
|
|
|
if (WAIT_OBJECT_0 != WaitForSingleObject(
|
|
hCertPerfSharedMemoryMutex,
|
|
CERT_PERF_SHARED_MEMORY_MUTEX_TIMEOUT
|
|
))
|
|
goto WaitForMutexError;
|
|
else
|
|
fReleaseMutex = TRUE;
|
|
|
|
pDataDef = (PCERT_PERF_DATA_DEFINITION) *ppvData;
|
|
|
|
// always return an "instance sized" buffer after the definition blocks
|
|
// to prevent perfmon from reading bogus data. This is strictly a hack
|
|
// to accomodate how PERFMON handles the "0" instance case.
|
|
// By doing this, perfmon won't choke when there are no instances
|
|
// and the counter object & counters will be displayed in the
|
|
// list boxes, even though no instances will be listed.
|
|
|
|
dwProcessCnt = pCertPerfSharedMemory->dwProcessCnt;
|
|
if (CERT_PERF_MAX_PROCESS_CNT < dwProcessCnt)
|
|
goto InvalidProcessData;
|
|
|
|
cbNeededBytes = (DWORD)( sizeof(CERT_PERF_DATA_DEFINITION) +
|
|
(dwProcessCnt > 0 ? dwProcessCnt : 1 ) * (
|
|
sizeof(PERF_INSTANCE_DEFINITION) +
|
|
CERT_PERF_MAX_PROCESS_NAME_LEN +
|
|
sizeof(CERT_PERF_COUNTERS)) );
|
|
if (*pcbTotalBytes < cbNeededBytes) {
|
|
dwErr = ERROR_MORE_DATA;
|
|
goto MoreDataError;
|
|
}
|
|
|
|
// copy the object & counter definition information
|
|
memcpy(pDataDef, &CertPerfDataDefinition,
|
|
sizeof(CERT_PERF_DATA_DEFINITION));
|
|
|
|
// Update the instance data for each InUse process.
|
|
pInstanceDef = (PERF_INSTANCE_DEFINITION *) &pDataDef[1];
|
|
dwInUseIndex = pCertPerfSharedMemory->dwFirstInUseIndex;
|
|
NumInstances = 0;
|
|
while (NumInstances < (LONG) dwProcessCnt &&
|
|
CERT_PERF_MAX_PROCESS_CNT > dwInUseIndex) {
|
|
PCERT_PERF_PROCESS_DATA pInUseData;
|
|
PCERT_PERF_COUNTERS pCtr;
|
|
DWORD cchProcessName;
|
|
DWORD NameLength;
|
|
DWORD ByteLength;
|
|
|
|
pInUseData = &pCertPerfSharedMemory->rgProcessData[dwInUseIndex];
|
|
dwInUseIndex = pInUseData->dwNextIndex;
|
|
|
|
if (0 == pInUseData->dwProcessId)
|
|
continue;
|
|
|
|
// The following is updated for each InUse process:
|
|
// - PERF_INSTANCE_DEFINITION
|
|
// - wcszProcessName
|
|
// - optional padding for DWORD alignment
|
|
// - CERT_PERF_COUNTERS
|
|
|
|
// Get process name and instance definition byte lengths
|
|
for (cchProcessName = 0;
|
|
cchProcessName < CERT_PERF_MAX_PROCESS_NAME_LEN &&
|
|
L'\0' != pInUseData->wcszProcessName[cchProcessName];
|
|
cchProcessName++)
|
|
;
|
|
if (CERT_PERF_MAX_PROCESS_NAME_LEN <= cchProcessName)
|
|
goto InvalidProcessData;
|
|
|
|
// Include trailing null in name length
|
|
NameLength = cchProcessName * sizeof(WCHAR) + sizeof(WCHAR);
|
|
ByteLength = sizeof(PERF_INSTANCE_DEFINITION) +
|
|
DWORD_MULTIPLE(NameLength);
|
|
|
|
|
|
// Update the instance definition fields
|
|
pInstanceDef->ByteLength = ByteLength;
|
|
pInstanceDef->ParentObjectTitleIndex = 0; // no parent
|
|
pInstanceDef->ParentObjectInstance = 0; // " "
|
|
pInstanceDef->UniqueID = PERF_NO_UNIQUE_ID;
|
|
pInstanceDef->NameOffset = sizeof(PERF_INSTANCE_DEFINITION);
|
|
pInstanceDef->NameLength = NameLength;
|
|
|
|
// Update the process name that immediately follows the
|
|
// instance definition
|
|
memcpy(&pInstanceDef[1], pInUseData->wcszProcessName,
|
|
NameLength);
|
|
|
|
// Update the performance counters immediately following the
|
|
// above process name. Note, start of counters is DWORD aligned
|
|
pCtr = (PCERT_PERF_COUNTERS) (((PBYTE) pInstanceDef) + ByteLength);
|
|
pCtr->CounterBlock.ByteLength = sizeof(CERT_PERF_COUNTERS);
|
|
pCtr->dwChainCnt = (DWORD) pInUseData->Counters.lChainCnt;
|
|
pCtr->dwChainElementCnt = (DWORD) pInUseData->Counters.lChainElementCnt;
|
|
pCtr->dwChainEngineCurrentCnt =
|
|
(DWORD) pInUseData->Counters.lChainEngineCurrentCnt;
|
|
pCtr->dwChainEngineTotalCnt =
|
|
(DWORD) pInUseData->Counters.lChainEngineTotalCnt;
|
|
pCtr->dwChainEngineResyncCnt =
|
|
(DWORD) pInUseData->Counters.lChainEngineResyncCnt;
|
|
pCtr->dwChainCertCacheCnt =
|
|
(DWORD) pInUseData->Counters.lChainCertCacheCnt;
|
|
pCtr->dwChainCtlCacheCnt =
|
|
(DWORD) pInUseData->Counters.lChainCtlCacheCnt;
|
|
pCtr->dwChainEndCertInCacheCnt =
|
|
(DWORD) pInUseData->Counters.lChainEndCertInCacheCnt;
|
|
pCtr->dwChainCacheEndCertCnt =
|
|
(DWORD) pInUseData->Counters.lChainCacheEndCertCnt;
|
|
pCtr->dwChainRevocationCnt =
|
|
(DWORD) pInUseData->Counters.lChainRevocationCnt;
|
|
pCtr->dwChainRevokedCnt =
|
|
(DWORD) pInUseData->Counters.lChainRevokedCnt;
|
|
pCtr->dwChainRevocationOfflineCnt =
|
|
(DWORD) pInUseData->Counters.lChainRevocationOfflineCnt;
|
|
pCtr->dwChainNoRevocationCheckCnt =
|
|
(DWORD) pInUseData->Counters.lChainNoRevocationCheckCnt;
|
|
pCtr->dwChainVerifyCertSignatureCnt =
|
|
(DWORD) pInUseData->Counters.lChainVerifyCertSignatureCnt;
|
|
pCtr->dwChainCompareIssuerPublicKeyCnt =
|
|
(DWORD) pInUseData->Counters.lChainCompareIssuerPublicKeyCnt;
|
|
pCtr->dwChainVerifyCtlSignatureCnt =
|
|
(DWORD) pInUseData->Counters.lChainVerifyCtlSignatureCnt;
|
|
pCtr->dwChainBeenVerifiedCtlSignatureCnt =
|
|
(DWORD) pInUseData->Counters.lChainBeenVerifiedCtlSignatureCnt;
|
|
pCtr->dwChainUrlIssuerCnt =
|
|
(DWORD) pInUseData->Counters.lChainUrlIssuerCnt;
|
|
pCtr->dwChainCacheOnlyUrlIssuerCnt =
|
|
(DWORD) pInUseData->Counters.lChainCacheOnlyUrlIssuerCnt;
|
|
pCtr->dwChainRequestedEngineResyncCnt =
|
|
(DWORD) pInUseData->Counters.lChainRequestedEngineResyncCnt;
|
|
pCtr->dwChangeNotifyCnt =
|
|
(DWORD) pInUseData->Counters.lChangeNotifyCnt;
|
|
pCtr->dwChangeNotifyLmGpCnt =
|
|
(DWORD) pInUseData->Counters.lChangeNotifyLmGpCnt;
|
|
pCtr->dwChangeNotifyCuGpCnt =
|
|
(DWORD) pInUseData->Counters.lChangeNotifyCuGpCnt;
|
|
pCtr->dwChangeNotifyCuMyCnt =
|
|
(DWORD) pInUseData->Counters.lChangeNotifyCuMyCnt;
|
|
pCtr->dwChangeNotifyRegCnt =
|
|
(DWORD) pInUseData->Counters.lChangeNotifyRegCnt;
|
|
pCtr->dwStoreCurrentCnt =
|
|
(DWORD) pInUseData->Counters.lStoreCurrentCnt;
|
|
pCtr->dwStoreTotalCnt =
|
|
(DWORD) pInUseData->Counters.lStoreTotalCnt;
|
|
pCtr->dwStoreRegCurrentCnt =
|
|
(DWORD) pInUseData->Counters.lStoreRegCurrentCnt;
|
|
pCtr->dwStoreRegTotalCnt =
|
|
(DWORD) pInUseData->Counters.lStoreRegTotalCnt;
|
|
pCtr->dwRegElementReadCnt =
|
|
(DWORD) pInUseData->Counters.lRegElementReadCnt;
|
|
pCtr->dwRegElementWriteCnt =
|
|
(DWORD) pInUseData->Counters.lRegElementWriteCnt;
|
|
pCtr->dwRegElementDeleteCnt =
|
|
(DWORD) pInUseData->Counters.lRegElementDeleteCnt;
|
|
pCtr->dwCertElementCurrentCnt =
|
|
(DWORD) pInUseData->Counters.lCertElementCurrentCnt;
|
|
pCtr->dwCertElementTotalCnt =
|
|
(DWORD) pInUseData->Counters.lCertElementTotalCnt;
|
|
pCtr->dwCrlElementCurrentCnt =
|
|
(DWORD) pInUseData->Counters.lCrlElementCurrentCnt;
|
|
pCtr->dwCrlElementTotalCnt =
|
|
(DWORD) pInUseData->Counters.lCrlElementTotalCnt;
|
|
pCtr->dwCtlElementCurrentCnt =
|
|
(DWORD) pInUseData->Counters.lCtlElementCurrentCnt;
|
|
pCtr->dwCtlElementTotalCnt =
|
|
(DWORD) pInUseData->Counters.lCtlElementTotalCnt;
|
|
|
|
|
|
//--### Add New Counters ###--
|
|
|
|
NumInstances++;
|
|
|
|
// setup for the next instance
|
|
// Next instance starts immediately after the counters
|
|
pInstanceDef = (PERF_INSTANCE_DEFINITION *) &pCtr[1];
|
|
}
|
|
|
|
if (0 == NumInstances) {
|
|
// zero fill one instance sized block of data if there are no
|
|
// data instances
|
|
|
|
memset(pInstanceDef, 0, sizeof(PERF_INSTANCE_DEFINITION) +
|
|
CERT_PERF_MAX_PROCESS_NAME_LEN +
|
|
sizeof(CERT_PERF_COUNTERS));
|
|
|
|
// Advance past the zero'ed instance
|
|
pInstanceDef = (PERF_INSTANCE_DEFINITION *) ((PBYTE) pInstanceDef +
|
|
sizeof(PERF_INSTANCE_DEFINITION) +
|
|
CERT_PERF_MAX_PROCESS_NAME_LEN +
|
|
sizeof(CERT_PERF_COUNTERS));
|
|
}
|
|
|
|
// update arguments for return
|
|
*ppvData = (LPVOID) pInstanceDef;
|
|
*pNumObjectTypes = 1;
|
|
|
|
pDataDef->ObjectType.NumInstances = NumInstances;
|
|
pDataDef->ObjectType.TotalByteLength = *pcbTotalBytes =
|
|
(DWORD)((PBYTE) pInstanceDef - (PBYTE) pDataDef);
|
|
|
|
assert(*pcbTotalBytes <= cbNeededBytes);
|
|
|
|
|
|
CommonReturn:
|
|
if (fReleaseMutex)
|
|
ReleaseMutex(hCertPerfSharedMemoryMutex);
|
|
return dwErr;
|
|
ErrorReturn:
|
|
*pcbTotalBytes = 0;
|
|
*pNumObjectTypes = 0;
|
|
goto CommonReturn;
|
|
|
|
TRACE_ERROR(NoProcessDataError)
|
|
TRACE_ERROR(ForeignQueryNotSupported)
|
|
TRACE_ERROR(ObjectTypeQueryNotSupported)
|
|
TRACE_ERROR(WaitForMutexError)
|
|
TRACE_ERROR(InvalidProcessData)
|
|
TRACE_ERROR(MoreDataError)
|
|
}
|
|
|
|
DWORD
|
|
APIENTRY
|
|
CloseCertPerformanceData()
|
|
{
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
// Example of timing the CertGetCertificateChain API
|
|
|
|
typedef struct _CERT_PERF_CHAIN_DATA {
|
|
union {
|
|
SYSTEMTIME stBefore;
|
|
LARGE_INTEGER liBefore;
|
|
};
|
|
} CERT_PERF_CHAIN_DATA, *PCERT_PERF_CHAIN_DATA;
|
|
|
|
|
|
void
|
|
WINAPI
|
|
CertPerfGetCertificateChainBefore(
|
|
OUT PCERT_PERF_CHAIN_DATA pData
|
|
)
|
|
{
|
|
if (pCertPerfProcessData) {
|
|
if (fCertPerfHighFreq)
|
|
QueryPerformanceCounter(&pData->liBefore);
|
|
else
|
|
GetSystemTime(&pData->stBefore);
|
|
}
|
|
}
|
|
|
|
void
|
|
WINAPI
|
|
CertPerfGetCertificateChainAfter(
|
|
IN PCERT_PERF_CHAIN_DATA pData,
|
|
IN PCCERT_CHAIN_CONTEXT pChainContext
|
|
)
|
|
{
|
|
if (pCertPerfProcessData) {
|
|
if (fCertPerfHighFreq) {
|
|
LARGE_INTEGER liAfter;
|
|
_int64 i64DeltaTime;
|
|
|
|
QueryPerformanceCounter(&liAfter);
|
|
i64DeltaTime = liAfter.QuadPart - pData->liBefore.QuadPart;
|
|
|
|
EnterCriticalSection(&CertPerfProcessCriticalSection);
|
|
|
|
pCertPerfProcessData->Counters.dwChainCnt++;
|
|
pCertPerfProcessData->Counters.i64TotalChainTime =
|
|
pCertPerfProcessData->Counters.i64TotalChainTime +
|
|
i64DeltaTime;
|
|
|
|
if (0 == pCertPerfProcessData->Counters.i64MinChainTime ||
|
|
i64DeltaTime <
|
|
pCertPerfProcessData->Counters.i64MinChainTime)
|
|
pCertPerfProcessData->Counters.i64MinChainTime =
|
|
i64DeltaTime;
|
|
|
|
if (i64DeltaTime > pCertPerfProcessData->Counters.i64MaxChainTime)
|
|
pCertPerfProcessData->Counters.i64MaxChainTime =
|
|
i64DeltaTime;
|
|
|
|
LeaveCriticalSection(&CertPerfProcessCriticalSection);
|
|
} else {
|
|
SYSTEMTIME stAfter;
|
|
FILETIME ftBefore;
|
|
FILETIME ftAfter;
|
|
_int64 i64DeltaTime;
|
|
|
|
GetSystemTime(&stAfter);
|
|
SystemTimeToFileTime(&pData->stBefore, &ftBefore);
|
|
SystemTimeToFileTime(&stAfter, &ftAfter);
|
|
|
|
i64DeltaTime = *((_int64 *) &ftAfter) - *((_int64 *) &ftBefore);
|
|
|
|
EnterCriticalSection(&CertPerfProcessCriticalSection);
|
|
|
|
pCertPerfProcessData->Counters.dwChainCnt++;
|
|
pCertPerfProcessData->Counters.i64TotalChainTime =
|
|
pCertPerfProcessData->Counters.i64TotalChainTime +
|
|
i64DeltaTime;
|
|
|
|
if (0 == pCertPerfProcessData->Counters.i64MinChainTime ||
|
|
i64DeltaTime <
|
|
pCertPerfProcessData->Counters.i64MinChainTime)
|
|
pCertPerfProcessData->Counters.i64MinChainTime =
|
|
i64DeltaTime;
|
|
|
|
if (i64DeltaTime > pCertPerfProcessData->Counters.i64MaxChainTime)
|
|
pCertPerfProcessData->Counters.i64MaxChainTime =
|
|
i64DeltaTime;
|
|
|
|
LeaveCriticalSection(&CertPerfProcessCriticalSection);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif
|