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
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
32 struct list properties
;
35 typedef struct _CONTEXT_PROPERTY
43 CONTEXT_PROPERTY_LIST
*ContextPropertyList_Create(void)
45 CONTEXT_PROPERTY_LIST
*list
= CryptMemAlloc(sizeof(CONTEXT_PROPERTY_LIST
));
49 InitializeCriticalSection(&list
->cs
);
50 list
->cs
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": PCONTEXT_PROPERTY_LIST->cs");
51 list_init(&list
->properties
);
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
,
63 list_remove(&prop
->entry
);
64 CryptMemFree(prop
->pbData
);
67 list
->cs
.DebugInfo
->Spare
[0] = 0;
68 DeleteCriticalSection(&list
->cs
);
72 BOOL
ContextPropertyList_FindProperty(CONTEXT_PROPERTY_LIST
*list
, DWORD id
,
73 PCRYPT_DATA_BLOB blob
)
75 CONTEXT_PROPERTY
*prop
;
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
;
91 LeaveCriticalSection(&list
->cs
);
95 BOOL
ContextPropertyList_SetProperty(CONTEXT_PROPERTY_LIST
*list
, DWORD id
,
96 const BYTE
*pbData
, size_t cbData
)
103 data
= CryptMemAlloc(cbData
);
105 memcpy(data
, pbData
, cbData
);
111 CONTEXT_PROPERTY
*prop
;
114 EnterCriticalSection(&list
->cs
);
115 LIST_FOR_EACH_ENTRY(prop
, &list
->properties
, CONTEXT_PROPERTY
, entry
)
117 if (prop
->propID
== id
)
125 CryptMemFree(prop
->pbData
);
126 prop
->cbData
= cbData
;
132 prop
= CryptMemAlloc(sizeof(CONTEXT_PROPERTY
));
136 prop
->cbData
= cbData
;
138 list_add_tail(&list
->properties
, &prop
->entry
);
144 LeaveCriticalSection(&list
->cs
);
149 void ContextPropertyList_RemoveProperty(CONTEXT_PROPERTY_LIST
*list
, DWORD id
)
151 CONTEXT_PROPERTY
*prop
, *next
;
153 EnterCriticalSection(&list
->cs
);
154 LIST_FOR_EACH_ENTRY_SAFE(prop
, next
, &list
->properties
, CONTEXT_PROPERTY
,
157 if (prop
->propID
== id
)
159 list_remove(&prop
->entry
);
160 CryptMemFree(prop
->pbData
);
165 LeaveCriticalSection(&list
->cs
);
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.
171 DWORD
ContextPropertyList_EnumPropIDs(CONTEXT_PROPERTY_LIST
*list
, DWORD id
)
175 EnterCriticalSection(&list
->cs
);
178 CONTEXT_PROPERTY
*cursor
= NULL
, *prop
;
180 LIST_FOR_EACH_ENTRY(prop
, &list
->properties
, CONTEXT_PROPERTY
, entry
)
182 if (prop
->propID
== id
)
190 if (cursor
->entry
.next
!= &list
->properties
)
191 ret
= LIST_ENTRY(cursor
->entry
.next
, CONTEXT_PROPERTY
,
199 else if (!list_empty(&list
->properties
))
200 ret
= LIST_ENTRY(list
->properties
.next
, CONTEXT_PROPERTY
,
204 LeaveCriticalSection(&list
->cs
);
208 void ContextPropertyList_Copy(CONTEXT_PROPERTY_LIST
*to
, CONTEXT_PROPERTY_LIST
*from
)
210 CONTEXT_PROPERTY
*prop
;
212 EnterCriticalSection(&from
->cs
);
213 LIST_FOR_EACH_ENTRY(prop
, &from
->properties
, CONTEXT_PROPERTY
, entry
)
215 ContextPropertyList_SetProperty(to
, prop
->propID
, prop
->pbData
,
218 LeaveCriticalSection(&from
->cs
);