xref: /reactos/dll/win32/crypt32/context.c (revision a6e10342)
1 /*
2  * Copyright 2006 Juan Lang
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18 #include <assert.h>
19 #include <stdarg.h>
20 #include "windef.h"
21 #include "winbase.h"
22 #include "wincrypt.h"
23 #include "wine/debug.h"
24 #include "crypt32_private.h"
25 
26 WINE_DEFAULT_DEBUG_CHANNEL(context);
27 
Context_CreateDataContext(size_t contextSize,const context_vtbl_t * vtbl,WINECRYPT_CERTSTORE * store)28 context_t *Context_CreateDataContext(size_t contextSize, const context_vtbl_t *vtbl, WINECRYPT_CERTSTORE *store)
29 {
30     context_t *context;
31 
32     context = CryptMemAlloc(sizeof(context_t) + contextSize);
33     if (!context)
34         return NULL;
35 
36     context->properties = ContextPropertyList_Create();
37     if (!context->properties)
38     {
39         CryptMemFree(context);
40         return NULL;
41     }
42 
43     context->vtbl = vtbl;
44     context->ref = 1;
45     context->linked = NULL;
46 
47     store->vtbl->addref(store);
48     context->store = store;
49 
50     TRACE("returning %p\n", context);
51     return context;
52 }
53 
Context_CreateLinkContext(unsigned int contextSize,context_t * linked,WINECRYPT_CERTSTORE * store)54 context_t *Context_CreateLinkContext(unsigned int contextSize, context_t *linked, WINECRYPT_CERTSTORE *store)
55 {
56     context_t *context;
57 
58     TRACE("(%d, %p)\n", contextSize, linked);
59 
60     context = CryptMemAlloc(sizeof(context_t) + contextSize);
61     if (!context)
62         return NULL;
63 
64     memcpy(context_ptr(context), context_ptr(linked), contextSize);
65     context->vtbl = linked->vtbl;
66     context->ref = 1;
67     context->linked = linked;
68     context->properties = linked->properties;
69     Context_AddRef(linked);
70 
71     store->vtbl->addref(store);
72     context->store = store;
73 
74     TRACE("returning %p\n", context);
75     return context;
76 }
77 
Context_AddRef(context_t * context)78 void Context_AddRef(context_t *context)
79 {
80     LONG ref = InterlockedIncrement(&context->ref);
81 
82     TRACE("(%p) ref=%d\n", context, context->ref);
83 
84     if(ref == 1) {
85         /* This is the first external (non-store) reference. Increase store ref cnt. */
86         context->store->vtbl->addref(context->store);
87     }
88 }
89 
Context_Free(context_t * context)90 void Context_Free(context_t *context)
91 {
92     TRACE("(%p)\n", context);
93 
94     assert(!context->ref);
95 
96     if (!context->linked) {
97         ContextPropertyList_Free(context->properties);
98         context->vtbl->free(context);
99     }else {
100         Context_Release(context->linked);
101     }
102 
103     CryptMemFree(context);
104 }
105 
Context_Release(context_t * context)106 void Context_Release(context_t *context)
107 {
108     LONG ref = InterlockedDecrement(&context->ref);
109 
110     TRACE("(%p) ref=%d\n", context, ref);
111     assert(ref >= 0);
112 
113     if (!ref) {
114         WINECRYPT_CERTSTORE *store = context->store;
115 
116         /* This is the last reference, but the context still may be in a store.
117          * We release our store reference, but leave it up to store to free or keep the context. */
118         store->vtbl->releaseContext(store, context);
119         store->vtbl->release(store, 0);
120     }
121 }
122 
Context_CopyProperties(const void * to,const void * from)123 void Context_CopyProperties(const void *to, const void *from)
124 {
125     CONTEXT_PROPERTY_LIST *toProperties, *fromProperties;
126 
127     toProperties = context_from_ptr(to)->properties;
128     fromProperties = context_from_ptr(from)->properties;
129     assert(toProperties && fromProperties);
130     ContextPropertyList_Copy(toProperties, fromProperties);
131 }
132