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
19 #include "crypt32_private.h"
21 WINE_DEFAULT_DEBUG_CHANNEL(crypt
);
23 struct _CONTEXT_PROPERTY_LIST
26 struct list properties
;
29 typedef struct _CONTEXT_PROPERTY
37 CONTEXT_PROPERTY_LIST
*ContextPropertyList_Create(void)
39 CONTEXT_PROPERTY_LIST
*list
= CryptMemAlloc(sizeof(CONTEXT_PROPERTY_LIST
));
43 InitializeCriticalSection(&list
->cs
);
44 list
->cs
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": PCONTEXT_PROPERTY_LIST->cs");
45 list_init(&list
->properties
);
50 void ContextPropertyList_Free(CONTEXT_PROPERTY_LIST
*list
)
52 CONTEXT_PROPERTY
*prop
, *next
;
54 LIST_FOR_EACH_ENTRY_SAFE(prop
, next
, &list
->properties
, CONTEXT_PROPERTY
,
57 list_remove(&prop
->entry
);
58 CryptMemFree(prop
->pbData
);
61 list
->cs
.DebugInfo
->Spare
[0] = 0;
62 DeleteCriticalSection(&list
->cs
);
66 BOOL
ContextPropertyList_FindProperty(CONTEXT_PROPERTY_LIST
*list
, DWORD id
,
67 PCRYPT_DATA_BLOB blob
)
69 CONTEXT_PROPERTY
*prop
;
72 TRACE("(%p, %d, %p)\n", list
, id
, blob
);
74 EnterCriticalSection(&list
->cs
);
75 LIST_FOR_EACH_ENTRY(prop
, &list
->properties
, CONTEXT_PROPERTY
, entry
)
77 if (prop
->propID
== id
)
79 blob
->cbData
= prop
->cbData
;
80 blob
->pbData
= prop
->pbData
;
85 LeaveCriticalSection(&list
->cs
);
89 BOOL
ContextPropertyList_SetProperty(CONTEXT_PROPERTY_LIST
*list
, DWORD id
,
90 const BYTE
*pbData
, size_t cbData
)
97 data
= CryptMemAlloc(cbData
);
99 memcpy(data
, pbData
, cbData
);
105 CONTEXT_PROPERTY
*prop
;
108 EnterCriticalSection(&list
->cs
);
109 LIST_FOR_EACH_ENTRY(prop
, &list
->properties
, CONTEXT_PROPERTY
, entry
)
111 if (prop
->propID
== id
)
119 CryptMemFree(prop
->pbData
);
120 prop
->cbData
= cbData
;
126 prop
= CryptMemAlloc(sizeof(CONTEXT_PROPERTY
));
130 prop
->cbData
= cbData
;
132 list_add_tail(&list
->properties
, &prop
->entry
);
138 LeaveCriticalSection(&list
->cs
);
143 void ContextPropertyList_RemoveProperty(CONTEXT_PROPERTY_LIST
*list
, DWORD id
)
145 CONTEXT_PROPERTY
*prop
;
147 EnterCriticalSection(&list
->cs
);
148 LIST_FOR_EACH_ENTRY(prop
, &list
->properties
, CONTEXT_PROPERTY
, entry
)
150 if (prop
->propID
== id
)
152 list_remove(&prop
->entry
);
153 CryptMemFree(prop
->pbData
);
158 LeaveCriticalSection(&list
->cs
);
161 /* Since the properties are stored in a list, this is a tad inefficient
162 * (O(n^2)) since I have to find the previous position every time.
164 DWORD
ContextPropertyList_EnumPropIDs(CONTEXT_PROPERTY_LIST
*list
, DWORD id
)
168 EnterCriticalSection(&list
->cs
);
171 CONTEXT_PROPERTY
*cursor
= NULL
, *prop
;
173 LIST_FOR_EACH_ENTRY(prop
, &list
->properties
, CONTEXT_PROPERTY
, entry
)
175 if (prop
->propID
== id
)
183 if (cursor
->entry
.next
!= &list
->properties
)
184 ret
= LIST_ENTRY(cursor
->entry
.next
, CONTEXT_PROPERTY
,
192 else if (!list_empty(&list
->properties
))
193 ret
= LIST_ENTRY(list
->properties
.next
, CONTEXT_PROPERTY
,
197 LeaveCriticalSection(&list
->cs
);
201 void ContextPropertyList_Copy(CONTEXT_PROPERTY_LIST
*to
, CONTEXT_PROPERTY_LIST
*from
)
203 CONTEXT_PROPERTY
*prop
;
205 EnterCriticalSection(&from
->cs
);
206 LIST_FOR_EACH_ENTRY(prop
, &from
->properties
, CONTEXT_PROPERTY
, entry
)
208 ContextPropertyList_SetProperty(to
, prop
->propID
, prop
->pbData
,
211 LeaveCriticalSection(&from
->cs
);