From c7d1082b4f0b6db5eea5e99e68ffb42108d6c507 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Mon, 14 Oct 2013 14:46:40 +0200 Subject: [PATCH] crypt32: Added new empty store type and use it for creating certificates with no store. --- dlls/crypt32/cert.c | 2 +- dlls/crypt32/crypt32_private.h | 4 +++ dlls/crypt32/main.c | 1 + dlls/crypt32/store.c | 72 ++++++++++++++++++++++++++++++++++++++++++ dlls/crypt32/tests/cert.c | 1 - dlls/crypt32/tests/store.c | 4 ++- 6 files changed, 81 insertions(+), 3 deletions(-) diff --git a/dlls/crypt32/cert.c b/dlls/crypt32/cert.c index e9d871773e6..561fd598473 100644 --- a/dlls/crypt32/cert.c +++ b/dlls/crypt32/cert.c @@ -169,7 +169,7 @@ PCCERT_CONTEXT WINAPI CertCreateCertificateContext(DWORD dwCertEncodingType, cert->pbCertEncoded = data; cert->cbCertEncoded = cbCertEncoded; cert->pCertInfo = certInfo; - cert->hCertStore = 0; + cert->hCertStore = &empty_store; } end: diff --git a/dlls/crypt32/crypt32_private.h b/dlls/crypt32/crypt32_private.h index d9f5c23051e..cc1477c914d 100644 --- a/dlls/crypt32/crypt32_private.h +++ b/dlls/crypt32/crypt32_private.h @@ -231,6 +231,7 @@ typedef enum _CertStoreType { StoreTypeMem, StoreTypeCollection, StoreTypeProvider, + StoreTypeEmpty } CertStoreType; typedef struct _CONTEXT_PROPERTY_LIST CONTEXT_PROPERTY_LIST; @@ -420,6 +421,9 @@ BOOL ContextList_Remove(struct ContextList *list, void *context) DECLSPEC_HIDDEN void ContextList_Free(struct ContextList *list) DECLSPEC_HIDDEN; +extern WINECRYPT_CERTSTORE empty_store; +void init_empty_store(void) DECLSPEC_HIDDEN; + /** * Utilities. */ diff --git a/dlls/crypt32/main.c b/dlls/crypt32/main.c index 78f14f901d7..c4f6c78031e 100644 --- a/dlls/crypt32/main.c +++ b/dlls/crypt32/main.c @@ -42,6 +42,7 @@ BOOL WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, PVOID pvReserved) case DLL_PROCESS_ATTACH: hInstance = hInst; DisableThreadLibraryCalls(hInst); + init_empty_store(); crypt_oid_init(); break; case DLL_PROCESS_DETACH: diff --git a/dlls/crypt32/store.c b/dlls/crypt32/store.c index 1054b044398..521fd4f705f 100644 --- a/dlls/crypt32/store.c +++ b/dlls/crypt32/store.c @@ -1488,3 +1488,75 @@ BOOL WINAPI CertRegisterPhysicalStore(const void *pvSystemStore, DWORD dwFlags, dwFlags, debugstr_w(pwszStoreName), pStoreInfo, pvReserved); return FALSE; } + +static void EmptyStore_addref(WINECRYPT_CERTSTORE *store) +{ + TRACE("(%p)\n", store); +} + +static DWORD EmptyStore_release(WINECRYPT_CERTSTORE *store, DWORD flags) +{ + TRACE("(%p)\n", store); + return E_UNEXPECTED; +} + +static BOOL EmptyStore_add(WINECRYPT_CERTSTORE *store, void *context, + void *replace, const void **ret_context) +{ + TRACE("(%p, %p, %p, %p)\n", store, context, replace, ret_context); + + /* FIXME: We should clone the context */ + if(ret_context) { + Context_AddRef(context); + *ret_context = context; + } + + return TRUE; +} + +static void *EmptyStore_enum(WINECRYPT_CERTSTORE *store, void *prev) +{ + TRACE("(%p, %p)\n", store, prev); + + SetLastError(CRYPT_E_NOT_FOUND); + return FALSE; +} + +static BOOL EmptyStore_delete(WINECRYPT_CERTSTORE *store, void *context) +{ + return TRUE; +} + +static BOOL EmptyStore_control(WINECRYPT_CERTSTORE *store, DWORD flags, DWORD ctrl_type, void const *ctrl_para) +{ + TRACE("()\n"); + + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +static const store_vtbl_t EmptyStoreVtbl = { + EmptyStore_addref, + EmptyStore_release, + EmptyStore_control, + { + EmptyStore_add, + EmptyStore_enum, + EmptyStore_delete + }, { + EmptyStore_add, + EmptyStore_enum, + EmptyStore_delete + }, { + EmptyStore_add, + EmptyStore_enum, + EmptyStore_delete + } +}; + +WINECRYPT_CERTSTORE empty_store; + +void init_empty_store(void) +{ + CRYPT_InitStore(&empty_store, CERT_STORE_READONLY_FLAG, StoreTypeEmpty, &EmptyStoreVtbl); +} diff --git a/dlls/crypt32/tests/cert.c b/dlls/crypt32/tests/cert.c index f31236a3bf0..dfb6921235c 100644 --- a/dlls/crypt32/tests/cert.c +++ b/dlls/crypt32/tests/cert.c @@ -660,7 +660,6 @@ static void testCreateCert(void) selfSignedCert, sizeof(selfSignedCert)); ok(cert != NULL, "creating cert failed: %08x\n", GetLastError()); /* Even in-memory certs are expected to have a store associated with them */ - todo_wine ok(cert->hCertStore != NULL, "expected created cert to have a store\n"); /* The cert doesn't have the archived property set (which would imply it * doesn't show up in enumerations.) diff --git a/dlls/crypt32/tests/store.c b/dlls/crypt32/tests/store.c index 25dd5f67fb2..2e852fb1e46 100644 --- a/dlls/crypt32/tests/store.c +++ b/dlls/crypt32/tests/store.c @@ -2515,7 +2515,7 @@ static void testEmptyStore(void) cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert)); ok(cert != NULL, "CertCreateCertificateContext failed\n"); - todo_wine ok(cert->hCertStore != NULL, "cert->hCertStore == NULL\n"); + ok(cert->hCertStore != NULL, "cert->hCertStore == NULL\n"); if(!cert->hCertStore) { CertFreeCertificateContext(cert); return; @@ -2555,6 +2555,8 @@ static void testEmptyStore(void) ok(res, "CertDeleteCertificateContextFromStore failed\n"); ok(cert3->hCertStore == store, "Unexpected hCertStore\n"); + CertFreeCertificateContext(cert3); + CertCloseStore(store, 0); res = CertCloseStore(cert->hCertStore, CERT_CLOSE_STORE_CHECK_FLAG); -- 2.11.4.GIT