ReactOS 0.4.16-dev-334-g4d9f67c
collectionstore.c
Go to the documentation of this file.
1/*
2 * Copyright 2004-2007 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 <stdarg.h>
19#include "windef.h"
20#include "winbase.h"
21#include "wincrypt.h"
22#include "wine/debug.h"
23#include "crypt32_private.h"
24
26
28{
32 struct list entry;
34
36{
39 struct list stores;
41
43{
45 TRACE("ref = %d\n", ref);
46}
47
49{
52 LONG ref;
53
54 if(flags)
55 FIXME("Unimplemented flags %x\n", flags);
56
57 ref = InterlockedDecrement(&cs->hdr.ref);
58 TRACE("(%p) ref=%d\n", store, ref);
59 if(ref)
60 return ERROR_SUCCESS;
61
63 {
64 TRACE("closing %p\n", entry);
65 entry->store->vtbl->release(entry->store, flags);
67 }
68 cs->cs.DebugInfo->Spare[0] = 0;
70 CRYPT_FreeStore(store);
71 return ERROR_SUCCESS;
72}
73
75{
76 /* We don't cache context links, so just free them. */
78}
79
82{
84
85 ret = child->vtbl->clone(child, &store->hdr, TRUE);
86 if (!ret)
87 return NULL;
88
89 ret->u.ptr = storeEntry;
90 return ret;
91}
92
94 unsigned int contextFuncsOffset, context_t *context, context_t *toReplace,
95 context_t **pChildContext)
96{
97 BOOL ret;
98 context_t *childContext = NULL;
99 WINE_STORE_LIST_ENTRY *storeEntry = NULL;
100
101 TRACE("(%p, %d, %p, %p)\n", store, contextFuncsOffset, context, toReplace);
102
103 ret = FALSE;
104 if (toReplace)
105 {
106 context_t *existingLinked = toReplace->linked;
107 CONTEXT_FUNCS *contextFuncs;
108
109 storeEntry = toReplace->u.ptr;
110 contextFuncs = (CONTEXT_FUNCS*)((LPBYTE)storeEntry->store->vtbl +
111 contextFuncsOffset);
112 ret = contextFuncs->addContext(storeEntry->store, context,
113 existingLinked, &childContext, TRUE);
114 }
115 else
116 {
118
119 EnterCriticalSection(&store->cs);
121 {
122 if (entry->dwUpdateFlags & CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG)
123 {
124 CONTEXT_FUNCS *contextFuncs = (CONTEXT_FUNCS*)(
125 (LPBYTE)entry->store->vtbl + contextFuncsOffset);
126
127 storeEntry = entry;
128 ret = contextFuncs->addContext(entry->store, context, NULL, &childContext, TRUE);
129 break;
130 }
131 }
132 LeaveCriticalSection(&store->cs);
133 if (!storeEntry)
135 }
136 *pChildContext = childContext;
137 return ret;
138}
139
140/* Advances a collection enumeration by one context, if possible, where
141 * advancing means:
142 * - calling the current store's enumeration function once, and returning
143 * the enumerated context if one is returned
144 * - moving to the next store if the current store has no more items, and
145 * recursively calling itself to get the next item.
146 * Returns NULL if the collection contains no more items or on error.
147 * Assumes the collection store's lock is held.
148 */
150 WINE_STORE_LIST_ENTRY *storeEntry, const CONTEXT_FUNCS *contextFuncs,
151 context_t *prev)
152{
154 struct list *storeNext = list_next(&store->stores, &storeEntry->entry);
155
156 TRACE("(%p, %p, %p)\n", store, storeEntry, prev);
157
158 if (prev)
159 {
160 /* Ref-counting funny business: "duplicate" (addref) the child, because
161 * the free(pPrev) below can cause the ref count to become negative.
162 */
163 child = prev->linked;
165 child = contextFuncs->enumContext(storeEntry->store, child);
166 Context_Release(prev);
167 }
168 else
169 {
170 child = contextFuncs->enumContext(storeEntry->store, NULL);
171 }
172 if (child) {
175 }
176 else
177 {
178 if (storeNext)
179 {
180 /* We always want the same function pointers (from certs, crls)
181 * in the next store, so use the same offset into the next store.
182 */
183 size_t offset = (const BYTE *)contextFuncs - (LPBYTE)storeEntry->store->vtbl;
184 WINE_STORE_LIST_ENTRY *storeNextEntry =
186 CONTEXT_FUNCS *storeNextContexts =
187 (CONTEXT_FUNCS*)((LPBYTE)storeNextEntry->store->vtbl + offset);
188
189 ret = CRYPT_CollectionAdvanceEnum(store, storeNextEntry,
190 storeNextContexts, NULL);
191 }
192 else
193 {
195 ret = NULL;
196 }
197 }
198 TRACE("returning %p\n", ret);
199 return ret;
200}
201
203 context_t *toReplace, context_t **ppStoreContext, BOOL use_link)
204{
205 BOOL ret;
206 context_t *childContext = NULL;
208
210 cert, toReplace, &childContext);
211 if (ppStoreContext && childContext)
212 {
213 WINE_STORE_LIST_ENTRY *storeEntry = childContext->u.ptr;
215 childContext);
216
217 *ppStoreContext = &context->base;
218 }
219 if (childContext)
220 Context_Release(childContext);
221 return ret;
222}
223
225{
227 context_t *ret;
228
229 TRACE("(%p, %p)\n", store, prev);
230
232 if (prev)
233 {
234 WINE_STORE_LIST_ENTRY *storeEntry = prev->u.ptr;
235
236 ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
237 &storeEntry->store->vtbl->certs, prev);
238 }
239 else
240 {
241 if (!list_empty(&cs->stores))
242 {
243 WINE_STORE_LIST_ENTRY *storeEntry = LIST_ENTRY(cs->stores.next,
245
246 ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
247 &storeEntry->store->vtbl->certs, NULL);
248 }
249 else
250 {
252 ret = NULL;
253 }
254 }
256 TRACE("returning %p\n", ret);
257 return ret;
258}
259
261{
263 cert_t *linked;
264
265 TRACE("(%p, %p)\n", store, cert);
266
267 linked = (cert_t*)context->linked;
268 return CertDeleteCertificateFromStore(&linked->ctx);
269}
270
272 context_t *toReplace, context_t **ppStoreContext, BOOL use_link)
273{
274 BOOL ret;
275 context_t *childContext = NULL;
277
279 crl, toReplace, &childContext);
280 if (ppStoreContext && childContext)
281 {
282 WINE_STORE_LIST_ENTRY *storeEntry = childContext->u.ptr;
284 childContext);
285
286 *ppStoreContext = &context->base;
287 }
288 if (childContext)
289 Context_Release(childContext);
290 return ret;
291}
292
294{
296 context_t *ret;
297
298 TRACE("(%p, %p)\n", store, prev);
299
301 if (prev)
302 {
303 WINE_STORE_LIST_ENTRY *storeEntry = prev->u.ptr;
304
305 ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
306 &storeEntry->store->vtbl->crls, prev);
307 }
308 else
309 {
310 if (!list_empty(&cs->stores))
311 {
312 WINE_STORE_LIST_ENTRY *storeEntry = LIST_ENTRY(cs->stores.next,
314
315 ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
316 &storeEntry->store->vtbl->crls, NULL);
317 }
318 else
319 {
321 ret = NULL;
322 }
323 }
325 TRACE("returning %p\n", ret);
326 return ret;
327}
328
330{
331 crl_t *crl = (crl_t*)context, *linked;
332
333 TRACE("(%p, %p)\n", store, crl);
334
335 linked = (crl_t*)context->linked;
336 return CertDeleteCRLFromStore(&linked->ctx);
337}
338
340 context_t *toReplace, context_t **ppStoreContext, BOOL use_link)
341{
342 BOOL ret;
343 context_t *childContext = NULL;
345
347 ctl, toReplace, &childContext);
348 if (ppStoreContext && childContext)
349 {
350 WINE_STORE_LIST_ENTRY *storeEntry = childContext->u.ptr;
352 childContext);
353
354 *ppStoreContext = &context->base;
355 }
356 if (childContext)
357 Context_Release(childContext);
358 return ret;
359}
360
362{
364 void *ret;
365
366 TRACE("(%p, %p)\n", store, prev);
367
369 if (prev)
370 {
371 WINE_STORE_LIST_ENTRY *storeEntry = prev->u.ptr;
372
373 ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
374 &storeEntry->store->vtbl->ctls, prev);
375 }
376 else
377 {
378 if (!list_empty(&cs->stores))
379 {
380 WINE_STORE_LIST_ENTRY *storeEntry = LIST_ENTRY(cs->stores.next,
382
383 ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
384 &storeEntry->store->vtbl->ctls, NULL);
385 }
386 else
387 {
389 ret = NULL;
390 }
391 }
393 TRACE("returning %p\n", ret);
394 return ret;
395}
396
398{
399 ctl_t *ctl = (ctl_t*)context, *linked;
400
401 TRACE("(%p, %p)\n", store, ctl);
402
403 linked = (ctl_t*)context->linked;
404 return CertDeleteCTLFromStore(&linked->ctx);
405}
406
408 DWORD dwCtrlType, void const *pvCtrlPara)
409{
410 BOOL ret;
413
414 TRACE("(%p, %08x, %d, %p)\n", cert_store, dwFlags, dwCtrlType, pvCtrlPara);
415
416 if (!store)
417 return TRUE;
419 {
421 return FALSE;
422 }
423 if (store->hdr.type != StoreTypeCollection)
424 {
426 return FALSE;
427 }
428
429 ret = TRUE;
430 EnterCriticalSection(&store->cs);
432 {
433 if (entry->store->vtbl->control)
434 {
435 ret = entry->store->vtbl->control(entry->store, dwFlags, dwCtrlType, pvCtrlPara);
436 if (!ret)
437 break;
438 }
439 }
440 LeaveCriticalSection(&store->cs);
441 return ret;
442}
443
449 {
453 }, {
457 }, {
461 }
462};
463
465 DWORD dwFlags, const void *pvPara)
466{
468
470 {
472 store = NULL;
473 }
474 else
475 {
476 store = CryptMemAlloc(sizeof(WINE_COLLECTIONSTORE));
477 if (store)
478 {
479 memset(store, 0, sizeof(WINE_COLLECTIONSTORE));
482 store->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PWINE_COLLECTIONSTORE->cs");
483 list_init(&store->stores);
484 }
485 }
486 return (WINECRYPT_CERTSTORE*)store;
487}
488
490 HCERTSTORE hSiblingStore, DWORD dwUpdateFlags, DWORD dwPriority)
491{
492 WINE_COLLECTIONSTORE *collection = hCollectionStore;
493 WINECRYPT_CERTSTORE *sibling = hSiblingStore;
495 BOOL ret;
496
497 TRACE("(%p, %p, %08x, %d)\n", hCollectionStore, hSiblingStore,
498 dwUpdateFlags, dwPriority);
499
500 if (!collection || !sibling)
501 return TRUE;
502 if (collection->hdr.dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
503 {
505 return FALSE;
506 }
507 if (collection->hdr.type != StoreTypeCollection)
508 {
510 return FALSE;
511 }
512 if (sibling->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
513 {
515 return FALSE;
516 }
517
519 if (entry)
520 {
521 InterlockedIncrement(&sibling->ref);
522 TRACE("sibling %p's ref count is %d\n", sibling, sibling->ref);
523 entry->store = sibling;
524 entry->dwUpdateFlags = dwUpdateFlags;
525 entry->dwPriority = dwPriority;
526 TRACE("%p: adding %p, priority %d\n", collection, entry, dwPriority);
528 if (dwPriority)
529 {
531 BOOL added = FALSE;
532
535 {
536 if (cursor->dwPriority < dwPriority)
537 {
538 list_add_before(&cursor->entry, &entry->entry);
539 added = TRUE;
540 break;
541 }
542 }
543 if (!added)
544 list_add_tail(&collection->stores, &entry->entry);
545 }
546 else
547 list_add_tail(&collection->stores, &entry->entry);
549 ret = TRUE;
550 }
551 else
552 ret = FALSE;
553 return ret;
554}
555
557 HCERTSTORE hSiblingStore)
558{
559 WINE_COLLECTIONSTORE *collection = hCollectionStore;
560 WINECRYPT_CERTSTORE *sibling = hSiblingStore;
562
563 TRACE("(%p, %p)\n", hCollectionStore, hSiblingStore);
564
565 if (!collection || !sibling)
566 return;
567 if (collection->hdr.dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
568 {
570 return;
571 }
572 if (collection->hdr.type != StoreTypeCollection)
573 return;
574 if (sibling->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
575 {
577 return;
578 }
581 {
582 if (store->store == sibling)
583 {
584 list_remove(&store->entry);
585 CertCloseStore(store->store, 0);
586 CryptMemFree(store);
587 break;
588 }
589 }
591}
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static int list_empty(struct list_entry *head)
Definition: list.h:58
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
static void list_init(struct list_entry *head)
Definition: list.h:51
#define FIXME(fmt,...)
Definition: precomp.h:53
Definition: list.h:37
static void Collection_releaseContext(WINECRYPT_CERTSTORE *store, context_t *context)
static BOOL Collection_deleteCert(WINECRYPT_CERTSTORE *store, context_t *context)
static BOOL Collection_control(WINECRYPT_CERTSTORE *cert_store, DWORD dwFlags, DWORD dwCtrlType, void const *pvCtrlPara)
static context_t * CRYPT_CollectionAdvanceEnum(WINE_COLLECTIONSTORE *store, WINE_STORE_LIST_ENTRY *storeEntry, const CONTEXT_FUNCS *contextFuncs, context_t *prev)
static DWORD Collection_release(WINECRYPT_CERTSTORE *store, DWORD flags)
static BOOL CRYPT_CollectionAddContext(WINE_COLLECTIONSTORE *store, unsigned int contextFuncsOffset, context_t *context, context_t *toReplace, context_t **pChildContext)
static BOOL Collection_addCTL(WINECRYPT_CERTSTORE *store, context_t *ctl, context_t *toReplace, context_t **ppStoreContext, BOOL use_link)
struct _WINE_STORE_LIST_ENTRY WINE_STORE_LIST_ENTRY
static context_t * Collection_enumCRL(WINECRYPT_CERTSTORE *store, context_t *prev)
BOOL WINAPI CertAddStoreToCollection(HCERTSTORE hCollectionStore, HCERTSTORE hSiblingStore, DWORD dwUpdateFlags, DWORD dwPriority)
static void Collection_addref(WINECRYPT_CERTSTORE *store)
static BOOL Collection_addCert(WINECRYPT_CERTSTORE *store, context_t *cert, context_t *toReplace, context_t **ppStoreContext, BOOL use_link)
static const store_vtbl_t CollectionStoreVtbl
static BOOL Collection_deleteCTL(WINECRYPT_CERTSTORE *store, context_t *context)
WINECRYPT_CERTSTORE * CRYPT_CollectionOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags, const void *pvPara)
static context_t * Collection_enumCTL(WINECRYPT_CERTSTORE *store, context_t *prev)
void WINAPI CertRemoveStoreFromCollection(HCERTSTORE hCollectionStore, HCERTSTORE hSiblingStore)
static context_t * CRYPT_CollectionCreateContextFromChild(WINE_COLLECTIONSTORE *store, WINE_STORE_LIST_ENTRY *storeEntry, context_t *child)
struct _WINE_COLLECTIONSTORE WINE_COLLECTIONSTORE
static BOOL Collection_addCRL(WINECRYPT_CERTSTORE *store, context_t *crl, context_t *toReplace, context_t **ppStoreContext, BOOL use_link)
static BOOL Collection_deleteCRL(WINECRYPT_CERTSTORE *store, context_t *context)
static context_t * Collection_enumCert(WINECRYPT_CERTSTORE *store, context_t *prev)
#define WINE_CRYPTCERTSTORE_MAGIC
void CRYPT_FreeStore(WINECRYPT_CERTSTORE *store) DECLSPEC_HIDDEN
Definition: store.c:101
@ StoreTypeCollection
void CRYPT_InitStore(WINECRYPT_CERTSTORE *store, DWORD dwFlags, CertStoreType type, const store_vtbl_t *) DECLSPEC_HIDDEN
Definition: store.c:91
#define E_INVALIDARG
Definition: ddrawi.h:101
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
void Context_AddRef(context_t *context)
Definition: context.c:78
void Context_Release(context_t *context)
Definition: context.c:106
void Context_Free(context_t *context)
Definition: context.c:90
BOOL WINAPI CertDeleteCTLFromStore(PCCTL_CONTEXT pCtlContext)
Definition: ctl.c:341
LPVOID WINAPI CryptMemAlloc(ULONG cbSize)
Definition: main.c:131
VOID WINAPI CryptMemFree(LPVOID pv)
Definition: main.c:141
BOOL WINAPI CertDeleteCRLFromStore(PCCRL_CONTEXT pCrlContext)
Definition: store.c:1080
BOOL WINAPI CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
Definition: store.c:1127
BOOL WINAPI CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext)
Definition: store.c:943
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define SetLastError(x)
Definition: compat.h:752
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLbitfield flags
Definition: glext.h:7161
GLintptr offset
Definition: glext.h:5920
#define cs
Definition: i386-dis.c:442
const char cursor[]
Definition: icontest.c:13
uint32_t entry
Definition: isohybrid.c:63
static const BYTE crl[]
Definition: message.c:864
static BYTE cert[]
Definition: msg.c:1437
DWORD cert_store
Definition: store.c:344
static ICollection collection
Definition: typelib.c:184
static HWND child
Definition: cursoricon.c:298
long LONG
Definition: pedump.c:60
static unsigned __int64 next
Definition: rand_nt.c:6
#define offsetof(TYPE, MEMBER)
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:204
__WINE_SERVER_LIST_INLINE struct list * list_next(const struct list *list, const struct list *elem)
Definition: list.h:115
__WINE_SERVER_LIST_INLINE void list_add_before(struct list *elem, struct list *to_add)
Definition: list.h:87
#define memset(x, y, z)
Definition: compat.h:39
#define TRACE(s)
Definition: solgame.cpp:4
const store_vtbl_t * vtbl
context_t *(* enumContext)(struct WINE_CRYPTCERTSTORE *store, context_t *prev)
BOOL(* addContext)(struct WINE_CRYPTCERTSTORE *, context_t *, context_t *, context_t **, BOOL)
DWORD_PTR Spare[8/sizeof(DWORD_PTR)]
Definition: winbase.h:912
PCRITICAL_SECTION_DEBUG DebugInfo
Definition: winbase.h:919
WINECRYPT_CERTSTORE hdr
CRITICAL_SECTION cs
DWORD dwUpdateFlags
struct list entry
DWORD dwPriority
WINECRYPT_CERTSTORE * store
struct _context_t * linked
union _context_t::@350 u
CERT_CONTEXT ctx
Definition: http.c:7252
struct define * next
Definition: compiler.c:65
Definition: send.c:48
CONTEXT_FUNCS ctls
CONTEXT_FUNCS crls
CONTEXT_FUNCS certs
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
#define LIST_ENTRY(type)
Definition: queue.h:175
#define DWORD_PTR
Definition: treelist.c:76
unsigned char * LPBYTE
Definition: typedefs.h:53
int ret
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
#define CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG
Definition: wincrypt.h:2580
ULONG_PTR HCRYPTPROV
Definition: wincrypt.h:46
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
_In_ void * pvPara
Definition: wincrypt.h:6077
_In_ PCCERT_CONTEXT _In_ DWORD _Outptr_opt_ PCCERT_CONTEXT * ppStoreContext
Definition: wincrypt.h:4985
#define CERT_STORE_DELETE_FLAG
Definition: wincrypt.h:2455
#define WINAPI
Definition: msvc.h:6
#define CRYPT_E_NOT_FOUND
Definition: winerror.h:3007
#define E_ACCESSDENIED
Definition: winerror.h:2849
unsigned char BYTE
Definition: xxhash.c:193