msvcp100: Add _Concurrent_queue_base_v4 push/pop implementation.
[wine.git] / dlls / crypt32 / proplist.c
blobf5ae2213525fac8caa23e1c14992bc12d1abb250
1 /*
2 * Copyright 2004-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
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 "wine/list.h"
25 #include "crypt32_private.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(crypt);
29 struct _CONTEXT_PROPERTY_LIST
31 CRITICAL_SECTION cs;
32 struct list properties;
35 typedef struct _CONTEXT_PROPERTY
37 DWORD propID;
38 DWORD cbData;
39 LPBYTE pbData;
40 struct list entry;
41 } CONTEXT_PROPERTY;
43 CONTEXT_PROPERTY_LIST *ContextPropertyList_Create(void)
45 CONTEXT_PROPERTY_LIST *list = CryptMemAlloc(sizeof(CONTEXT_PROPERTY_LIST));
47 if (list)
49 InitializeCriticalSection(&list->cs);
50 list->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PCONTEXT_PROPERTY_LIST->cs");
51 list_init(&list->properties);
53 return list;
56 void ContextPropertyList_Free(CONTEXT_PROPERTY_LIST *list)
58 CONTEXT_PROPERTY *prop, *next;
60 LIST_FOR_EACH_ENTRY_SAFE(prop, next, &list->properties, CONTEXT_PROPERTY,
61 entry)
63 list_remove(&prop->entry);
64 CryptMemFree(prop->pbData);
65 CryptMemFree(prop);
67 list->cs.DebugInfo->Spare[0] = 0;
68 DeleteCriticalSection(&list->cs);
69 CryptMemFree(list);
72 BOOL ContextPropertyList_FindProperty(CONTEXT_PROPERTY_LIST *list, DWORD id,
73 PCRYPT_DATA_BLOB blob)
75 CONTEXT_PROPERTY *prop;
76 BOOL ret = FALSE;
78 TRACE("(%p, %d, %p)\n", list, id, blob);
80 EnterCriticalSection(&list->cs);
81 LIST_FOR_EACH_ENTRY(prop, &list->properties, CONTEXT_PROPERTY, entry)
83 if (prop->propID == id)
85 blob->cbData = prop->cbData;
86 blob->pbData = prop->pbData;
87 ret = TRUE;
88 break;
91 LeaveCriticalSection(&list->cs);
92 return ret;
95 BOOL ContextPropertyList_SetProperty(CONTEXT_PROPERTY_LIST *list, DWORD id,
96 const BYTE *pbData, size_t cbData)
98 LPBYTE data;
99 BOOL ret = FALSE;
101 if (cbData)
103 data = CryptMemAlloc(cbData);
104 if (data)
105 memcpy(data, pbData, cbData);
107 else
108 data = NULL;
109 if (!cbData || data)
111 CONTEXT_PROPERTY *prop;
112 BOOL found = FALSE;
114 EnterCriticalSection(&list->cs);
115 LIST_FOR_EACH_ENTRY(prop, &list->properties, CONTEXT_PROPERTY, entry)
117 if (prop->propID == id)
119 found = TRUE;
120 break;
123 if (found)
125 CryptMemFree(prop->pbData);
126 prop->cbData = cbData;
127 prop->pbData = data;
128 ret = TRUE;
130 else
132 prop = CryptMemAlloc(sizeof(CONTEXT_PROPERTY));
133 if (prop)
135 prop->propID = id;
136 prop->cbData = cbData;
137 prop->pbData = data;
138 list_add_tail(&list->properties, &prop->entry);
139 ret = TRUE;
141 else
142 CryptMemFree(data);
144 LeaveCriticalSection(&list->cs);
146 return ret;
149 void ContextPropertyList_RemoveProperty(CONTEXT_PROPERTY_LIST *list, DWORD id)
151 CONTEXT_PROPERTY *prop;
153 EnterCriticalSection(&list->cs);
154 LIST_FOR_EACH_ENTRY(prop, &list->properties, CONTEXT_PROPERTY, entry)
156 if (prop->propID == id)
158 list_remove(&prop->entry);
159 CryptMemFree(prop->pbData);
160 CryptMemFree(prop);
161 break;
164 LeaveCriticalSection(&list->cs);
167 /* Since the properties are stored in a list, this is a tad inefficient
168 * (O(n^2)) since I have to find the previous position every time.
170 DWORD ContextPropertyList_EnumPropIDs(CONTEXT_PROPERTY_LIST *list, DWORD id)
172 DWORD ret;
174 EnterCriticalSection(&list->cs);
175 if (id)
177 CONTEXT_PROPERTY *cursor = NULL, *prop;
179 LIST_FOR_EACH_ENTRY(prop, &list->properties, CONTEXT_PROPERTY, entry)
181 if (prop->propID == id)
183 cursor = prop;
184 break;
187 if (cursor)
189 if (cursor->entry.next != &list->properties)
190 ret = LIST_ENTRY(cursor->entry.next, CONTEXT_PROPERTY,
191 entry)->propID;
192 else
193 ret = 0;
195 else
196 ret = 0;
198 else if (!list_empty(&list->properties))
199 ret = LIST_ENTRY(list->properties.next, CONTEXT_PROPERTY,
200 entry)->propID;
201 else
202 ret = 0;
203 LeaveCriticalSection(&list->cs);
204 return ret;
207 void ContextPropertyList_Copy(CONTEXT_PROPERTY_LIST *to, CONTEXT_PROPERTY_LIST *from)
209 CONTEXT_PROPERTY *prop;
211 EnterCriticalSection(&from->cs);
212 LIST_FOR_EACH_ENTRY(prop, &from->properties, CONTEXT_PROPERTY, entry)
214 ContextPropertyList_SetProperty(to, prop->propID, prop->pbData,
215 prop->cbData);
217 LeaveCriticalSection(&from->cs);