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 void *Context_CreateDataContext(size_t contextSize
, const context_vtbl_t
*vtbl
)
32 context
= CryptMemAlloc(sizeof(context_t
) + contextSize
);
38 context
->linked
= NULL
;
39 context
->properties
= ContextPropertyList_Create();
40 if (!context
->properties
)
42 CryptMemFree(context
);
46 TRACE("returning %p\n", context
);
47 return context_ptr(context
);
50 context_t
*Context_CreateLinkContext(unsigned int contextSize
, context_t
*linked
)
54 TRACE("(%d, %p)\n", contextSize
, linked
);
56 context
= CryptMemAlloc(sizeof(context_t
) + contextSize
);
60 memcpy(context_ptr(context
), context_ptr(linked
), contextSize
);
61 context
->vtbl
= linked
->vtbl
;
63 context
->linked
= linked
;
64 context
->properties
= linked
->properties
;
65 Context_AddRef(linked
);
67 TRACE("returning %p\n", context
);
71 void Context_AddRef(context_t
*context
)
73 InterlockedIncrement(&context
->ref
);
74 TRACE("(%p) ref=%d\n", context
, context
->ref
);
77 BOOL
Context_Release(context_t
*context
)
81 if (context
->ref
<= 0)
83 ERR("%p's ref count is %d\n", context
, context
->ref
);
86 if (InterlockedDecrement(&context
->ref
) == 0)
88 TRACE("freeing %p\n", context
);
91 ContextPropertyList_Free(context
->properties
);
92 context
->vtbl
->free(context
);
94 Context_Release(context
->linked
);
96 CryptMemFree(context
);
99 TRACE("%p's ref count is %d\n", context
, context
->ref
);
103 void Context_CopyProperties(const void *to
, const void *from
)
105 CONTEXT_PROPERTY_LIST
*toProperties
, *fromProperties
;
107 toProperties
= context_from_ptr(to
)->properties
;
108 fromProperties
= context_from_ptr(from
)->properties
;
109 assert(toProperties
&& fromProperties
);
110 ContextPropertyList_Copy(toProperties
, fromProperties
);
116 struct list contexts
;
119 struct ContextList
*ContextList_Create(void)
121 struct ContextList
*list
= CryptMemAlloc(sizeof(struct ContextList
));
125 InitializeCriticalSection(&list
->cs
);
126 list
->cs
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": ContextList.cs");
127 list_init(&list
->contexts
);
132 context_t
*ContextList_Add(struct ContextList
*list
, context_t
*toLink
, context_t
*existing
, struct WINE_CRYPTCERTSTORE
*store
, BOOL use_link
)
136 TRACE("(%p, %p, %p)\n", list
, toLink
, existing
);
138 context
= toLink
->vtbl
->clone(toLink
, store
, use_link
);
141 TRACE("adding %p\n", context
);
142 EnterCriticalSection(&list
->cs
);
145 context
->u
.entry
.prev
= existing
->u
.entry
.prev
;
146 context
->u
.entry
.next
= existing
->u
.entry
.next
;
147 context
->u
.entry
.prev
->next
= &context
->u
.entry
;
148 context
->u
.entry
.next
->prev
= &context
->u
.entry
;
149 list_init(&existing
->u
.entry
);
150 Context_Release(existing
);
153 list_add_head(&list
->contexts
, &context
->u
.entry
);
154 LeaveCriticalSection(&list
->cs
);
159 context_t
*ContextList_Enum(struct ContextList
*list
, context_t
*prev
)
161 struct list
*listNext
;
164 EnterCriticalSection(&list
->cs
);
167 listNext
= list_next(&list
->contexts
, &prev
->u
.entry
);
168 Context_Release(prev
);
171 listNext
= list_next(&list
->contexts
, &list
->contexts
);
172 LeaveCriticalSection(&list
->cs
);
176 ret
= LIST_ENTRY(listNext
, context_t
, u
.entry
);
184 BOOL
ContextList_Remove(struct ContextList
*list
, context_t
*context
)
188 EnterCriticalSection(&list
->cs
);
189 if (!list_empty(&context
->u
.entry
))
191 list_remove(&context
->u
.entry
);
192 list_init(&context
->u
.entry
);
195 LeaveCriticalSection(&list
->cs
);
200 static void ContextList_Empty(struct ContextList
*list
)
202 context_t
*context
, *next
;
204 EnterCriticalSection(&list
->cs
);
205 LIST_FOR_EACH_ENTRY_SAFE(context
, next
, &list
->contexts
, context_t
, u
.entry
)
207 TRACE("removing %p\n", context
);
208 list_remove(&context
->u
.entry
);
209 Context_Release(context
);
211 LeaveCriticalSection(&list
->cs
);
214 void ContextList_Free(struct ContextList
*list
)
216 ContextList_Empty(list
);
217 list
->cs
.DebugInfo
->Spare
[0] = 0;
218 DeleteCriticalSection(&list
->cs
);