crypt32(1/13): Add return value to Context_Release to allow detecting reference counting errors

View: New views
1 Messages — Rating Filter:   Alert me  

crypt32(1/13): Add return value to Context_Release to allow detecting reference counting errors

by Juan Lang-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

--Juan

[0001-Add-return-value-to-Context_Release-to-allow-detecti.patch]

From cb40abbd119e7907d06df1df7ab9122400955c8a Mon Sep 17 00:00:00 2001
From: Juan Lang <juan.lang@...>
Date: Fri, 30 Oct 2009 15:06:39 -0700
Subject: [PATCH] Add return value to Context_Release to allow detecting reference counting errors

---
 dlls/crypt32/cert.c            |    6 ++++--
 dlls/crypt32/context.c         |    8 ++++++--
 dlls/crypt32/crl.c             |    6 ++++--
 dlls/crypt32/crypt32_private.h |    3 ++-
 dlls/crypt32/ctl.c             |    6 ++++--
 5 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/dlls/crypt32/cert.c b/dlls/crypt32/cert.c
index cb1b973..77a6f69 100644
--- a/dlls/crypt32/cert.c
+++ b/dlls/crypt32/cert.c
@@ -133,12 +133,14 @@ static void CertDataContext_Free(void *context)
 
 BOOL WINAPI CertFreeCertificateContext(PCCERT_CONTEXT pCertContext)
 {
+    BOOL ret = TRUE;
+
     TRACE("(%p)\n", pCertContext);
 
     if (pCertContext)
-        Context_Release((void *)pCertContext, sizeof(CERT_CONTEXT),
+        ret = Context_Release((void *)pCertContext, sizeof(CERT_CONTEXT),
          CertDataContext_Free);
-    return TRUE;
+    return ret;
 }
 
 DWORD WINAPI CertEnumCertificateContextProperties(PCCERT_CONTEXT pCertContext,
diff --git a/dlls/crypt32/context.c b/dlls/crypt32/context.c
index bb87799..9ada6bf 100644
--- a/dlls/crypt32/context.c
+++ b/dlls/crypt32/context.c
@@ -135,11 +135,14 @@ PCONTEXT_PROPERTY_LIST Context_GetProperties(const void *context, size_t context
      ((PDATA_CONTEXT)ptr)->properties : NULL;
 }
 
-void Context_Release(void *context, size_t contextSize,
+BOOL Context_Release(void *context, size_t contextSize,
  ContextFreeFunc dataContextFree)
 {
     PBASE_CONTEXT base = BASE_CONTEXT_FROM_CONTEXT(context, contextSize);
+    BOOL ret = TRUE;
 
+    if (base->ref <= 0)
+        return FALSE;
     if (InterlockedDecrement(&base->ref) == 0)
     {
         TRACE("freeing %p\n", context);
@@ -153,7 +156,7 @@ void Context_Release(void *context, size_t contextSize,
             /* The linked context is of the same type as this, so release
              * it as well, using the same offset and data free function.
              */
-            Context_Release(CONTEXT_FROM_BASE_CONTEXT(
+            ret = Context_Release(CONTEXT_FROM_BASE_CONTEXT(
              ((PLINK_CONTEXT)base)->linked, contextSize), contextSize,
              dataContextFree);
             break;
@@ -164,6 +167,7 @@ void Context_Release(void *context, size_t contextSize,
     }
     else
         TRACE("%p's ref count is %d\n", context, base->ref);
+    return ret;
 }
 
 void Context_CopyProperties(const void *to, const void *from,
diff --git a/dlls/crypt32/crl.c b/dlls/crypt32/crl.c
index 80fe86f..522aadf 100644
--- a/dlls/crypt32/crl.c
+++ b/dlls/crypt32/crl.c
@@ -243,12 +243,14 @@ static void CrlDataContext_Free(void *context)
 
 BOOL WINAPI CertFreeCRLContext( PCCRL_CONTEXT pCrlContext)
 {
+    BOOL ret = TRUE;
+
     TRACE("(%p)\n", pCrlContext);
 
     if (pCrlContext)
-        Context_Release((void *)pCrlContext, sizeof(CRL_CONTEXT),
+        ret = Context_Release((void *)pCrlContext, sizeof(CRL_CONTEXT),
          CrlDataContext_Free);
-    return TRUE;
+    return ret;
 }
 
 DWORD WINAPI CertEnumCRLContextProperties(PCCRL_CONTEXT pCRLContext,
diff --git a/dlls/crypt32/crypt32_private.h b/dlls/crypt32/crypt32_private.h
index 8c5b13b..dd96e0f 100644
--- a/dlls/crypt32/crypt32_private.h
+++ b/dlls/crypt32/crypt32_private.h
@@ -346,8 +346,9 @@ typedef void (*ContextFreeFunc)(void *context);
 /* Decrements context's ref count.  If context is a link context, releases its
  * linked context as well.
  * If a data context has its ref count reach 0, calls dataContextFree on it.
+ * Returns FALSE if the reference count is <= 0 when called.
  */
-void Context_Release(void *context, size_t contextSize,
+BOOL Context_Release(void *context, size_t contextSize,
  ContextFreeFunc dataContextFree);
 
 /**
diff --git a/dlls/crypt32/ctl.c b/dlls/crypt32/ctl.c
index 1bd60e7..e2511fa 100644
--- a/dlls/crypt32/ctl.c
+++ b/dlls/crypt32/ctl.c
@@ -472,12 +472,14 @@ static void CTLDataContext_Free(void *context)
 
 BOOL WINAPI CertFreeCTLContext(PCCTL_CONTEXT pCTLContext)
 {
+    BOOL ret = TRUE;
+
     TRACE("(%p)\n", pCTLContext);
 
     if (pCTLContext)
-        Context_Release((void *)pCTLContext, sizeof(CTL_CONTEXT),
+        ret = Context_Release((void *)pCTLContext, sizeof(CTL_CONTEXT),
          CTLDataContext_Free);
-    return TRUE;
+    return ret;
 }
 
 DWORD WINAPI CertEnumCTLContextProperties(PCCTL_CONTEXT pCTLContext,
--
1.6.0.6