dinput: Keyboard should be acquired before calling GetDeviceState.
[wine/multimedia.git] / dlls / crypt32 / proplist.c
blobc0301534880733fc6dc2e78e11718ed454144662
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 typedef struct _CONTEXT_PROPERTY_LIST
31 CRITICAL_SECTION cs;
32 struct list properties;
33 } CONTEXT_PROPERTY_LIST;
35 typedef struct _CONTEXT_PROPERTY
37 DWORD propID;
38 DWORD cbData;
39 LPBYTE pbData;
40 struct list entry;
41 } CONTEXT_PROPERTY, *PCONTEXT_PROPERTY;
43 PCONTEXT_PROPERTY_LIST ContextPropertyList_Create(void)
45 PCONTEXT_PROPERTY_LIST list = CryptMemAlloc(sizeof(CONTEXT_PROPERTY_LIST));
47 if (list)
49 InitializeCriticalSection(&list->cs);
50 list_init(&list->properties);
52 return list;
55 void ContextPropertyList_Free(PCONTEXT_PROPERTY_LIST list)
57 PCONTEXT_PROPERTY prop, next;
59 LIST_FOR_EACH_ENTRY_SAFE(prop, next, &list->properties, CONTEXT_PROPERTY,
60 entry)
62 list_remove(&prop->entry);
63 CryptMemFree(prop->pbData);
64 CryptMemFree(prop);
66 DeleteCriticalSection(&list->cs);
67 CryptMemFree(list);
70 BOOL ContextPropertyList_FindProperty(PCONTEXT_PROPERTY_LIST list, DWORD id,
71 PCRYPT_DATA_BLOB blob)
73 PCONTEXT_PROPERTY prop;
74 BOOL ret = FALSE;
76 TRACE("(%p, %ld, %p)\n", list, id, blob);
78 EnterCriticalSection(&list->cs);
79 LIST_FOR_EACH_ENTRY(prop, &list->properties, CONTEXT_PROPERTY, entry)
81 if (prop->propID == id)
83 blob->cbData = prop->cbData;
84 blob->pbData = prop->pbData;
85 ret = TRUE;
86 break;
89 LeaveCriticalSection(&list->cs);
90 return ret;
93 BOOL ContextPropertyList_SetProperty(PCONTEXT_PROPERTY_LIST list, DWORD id,
94 const BYTE *pbData, size_t cbData)
96 LPBYTE data;
97 BOOL ret = FALSE;
99 if (cbData)
101 data = CryptMemAlloc(cbData);
102 if (data)
103 memcpy(data, pbData, cbData);
105 else
106 data = NULL;
107 if (!cbData || data)
109 PCONTEXT_PROPERTY prop;
110 BOOL found = FALSE;
112 EnterCriticalSection(&list->cs);
113 LIST_FOR_EACH_ENTRY(prop, &list->properties, CONTEXT_PROPERTY, entry)
115 if (prop->propID == id)
117 found = TRUE;
118 break;
121 if (found)
123 CryptMemFree(prop->pbData);
124 prop->cbData = cbData;
125 prop->pbData = data;
126 ret = TRUE;
128 else
130 prop = CryptMemAlloc(sizeof(CONTEXT_PROPERTY));
131 if (prop)
133 prop->propID = id;
134 prop->cbData = cbData;
135 prop->pbData = data;
136 list_add_tail(&list->properties, &prop->entry);
137 ret = TRUE;
139 else
140 CryptMemFree(data);
142 LeaveCriticalSection(&list->cs);
144 return ret;
147 void ContextPropertyList_RemoveProperty(PCONTEXT_PROPERTY_LIST list, DWORD id)
149 PCONTEXT_PROPERTY prop, next;
151 EnterCriticalSection(&list->cs);
152 LIST_FOR_EACH_ENTRY_SAFE(prop, next, &list->properties, CONTEXT_PROPERTY,
153 entry)
155 if (prop->propID == id)
157 list_remove(&prop->entry);
158 CryptMemFree(prop->pbData);
159 CryptMemFree(prop);
160 break;
163 LeaveCriticalSection(&list->cs);
166 /* Since the properties are stored in a list, this is a tad inefficient
167 * (O(n^2)) since I have to find the previous position every time.
169 DWORD ContextPropertyList_EnumPropIDs(PCONTEXT_PROPERTY_LIST list, DWORD id)
171 DWORD ret;
173 EnterCriticalSection(&list->cs);
174 if (id)
176 PCONTEXT_PROPERTY cursor = NULL;
178 LIST_FOR_EACH_ENTRY(cursor, &list->properties, CONTEXT_PROPERTY, entry)
180 if (cursor->propID == id)
181 break;
183 if (cursor)
185 if (cursor->entry.next != &list->properties)
186 ret = LIST_ENTRY(cursor->entry.next, CONTEXT_PROPERTY,
187 entry)->propID;
188 else
189 ret = 0;
191 else
192 ret = 0;
194 else if (!list_empty(&list->properties))
195 ret = LIST_ENTRY(list->properties.next, CONTEXT_PROPERTY,
196 entry)->propID;
197 else
198 ret = 0;
199 LeaveCriticalSection(&list->cs);
200 return ret;
203 void ContextPropertyList_Copy(PCONTEXT_PROPERTY_LIST to,
204 PCONTEXT_PROPERTY_LIST from)
206 PCONTEXT_PROPERTY prop;
208 EnterCriticalSection(&from->cs);
209 LIST_FOR_EACH_ENTRY(prop, &from->properties, CONTEXT_PROPERTY, entry)
211 ContextPropertyList_SetProperty(to, prop->propID, prop->pbData,
212 prop->cbData);
214 LeaveCriticalSection(&from->cs);