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 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 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 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 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 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 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