CryptAcquireCertificatePrivateKey得到的hCryptProv到底要不要释放?
Tommy 2006-04-13 05:31:08 BOOL WINAPI CryptAcquireCertificatePrivateKey(
PCCERT_CONTEXT pCert,
DWORD dwFlags,
void* pvReserved,
HCRYPTPROV* phCryptProv,
DWORD* pdwKeySpec,
BOOL* pfCallerFreeProv
);
在MSDN中说明了如果×pfCallerFreeProv是TRUE,就要调用CryptReleaseContext()释放hCryptProv,但是我看MSDN中的例子Example C Program: Sending and Receiving a Signed and Encrypted Message是不释放的,而我试了,如果释放的话,会出现“capi2.exe 中的 0x02ff2215 处最可能的异常: 0xC0000005: 读取位置 0xfeeeff06 时发生访问冲突”的错。
如果使用CRYPT_ACQUIRE_CACHE_FLAG标志,则fCallerFreeProv=FALSE,不用释放,但是在调用CertCloseStore时同样会出一样的错。
HCERTSTORE hCertStore = NULL;
if(!(hCertStore=CertOpenStore(CERT_STORE_PROV_SYSTEM,0,NULL,CERT_SYSTEM_STORE_CURRENT_USER ,L"MY")))
{
// printf("open system store failed(errno=%x)\n",GetLastError());
return;
}
PCCERT_CONTEXT pCertContext = NULL;
HCRYPTPROV hProv;
DWORD dwKeySpec=AT_KEYEXCHANGE;
BOOL fCallerFreeProv;
while(pCertContext=CertEnumCertificatesInStore(hCertStore,pCertContext))
{
char subject[256];
if(CertGetNameString(
pCertContext,
CERT_NAME_SIMPLE_DISPLAY_TYPE,
0,
NULL,
subject,
sizeof(subject)))
{
printf("subject: %s\n", subject);
}
if(!CryptAcquireCertificatePrivateKey(pCertContext,CRYPT_ACQUIRE_CACHE_FLAG,0,&hProv,&dwKeySpec,&fCallerFreeProv))
{
printf("CryptAcquireCertificatePrivateKey failed(err=%x)",GetLastError());
continue;
}
std::vector<BYTE> provider;
if (!GetProvParam(hProv, PP_NAME, provider))
{
//printf("get provider name failed(err=%x)\n", err);
if(fCallerFreeProv)
CryptReleaseContext(hProv,0);
continue;
}
printf("Provider: %s\n", &provider[0]);
if(!providerName.empty())
{
if(strncmp(providerName.c_str(), (const char *)&provider[0], provider.size())!=0)
{
if(fCallerFreeProv)
CryptReleaseContext(hProv,0);
continue;
}
}
if(fCallerFreeProv)
CryptReleaseContext(hProv,0);
break;
}
if(pCertContext)
CertFreeCertificateContext(pCertContext);
if(hCertStore)
CertCloseStore(hCertStore, CERT_CLOSE_STORE_CHECK_FLAG);