From: Paul Gofman pgofman@codeweavers.com
--- dlls/crypt32/crypt32_private.h | 1 + dlls/crypt32/store.c | 60 ++++++++++++++++++++++++---------- 2 files changed, 44 insertions(+), 17 deletions(-)
diff --git a/dlls/crypt32/crypt32_private.h b/dlls/crypt32/crypt32_private.h index 9ac5b4a3067..0d0e9908df8 100644 --- a/dlls/crypt32/crypt32_private.h +++ b/dlls/crypt32/crypt32_private.h @@ -192,6 +192,7 @@ struct _context_t { struct list entry; void *ptr; } u; + struct list enum_entry; };
static inline context_t *context_from_ptr(const void *ptr) diff --git a/dlls/crypt32/store.c b/dlls/crypt32/store.c index 565368714b1..54904725124 100644 --- a/dlls/crypt32/store.c +++ b/dlls/crypt32/store.c @@ -80,9 +80,14 @@ typedef struct _WINE_MEMSTORE { WINECRYPT_CERTSTORE hdr; CRITICAL_SECTION cs; + /* Objects are deleteted from the main list upon deleting from store and from _enum lists + * upon deleting objects themselves. */ struct list certs; + struct list certs_enum; struct list crls; + struct list crls_enum; struct list ctls; + struct list ctls_enum; } WINE_MEMSTORE;
void CRYPT_InitStore(WINECRYPT_CERTSTORE *store, DWORD dwFlags, CertStoreType type, const store_vtbl_t *vtbl) @@ -140,8 +145,8 @@ BOOL WINAPI I_CertUpdateStore(HCERTSTORE store1, HCERTSTORE store2, DWORD unk0, return TRUE; }
-static BOOL MemStore_addContext(WINE_MEMSTORE *store, struct list *list, context_t *orig_context, - context_t *existing, context_t **ret_context, BOOL use_link) +static BOOL MemStore_addContext(WINE_MEMSTORE *store, struct list *list, struct list *list_enum, + context_t *orig_context, context_t *existing, context_t **ret_context, BOOL use_link) { context_t *context;
@@ -152,15 +157,16 @@ static BOOL MemStore_addContext(WINE_MEMSTORE *store, struct list *list, context TRACE("adding %p\n", context); EnterCriticalSection(&store->cs); if (existing) { - context->u.entry.prev = existing->u.entry.prev; - context->u.entry.next = existing->u.entry.next; - context->u.entry.prev->next = &context->u.entry; - context->u.entry.next->prev = &context->u.entry; + list_add_before(&existing->u.entry, &context->u.entry); + list_remove(&existing->u.entry); list_init(&existing->u.entry); + list_add_before(&existing->enum_entry, &context->enum_entry); + /* existing will be removed from enum list on deleteing context. */ if(!existing->ref) Context_Release(existing); }else { list_add_head(list, &context->u.entry); + list_add_head(list_enum, &context->enum_entry); } LeaveCriticalSection(&store->cs);
@@ -171,32 +177,49 @@ static BOOL MemStore_addContext(WINE_MEMSTORE *store, struct list *list, context return TRUE; }
-static context_t *MemStore_enumContext(WINE_MEMSTORE *store, struct list *list, context_t *prev) +static context_t *MemStore_enumContext(WINE_MEMSTORE *store, struct list *list_enum, context_t *prev) { struct list *next; context_t *ret;
EnterCriticalSection(&store->cs); if (prev) { - next = list_next(list, &prev->u.entry); + next = list_next(list_enum, &prev->enum_entry); Context_Release(prev); }else { - next = list_next(list, list); + next = list_head(list_enum); } + + while (next) + { + ret = LIST_ENTRY(next, context_t, enum_entry); + if (!list_empty(&ret->u.entry)) + break; + next = list_next(list_enum, next); + } + if (!next) + ret = NULL; LeaveCriticalSection(&store->cs);
- if (!next) { + if (!ret) { SetLastError(CRYPT_E_NOT_FOUND); return NULL; }
- ret = LIST_ENTRY(next, context_t, u.entry); Context_AddRef(ret); return ret; }
static void memstore_free_context(context_t *context) { + WINE_MEMSTORE *store = (WINE_MEMSTORE *)context->store; + + TRACE(".\n"); + + EnterCriticalSection(&store->cs); + list_remove(&context->enum_entry); + LeaveCriticalSection(&store->cs); + Context_Free(context); }
@@ -242,7 +265,7 @@ static BOOL MemStore_addCert(WINECRYPT_CERTSTORE *store, context_t *cert, WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
TRACE("(%p, %p, %p, %p)\n", store, cert, toReplace, ppStoreContext); - return MemStore_addContext(ms, &ms->certs, cert, toReplace, ppStoreContext, use_link); + return MemStore_addContext(ms, &ms->certs, &ms->certs_enum, cert, toReplace, ppStoreContext, use_link); }
static context_t *MemStore_enumCert(WINECRYPT_CERTSTORE *store, context_t *prev) @@ -251,7 +274,7 @@ static context_t *MemStore_enumCert(WINECRYPT_CERTSTORE *store, context_t *prev)
TRACE("(%p, %p)\n", store, prev);
- return MemStore_enumContext(ms, &ms->certs, prev); + return MemStore_enumContext(ms, &ms->certs_enum, prev); }
static BOOL MemStore_deleteCert(WINECRYPT_CERTSTORE *store, context_t *context) @@ -270,7 +293,7 @@ static BOOL MemStore_addCRL(WINECRYPT_CERTSTORE *store, context_t *crl,
TRACE("(%p, %p, %p, %p)\n", store, crl, toReplace, ppStoreContext);
- return MemStore_addContext(ms, &ms->crls, crl, toReplace, ppStoreContext, use_link); + return MemStore_addContext(ms, &ms->crls, &ms->crls_enum, crl, toReplace, ppStoreContext, use_link); }
static context_t *MemStore_enumCRL(WINECRYPT_CERTSTORE *store, context_t *prev) @@ -279,7 +302,7 @@ static context_t *MemStore_enumCRL(WINECRYPT_CERTSTORE *store, context_t *prev)
TRACE("(%p, %p)\n", store, prev);
- return MemStore_enumContext(ms, &ms->crls, prev); + return MemStore_enumContext(ms, &ms->crls_enum, prev); }
static BOOL MemStore_deleteCRL(WINECRYPT_CERTSTORE *store, context_t *context) @@ -298,7 +321,7 @@ static BOOL MemStore_addCTL(WINECRYPT_CERTSTORE *store, context_t *ctl,
TRACE("(%p, %p, %p, %p)\n", store, ctl, toReplace, ppStoreContext);
- return MemStore_addContext(ms, &ms->ctls, ctl, toReplace, ppStoreContext, use_link); + return MemStore_addContext(ms, &ms->ctls, &ms->ctls_enum, ctl, toReplace, ppStoreContext, use_link); }
static context_t *MemStore_enumCTL(WINECRYPT_CERTSTORE *store, context_t *prev) @@ -307,7 +330,7 @@ static context_t *MemStore_enumCTL(WINECRYPT_CERTSTORE *store, context_t *prev)
TRACE("(%p, %p)\n", store, prev);
- return MemStore_enumContext(ms, &ms->ctls, prev); + return MemStore_enumContext(ms, &ms->ctls_enum, prev); }
static BOOL MemStore_deleteCTL(WINECRYPT_CERTSTORE *store, context_t *context) @@ -396,8 +419,11 @@ static WINECRYPT_CERTSTORE *CRYPT_MemOpenStore(HCRYPTPROV hCryptProv, InitializeCriticalSectionEx(&store->cs, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO); store->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ContextList.cs"); list_init(&store->certs); + list_init(&store->certs_enum); list_init(&store->crls); + list_init(&store->crls_enum); list_init(&store->ctls); + list_init(&store->ctls_enum); /* Mem store doesn't need crypto provider, so close it */ if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG)) CryptReleaseContext(hCryptProv, 0);