crypt32: Support HCCE_LOCAL_MACHINE.

Ben Deane wine at elbeno.com
Tue Sep 24 23:46:04 CDT 2013


Hi,

this fixes bug 33947 - Battle.net desktop app crashes after 15 seconds
(http://bugs.winehq.org/show_bug.cgi?id=33947).

regards,
Ben Deane

---
 dlls/crypt32/chain.c           | 29 ++++++++++++++++++-----------
 dlls/crypt32/crypt32_private.h |  2 +-
 dlls/crypt32/main.c            |  3 ++-
 3 files changed, 21 insertions(+), 13 deletions(-)

-------------- next part --------------
>From 635216acb2f5d5d0aed494f1deaa5a28c4b6b696 Mon Sep 17 00:00:00 2001
From: Ben Deane <wine at elbeno.com>
Date: Tue, 24 Sep 2013 21:27:43 -0700
Subject: crypt32: Support HCCE_LOCAL_MACHINE.

Add simple support for HCCE_LOCAL_MACHINE for
CertGetCertificateChainEngine et al.
---
 dlls/crypt32/chain.c           | 29 ++++++++++++++++++-----------
 dlls/crypt32/crypt32_private.h |  2 +-
 dlls/crypt32/main.c            |  3 ++-
 3 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/dlls/crypt32/chain.c b/dlls/crypt32/chain.c
index 1a83dee..953c02a 100644
--- a/dlls/crypt32/chain.c
+++ b/dlls/crypt32/chain.c
@@ -33,7 +33,10 @@ WINE_DECLARE_DEBUG_CHANNEL(chain);
 
 #define DEFAULT_CYCLE_MODULUS 7
 
-static HCERTCHAINENGINE CRYPT_defaultChainEngine;
+/* There are two default chain engines which correspond to HCCE_CURRENT_USER and
+ * HCCE_LOCAL_MACHINE.
+*/
+static HCERTCHAINENGINE CRYPT_defaultChainEngine[2] = { NULL, NULL };
 
 /* This represents a subset of a certificate chain engine:  it doesn't include
  * the "hOther" store described by MSDN, because I'm not sure how that's used.
@@ -212,7 +215,8 @@ VOID WINAPI CertFreeCertificateChainEngine(HCERTCHAINENGINE hChainEngine)
 
     TRACE("(%p)\n", hChainEngine);
 
-    if (engine && InterlockedDecrement(&engine->ref) == 0)
+    if (hChainEngine > HCCE_LOCAL_MACHINE
+        && InterlockedDecrement(&engine->ref) == 0)
     {
         CertCloseStore(engine->hWorld, 0);
         CertCloseStore(engine->hRoot, 0);
@@ -220,26 +224,28 @@ VOID WINAPI CertFreeCertificateChainEngine(HCERTCHAINENGINE hChainEngine)
     }
 }
 
-static HCERTCHAINENGINE CRYPT_GetDefaultChainEngine(void)
+static HCERTCHAINENGINE CRYPT_GetDefaultChainEngine(HCERTCHAINENGINE h)
 {
-    if (!CRYPT_defaultChainEngine)
+    if (!CRYPT_defaultChainEngine[(int)h])
     {
         CERT_CHAIN_ENGINE_CONFIG config = { 0 };
         HCERTCHAINENGINE engine;
 
         config.cbSize = sizeof(config);
+        if (h == HCCE_LOCAL_MACHINE)
+            config.dwFlags = CERT_CHAIN_USE_LOCAL_MACHINE_STORE;
         CertCreateCertificateChainEngine(&config, &engine);
-        InterlockedCompareExchangePointer(&CRYPT_defaultChainEngine, engine,
+        InterlockedCompareExchangePointer(&CRYPT_defaultChainEngine[(int)h], engine,
          NULL);
-        if (CRYPT_defaultChainEngine != engine)
+        if (CRYPT_defaultChainEngine[(int)h] != engine)
             CertFreeCertificateChainEngine(engine);
     }
-    return CRYPT_defaultChainEngine;
+    return CRYPT_defaultChainEngine[(int)h];
 }
 
-void default_chain_engine_free(void)
+void default_chain_engine_free(HCERTCHAINENGINE h)
 {
-    CertFreeCertificateChainEngine(CRYPT_defaultChainEngine);
+    CertFreeCertificateChainEngine(CRYPT_defaultChainEngine[(int)h]);
 }
 
 typedef struct _CertificateChain
@@ -2886,8 +2892,9 @@ BOOL WINAPI CertGetCertificateChain(HCERTCHAINENGINE hChainEngine,
         return FALSE;
     }
 
-    if (!engine)
-        engine = CRYPT_GetDefaultChainEngine();
+    if (hChainEngine <= HCCE_LOCAL_MACHINE)
+        engine = (CertificateChainEngine*)CRYPT_GetDefaultChainEngine(
+         hChainEngine);
     if (TRACE_ON(chain))
         dump_chain_para(pChainPara);
     /* FIXME: what about HCCE_LOCAL_MACHINE? */
diff --git a/dlls/crypt32/crypt32_private.h b/dlls/crypt32/crypt32_private.h
index 6793e3d..dd4a1f0 100644
--- a/dlls/crypt32/crypt32_private.h
+++ b/dlls/crypt32/crypt32_private.h
@@ -155,7 +155,7 @@ void crypt_oid_init(void) DECLSPEC_HIDDEN;
 void crypt_oid_free(void) DECLSPEC_HIDDEN;
 void crypt_sip_free(void) DECLSPEC_HIDDEN;
 void root_store_free(void) DECLSPEC_HIDDEN;
-void default_chain_engine_free(void) DECLSPEC_HIDDEN;
+void default_chain_engine_free(HCERTCHAINENGINE) DECLSPEC_HIDDEN;
 
 /* Some typedefs that make it easier to abstract which type of context we're
  * working with.
diff --git a/dlls/crypt32/main.c b/dlls/crypt32/main.c
index 78f14f9..b3d97aa 100644
--- a/dlls/crypt32/main.c
+++ b/dlls/crypt32/main.c
@@ -49,7 +49,8 @@ BOOL WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, PVOID pvReserved)
             crypt_oid_free();
             crypt_sip_free();
             root_store_free();
-            default_chain_engine_free();
+            default_chain_engine_free(HCCE_CURRENT_USER);
+            default_chain_engine_free(HCCE_LOCAL_MACHINE);
             if (hDefProv) CryptReleaseContext(hDefProv, 0);
             break;
     }
-- 
1.8.1.2



More information about the wine-patches mailing list