Постоянно увеличивает физическую память Visual C ++ CertGetCertificateChain - PullRequest
2 голосов
/ 18 августа 2011

Я использую C ++ и Visual Studio 2005.

Я не знаю почему, я пытался изменить порядок кода, но это кажется странным.Физическая память увеличивается при запуске простого проекта.

//has to include crypt32.lib in links
#include <windows.h>

void memoryUP2( PCCERT_CONTEXT __pCert )
{
    PCCERT_CHAIN_CONTEXT     _pChainContext     = NULL;
    CERT_ENHKEY_USAGE        _EnhkeyUsage;
    CERT_USAGE_MATCH         _CertUsage;  
    CERT_CHAIN_PARA          _ChainPara;
    DWORD                    _dwFlags           = CERT_CHAIN_RETURN_LOWER_QUALITY_CONTEXTS; //0;

    _EnhkeyUsage.cUsageIdentifier = 0;
    _EnhkeyUsage.rgpszUsageIdentifier=NULL;
    _CertUsage.dwType = USAGE_MATCH_TYPE_AND;
    _CertUsage.Usage  = _EnhkeyUsage;
    _ChainPara.cbSize = sizeof(CERT_CHAIN_PARA);
    _ChainPara.RequestedUsage=_CertUsage;

    {
        if(!CertGetCertificateChain(
            NULL,                  // default engine
            __pCert,   // certificate ctx
            NULL,                  // time
            NULL,                  // default store
            &_ChainPara,            // use AND logic and enhanced key usage 
                                    //  as indicated in the ChainPara 
                                    //  data structure
            _dwFlags,
            NULL,                  // currently reserved
            &_pChainContext))       // return a pointer to the chain created
        {
            //Error... Do nothing
        }
    }

    if (_pChainContext != NULL)
    {
        CertFreeCertificateChain(_pChainContext);
    }
}

Используя это, «память не увеличивается»:

int main(int argc, char** argv)
{
    MyFile myfile = myReadFile("c:\\certificate.cer");

    for(int i=0;i<550000;++i)
    {

        PCCERT_CONTEXT certCtx = CertCreateCertificateContext( (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING),
                                                                      (const BYTE *)myfile._data, 
                                                                      myfile._length);

        if(certCtx!=NULL)
            CertFreeCertificateContext(certCtx);
    }

    return 0;
}

Используя это, «память постоянно увеличивается»:

int main(int argc, char** argv)
{
    MyFile myfile = myReadFile("c:\\certificate.cer");

    for(int i=0;i<80000;++i)
    {

        PCCERT_CONTEXT certCtx = CertCreateCertificateContext( (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING),
                                                                      (const BYTE *)myfile._data, 
                                                                      myfile._length);
        memoryUP2(certCtx);

        if(certCtx!=NULL)
            CertFreeCertificateContext(certCtx);
    }

    return 0;
}

Использованиеэто, «память не увеличивается»:

int main(int argc, char** argv)
{
    MyFile myfile = myReadFile("c:\\certificate.cer");

    PCCERT_CONTEXT certCtx = CertCreateCertificateContext( (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING),
                                                                      (const BYTE *)myfile._data, 
                                                                      myfile._length);
    for(int i=0;i<80000;++i)
    {
        memoryUP2(certCtx);
    }

    if(certCtx!=NULL)
            CertFreeCertificateContext(certCtx);

    return 0;
}

Используя это, «память постоянно увеличивается»:

int main(int argc, char** argv)
{
    MyFile myfile = myReadFile("c:\\certificate.cer");

    for(int j=0;j<5000;j++)
    {
        PCCERT_CONTEXT certCtx = CertCreateCertificateContext( (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING),
                                                                          (const BYTE *)myfile._data, 
                                                                          myfile._length);
        for(int i=0;i<50;++i)
        {
            memoryUP2(certCtx);
        }

        if(certCtx!=NULL)
                CertFreeCertificateContext(certCtx);
    }

    return 0;
}

Как я могу использовать это без утечки памяти?

for(int i=0;i<80000;++i)
{

    PCCERT_CONTEXT certCtx = CertCreateCertificateContext( (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING),
                                                                  (const BYTE *)myfile._data, 
                                                                  myfile._length);
    memoryUP2(certCtx);

    if(certCtx!=NULL)
        CertFreeCertificateContext(certCtx);
}

Почему это происходит?

Обновление # 1

Я думаю, что это связано с CertCreateCertificateChainEngine, глядя на MSDN Создание цепочки сертификатов

Я изменяю код на:

void memoryUP2( PCCERT_CONTEXT __pCert )
{
    PCCERT_CHAIN_CONTEXT     _pChainContext     = NULL;
    CERT_ENHKEY_USAGE        _EnhkeyUsage;
    CERT_USAGE_MATCH         _CertUsage;  
    CERT_CHAIN_PARA          _ChainPara;
    DWORD                    _dwFlags           = CERT_CHAIN_RETURN_LOWER_QUALITY_CONTEXTS; //0;

    HCERTCHAINENGINE         hChainEngine;
    CERT_CHAIN_ENGINE_CONFIG ChainConfig;

    ChainConfig.cbSize = sizeof(CERT_CHAIN_ENGINE_CONFIG);
    ChainConfig.hRestrictedRoot= NULL ;
    ChainConfig.hRestrictedTrust= NULL ;
    ChainConfig.hRestrictedOther= NULL ;
    ChainConfig.cAdditionalStore=0 ;
    ChainConfig.rghAdditionalStore = NULL ;
    ChainConfig.dwFlags = CERT_CHAIN_CACHE_END_CERT;
    ChainConfig.dwUrlRetrievalTimeout= 0 ;
    ChainConfig.MaximumCachedCertificates=0 ;
    ChainConfig.CycleDetectionModulus = 0;

    CertCreateCertificateChainEngine(
         &ChainConfig,
         &hChainEngine);

    _EnhkeyUsage.cUsageIdentifier = 0;
    _EnhkeyUsage.rgpszUsageIdentifier=NULL;
    _CertUsage.dwType = USAGE_MATCH_TYPE_AND;
    _CertUsage.Usage  = _EnhkeyUsage;
    _ChainPara.cbSize = sizeof(CERT_CHAIN_PARA);
    _ChainPara.RequestedUsage=_CertUsage;

    {
        if(!CertGetCertificateChain(
            NULL,                  // default engine
            __pCert,   // certificate ctx
            NULL,                  // time
            NULL,                  // default store
            &_ChainPara,            // use AND logic and enhanced key usage 
                                    //  as indicated in the ChainPara 
                                    //  data structure
            _dwFlags,
            NULL,                  // currently reserved
            &_pChainContext))       // return a pointer to the chain created
        {
            //Error... Do nothing
        }
    }

    if (_pChainContext != NULL)
    {
        CertFreeCertificateChain(_pChainContext);
        _pChainContext = NULL;
    }

    CertFreeCertificateChainEngine(hChainEngine);
}

Память "Не увеличивается" Только "очень мало".

Почему двигатель по умолчанию вызывает утечку памяти?
Зачем объявлять движок и использовать параметр CertGetCertificateChain (NULL, ...)?

...