source: branches/swt/src/crypt32/proplist.c

Last change on this file was 22020, checked in by dmik, 13 years ago

Disable debug fields of RTL_CRITICAL_SECTION_DEBUG.

Odin uses the DebugInfo ptr in CRITICAL_SECTION for its own purposes
which are incompatible with NT. For this reason any NT-style usage must
be disabled.

This in particular fixes debug assertions and crashes in CRYPT32.DLL (due to
misinterpretation of the structure fields) which happened e.g. during playback of
some Flash content.

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