ReactOS  0.4.14-dev-49-gfb4591c
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 
27 typedef struct _WINE_STORE_LIST_ENTRY
28 {
32  struct list entry;
34 
35 typedef struct _WINE_COLLECTIONSTORE
36 {
39  struct list stores;
41 
43 {
44  LONG ref = InterlockedIncrement(&store->ref);
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 {
83  context_t *ret;
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 {
153  context_t *child, *ret;
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);
167  }
168  else
169  {
170  child = contextFuncs->enumContext(storeEntry->store, NULL);
171  }
172  if (child) {
173  ret = CRYPT_CollectionCreateContextFromChild(store, storeEntry, 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 
231  EnterCriticalSection(&cs->cs);
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  }
255  LeaveCriticalSection(&cs->cs);
256  TRACE("returning %p\n", ret);
257  return ret;
258 }
259 
261 {
262  cert_t *cert = (cert_t*)context;
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 
300  EnterCriticalSection(&cs->cs);
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  }
324  LeaveCriticalSection(&cs->cs);
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 
368  EnterCriticalSection(&cs->cs);
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  }
392  LeaveCriticalSection(&cs->cs);
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;
418  if (store->hdr.dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
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 {
467  WINE_COLLECTIONSTORE *store;
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));
481  InitializeCriticalSection(&store->cs);
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;
561  WINE_STORE_LIST_ENTRY *store;
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 CERT_STORE_DELETE_FLAG
Definition: wincrypt.h:2455
WINECRYPT_CERTSTORE * CRYPT_CollectionOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags, const void *pvPara)
CERT_CONTEXT ctx
#define E_ACCESSDENIED
Definition: winerror.h:2849
struct list * prev
Definition: list.h:39
#define TRUE
Definition: types.h:120
static const BYTE crl[]
Definition: message.c:864
#define ERROR_SUCCESS
Definition: deptool.c:10
#define CRYPT_E_NOT_FOUND
Definition: winerror.h:3007
#define DWORD_PTR
Definition: treelist.c:76
Definition: http.c:6587
static BOOL Collection_addCTL(WINECRYPT_CERTSTORE *store, context_t *ctl, context_t *toReplace, context_t **ppStoreContext, BOOL use_link)
static const store_vtbl_t CollectionStoreVtbl
static void Collection_addref(WINECRYPT_CERTSTORE *store)
DWORD dwPriority
GLintptr offset
Definition: glext.h:5920
CRITICAL_SECTION cs
static BOOL Collection_deleteCert(WINECRYPT_CERTSTORE *store, context_t *context)
WINE_DEFAULT_DEBUG_CHANNEL(crypt)
DWORD dwUpdateFlags
void Context_AddRef(context_t *context)
Definition: context.c:78
void CRYPT_FreeStore(WINECRYPT_CERTSTORE *store) DECLSPEC_HIDDEN
Definition: store.c:101
static BOOL CRYPT_CollectionAddContext(WINE_COLLECTIONSTORE *store, unsigned int contextFuncsOffset, context_t *context, context_t *toReplace, context_t **pChildContext)
BOOL WINAPI CertAddStoreToCollection(HCERTSTORE hCollectionStore, HCERTSTORE hSiblingStore, DWORD dwUpdateFlags, DWORD dwPriority)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
static BOOL Collection_deleteCTL(WINECRYPT_CERTSTORE *store, context_t *context)
CONTEXT_FUNCS crls
Definition: send.c:47
static HWND child
Definition: cursoricon.c:298
void Context_Release(context_t *context)
Definition: context.c:106
BOOL(* addContext)(struct WINE_CRYPTCERTSTORE *, context_t *, context_t *, context_t **, BOOL)
_In_ PCCERT_CONTEXT _In_ DWORD _Outptr_opt_ PCCERT_CONTEXT * ppStoreContext
Definition: wincrypt.h:4987
static context_t * CRYPT_CollectionCreateContextFromChild(WINE_COLLECTIONSTORE *store, WINE_STORE_LIST_ENTRY *storeEntry, context_t *child)
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
Definition: list.h:102
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
uint32_t cs
Definition: isohybrid.c:75
static context_t * CRYPT_CollectionAdvanceEnum(WINE_COLLECTIONSTORE *store, WINE_STORE_LIST_ENTRY *storeEntry, const CONTEXT_FUNCS *contextFuncs, context_t *prev)
LPVOID WINAPI CryptMemAlloc(ULONG cbSize)
Definition: main.c:131
WINECRYPT_CERTSTORE * store
CONTEXT_FUNCS ctls
unsigned char * LPBYTE
Definition: typedefs.h:52
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
struct _WINE_COLLECTIONSTORE WINE_COLLECTIONSTORE
GLenum GLint ref
Definition: glext.h:6028
CONTEXT_FUNCS certs
#define FIXME(fmt,...)
Definition: debug.h:110
BOOL WINAPI CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext)
Definition: store.c:943
#define E_INVALIDARG
Definition: ddrawi.h:101
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
smooth NULL
Definition: ftsmooth.c:416
#define offsetof(TYPE, MEMBER)
BOOL WINAPI CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
Definition: store.c:1127
static BYTE cert[]
Definition: msg.c:1437
void Context_Free(context_t *context)
Definition: context.c:90
static DWORD Collection_release(WINECRYPT_CERTSTORE *store, DWORD flags)
union _context_t::@334 u
struct list entry
__WINE_SERVER_LIST_INLINE void list_remove(struct list *elem)
Definition: list.h:108
#define TRACE(s)
Definition: solgame.cpp:4
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
const store_vtbl_t * vtbl
WINECRYPT_CERTSTORE hdr
#define WINE_CRYPTCERTSTORE_MAGIC
#define WINAPI
Definition: msvc.h:8
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:409
void WINAPI CertRemoveStoreFromCollection(HCERTSTORE hCollectionStore, HCERTSTORE hSiblingStore)
PCRITICAL_SECTION_DEBUG DebugInfo
Definition: winbase.h:859
GLbitfield flags
Definition: glext.h:7161
BOOL WINAPI CertDeleteCTLFromStore(PCCTL_CONTEXT pCtlContext)
Definition: ctl.c:341
static context_t * Collection_enumCert(WINECRYPT_CERTSTORE *store, context_t *prev)
int ret
#define InterlockedDecrement
Definition: armddk.h:52
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
uint32_t entry
Definition: isohybrid.c:63
static context_t * Collection_enumCTL(WINECRYPT_CERTSTORE *store, context_t *prev)
static BOOL Collection_addCRL(WINECRYPT_CERTSTORE *store, context_t *crl, context_t *toReplace, context_t **ppStoreContext, BOOL use_link)
unsigned char BYTE
Definition: mem.h:68
Definition: _list.h:228
DWORD cert_store
Definition: store.c:344
context_t *(* enumContext)(struct WINE_CRYPTCERTSTORE *store, context_t *prev)
__WINE_SERVER_LIST_INLINE int list_empty(const struct list *list)
Definition: list.h:143
struct _context_t * linked
static unsigned __int64 next
Definition: rand_nt.c:6
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:204
#define InterlockedIncrement
Definition: armddk.h:53
const char cursor[]
Definition: icontest.c:13
ULONG_PTR HCRYPTPROV
Definition: wincrypt.h:46
struct _WINE_STORE_LIST_ENTRY WINE_STORE_LIST_ENTRY
static ICollection collection
Definition: typelib.c:184
BOOL WINAPI CertDeleteCRLFromStore(PCCRL_CONTEXT pCrlContext)
Definition: store.c:1080
__WINE_SERVER_LIST_INLINE void list_add_before(struct list *elem, struct list *to_add)
Definition: list.h:87
VOID WINAPI CryptMemFree(LPVOID pv)
Definition: main.c:141
static context_t * Collection_enumCRL(WINECRYPT_CERTSTORE *store, context_t *prev)
static BOOL Collection_addCert(WINECRYPT_CERTSTORE *store, context_t *cert, context_t *toReplace, context_t **ppStoreContext, BOOL use_link)
__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_init(struct list *list)
Definition: list.h:149
static BOOL Collection_control(WINECRYPT_CERTSTORE *cert_store, DWORD dwFlags, DWORD dwCtrlType, void const *pvCtrlPara)
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:92
_In_ void * pvPara
Definition: wincrypt.h:6081
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
#define LIST_ENTRY(type)
Definition: queue.h:175
#define CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG
Definition: wincrypt.h:2580
static BOOL Collection_deleteCRL(WINECRYPT_CERTSTORE *store, context_t *context)
#define memset(x, y, z)
Definition: compat.h:39
static void Collection_releaseContext(WINECRYPT_CERTSTORE *store, context_t *context)
void CRYPT_InitStore(WINECRYPT_CERTSTORE *store, DWORD dwFlags, CertStoreType type, const store_vtbl_t *) DECLSPEC_HIDDEN
Definition: store.c:91
DWORD_PTR Spare[8/sizeof(DWORD_PTR)]
Definition: winbase.h:852