Module: wine Branch: master Commit: 976c6ff3f8fd679b70f3a92e3fa71c58256ec28f URL: http://source.winehq.org/git/wine.git/?a=commit;h=976c6ff3f8fd679b70f3a92e3f...
Author: Juan Lang juan.lang@gmail.com Date: Tue Nov 3 17:04:32 2009 -0800
crypt32: Correct reference counting when deleting contexts from collections.
---
dlls/crypt32/collectionstore.c | 34 ++++++++++++++++++++++++++++------ dlls/crypt32/tests/store.c | 22 ++++++++++++++++++++++ 2 files changed, 50 insertions(+), 6 deletions(-)
diff --git a/dlls/crypt32/collectionstore.c b/dlls/crypt32/collectionstore.c index 12eb7c3..e55c1bf 100644 --- a/dlls/crypt32/collectionstore.c +++ b/dlls/crypt32/collectionstore.c @@ -255,11 +255,19 @@ static BOOL CRYPT_CollectionDeleteCert(PWINECRYPT_CERTSTORE store, void *pCertContext) { BOOL ret; + PCCERT_CONTEXT linked;
TRACE("(%p, %p)\n", store, pCertContext);
- ret = CertDeleteCertificateFromStore( - Context_GetLinkedContext(pCertContext, sizeof(CERT_CONTEXT))); + /* Deleting the linked context results in its ref count getting + * decreased, but the caller of this (CertDeleteCertificateFromStore) also + * decreases pCertContext's ref count, by calling + * CertFreeCertificateContext. Increase ref count of linked context to + * compensate. + */ + linked = Context_GetLinkedContext(pCertContext, sizeof(CERT_CONTEXT)); + CertDuplicateCertificateContext(linked); + ret = CertDeleteCertificateFromStore(linked); return ret; }
@@ -333,11 +341,18 @@ static BOOL CRYPT_CollectionDeleteCRL(PWINECRYPT_CERTSTORE store, void *pCrlContext) { BOOL ret; + PCCRL_CONTEXT linked;
TRACE("(%p, %p)\n", store, pCrlContext);
- ret = CertDeleteCRLFromStore( - Context_GetLinkedContext(pCrlContext, sizeof(CRL_CONTEXT))); + /* Deleting the linked context results in its ref count getting + * decreased, but the caller of this (CertDeleteCRLFromStore) also + * decreases pCrlContext's ref count, by calling CertFreeCRLContext. + * Increase ref count of linked context to compensate. + */ + linked = Context_GetLinkedContext(pCrlContext, sizeof(CRL_CONTEXT)); + CertDuplicateCRLContext(linked); + ret = CertDeleteCRLFromStore(linked); return ret; }
@@ -411,11 +426,18 @@ static BOOL CRYPT_CollectionDeleteCTL(PWINECRYPT_CERTSTORE store, void *pCtlContext) { BOOL ret; + PCCTL_CONTEXT linked;
TRACE("(%p, %p)\n", store, pCtlContext);
- ret = CertDeleteCTLFromStore( - Context_GetLinkedContext(pCtlContext, sizeof(CTL_CONTEXT))); + /* Deleting the linked context results in its ref count getting + * decreased, but the caller of this (CertDeleteCTLFromStore) also + * decreases pCtlContext's ref count, by calling CertFreeCTLContext. + * Increase ref count of linked context to compensate. + */ + linked = Context_GetLinkedContext(pCtlContext, sizeof(CTL_CONTEXT)); + CertDuplicateCTLContext(linked); + ret = CertDeleteCTLFromStore(linked); return ret; }
diff --git a/dlls/crypt32/tests/store.c b/dlls/crypt32/tests/store.c index 88f53ed..1f6609c 100644 --- a/dlls/crypt32/tests/store.c +++ b/dlls/crypt32/tests/store.c @@ -574,6 +574,28 @@ static void testCollectionStore(void) CertCloseStore(collection, 0); CertCloseStore(store2, 0); CertCloseStore(store1, 0); + + /* Test adding certificates to and deleting certificates from collections. + */ + store1 = CertOpenSystemStoreA(0, "My"); + collection = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0, + CERT_STORE_CREATE_NEW_FLAG, NULL); + + ret = CertAddEncodedCertificateToStore(store1, X509_ASN_ENCODING, + bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &context); + ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError()); + CertDeleteCertificateFromStore(context); + + CertAddStoreToCollection(collection, store1, + CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0); + + ret = CertAddEncodedCertificateToStore(collection, X509_ASN_ENCODING, + bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &context); + ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError()); + CertDeleteCertificateFromStore(context); + + CertCloseStore(collection, 0); + CertCloseStore(store1, 0); }
/* Looks for the property with ID propID in the buffer buf. Returns a pointer