crypt32(8/11): Move collection stores to a separate file
Juan Lang
juan.lang at gmail.com
Thu Aug 16 13:03:36 CDT 2007
--Juan
-------------- next part --------------
From a7054228af7a932eaba19fadc7b511ebca522925 Mon Sep 17 00:00:00 2001
From: Juan Lang <juan.lang at gmail.com>
Date: Thu, 16 Aug 2007 10:49:33 -0700
Subject: [PATCH] Move collection stores to a separate file
---
dlls/crypt32/Makefile.in | 1
dlls/crypt32/collectionstore.c | 481 ++++++++++++++++++++++++++++++++++++++++
dlls/crypt32/crypt32_private.h | 7 +
dlls/crypt32/store.c | 459 --------------------------------------
4 files changed, 491 insertions(+), 457 deletions(-)
diff --git a/dlls/crypt32/Makefile.in b/dlls/crypt32/Makefile.in
index e065c40..9fd2939 100644
--- a/dlls/crypt32/Makefile.in
+++ b/dlls/crypt32/Makefile.in
@@ -11,6 +11,7 @@ C_SRCS = \
base64.c \
cert.c \
chain.c \
+ collectionstore.c \
crl.c \
context.c \
decode.c \
diff --git a/dlls/crypt32/collectionstore.c b/dlls/crypt32/collectionstore.c
new file mode 100644
index 0000000..e412337
--- /dev/null
+++ b/dlls/crypt32/collectionstore.c
@@ -0,0 +1,481 @@
+/*
+ * Copyright 2004-2007 Juan Lang
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#include <stdarg.h>
+#include "windef.h"
+#include "winbase.h"
+#include "wincrypt.h"
+#include "wine/debug.h"
+#include "wine/list.h"
+#include "crypt32_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(crypt);
+
+typedef struct _WINE_STORE_LIST_ENTRY
+{
+ PWINECRYPT_CERTSTORE store;
+ DWORD dwUpdateFlags;
+ DWORD dwPriority;
+ struct list entry;
+} WINE_STORE_LIST_ENTRY, *PWINE_STORE_LIST_ENTRY;
+
+typedef struct _WINE_COLLECTIONSTORE
+{
+ WINECRYPT_CERTSTORE hdr;
+ CRITICAL_SECTION cs;
+ struct list stores;
+} WINE_COLLECTIONSTORE, *PWINE_COLLECTIONSTORE;
+
+static void WINAPI CRYPT_CollectionCloseStore(HCERTSTORE store, DWORD dwFlags)
+{
+ PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
+ PWINE_STORE_LIST_ENTRY entry, next;
+
+ TRACE("(%p, %08x)\n", store, dwFlags);
+
+ LIST_FOR_EACH_ENTRY_SAFE(entry, next, &cs->stores, WINE_STORE_LIST_ENTRY,
+ entry)
+ {
+ TRACE("closing %p\n", entry);
+ CertCloseStore((HCERTSTORE)entry->store, dwFlags);
+ CryptMemFree(entry);
+ }
+ cs->cs.DebugInfo->Spare[0] = 0;
+ DeleteCriticalSection(&cs->cs);
+ CRYPT_FreeStore((PWINECRYPT_CERTSTORE)store);
+}
+
+static void *CRYPT_CollectionCreateContextFromChild(PWINE_COLLECTIONSTORE store,
+ PWINE_STORE_LIST_ENTRY storeEntry, void *child, size_t contextSize,
+ BOOL addRef)
+{
+ void *ret = Context_CreateLinkContext(contextSize, child,
+ sizeof(PWINE_STORE_LIST_ENTRY), addRef);
+
+ if (ret)
+ *(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(ret, contextSize)
+ = storeEntry;
+
+ return ret;
+}
+
+static BOOL CRYPT_CollectionAddContext(PWINE_COLLECTIONSTORE store,
+ unsigned int contextFuncsOffset, void *context, void *toReplace, unsigned int contextSize,
+ void **pChildContext)
+{
+ BOOL ret;
+ void *childContext = NULL;
+ PWINE_STORE_LIST_ENTRY storeEntry = NULL;
+
+ TRACE("(%p, %d, %p, %p, %d)\n", store, contextFuncsOffset, context,
+ toReplace, contextSize);
+
+ ret = FALSE;
+ if (toReplace)
+ {
+ void *existingLinked = Context_GetLinkedContext(toReplace, contextSize);
+ PCONTEXT_FUNCS contextFuncs;
+
+ storeEntry = *(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(toReplace,
+ contextSize);
+ contextFuncs = (PCONTEXT_FUNCS)((LPBYTE)storeEntry->store +
+ contextFuncsOffset);
+ ret = contextFuncs->addContext(storeEntry->store, context,
+ existingLinked, childContext);
+ }
+ else
+ {
+ PWINE_STORE_LIST_ENTRY entry, next;
+
+ EnterCriticalSection(&store->cs);
+ LIST_FOR_EACH_ENTRY_SAFE(entry, next, &store->stores,
+ WINE_STORE_LIST_ENTRY, entry)
+ {
+ if (entry->dwUpdateFlags & CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG)
+ {
+ PCONTEXT_FUNCS contextFuncs = (PCONTEXT_FUNCS)(
+ (LPBYTE)entry->store + contextFuncsOffset);
+
+ storeEntry = entry;
+ ret = contextFuncs->addContext(entry->store, context, NULL,
+ (const void **)&childContext);
+ break;
+ }
+ }
+ LeaveCriticalSection(&store->cs);
+ if (!storeEntry)
+ SetLastError(E_ACCESSDENIED);
+ }
+ *pChildContext = childContext;
+ return ret;
+}
+
+/* Advances a collection enumeration by one context, if possible, where
+ * advancing means:
+ * - calling the current store's enumeration function once, and returning
+ * the enumerated context if one is returned
+ * - moving to the next store if the current store has no more items, and
+ * recursively calling itself to get the next item.
+ * Returns NULL if the collection contains no more items or on error.
+ * Assumes the collection store's lock is held.
+ */
+static void *CRYPT_CollectionAdvanceEnum(PWINE_COLLECTIONSTORE store,
+ PWINE_STORE_LIST_ENTRY storeEntry, PCONTEXT_FUNCS contextFuncs,
+ PCWINE_CONTEXT_INTERFACE contextInterface, void *pPrev, size_t contextSize)
+{
+ void *ret, *child;
+ struct list *storeNext = list_next(&store->stores, &storeEntry->entry);
+
+ TRACE("(%p, %p, %p)\n", store, storeEntry, pPrev);
+
+ if (pPrev)
+ {
+ /* Ref-counting funny business: "duplicate" (addref) the child, because
+ * the free(pPrev) below can cause the ref count to become negative.
+ */
+ child = Context_GetLinkedContext(pPrev, contextSize);
+ contextInterface->duplicate(child);
+ child = contextFuncs->enumContext(storeEntry->store, child);
+ contextInterface->free(pPrev);
+ pPrev = NULL;
+ }
+ else
+ child = contextFuncs->enumContext(storeEntry->store, NULL);
+ if (child)
+ ret = CRYPT_CollectionCreateContextFromChild(store, storeEntry, child,
+ contextSize, FALSE);
+ else
+ {
+ if (storeNext)
+ {
+ /* We always want the same function pointers (from certs, crls)
+ * in the next store, so use the same offset into the next store.
+ */
+ size_t offset = (LPBYTE)contextFuncs - (LPBYTE)storeEntry->store;
+ PWINE_STORE_LIST_ENTRY storeNextEntry =
+ LIST_ENTRY(storeNext, WINE_STORE_LIST_ENTRY, entry);
+ PCONTEXT_FUNCS storeNextContexts =
+ (PCONTEXT_FUNCS)((LPBYTE)storeNextEntry->store + offset);
+
+ ret = CRYPT_CollectionAdvanceEnum(store, storeNextEntry,
+ storeNextContexts, contextInterface, NULL, contextSize);
+ }
+ else
+ {
+ SetLastError(CRYPT_E_NOT_FOUND);
+ ret = NULL;
+ }
+ }
+ TRACE("returning %p\n", ret);
+ return ret;
+}
+
+static BOOL CRYPT_CollectionAddCert(PWINECRYPT_CERTSTORE store, void *cert,
+ void *toReplace, const void **ppStoreContext)
+{
+ BOOL ret;
+ void *childContext = NULL;
+ PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
+
+ ret = CRYPT_CollectionAddContext(cs, offsetof(WINECRYPT_CERTSTORE, certs),
+ cert, toReplace, sizeof(CERT_CONTEXT), &childContext);
+ if (ppStoreContext && childContext)
+ {
+ PWINE_STORE_LIST_ENTRY storeEntry = *(PWINE_STORE_LIST_ENTRY *)
+ Context_GetExtra(childContext, sizeof(CERT_CONTEXT));
+ PCERT_CONTEXT context =
+ CRYPT_CollectionCreateContextFromChild(cs, storeEntry, childContext,
+ sizeof(CERT_CONTEXT), TRUE);
+
+ if (context)
+ context->hCertStore = store;
+ *ppStoreContext = context;
+ }
+ CertFreeCertificateContext((PCCERT_CONTEXT)childContext);
+ return ret;
+}
+
+static void *CRYPT_CollectionEnumCert(PWINECRYPT_CERTSTORE store, void *pPrev)
+{
+ PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
+ void *ret;
+
+ TRACE("(%p, %p)\n", store, pPrev);
+
+ EnterCriticalSection(&cs->cs);
+ if (pPrev)
+ {
+ PWINE_STORE_LIST_ENTRY storeEntry =
+ *(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(pPrev,
+ sizeof(CERT_CONTEXT));
+
+ ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
+ &storeEntry->store->certs, pCertInterface, pPrev,
+ sizeof(CERT_CONTEXT));
+ }
+ else
+ {
+ if (!list_empty(&cs->stores))
+ {
+ PWINE_STORE_LIST_ENTRY storeEntry = LIST_ENTRY(cs->stores.next,
+ WINE_STORE_LIST_ENTRY, entry);
+
+ ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
+ &storeEntry->store->certs, pCertInterface, NULL,
+ sizeof(CERT_CONTEXT));
+ }
+ else
+ {
+ SetLastError(CRYPT_E_NOT_FOUND);
+ ret = NULL;
+ }
+ }
+ LeaveCriticalSection(&cs->cs);
+ if (ret)
+ ((PCERT_CONTEXT)ret)->hCertStore = store;
+ TRACE("returning %p\n", ret);
+ return ret;
+}
+
+static BOOL CRYPT_CollectionDeleteCert(PWINECRYPT_CERTSTORE store,
+ void *pCertContext)
+{
+ BOOL ret;
+
+ TRACE("(%p, %p)\n", store, pCertContext);
+
+ ret = CertDeleteCertificateFromStore((PCCERT_CONTEXT)
+ Context_GetLinkedContext(pCertContext, sizeof(CERT_CONTEXT)));
+ return ret;
+}
+
+static BOOL CRYPT_CollectionAddCRL(PWINECRYPT_CERTSTORE store, void *crl,
+ void *toReplace, const void **ppStoreContext)
+{
+ BOOL ret;
+ void *childContext = NULL;
+ PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
+
+ ret = CRYPT_CollectionAddContext(cs, offsetof(WINECRYPT_CERTSTORE, crls),
+ crl, toReplace, sizeof(CRL_CONTEXT), &childContext);
+ if (ppStoreContext && childContext)
+ {
+ PWINE_STORE_LIST_ENTRY storeEntry = *(PWINE_STORE_LIST_ENTRY *)
+ Context_GetExtra(childContext, sizeof(CRL_CONTEXT));
+ PCRL_CONTEXT context =
+ CRYPT_CollectionCreateContextFromChild(cs, storeEntry, childContext,
+ sizeof(CRL_CONTEXT), TRUE);
+
+ if (context)
+ context->hCertStore = store;
+ *ppStoreContext = context;
+ }
+ CertFreeCRLContext((PCCRL_CONTEXT)childContext);
+ return ret;
+}
+
+static void *CRYPT_CollectionEnumCRL(PWINECRYPT_CERTSTORE store, void *pPrev)
+{
+ PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
+ void *ret;
+
+ TRACE("(%p, %p)\n", store, pPrev);
+
+ EnterCriticalSection(&cs->cs);
+ if (pPrev)
+ {
+ PWINE_STORE_LIST_ENTRY storeEntry =
+ *(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(pPrev,
+ sizeof(CRL_CONTEXT));
+
+ ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
+ &storeEntry->store->crls, pCRLInterface, pPrev, sizeof(CRL_CONTEXT));
+ }
+ else
+ {
+ if (!list_empty(&cs->stores))
+ {
+ PWINE_STORE_LIST_ENTRY storeEntry = LIST_ENTRY(cs->stores.next,
+ WINE_STORE_LIST_ENTRY, entry);
+
+ ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
+ &storeEntry->store->crls, pCRLInterface, NULL,
+ sizeof(CRL_CONTEXT));
+ }
+ else
+ {
+ SetLastError(CRYPT_E_NOT_FOUND);
+ ret = NULL;
+ }
+ }
+ LeaveCriticalSection(&cs->cs);
+ if (ret)
+ ((PCRL_CONTEXT)ret)->hCertStore = store;
+ TRACE("returning %p\n", ret);
+ return ret;
+}
+
+static BOOL CRYPT_CollectionDeleteCRL(PWINECRYPT_CERTSTORE store,
+ void *pCrlContext)
+{
+ BOOL ret;
+
+ TRACE("(%p, %p)\n", store, pCrlContext);
+
+ ret = CertDeleteCRLFromStore((PCCRL_CONTEXT)
+ Context_GetLinkedContext(pCrlContext, sizeof(CRL_CONTEXT)));
+ return ret;
+}
+
+PWINECRYPT_CERTSTORE CRYPT_CollectionOpenStore(HCRYPTPROV hCryptProv,
+ DWORD dwFlags, const void *pvPara)
+{
+ PWINE_COLLECTIONSTORE store;
+
+ if (dwFlags & CERT_STORE_DELETE_FLAG)
+ {
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ store = NULL;
+ }
+ else
+ {
+ store = CryptMemAlloc(sizeof(WINE_COLLECTIONSTORE));
+ if (store)
+ {
+ memset(store, 0, sizeof(WINE_COLLECTIONSTORE));
+ CRYPT_InitStore(&store->hdr, hCryptProv, dwFlags,
+ StoreTypeCollection);
+ store->hdr.closeStore = CRYPT_CollectionCloseStore;
+ store->hdr.certs.addContext = CRYPT_CollectionAddCert;
+ store->hdr.certs.enumContext = CRYPT_CollectionEnumCert;
+ store->hdr.certs.deleteContext = CRYPT_CollectionDeleteCert;
+ store->hdr.crls.addContext = CRYPT_CollectionAddCRL;
+ store->hdr.crls.enumContext = CRYPT_CollectionEnumCRL;
+ store->hdr.crls.deleteContext = CRYPT_CollectionDeleteCRL;
+ InitializeCriticalSection(&store->cs);
+ store->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PWINE_COLLECTIONSTORE->cs");
+ list_init(&store->stores);
+ }
+ }
+ return (PWINECRYPT_CERTSTORE)store;
+}
+
+BOOL WINAPI CertAddStoreToCollection(HCERTSTORE hCollectionStore,
+ HCERTSTORE hSiblingStore, DWORD dwUpdateFlags, DWORD dwPriority)
+{
+ PWINE_COLLECTIONSTORE collection = (PWINE_COLLECTIONSTORE)hCollectionStore;
+ WINECRYPT_CERTSTORE *sibling = (WINECRYPT_CERTSTORE *)hSiblingStore;
+ PWINE_STORE_LIST_ENTRY entry;
+ BOOL ret;
+
+ TRACE("(%p, %p, %08x, %d)\n", hCollectionStore, hSiblingStore,
+ dwUpdateFlags, dwPriority);
+
+ if (!collection || !sibling)
+ return TRUE;
+ if (collection->hdr.dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
+ {
+ SetLastError(E_INVALIDARG);
+ return FALSE;
+ }
+ if (collection->hdr.type != StoreTypeCollection)
+ {
+ SetLastError(E_INVALIDARG);
+ return FALSE;
+ }
+ if (sibling->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
+ {
+ SetLastError(E_INVALIDARG);
+ return FALSE;
+ }
+
+ entry = CryptMemAlloc(sizeof(WINE_STORE_LIST_ENTRY));
+ if (entry)
+ {
+ InterlockedIncrement(&sibling->ref);
+ TRACE("sibling %p's ref count is %d\n", sibling, sibling->ref);
+ entry->store = sibling;
+ entry->dwUpdateFlags = dwUpdateFlags;
+ entry->dwPriority = dwPriority;
+ list_init(&entry->entry);
+ TRACE("%p: adding %p, priority %d\n", collection, entry, dwPriority);
+ EnterCriticalSection(&collection->cs);
+ if (dwPriority)
+ {
+ PWINE_STORE_LIST_ENTRY cursor;
+ BOOL added = FALSE;
+
+ LIST_FOR_EACH_ENTRY(cursor, &collection->stores,
+ WINE_STORE_LIST_ENTRY, entry)
+ {
+ if (cursor->dwPriority < dwPriority)
+ {
+ list_add_before(&cursor->entry, &entry->entry);
+ added = TRUE;
+ break;
+ }
+ }
+ if (!added)
+ list_add_tail(&collection->stores, &entry->entry);
+ }
+ else
+ list_add_tail(&collection->stores, &entry->entry);
+ LeaveCriticalSection(&collection->cs);
+ ret = TRUE;
+ }
+ else
+ ret = FALSE;
+ return ret;
+}
+
+void WINAPI CertRemoveStoreFromCollection(HCERTSTORE hCollectionStore,
+ HCERTSTORE hSiblingStore)
+{
+ PWINE_COLLECTIONSTORE collection = (PWINE_COLLECTIONSTORE)hCollectionStore;
+ WINECRYPT_CERTSTORE *sibling = (WINECRYPT_CERTSTORE *)hSiblingStore;
+ PWINE_STORE_LIST_ENTRY store, next;
+
+ TRACE("(%p, %p)\n", hCollectionStore, hSiblingStore);
+
+ if (!collection || !sibling)
+ return;
+ if (collection->hdr.dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
+ {
+ SetLastError(E_INVALIDARG);
+ return;
+ }
+ if (collection->hdr.type != StoreTypeCollection)
+ return;
+ if (sibling->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
+ {
+ SetLastError(E_INVALIDARG);
+ return;
+ }
+ EnterCriticalSection(&collection->cs);
+ LIST_FOR_EACH_ENTRY_SAFE(store, next, &collection->stores,
+ WINE_STORE_LIST_ENTRY, entry)
+ {
+ if (store->store == sibling)
+ {
+ list_remove(&store->entry);
+ CertCloseStore(store->store, 0);
+ CryptMemFree(store);
+ break;
+ }
+ }
+ LeaveCriticalSection(&collection->cs);
+}
diff --git a/dlls/crypt32/crypt32_private.h b/dlls/crypt32/crypt32_private.h
index fe1c39e..9f47acf 100644
--- a/dlls/crypt32/crypt32_private.h
+++ b/dlls/crypt32/crypt32_private.h
@@ -231,6 +231,13 @@ typedef struct WINE_CRYPTCERTSTORE
PCONTEXT_PROPERTY_LIST properties;
} WINECRYPT_CERTSTORE, *PWINECRYPT_CERTSTORE;
+void CRYPT_InitStore(WINECRYPT_CERTSTORE *store, HCRYPTPROV hCryptProv,
+ DWORD dwFlags, CertStoreType type);
+void CRYPT_FreeStore(PWINECRYPT_CERTSTORE store);
+
+PWINECRYPT_CERTSTORE CRYPT_CollectionOpenStore(HCRYPTPROV hCryptProv,
+ DWORD dwFlags, const void *pvPara);
+
/* Helper function for store reading functions and
* CertAddSerializedElementToStore. Returns a context of the appropriate type
* if it can, or NULL otherwise. Doesn't validate any of the properties in
diff --git a/dlls/crypt32/store.c b/dlls/crypt32/store.c
index d2687fb..a2b7666 100644
--- a/dlls/crypt32/store.c
+++ b/dlls/crypt32/store.c
@@ -128,21 +128,6 @@ typedef struct _WINE_MSGSTOREINFO
HCRYPTMSG msg;
} WINE_MSGSTOREINFO, *PWINE_MSGSTOREINFO;
-typedef struct _WINE_STORE_LIST_ENTRY
-{
- PWINECRYPT_CERTSTORE store;
- DWORD dwUpdateFlags;
- DWORD dwPriority;
- struct list entry;
-} WINE_STORE_LIST_ENTRY, *PWINE_STORE_LIST_ENTRY;
-
-typedef struct _WINE_COLLECTIONSTORE
-{
- WINECRYPT_CERTSTORE hdr;
- CRITICAL_SECTION cs;
- struct list stores;
-} WINE_COLLECTIONSTORE, *PWINE_COLLECTIONSTORE;
-
typedef struct _WINE_PROVIDERSTORE
{
WINECRYPT_CERTSTORE hdr;
@@ -157,7 +142,7 @@ typedef struct _WINE_PROVIDERSTORE
PFN_CERT_STORE_PROV_CONTROL provControl;
} WINE_PROVIDERSTORE, *PWINE_PROVIDERSTORE;
-static void CRYPT_InitStore(WINECRYPT_CERTSTORE *store, HCRYPTPROV hCryptProv,
+void CRYPT_InitStore(WINECRYPT_CERTSTORE *store, HCRYPTPROV hCryptProv,
DWORD dwFlags, CertStoreType type)
{
store->ref = 1;
@@ -173,7 +158,7 @@ static void CRYPT_InitStore(WINECRYPT_CE
store->properties = NULL;
}
-static void CRYPT_FreeStore(PWINECRYPT_CERTSTORE store)
+void CRYPT_FreeStore(PWINECRYPT_CERTSTORE store)
{
if (store->properties)
ContextPropertyList_Free(store->properties);
@@ -328,340 +313,6 @@ static WINECRYPT_CERTSTORE *CRYPT_MemOpe
return (PWINECRYPT_CERTSTORE)store;
}
-static void WINAPI CRYPT_CollectionCloseStore(HCERTSTORE store, DWORD dwFlags)
-{
- PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
- PWINE_STORE_LIST_ENTRY entry, next;
-
- TRACE("(%p, %08x)\n", store, dwFlags);
-
- LIST_FOR_EACH_ENTRY_SAFE(entry, next, &cs->stores, WINE_STORE_LIST_ENTRY,
- entry)
- {
- TRACE("closing %p\n", entry);
- CertCloseStore((HCERTSTORE)entry->store, dwFlags);
- CryptMemFree(entry);
- }
- cs->cs.DebugInfo->Spare[0] = 0;
- DeleteCriticalSection(&cs->cs);
- CRYPT_FreeStore((PWINECRYPT_CERTSTORE)store);
-}
-
-static void *CRYPT_CollectionCreateContextFromChild(PWINE_COLLECTIONSTORE store,
- PWINE_STORE_LIST_ENTRY storeEntry, void *child, size_t contextSize,
- BOOL addRef)
-{
- void *ret = Context_CreateLinkContext(contextSize, child,
- sizeof(PWINE_STORE_LIST_ENTRY), addRef);
-
- if (ret)
- *(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(ret, contextSize)
- = storeEntry;
-
- return ret;
-}
-
-static BOOL CRYPT_CollectionAddContext(PWINE_COLLECTIONSTORE store,
- unsigned int contextFuncsOffset, void *context, void *toReplace, unsigned int contextSize,
- void **pChildContext)
-{
- BOOL ret;
- void *childContext = NULL;
- PWINE_STORE_LIST_ENTRY storeEntry = NULL;
-
- TRACE("(%p, %d, %p, %p, %d)\n", store, contextFuncsOffset, context,
- toReplace, contextSize);
-
- ret = FALSE;
- if (toReplace)
- {
- void *existingLinked = Context_GetLinkedContext(toReplace, contextSize);
- PCONTEXT_FUNCS contextFuncs;
-
- storeEntry = *(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(toReplace,
- contextSize);
- contextFuncs = (PCONTEXT_FUNCS)((LPBYTE)storeEntry->store +
- contextFuncsOffset);
- ret = contextFuncs->addContext(storeEntry->store, context,
- existingLinked, childContext);
- }
- else
- {
- PWINE_STORE_LIST_ENTRY entry, next;
-
- EnterCriticalSection(&store->cs);
- LIST_FOR_EACH_ENTRY_SAFE(entry, next, &store->stores,
- WINE_STORE_LIST_ENTRY, entry)
- {
- if (entry->dwUpdateFlags & CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG)
- {
- PCONTEXT_FUNCS contextFuncs = (PCONTEXT_FUNCS)(
- (LPBYTE)entry->store + contextFuncsOffset);
-
- storeEntry = entry;
- ret = contextFuncs->addContext(entry->store, context, NULL,
- (const void **)&childContext);
- break;
- }
- }
- LeaveCriticalSection(&store->cs);
- if (!storeEntry)
- SetLastError(E_ACCESSDENIED);
- }
- *pChildContext = childContext;
- return ret;
-}
-
-/* Advances a collection enumeration by one context, if possible, where
- * advancing means:
- * - calling the current store's enumeration function once, and returning
- * the enumerated context if one is returned
- * - moving to the next store if the current store has no more items, and
- * recursively calling itself to get the next item.
- * Returns NULL if the collection contains no more items or on error.
- * Assumes the collection store's lock is held.
- */
-static void *CRYPT_CollectionAdvanceEnum(PWINE_COLLECTIONSTORE store,
- PWINE_STORE_LIST_ENTRY storeEntry, PCONTEXT_FUNCS contextFuncs,
- PCWINE_CONTEXT_INTERFACE contextInterface, void *pPrev, size_t contextSize)
-{
- void *ret, *child;
- struct list *storeNext = list_next(&store->stores, &storeEntry->entry);
-
- TRACE("(%p, %p, %p)\n", store, storeEntry, pPrev);
-
- if (pPrev)
- {
- /* Ref-counting funny business: "duplicate" (addref) the child, because
- * the free(pPrev) below can cause the ref count to become negative.
- */
- child = Context_GetLinkedContext(pPrev, contextSize);
- contextInterface->duplicate(child);
- child = contextFuncs->enumContext(storeEntry->store, child);
- contextInterface->free(pPrev);
- pPrev = NULL;
- }
- else
- child = contextFuncs->enumContext(storeEntry->store, NULL);
- if (child)
- ret = CRYPT_CollectionCreateContextFromChild(store, storeEntry, child,
- contextSize, FALSE);
- else
- {
- if (storeNext)
- {
- /* We always want the same function pointers (from certs, crls)
- * in the next store, so use the same offset into the next store.
- */
- size_t offset = (LPBYTE)contextFuncs - (LPBYTE)storeEntry->store;
- PWINE_STORE_LIST_ENTRY storeNextEntry =
- LIST_ENTRY(storeNext, WINE_STORE_LIST_ENTRY, entry);
- PCONTEXT_FUNCS storeNextContexts =
- (PCONTEXT_FUNCS)((LPBYTE)storeNextEntry->store + offset);
-
- ret = CRYPT_CollectionAdvanceEnum(store, storeNextEntry,
- storeNextContexts, contextInterface, NULL, contextSize);
- }
- else
- {
- SetLastError(CRYPT_E_NOT_FOUND);
- ret = NULL;
- }
- }
- TRACE("returning %p\n", ret);
- return ret;
-}
-
-static BOOL CRYPT_CollectionAddCert(PWINECRYPT_CERTSTORE store, void *cert,
- void *toReplace, const void **ppStoreContext)
-{
- BOOL ret;
- void *childContext = NULL;
- PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
-
- ret = CRYPT_CollectionAddContext(cs, offsetof(WINECRYPT_CERTSTORE, certs),
- cert, toReplace, sizeof(CERT_CONTEXT), &childContext);
- if (ppStoreContext && childContext)
- {
- PWINE_STORE_LIST_ENTRY storeEntry = *(PWINE_STORE_LIST_ENTRY *)
- Context_GetExtra(childContext, sizeof(CERT_CONTEXT));
- PCERT_CONTEXT context =
- CRYPT_CollectionCreateContextFromChild(cs, storeEntry, childContext,
- sizeof(CERT_CONTEXT), TRUE);
-
- if (context)
- context->hCertStore = store;
- *ppStoreContext = context;
- }
- CertFreeCertificateContext((PCCERT_CONTEXT)childContext);
- return ret;
-}
-
-static void *CRYPT_CollectionEnumCert(PWINECRYPT_CERTSTORE store, void *pPrev)
-{
- PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
- void *ret;
-
- TRACE("(%p, %p)\n", store, pPrev);
-
- EnterCriticalSection(&cs->cs);
- if (pPrev)
- {
- PWINE_STORE_LIST_ENTRY storeEntry =
- *(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(pPrev,
- sizeof(CERT_CONTEXT));
-
- ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
- &storeEntry->store->certs, pCertInterface, pPrev,
- sizeof(CERT_CONTEXT));
- }
- else
- {
- if (!list_empty(&cs->stores))
- {
- PWINE_STORE_LIST_ENTRY storeEntry = LIST_ENTRY(cs->stores.next,
- WINE_STORE_LIST_ENTRY, entry);
-
- ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
- &storeEntry->store->certs, pCertInterface, NULL,
- sizeof(CERT_CONTEXT));
- }
- else
- {
- SetLastError(CRYPT_E_NOT_FOUND);
- ret = NULL;
- }
- }
- LeaveCriticalSection(&cs->cs);
- if (ret)
- ((PCERT_CONTEXT)ret)->hCertStore = store;
- TRACE("returning %p\n", ret);
- return ret;
-}
-
-static BOOL CRYPT_CollectionDeleteCert(PWINECRYPT_CERTSTORE store,
- void *pCertContext)
-{
- BOOL ret;
-
- TRACE("(%p, %p)\n", store, pCertContext);
-
- ret = CertDeleteCertificateFromStore((PCCERT_CONTEXT)
- Context_GetLinkedContext(pCertContext, sizeof(CERT_CONTEXT)));
- return ret;
-}
-
-static BOOL CRYPT_CollectionAddCRL(PWINECRYPT_CERTSTORE store, void *crl,
- void *toReplace, const void **ppStoreContext)
-{
- BOOL ret;
- void *childContext = NULL;
- PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
-
- ret = CRYPT_CollectionAddContext(cs, offsetof(WINECRYPT_CERTSTORE, crls),
- crl, toReplace, sizeof(CRL_CONTEXT), &childContext);
- if (ppStoreContext && childContext)
- {
- PWINE_STORE_LIST_ENTRY storeEntry = *(PWINE_STORE_LIST_ENTRY *)
- Context_GetExtra(childContext, sizeof(CRL_CONTEXT));
- PCRL_CONTEXT context =
- CRYPT_CollectionCreateContextFromChild(cs, storeEntry, childContext,
- sizeof(CRL_CONTEXT), TRUE);
-
- if (context)
- context->hCertStore = store;
- *ppStoreContext = context;
- }
- CertFreeCRLContext((PCCRL_CONTEXT)childContext);
- return ret;
-}
-
-static void *CRYPT_CollectionEnumCRL(PWINECRYPT_CERTSTORE store, void *pPrev)
-{
- PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
- void *ret;
-
- TRACE("(%p, %p)\n", store, pPrev);
-
- EnterCriticalSection(&cs->cs);
- if (pPrev)
- {
- PWINE_STORE_LIST_ENTRY storeEntry =
- *(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(pPrev,
- sizeof(CRL_CONTEXT));
-
- ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
- &storeEntry->store->crls, pCRLInterface, pPrev, sizeof(CRL_CONTEXT));
- }
- else
- {
- if (!list_empty(&cs->stores))
- {
- PWINE_STORE_LIST_ENTRY storeEntry = LIST_ENTRY(cs->stores.next,
- WINE_STORE_LIST_ENTRY, entry);
-
- ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
- &storeEntry->store->crls, pCRLInterface, NULL,
- sizeof(CRL_CONTEXT));
- }
- else
- {
- SetLastError(CRYPT_E_NOT_FOUND);
- ret = NULL;
- }
- }
- LeaveCriticalSection(&cs->cs);
- if (ret)
- ((PCRL_CONTEXT)ret)->hCertStore = store;
- TRACE("returning %p\n", ret);
- return ret;
-}
-
-static BOOL CRYPT_CollectionDeleteCRL(PWINECRYPT_CERTSTORE store,
- void *pCrlContext)
-{
- BOOL ret;
-
- TRACE("(%p, %p)\n", store, pCrlContext);
-
- ret = CertDeleteCRLFromStore((PCCRL_CONTEXT)
- Context_GetLinkedContext(pCrlContext, sizeof(CRL_CONTEXT)));
- return ret;
-}
-
-static WINECRYPT_CERTSTORE *CRYPT_CollectionOpenStore(HCRYPTPROV hCryptProv,
- DWORD dwFlags, const void *pvPara)
-{
- PWINE_COLLECTIONSTORE store;
-
- if (dwFlags & CERT_STORE_DELETE_FLAG)
- {
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- store = NULL;
- }
- else
- {
- store = CryptMemAlloc(sizeof(WINE_COLLECTIONSTORE));
- if (store)
- {
- memset(store, 0, sizeof(WINE_COLLECTIONSTORE));
- CRYPT_InitStore(&store->hdr, hCryptProv, dwFlags,
- StoreTypeCollection);
- store->hdr.closeStore = CRYPT_CollectionCloseStore;
- store->hdr.certs.addContext = CRYPT_CollectionAddCert;
- store->hdr.certs.enumContext = CRYPT_CollectionEnumCert;
- store->hdr.certs.deleteContext = CRYPT_CollectionDeleteCert;
- store->hdr.crls.addContext = CRYPT_CollectionAddCRL;
- store->hdr.crls.enumContext = CRYPT_CollectionEnumCRL;
- store->hdr.crls.deleteContext = CRYPT_CollectionDeleteCRL;
- InitializeCriticalSection(&store->cs);
- store->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PWINE_COLLECTIONSTORE->cs");
- list_init(&store->stores);
- }
- }
- return (PWINECRYPT_CERTSTORE)store;
-}
-
static void WINAPI CRYPT_ProvCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
{
PWINE_PROVIDERSTORE store = (PWINE_PROVIDERSTORE)hCertStore;
@@ -2665,112 +2316,6 @@ BOOL WINAPI CertSetCTLContextProperty(PC
return FALSE;
}
-BOOL WINAPI CertAddStoreToCollection(HCERTSTORE hCollectionStore,
- HCERTSTORE hSiblingStore, DWORD dwUpdateFlags, DWORD dwPriority)
-{
- PWINE_COLLECTIONSTORE collection = (PWINE_COLLECTIONSTORE)hCollectionStore;
- WINECRYPT_CERTSTORE *sibling = (WINECRYPT_CERTSTORE *)hSiblingStore;
- PWINE_STORE_LIST_ENTRY entry;
- BOOL ret;
-
- TRACE("(%p, %p, %08x, %d)\n", hCollectionStore, hSiblingStore,
- dwUpdateFlags, dwPriority);
-
- if (!collection || !sibling)
- return TRUE;
- if (collection->hdr.dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
- {
- SetLastError(E_INVALIDARG);
- return FALSE;
- }
- if (collection->hdr.type != StoreTypeCollection)
- {
- SetLastError(E_INVALIDARG);
- return FALSE;
- }
- if (sibling->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
- {
- SetLastError(E_INVALIDARG);
- return FALSE;
- }
-
- entry = CryptMemAlloc(sizeof(WINE_STORE_LIST_ENTRY));
- if (entry)
- {
- InterlockedIncrement(&sibling->ref);
- TRACE("sibling %p's ref count is %d\n", sibling, sibling->ref);
- entry->store = sibling;
- entry->dwUpdateFlags = dwUpdateFlags;
- entry->dwPriority = dwPriority;
- list_init(&entry->entry);
- TRACE("%p: adding %p, priority %d\n", collection, entry, dwPriority);
- EnterCriticalSection(&collection->cs);
- if (dwPriority)
- {
- PWINE_STORE_LIST_ENTRY cursor;
- BOOL added = FALSE;
-
- LIST_FOR_EACH_ENTRY(cursor, &collection->stores,
- WINE_STORE_LIST_ENTRY, entry)
- {
- if (cursor->dwPriority < dwPriority)
- {
- list_add_before(&cursor->entry, &entry->entry);
- added = TRUE;
- break;
- }
- }
- if (!added)
- list_add_tail(&collection->stores, &entry->entry);
- }
- else
- list_add_tail(&collection->stores, &entry->entry);
- LeaveCriticalSection(&collection->cs);
- ret = TRUE;
- }
- else
- ret = FALSE;
- return ret;
-}
-
-void WINAPI CertRemoveStoreFromCollection(HCERTSTORE hCollectionStore,
- HCERTSTORE hSiblingStore)
-{
- PWINE_COLLECTIONSTORE collection = (PWINE_COLLECTIONSTORE)hCollectionStore;
- WINECRYPT_CERTSTORE *sibling = (WINECRYPT_CERTSTORE *)hSiblingStore;
- PWINE_STORE_LIST_ENTRY store, next;
-
- TRACE("(%p, %p)\n", hCollectionStore, hSiblingStore);
-
- if (!collection || !sibling)
- return;
- if (collection->hdr.dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
- {
- SetLastError(E_INVALIDARG);
- return;
- }
- if (collection->hdr.type != StoreTypeCollection)
- return;
- if (sibling->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
- {
- SetLastError(E_INVALIDARG);
- return;
- }
- EnterCriticalSection(&collection->cs);
- LIST_FOR_EACH_ENTRY_SAFE(store, next, &collection->stores,
- WINE_STORE_LIST_ENTRY, entry)
- {
- if (store->store == sibling)
- {
- list_remove(&store->entry);
- CertCloseStore(store->store, 0);
- CryptMemFree(store);
- break;
- }
- }
- LeaveCriticalSection(&collection->cs);
-}
-
static LONG CRYPT_OpenParentStore(DWORD dwFlags,
void *pvSystemStoreLocationPara, HKEY *key)
{
--
1.4.1
More information about the wine-patches
mailing list