user32: Added stub for GetMouseMovePointsEx.
[wine] / dlls / crypt32 / proplist.c
CommitLineData
91b80fc8
JL
1/*
2 * Copyright 2004-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
360a3f91 16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
91b80fc8
JL
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 "wine/list.h"
25#include "crypt32_private.h"
26
27WINE_DEFAULT_DEBUG_CHANNEL(crypt);
28
29typedef struct _CONTEXT_PROPERTY_LIST
30{
31 CRITICAL_SECTION cs;
32 struct list properties;
33} CONTEXT_PROPERTY_LIST;
34
35typedef struct _CONTEXT_PROPERTY
36{
37 DWORD propID;
38 DWORD cbData;
39 LPBYTE pbData;
40 struct list entry;
41} CONTEXT_PROPERTY, *PCONTEXT_PROPERTY;
42
43PCONTEXT_PROPERTY_LIST ContextPropertyList_Create(void)
44{
45 PCONTEXT_PROPERTY_LIST list = CryptMemAlloc(sizeof(CONTEXT_PROPERTY_LIST));
46
47 if (list)
48 {
49 InitializeCriticalSection(&list->cs);
e8956eb4 50 list->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PCONTEXT_PROPERTY_LIST->cs");
91b80fc8
JL
51 list_init(&list->properties);
52 }
53 return list;
54}
55
56void ContextPropertyList_Free(PCONTEXT_PROPERTY_LIST list)
57{
58 PCONTEXT_PROPERTY prop, next;
59
60 LIST_FOR_EACH_ENTRY_SAFE(prop, next, &list->properties, CONTEXT_PROPERTY,
61 entry)
62 {
63 list_remove(&prop->entry);
64 CryptMemFree(prop->pbData);
65 CryptMemFree(prop);
66 }
e8956eb4 67 list->cs.DebugInfo->Spare[0] = 0;
91b80fc8
JL
68 DeleteCriticalSection(&list->cs);
69 CryptMemFree(list);
70}
71
72BOOL ContextPropertyList_FindProperty(PCONTEXT_PROPERTY_LIST list, DWORD id,
73 PCRYPT_DATA_BLOB blob)
74{
75 PCONTEXT_PROPERTY prop;
76 BOOL ret = FALSE;
77
f3a1f2bf 78 TRACE("(%p, %d, %p)\n", list, id, blob);
91b80fc8
JL
79
80 EnterCriticalSection(&list->cs);
81 LIST_FOR_EACH_ENTRY(prop, &list->properties, CONTEXT_PROPERTY, entry)
82 {
83 if (prop->propID == id)
84 {
85 blob->cbData = prop->cbData;
86 blob->pbData = prop->pbData;
87 ret = TRUE;
88 break;
89 }
90 }
91 LeaveCriticalSection(&list->cs);
92 return ret;
93}
94
95BOOL ContextPropertyList_SetProperty(PCONTEXT_PROPERTY_LIST list, DWORD id,
96 const BYTE *pbData, size_t cbData)
97{
98 LPBYTE data;
99 BOOL ret = FALSE;
100
101 if (cbData)
102 {
103 data = CryptMemAlloc(cbData);
104 if (data)
105 memcpy(data, pbData, cbData);
106 }
107 else
108 data = NULL;
109 if (!cbData || data)
110 {
111 PCONTEXT_PROPERTY prop;
112 BOOL found = FALSE;
113
114 EnterCriticalSection(&list->cs);
115 LIST_FOR_EACH_ENTRY(prop, &list->properties, CONTEXT_PROPERTY, entry)
116 {
117 if (prop->propID == id)
118 {
119 found = TRUE;
120 break;
121 }
122 }
123 if (found)
124 {
125 CryptMemFree(prop->pbData);
126 prop->cbData = cbData;
127 prop->pbData = data;
128 ret = TRUE;
129 }
130 else
131 {
132 prop = CryptMemAlloc(sizeof(CONTEXT_PROPERTY));
133 if (prop)
134 {
135 prop->propID = id;
136 prop->cbData = cbData;
91b80fc8
JL
137 prop->pbData = data;
138 list_add_tail(&list->properties, &prop->entry);
139 ret = TRUE;
140 }
141 else
142 CryptMemFree(data);
143 }
144 LeaveCriticalSection(&list->cs);
145 }
146 return ret;
147}
148
149void ContextPropertyList_RemoveProperty(PCONTEXT_PROPERTY_LIST list, DWORD id)
150{
151 PCONTEXT_PROPERTY prop, next;
152
153 EnterCriticalSection(&list->cs);
154 LIST_FOR_EACH_ENTRY_SAFE(prop, next, &list->properties, CONTEXT_PROPERTY,
155 entry)
156 {
157 if (prop->propID == id)
158 {
159 list_remove(&prop->entry);
160 CryptMemFree(prop->pbData);
161 CryptMemFree(prop);
04ed9c2a 162 break;
91b80fc8
JL
163 }
164 }
165 LeaveCriticalSection(&list->cs);
166}
167
168/* Since the properties are stored in a list, this is a tad inefficient
169 * (O(n^2)) since I have to find the previous position every time.
170 */
171DWORD ContextPropertyList_EnumPropIDs(PCONTEXT_PROPERTY_LIST list, DWORD id)
172{
173 DWORD ret;
174
175 EnterCriticalSection(&list->cs);
176 if (id)
177 {
178 PCONTEXT_PROPERTY cursor = NULL;
179
180 LIST_FOR_EACH_ENTRY(cursor, &list->properties, CONTEXT_PROPERTY, entry)
181 {
182 if (cursor->propID == id)
183 break;
184 }
185 if (cursor)
186 {
187 if (cursor->entry.next != &list->properties)
188 ret = LIST_ENTRY(cursor->entry.next, CONTEXT_PROPERTY,
189 entry)->propID;
190 else
191 ret = 0;
192 }
193 else
194 ret = 0;
195 }
196 else if (!list_empty(&list->properties))
197 ret = LIST_ENTRY(list->properties.next, CONTEXT_PROPERTY,
198 entry)->propID;
199 else
200 ret = 0;
201 LeaveCriticalSection(&list->cs);
202 return ret;
203}
204
205void ContextPropertyList_Copy(PCONTEXT_PROPERTY_LIST to,
206 PCONTEXT_PROPERTY_LIST from)
207{
208 PCONTEXT_PROPERTY prop;
209
210 EnterCriticalSection(&from->cs);
211 LIST_FOR_EACH_ENTRY(prop, &from->properties, CONTEXT_PROPERTY, entry)
212 {
213 ContextPropertyList_SetProperty(to, prop->propID, prop->pbData,
214 prop->cbData);
215 }
216 LeaveCriticalSection(&from->cs);
217}