crypt32: When add-ref'ing a context, add-ref its linked contexts too.
authorJuan Lang <juan.lang@gmail.com>
Sat, 31 Oct 2009 00:25:28 +0000 (17:25 -0700)
committerAlexander Morozov <amorozov@etersoft.ru>
Thu, 1 Jul 2010 13:18:07 +0000 (17:18 +0400)
dlls/crypt32/context.c

index 20fe0245f8ad3acaed7cddfa28c523b367008536..4d325c15e46bfe800a80af9d16a5eed1f4f01a85 100644 (file)
@@ -106,6 +106,34 @@ void Context_AddRef(void *context, size_t contextSize)
     PBASE_CONTEXT baseContext = BASE_CONTEXT_FROM_CONTEXT(context, contextSize);
 
     InterlockedIncrement(&baseContext->ref);
+    if (baseContext->type == ContextTypeLink)
+    {
+        void *linkedContext = Context_GetLinkedContext(context, contextSize);
+        PBASE_CONTEXT linkedBase = BASE_CONTEXT_FROM_CONTEXT(linkedContext,
+         contextSize);
+
+        /* Add-ref the linked contexts too */
+        while (linkedContext && linkedBase->type == ContextTypeLink)
+        {
+            InterlockedIncrement(&linkedBase->ref);
+            linkedContext = Context_GetLinkedContext(linkedContext,
+             contextSize);
+            if (linkedContext)
+                linkedBase = BASE_CONTEXT_FROM_CONTEXT(linkedContext,
+                 contextSize);
+            else
+                linkedBase = NULL;
+        }
+        if (linkedContext)
+        {
+            /* It's not a link context, so it wasn't add-ref'ed in the while
+             * loop, so add-ref it here.
+             */
+            linkedBase = BASE_CONTEXT_FROM_CONTEXT(linkedContext,
+             contextSize);
+            InterlockedIncrement(&linkedBase->ref);
+        }
+    }
 }
 
 void *Context_GetExtra(const void *context, size_t contextSize)