05.09.2006 9:02:08Трабл с CertFindCertificateInStore Ответов: 0
Андрей Горячев
Есть некий код на Visual C++ (VS 2005) по выбору сертификатов:

// Это CAPICOM, для того чтобы вызвать окно с выбором сертификата
IStorePtr pIStore(__uuidof(Store));
ICertificates2Ptr pICertificates(__uuidof(Certificates));
ICertificate2Ptr pICertificate(__uuidof(Certificate));
IUtilitiesPtr utilites(__uuidof(Utilities));

pIStore->Open(CAPICOM_CURRENT_USER_STORE, this->certStoreName, CAPICOM_STORE_OPEN_READ_ONLY);
pICertificates = pIStore->Certificates;
pICertificates = pICertificates->Find(CAPICOM_CERTIFICATE_FIND_TIME_VALID, NULL, true);

// кстати, можно ли такое же сделать в CryptoAPI?
pICertificates = pICertificates->Select("", "", false);
pICertificate = pICertificates->GetItem(1);

BYTE bytes[20];
CRYPT_HASH_BLOB blob;
blob.cbData = 20;
blob.pbData = bytes;

this->BStrToByte(pICertificate->Thumbprint.GetBSTR(), &blob);

if (!(this->curentCert = CertFindCertificateInStore(this->hCertStore, this->encodingType, 0, CERT_FIND_HASH, &blob, NULL)))
{
this->setLastError();
return false;
}

и функция

void BStrToByte(BSTR bstr, CRYPT_HASH_BLOB* blob)
{
int b;
int i;
char c1, c2;
char str[41];

for (int i = 0; i < 40; i++)
{
str[i] = (char)bstr[i];
}

str[40] = '\0';

if (blob->cbData == strlen(str) / 2)
{
for (i = 0; i < strlen(str); i += 2)
{
c1 = str[i];
c2 = str[i + 1];

if(c1 <= '9')
{
b = 16 * atoi(&c1);
}
else
{
b = 16 * (10 + (int)c1 - 'A');
}

if(c2 <= '9')
{
b += atoi(&c2);
}
else
{
b += 10 + (int)c2 - 'A';
}

blob->pbData[int(i/2)] = b;
}
}
else
{
return;
}
}

Здесь всё отлично работает.
Трабл в следующем, пишу на .NET C#, там экспортирую .dll на C++ которая скомпилирована при помощи cl.exe /LD
функция выглядит следующим образом в cpp:

extern "C" bool __declspec(dllexport) SelectCert()
{
CoInitialize(0);

IStorePtr pIStore(__uuidof(Store));
ICertificates2Ptr pICertificates(__uuidof(Certificates));
ICertificate2Ptr pICertificate(__uuidof(Certificate));
IUtilitiesPtr utilites(__uuidof(Utilities));

pIStore->Open(CAPICOM_CURRENT_USER_STORE, certStoreName, CAPICOM_STORE_OPEN_READ_ONLY);
pICertificates = pIStore->Certificates;
pICertificates = pICertificates->Find(CAPICOM_CERTIFICATE_FIND_TIME_VALID, NULL, true);
pICertificates = pICertificates->Select("", "", false);
pICertificate = pICertificates->GetItem(1);

BYTE bytes[20];
CRYPT_HASH_BLOB blob;
blob.cbData = 20;
blob.pbData = bytes;

BStrToByte(pICertificate->Thumbprint.GetBSTR(), &blob);

if (!(curentCert = CertFindCertificateInStore(hCertStore, MY_ENCODING_TYPE, 0, CERT_FIND_HASH, &blob, NULL)))
{
setLastError();
return false;
}

return true;
}

то же самое, но при этом говорит что ничего не найдено. Ошибка "Объект или свойство не найдено.".
В чём может быть причина?