2 * Copyright 2006 Juan Lang
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.
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.
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
23 #include "wine/debug.h"
24 #include "crypt32_private.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(context
);
28 #define CONTEXT_FROM_BASE_CONTEXT(p) (void*)(p+1)
29 #define BASE_CONTEXT_FROM_CONTEXT(p) ((BASE_CONTEXT*)(p)-1)
31 void *Context_CreateDataContext(size_t contextSize
, const context_vtbl_t
*vtbl
)
33 BASE_CONTEXT
*context
;
35 context
= CryptMemAlloc(contextSize
+ sizeof(BASE_CONTEXT
));
41 context
->linked
= NULL
;
42 context
->properties
= ContextPropertyList_Create();
43 if (!context
->properties
)
45 CryptMemFree(context
);
49 TRACE("returning %p\n", context
);
50 return CONTEXT_FROM_BASE_CONTEXT(context
);
53 context_t
*Context_CreateLinkContext(unsigned int contextSize
, context_t
*linked
)
57 TRACE("(%d, %p)\n", contextSize
, linked
);
59 context
= CryptMemAlloc(sizeof(context_t
) + contextSize
);
63 memcpy(context_ptr(context
), context_ptr(linked
), contextSize
);
64 context
->vtbl
= linked
->vtbl
;
66 context
->linked
= linked
;
67 context
->properties
= linked
->properties
;
68 Context_AddRef(linked
);
70 TRACE("returning %p\n", context
);
74 void Context_AddRef(context_t
*context
)
76 InterlockedIncrement(&context
->ref
);
77 TRACE("(%p) ref=%d\n", context
, context
->ref
);
80 BOOL
Context_Release(context_t
*context
)
84 if (context
->ref
<= 0)
86 ERR("%p's ref count is %d\n", context
, context
->ref
);
89 if (InterlockedDecrement(&context
->ref
) == 0)
91 TRACE("freeing %p\n", context
);
94 ContextPropertyList_Free(context
->properties
);
95 context
->vtbl
->free(context
);
97 Context_Release(context
->linked
);
99 CryptMemFree(context
);
102 TRACE("%p's ref count is %d\n", context
, context
->ref
);
106 void Context_CopyProperties(const void *to
, const void *from
)
108 CONTEXT_PROPERTY_LIST
*toProperties
, *fromProperties
;
110 toProperties
= context_from_ptr(to
)->properties
;
111 fromProperties
= context_from_ptr(from
)->properties
;
112 assert(toProperties
&& fromProperties
);
113 ContextPropertyList_Copy(toProperties
, fromProperties
);
118 const WINE_CONTEXT_INTERFACE
*contextInterface
;
121 struct list contexts
;
124 struct ContextList
*ContextList_Create(
125 const WINE_CONTEXT_INTERFACE
*contextInterface
, size_t contextSize
)
127 struct ContextList
*list
= CryptMemAlloc(sizeof(struct ContextList
));
131 list
->contextInterface
= contextInterface
;
132 list
->contextSize
= contextSize
;
133 InitializeCriticalSection(&list
->cs
);
134 list
->cs
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": ContextList.cs");
135 list_init(&list
->contexts
);
140 void *ContextList_Add(struct ContextList
*list
, void *toLink
, void *toReplace
, struct WINE_CRYPTCERTSTORE
*store
, BOOL use_link
)
144 TRACE("(%p, %p, %p)\n", list
, toLink
, toReplace
);
146 context
= context_from_ptr(toLink
)->vtbl
->clone(BASE_CONTEXT_FROM_CONTEXT(toLink
), store
, use_link
);
149 TRACE("adding %p\n", context
);
150 EnterCriticalSection(&list
->cs
);
153 context_t
*existing
= context_from_ptr(toReplace
);
155 context
->u
.entry
.prev
= existing
->u
.entry
.prev
;
156 context
->u
.entry
.next
= existing
->u
.entry
.next
;
157 context
->u
.entry
.prev
->next
= &context
->u
.entry
;
158 context
->u
.entry
.next
->prev
= &context
->u
.entry
;
159 list_init(&existing
->u
.entry
);
160 Context_Release(context_from_ptr(toReplace
));
163 list_add_head(&list
->contexts
, &context
->u
.entry
);
164 LeaveCriticalSection(&list
->cs
);
166 return CONTEXT_FROM_BASE_CONTEXT(context
);
169 void *ContextList_Enum(struct ContextList
*list
, void *pPrev
)
171 struct list
*listNext
;
174 EnterCriticalSection(&list
->cs
);
177 listNext
= list_next(&list
->contexts
, &context_from_ptr(pPrev
)->u
.entry
);
178 Context_Release(context_from_ptr(pPrev
));
181 listNext
= list_next(&list
->contexts
, &list
->contexts
);
182 LeaveCriticalSection(&list
->cs
);
186 ret
= CONTEXT_FROM_BASE_CONTEXT(LIST_ENTRY(listNext
, context_t
, u
.entry
));
187 Context_AddRef(context_from_ptr(ret
));
194 BOOL
ContextList_Remove(struct ContextList
*list
, context_t
*context
)
198 EnterCriticalSection(&list
->cs
);
199 if (!list_empty(&context
->u
.entry
))
201 list_remove(&context
->u
.entry
);
202 list_init(&context
->u
.entry
);
205 LeaveCriticalSection(&list
->cs
);
210 static void ContextList_Empty(struct ContextList
*list
)
212 context_t
*context
, *next
;
214 EnterCriticalSection(&list
->cs
);
215 LIST_FOR_EACH_ENTRY_SAFE(context
, next
, &list
->contexts
, context_t
, u
.entry
)
217 TRACE("removing %p\n", context
);
218 list_remove(&context
->u
.entry
);
219 Context_Release(context
);
221 LeaveCriticalSection(&list
->cs
);
224 void ContextList_Free(struct ContextList
*list
)
226 ContextList_Empty(list
);
227 list
->cs
.DebugInfo
->Spare
[0] = 0;
228 DeleteCriticalSection(&list
->cs
);