From 2256a728fec06bf1585fbf1e39da49cb6e4710e0 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Mon, 14 Oct 2013 14:45:43 +0200 Subject: [PATCH] crypt32: Moved store release implementation to vtbl. --- dlls/crypt32/collectionstore.c | 19 +++++++++++++------ dlls/crypt32/crypt32_private.h | 2 +- dlls/crypt32/provstore.c | 21 +++++++++++++++------ dlls/crypt32/store.c | 34 +++++++++++++++++++--------------- 4 files changed, 48 insertions(+), 28 deletions(-) diff --git a/dlls/crypt32/collectionstore.c b/dlls/crypt32/collectionstore.c index 2278c4d46ee..b64f0890b19 100644 --- a/dlls/crypt32/collectionstore.c +++ b/dlls/crypt32/collectionstore.c @@ -46,23 +46,30 @@ static void Collection_addref(WINECRYPT_CERTSTORE *store) TRACE("ref = %d\n", ref); } -static void Collection_closeStore(WINECRYPT_CERTSTORE *store, DWORD dwFlags) +static DWORD Collection_release(WINECRYPT_CERTSTORE *store, DWORD flags) { WINE_COLLECTIONSTORE *cs = (WINE_COLLECTIONSTORE*)store; WINE_STORE_LIST_ENTRY *entry, *next; + LONG ref; - TRACE("(%p, %08x)\n", store, dwFlags); + if(flags) + FIXME("Unimplemented flags %x\n", flags); - LIST_FOR_EACH_ENTRY_SAFE(entry, next, &cs->stores, WINE_STORE_LIST_ENTRY, - entry) + ref = InterlockedDecrement(&cs->hdr.ref); + TRACE("(%p) ref=%d\n", store, ref); + if(ref) + return ERROR_SUCCESS; + + LIST_FOR_EACH_ENTRY_SAFE(entry, next, &cs->stores, WINE_STORE_LIST_ENTRY, entry) { TRACE("closing %p\n", entry); - CertCloseStore(entry->store, dwFlags); + entry->store->vtbl->release(entry->store, flags); CryptMemFree(entry); } cs->cs.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&cs->cs); CRYPT_FreeStore(store); + return ERROR_SUCCESS; } static void *CRYPT_CollectionCreateContextFromChild(WINE_COLLECTIONSTORE *store, @@ -484,7 +491,7 @@ static BOOL Collection_control(WINECRYPT_CERTSTORE *cert_store, DWORD dwFlags, static const store_vtbl_t CollectionStoreVtbl = { Collection_addref, - Collection_closeStore, + Collection_release, Collection_control }; diff --git a/dlls/crypt32/crypt32_private.h b/dlls/crypt32/crypt32_private.h index c939c5df8cd..235db904943 100644 --- a/dlls/crypt32/crypt32_private.h +++ b/dlls/crypt32/crypt32_private.h @@ -247,7 +247,7 @@ typedef struct _CONTEXT_PROPERTY_LIST CONTEXT_PROPERTY_LIST; typedef struct { void (*addref)(struct WINE_CRYPTCERTSTORE*); - void (*closeStore)(struct WINE_CRYPTCERTSTORE*,DWORD); + DWORD (*release)(struct WINE_CRYPTCERTSTORE*,DWORD); BOOL (*control)(struct WINE_CRYPTCERTSTORE*,DWORD,DWORD,void const*); } store_vtbl_t; diff --git a/dlls/crypt32/provstore.c b/dlls/crypt32/provstore.c index 06cfbc8f2c0..52f6a0b0fca 100644 --- a/dlls/crypt32/provstore.c +++ b/dlls/crypt32/provstore.c @@ -47,17 +47,26 @@ static void ProvStore_addref(WINECRYPT_CERTSTORE *store) TRACE("ref = %d\n", ref); } -static void ProvStore_closeStore(WINECRYPT_CERTSTORE *cert_store, DWORD dwFlags) +static DWORD ProvStore_release(WINECRYPT_CERTSTORE *cert_store, DWORD flags) { WINE_PROVIDERSTORE *store = (WINE_PROVIDERSTORE*)cert_store; + LONG ref; - TRACE("(%p, %08x)\n", store, dwFlags); + if(flags) + FIXME("Unimplemented flags %x\n", flags); + + ref = InterlockedDecrement(&store->hdr.ref); + TRACE("(%p) ref=%d\n", store, ref); + + if(ref) + return ERROR_SUCCESS; if (store->provCloseStore) - store->provCloseStore(store->hStoreProv, dwFlags); + store->provCloseStore(store->hStoreProv, flags); if (!(store->dwStoreProvFlags & CERT_STORE_PROV_EXTERNAL_FLAG)) - CertCloseStore(store->memStore, dwFlags); - CRYPT_FreeStore((WINECRYPT_CERTSTORE*)store); + store->memStore->vtbl->release(store->memStore, flags); + CRYPT_FreeStore(&store->hdr); + return ERROR_SUCCESS; } static BOOL CRYPT_ProvAddCert(WINECRYPT_CERTSTORE *store, void *cert, @@ -269,7 +278,7 @@ static BOOL ProvStore_control(WINECRYPT_CERTSTORE *cert_store, DWORD dwFlags, DW static const store_vtbl_t ProvStoreVtbl = { ProvStore_addref, - ProvStore_closeStore, + ProvStore_release, ProvStore_control }; diff --git a/dlls/crypt32/store.c b/dlls/crypt32/store.c index 96230944484..a584ec27413 100644 --- a/dlls/crypt32/store.c +++ b/dlls/crypt32/store.c @@ -108,6 +108,7 @@ void CRYPT_FreeStore(WINECRYPT_CERTSTORE *store) { if (store->properties) ContextPropertyList_Free(store->properties); + store->dwMagic = 0; CryptMemFree(store); } @@ -290,18 +291,24 @@ static void MemStore_addref(WINECRYPT_CERTSTORE *store) TRACE("ref = %d\n", ref); } -static void MemStore_closeStore(WINECRYPT_CERTSTORE *cert_store, DWORD dwFlags) +static DWORD MemStore_release(WINECRYPT_CERTSTORE *cert_store, DWORD flags) { WINE_MEMSTORE *store = (WINE_MEMSTORE*)cert_store; + LONG ref; - TRACE("(%p, %08x)\n", store, dwFlags); - if (dwFlags) - FIXME("Unimplemented flags: %08x\n", dwFlags); + if(flags) + FIXME("Unimplemented flags %x\n", flags); + + ref = InterlockedDecrement(&store->hdr.ref); + TRACE("(%p) ref=%d\n", store, ref); + if(ref) + return ERROR_SUCCESS; ContextList_Free(store->certs); ContextList_Free(store->crls); ContextList_Free(store->ctls); - CRYPT_FreeStore((WINECRYPT_CERTSTORE*)store); + CRYPT_FreeStore(&store->hdr); + return ERROR_SUCCESS; } static BOOL MemStore_control(WINECRYPT_CERTSTORE *store, DWORD dwFlags, @@ -313,7 +320,7 @@ static BOOL MemStore_control(WINECRYPT_CERTSTORE *store, DWORD dwFlags, static const store_vtbl_t MemStoreVtbl = { MemStore_addref, - MemStore_closeStore, + MemStore_release, MemStore_control }; @@ -1227,6 +1234,7 @@ HCERTSTORE WINAPI CertDuplicateStore(HCERTSTORE hCertStore) BOOL WINAPI CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags) { WINECRYPT_CERTSTORE *hcs = hCertStore; + DWORD res; TRACE("(%p, %08x)\n", hCertStore, dwFlags); @@ -1236,16 +1244,12 @@ BOOL WINAPI CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags) if ( hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC ) return FALSE; - if (hcs->ref <= 0) - ERR("%p's ref count is %d\n", hcs, hcs->ref); - if (InterlockedDecrement(&hcs->ref) == 0) - { - TRACE("%p's ref count is 0, freeing\n", hcs); - hcs->dwMagic = 0; - hcs->vtbl->closeStore(hcs, dwFlags); + res = hcs->vtbl->release(hcs, dwFlags); + if (res != ERROR_SUCCESS) { + SetLastError(res); + return FALSE; } - else - TRACE("%p's ref count is %d\n", hcs, hcs->ref); + return TRUE; }