~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/crypt32/collectionstore.c

Version: ~ [ wine-1.5.30 ] ~ [ wine-1.5.29 ] ~ [ wine-1.5.28 ] ~ [ wine-1.5.27 ] ~ [ wine-1.5.26 ] ~ [ wine-1.5.25 ] ~ [ wine-1.5.24 ] ~ [ wine-1.5.23 ] ~ [ wine-1.5.22 ] ~ [ wine-1.5.21 ] ~ [ wine-1.5.20 ] ~ [ wine-1.5.19 ] ~ [ wine-1.5.18 ] ~ [ wine-1.5.17 ] ~ [ wine-1.5.16 ] ~ [ wine-1.5.15 ] ~ [ wine-1.5.14 ] ~ [ wine-1.5.13 ] ~ [ wine-1.5.12 ] ~ [ wine-1.5.11 ] ~ [ wine-1.5.10 ] ~ [ wine-1.5.9 ] ~ [ wine-1.5.8 ] ~ [ wine-1.5.7 ] ~ [ wine-1.4.1 ] ~ [ wine-1.5.6 ] ~ [ wine-1.5.5 ] ~ [ wine-1.5.4 ] ~ [ wine-1.5.3 ] ~ [ wine-1.5.2 ] ~ [ wine-1.5.1 ] ~ [ wine-1.5.0 ] ~ [ wine-1.4 ] ~ [ wine-1.4-rc6 ] ~ [ wine-1.4-rc5 ] ~ [ wine-1.4-rc4 ] ~ [ wine-1.4-rc3 ] ~ [ wine-1.4-rc2 ] ~ [ wine-1.4-rc1 ] ~ [ wine-1.3.37 ] ~ [ wine-1.3.36 ] ~ [ wine-1.3.35 ] ~ [ wine-1.3.34 ] ~ [ wine-1.3.33 ] ~ [ wine-1.3.32 ] ~ [ wine-1.3.31 ] ~ [ wine-1.3.30 ] ~ [ wine-1.3.29 ] ~ [ wine-1.3.28 ] ~ [ wine-1.3.27 ] ~ [ wine-1.3.26 ] ~ [ wine-1.3.25 ] ~ [ wine-1.3.24 ] ~ [ wine-1.3.23 ] ~ [ wine-1.3.22 ] ~ [ wine-1.3.21 ] ~ [ wine-1.3.20 ] ~ [ wine-1.3.19 ] ~ [ wine-1.3.18 ] ~ [ wine-1.2.3 ] ~ [ wine-1.3.17 ] ~ [ wine-1.3.16 ] ~ [ wine-1.3.15 ] ~ [ wine-1.3.14 ] ~ [ wine-1.3.13 ] ~ [ wine-1.3.12 ] ~ [ wine-1.3.11 ] ~ [ wine-1.3.10 ] ~ [ wine-1.3.9 ] ~ [ wine-1.2.2 ] ~ [ wine-1.3.8 ] ~ [ wine-1.3.7 ] ~ [ wine-1.3.6 ] ~ [ wine-1.3.5 ] ~ [ wine-1.2.1 ] ~ [ wine-1.3.4 ] ~ [ wine-1.3.3 ] ~ [ wine-1.3.2 ] ~ [ wine-1.3.1 ] ~ [ wine-1.3.0 ] ~ [ wine-1.2 ] ~ [ wine-1.2-rc7 ] ~ [ wine-1.2-rc6 ] ~ [ wine-1.2-rc5 ] ~ [ wine-1.2-rc4 ] ~ [ wine-1.2-rc3 ] ~ [ wine-1.2-rc2 ] ~ [ wine-1.2-rc1 ] ~ [ wine-1.1.44 ] ~ [ wine-1.1.43 ] ~ [ wine-1.1.42 ] ~ [ wine-1.1.41 ] ~ [ wine-1.1.40 ] ~ [ wine-1.1.39 ] ~ [ wine-1.1.38 ] ~ [ wine-1.1.37 ] ~ [ wine-1.1.36 ] ~ [ wine-1.1.35 ] ~ [ wine-1.1.34 ] ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  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 "wine/list.h"
 24 #include "crypt32_private.h"
 25 
 26 WINE_DEFAULT_DEBUG_CHANNEL(crypt);
 27 
 28 typedef struct _WINE_STORE_LIST_ENTRY
 29 {
 30     PWINECRYPT_CERTSTORE store;
 31     DWORD                dwUpdateFlags;
 32     DWORD                dwPriority;
 33     struct list          entry;
 34 } WINE_STORE_LIST_ENTRY, *PWINE_STORE_LIST_ENTRY;
 35 
 36 typedef struct _WINE_COLLECTIONSTORE
 37 {
 38     WINECRYPT_CERTSTORE hdr;
 39     CRITICAL_SECTION    cs;
 40     struct list         stores;
 41 } WINE_COLLECTIONSTORE, *PWINE_COLLECTIONSTORE;
 42 
 43 static void WINAPI CRYPT_CollectionCloseStore(HCERTSTORE store, DWORD dwFlags)
 44 {
 45     PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
 46     PWINE_STORE_LIST_ENTRY entry, next;
 47 
 48     TRACE("(%p, %08x)\n", store, dwFlags);
 49 
 50     LIST_FOR_EACH_ENTRY_SAFE(entry, next, &cs->stores, WINE_STORE_LIST_ENTRY,
 51      entry)
 52     {
 53         TRACE("closing %p\n", entry);
 54         CertCloseStore((HCERTSTORE)entry->store, dwFlags);
 55         CryptMemFree(entry);
 56     }
 57     cs->cs.DebugInfo->Spare[0] = 0;
 58     DeleteCriticalSection(&cs->cs);
 59     CRYPT_FreeStore((PWINECRYPT_CERTSTORE)store);
 60 }
 61 
 62 static void *CRYPT_CollectionCreateContextFromChild(PWINE_COLLECTIONSTORE store,
 63  PWINE_STORE_LIST_ENTRY storeEntry, void *child, size_t contextSize,
 64  BOOL addRef)
 65 {
 66     void *ret = Context_CreateLinkContext(contextSize, child,
 67      sizeof(PWINE_STORE_LIST_ENTRY), addRef);
 68 
 69     if (ret)
 70         *(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(ret, contextSize)
 71          = storeEntry;
 72 
 73     return ret;
 74 }
 75 
 76 static BOOL CRYPT_CollectionAddContext(PWINE_COLLECTIONSTORE store,
 77  unsigned int contextFuncsOffset, void *context, void *toReplace, unsigned int contextSize,
 78  void **pChildContext)
 79 {
 80     BOOL ret;
 81     void *childContext = NULL;
 82     PWINE_STORE_LIST_ENTRY storeEntry = NULL;
 83 
 84     TRACE("(%p, %d, %p, %p, %d)\n", store, contextFuncsOffset, context,
 85      toReplace, contextSize);
 86 
 87     ret = FALSE;
 88     if (toReplace)
 89     {
 90         void *existingLinked = Context_GetLinkedContext(toReplace, contextSize);
 91         PCONTEXT_FUNCS contextFuncs;
 92 
 93         storeEntry = *(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(toReplace,
 94          contextSize);
 95         contextFuncs = (PCONTEXT_FUNCS)((LPBYTE)storeEntry->store +
 96          contextFuncsOffset);
 97         ret = contextFuncs->addContext(storeEntry->store, context,
 98          existingLinked, childContext);
 99     }
100     else
101     {
102         PWINE_STORE_LIST_ENTRY entry, next;
103 
104         EnterCriticalSection(&store->cs);
105         LIST_FOR_EACH_ENTRY_SAFE(entry, next, &store->stores,
106          WINE_STORE_LIST_ENTRY, entry)
107         {
108             if (entry->dwUpdateFlags & CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG)
109             {
110                 PCONTEXT_FUNCS contextFuncs = (PCONTEXT_FUNCS)(
111                  (LPBYTE)entry->store + contextFuncsOffset);
112 
113                 storeEntry = entry;
114                 ret = contextFuncs->addContext(entry->store, context, NULL,
115                  (const void **)&childContext);
116                 break;
117             }
118         }
119         LeaveCriticalSection(&store->cs);
120         if (!storeEntry)
121             SetLastError(E_ACCESSDENIED);
122     }
123     *pChildContext = childContext;
124     return ret;
125 }
126 
127 /* Advances a collection enumeration by one context, if possible, where
128  * advancing means:
129  * - calling the current store's enumeration function once, and returning
130  *   the enumerated context if one is returned
131  * - moving to the next store if the current store has no more items, and
132  *   recursively calling itself to get the next item.
133  * Returns NULL if the collection contains no more items or on error.
134  * Assumes the collection store's lock is held.
135  */
136 static void *CRYPT_CollectionAdvanceEnum(PWINE_COLLECTIONSTORE store,
137  PWINE_STORE_LIST_ENTRY storeEntry, PCONTEXT_FUNCS contextFuncs,
138  PCWINE_CONTEXT_INTERFACE contextInterface, void *pPrev, size_t contextSize)
139 {
140     void *ret, *child;
141     struct list *storeNext = list_next(&store->stores, &storeEntry->entry);
142 
143     TRACE("(%p, %p, %p)\n", store, storeEntry, pPrev);
144 
145     if (pPrev)
146     {
147         /* Ref-counting funny business: "duplicate" (addref) the child, because
148          * the free(pPrev) below can cause the ref count to become negative.
149          */
150         child = Context_GetLinkedContext(pPrev, contextSize);
151         contextInterface->duplicate(child);
152         child = contextFuncs->enumContext(storeEntry->store, child);
153         contextInterface->free(pPrev);
154         pPrev = NULL;
155     }
156     else
157         child = contextFuncs->enumContext(storeEntry->store, NULL);
158     if (child)
159         ret = CRYPT_CollectionCreateContextFromChild(store, storeEntry, child,
160          contextSize, FALSE);
161     else
162     {
163         if (storeNext)
164         {
165             /* We always want the same function pointers (from certs, crls)
166              * in the next store, so use the same offset into the next store.
167              */
168             size_t offset = (LPBYTE)contextFuncs - (LPBYTE)storeEntry->store;
169             PWINE_STORE_LIST_ENTRY storeNextEntry =
170              LIST_ENTRY(storeNext, WINE_STORE_LIST_ENTRY, entry);
171             PCONTEXT_FUNCS storeNextContexts =
172              (PCONTEXT_FUNCS)((LPBYTE)storeNextEntry->store + offset);
173 
174             ret = CRYPT_CollectionAdvanceEnum(store, storeNextEntry,
175              storeNextContexts, contextInterface, NULL, contextSize);
176         }
177         else
178         {
179             SetLastError(CRYPT_E_NOT_FOUND);
180             ret = NULL;
181         }
182     }
183     TRACE("returning %p\n", ret);
184     return ret;
185 }
186 
187 static BOOL CRYPT_CollectionAddCert(PWINECRYPT_CERTSTORE store, void *cert,
188  void *toReplace, const void **ppStoreContext)
189 {
190     BOOL ret;
191     void *childContext = NULL;
192     PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
193 
194     ret = CRYPT_CollectionAddContext(cs, offsetof(WINECRYPT_CERTSTORE, certs),
195      cert, toReplace, sizeof(CERT_CONTEXT), &childContext);
196     if (ppStoreContext && childContext)
197     {
198         PWINE_STORE_LIST_ENTRY storeEntry = *(PWINE_STORE_LIST_ENTRY *)
199          Context_GetExtra(childContext, sizeof(CERT_CONTEXT));
200         PCERT_CONTEXT context =
201          CRYPT_CollectionCreateContextFromChild(cs, storeEntry, childContext,
202          sizeof(CERT_CONTEXT), TRUE);
203 
204         if (context)
205             context->hCertStore = store;
206         *ppStoreContext = context;
207     }
208     CertFreeCertificateContext((PCCERT_CONTEXT)childContext);
209     return ret;
210 }
211 
212 static void *CRYPT_CollectionEnumCert(PWINECRYPT_CERTSTORE store, void *pPrev)
213 {
214     PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
215     void *ret;
216 
217     TRACE("(%p, %p)\n", store, pPrev);
218 
219     EnterCriticalSection(&cs->cs);
220     if (pPrev)
221     {
222         PWINE_STORE_LIST_ENTRY storeEntry =
223          *(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(pPrev,
224          sizeof(CERT_CONTEXT));
225 
226         ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
227          &storeEntry->store->certs, pCertInterface, pPrev,
228          sizeof(CERT_CONTEXT));
229     }
230     else
231     {
232         if (!list_empty(&cs->stores))
233         {
234             PWINE_STORE_LIST_ENTRY storeEntry = LIST_ENTRY(cs->stores.next,
235              WINE_STORE_LIST_ENTRY, entry);
236 
237             ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
238              &storeEntry->store->certs, pCertInterface, NULL,
239              sizeof(CERT_CONTEXT));
240         }
241         else
242         {
243             SetLastError(CRYPT_E_NOT_FOUND);
244             ret = NULL;
245         }
246     }
247     LeaveCriticalSection(&cs->cs);
248     if (ret)
249         ((PCERT_CONTEXT)ret)->hCertStore = store;
250     TRACE("returning %p\n", ret);
251     return ret;
252 }
253 
254 static BOOL CRYPT_CollectionDeleteCert(PWINECRYPT_CERTSTORE store,
255  void *pCertContext)
256 {
257     BOOL ret;
258 
259     TRACE("(%p, %p)\n", store, pCertContext);
260 
261     ret = CertDeleteCertificateFromStore((PCCERT_CONTEXT)
262      Context_GetLinkedContext(pCertContext, sizeof(CERT_CONTEXT)));
263     return ret;
264 }
265 
266 static BOOL CRYPT_CollectionAddCRL(PWINECRYPT_CERTSTORE store, void *crl,
267  void *toReplace, const void **ppStoreContext)
268 {
269     BOOL ret;
270     void *childContext = NULL;
271     PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
272 
273     ret = CRYPT_CollectionAddContext(cs, offsetof(WINECRYPT_CERTSTORE, crls),
274      crl, toReplace, sizeof(CRL_CONTEXT), &childContext);
275     if (ppStoreContext && childContext)
276     {
277         PWINE_STORE_LIST_ENTRY storeEntry = *(PWINE_STORE_LIST_ENTRY *)
278          Context_GetExtra(childContext, sizeof(CRL_CONTEXT));
279         PCRL_CONTEXT context =
280          CRYPT_CollectionCreateContextFromChild(cs, storeEntry, childContext,
281          sizeof(CRL_CONTEXT), TRUE);
282 
283         if (context)
284             context->hCertStore = store;
285         *ppStoreContext = context;
286     }
287     CertFreeCRLContext((PCCRL_CONTEXT)childContext);
288     return ret;
289 }
290 
291 static void *CRYPT_CollectionEnumCRL(PWINECRYPT_CERTSTORE store, void *pPrev)
292 {
293     PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
294     void *ret;
295 
296     TRACE("(%p, %p)\n", store, pPrev);
297 
298     EnterCriticalSection(&cs->cs);
299     if (pPrev)
300     {
301         PWINE_STORE_LIST_ENTRY storeEntry =
302          *(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(pPrev,
303          sizeof(CRL_CONTEXT));
304 
305         ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
306          &storeEntry->store->crls, pCRLInterface, pPrev, sizeof(CRL_CONTEXT));
307     }
308     else
309     {
310         if (!list_empty(&cs->stores))
311         {
312             PWINE_STORE_LIST_ENTRY storeEntry = LIST_ENTRY(cs->stores.next,
313              WINE_STORE_LIST_ENTRY, entry);
314 
315             ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
316              &storeEntry->store->crls, pCRLInterface, NULL,
317              sizeof(CRL_CONTEXT));
318         }
319         else
320         {
321             SetLastError(CRYPT_E_NOT_FOUND);
322             ret = NULL;
323         }
324     }
325     LeaveCriticalSection(&cs->cs);
326     if (ret)
327         ((PCRL_CONTEXT)ret)->hCertStore = store;
328     TRACE("returning %p\n", ret);
329     return ret;
330 }
331 
332 static BOOL CRYPT_CollectionDeleteCRL(PWINECRYPT_CERTSTORE store,
333  void *pCrlContext)
334 {
335     BOOL ret;
336 
337     TRACE("(%p, %p)\n", store, pCrlContext);
338 
339     ret = CertDeleteCRLFromStore((PCCRL_CONTEXT)
340      Context_GetLinkedContext(pCrlContext, sizeof(CRL_CONTEXT)));
341     return ret;
342 }
343 
344 static BOOL CRYPT_CollectionAddCTL(PWINECRYPT_CERTSTORE store, void *ctl,
345  void *toReplace, const void **ppStoreContext)
346 {
347     BOOL ret;
348     void *childContext = NULL;
349     PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
350 
351     ret = CRYPT_CollectionAddContext(cs, offsetof(WINECRYPT_CERTSTORE, ctls),
352      ctl, toReplace, sizeof(CTL_CONTEXT), &childContext);
353     if (ppStoreContext && childContext)
354     {
355         PWINE_STORE_LIST_ENTRY storeEntry = *(PWINE_STORE_LIST_ENTRY *)
356          Context_GetExtra(childContext, sizeof(CTL_CONTEXT));
357         PCTL_CONTEXT context =
358          CRYPT_CollectionCreateContextFromChild(cs, storeEntry, childContext,
359          sizeof(CTL_CONTEXT), TRUE);
360 
361         if (context)
362             context->hCertStore = store;
363         *ppStoreContext = context;
364     }
365     CertFreeCTLContext((PCCTL_CONTEXT)childContext);
366     return ret;
367 }
368 
369 static void *CRYPT_CollectionEnumCTL(PWINECRYPT_CERTSTORE store, void *pPrev)
370 {
371     PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
372     void *ret;
373 
374     TRACE("(%p, %p)\n", store, pPrev);
375 
376     EnterCriticalSection(&cs->cs);
377     if (pPrev)
378     {
379         PWINE_STORE_LIST_ENTRY storeEntry =
380          *(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(pPrev,
381          sizeof(CTL_CONTEXT));
382 
383         ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
384          &storeEntry->store->ctls, pCTLInterface, pPrev, sizeof(CTL_CONTEXT));
385     }
386     else
387     {
388         if (!list_empty(&cs->stores))
389         {
390             PWINE_STORE_LIST_ENTRY storeEntry = LIST_ENTRY(cs->stores.next,
391              WINE_STORE_LIST_ENTRY, entry);
392 
393             ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
394              &storeEntry->store->ctls, pCTLInterface, NULL,
395              sizeof(CTL_CONTEXT));
396         }
397         else
398         {
399             SetLastError(CRYPT_E_NOT_FOUND);
400             ret = NULL;
401         }
402     }
403     LeaveCriticalSection(&cs->cs);
404     if (ret)
405         ((PCTL_CONTEXT)ret)->hCertStore = store;
406     TRACE("returning %p\n", ret);
407     return ret;
408 }
409 
410 static BOOL CRYPT_CollectionDeleteCTL(PWINECRYPT_CERTSTORE store,
411  void *pCtlContext)
412 {
413     BOOL ret;
414 
415     TRACE("(%p, %p)\n", store, pCtlContext);
416 
417     ret = CertDeleteCTLFromStore((PCCTL_CONTEXT)
418      Context_GetLinkedContext(pCtlContext, sizeof(CTL_CONTEXT)));
419     return ret;
420 }
421 
422 PWINECRYPT_CERTSTORE CRYPT_CollectionOpenStore(HCRYPTPROV hCryptProv,
423  DWORD dwFlags, const void *pvPara)
424 {
425     PWINE_COLLECTIONSTORE store;
426 
427     if (dwFlags & CERT_STORE_DELETE_FLAG)
428     {
429         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
430         store = NULL;
431     }
432     else
433     {
434         store = CryptMemAlloc(sizeof(WINE_COLLECTIONSTORE));
435         if (store)
436         {
437             memset(store, 0, sizeof(WINE_COLLECTIONSTORE));
438             CRYPT_InitStore(&store->hdr, dwFlags, StoreTypeCollection);
439             store->hdr.closeStore          = CRYPT_CollectionCloseStore;
440             store->hdr.certs.addContext    = CRYPT_CollectionAddCert;
441             store->hdr.certs.enumContext   = CRYPT_CollectionEnumCert;
442             store->hdr.certs.deleteContext = CRYPT_CollectionDeleteCert;
443             store->hdr.crls.addContext     = CRYPT_CollectionAddCRL;
444             store->hdr.crls.enumContext    = CRYPT_CollectionEnumCRL;
445             store->hdr.crls.deleteContext  = CRYPT_CollectionDeleteCRL;
446             store->hdr.ctls.addContext     = CRYPT_CollectionAddCTL;
447             store->hdr.ctls.enumContext    = CRYPT_CollectionEnumCTL;
448             store->hdr.ctls.deleteContext  = CRYPT_CollectionDeleteCTL;
449             InitializeCriticalSection(&store->cs);
450             store->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PWINE_COLLECTIONSTORE->cs");
451             list_init(&store->stores);
452         }
453     }
454     return (PWINECRYPT_CERTSTORE)store;
455 }
456 
457 BOOL WINAPI CertAddStoreToCollection(HCERTSTORE hCollectionStore,
458  HCERTSTORE hSiblingStore, DWORD dwUpdateFlags, DWORD dwPriority)
459 {
460     PWINE_COLLECTIONSTORE collection = (PWINE_COLLECTIONSTORE)hCollectionStore;
461     WINECRYPT_CERTSTORE *sibling = (WINECRYPT_CERTSTORE *)hSiblingStore;
462     PWINE_STORE_LIST_ENTRY entry;
463     BOOL ret;
464 
465     TRACE("(%p, %p, %08x, %d)\n", hCollectionStore, hSiblingStore,
466      dwUpdateFlags, dwPriority);
467 
468     if (!collection || !sibling)
469         return TRUE;
470     if (collection->hdr.dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
471     {
472         SetLastError(E_INVALIDARG);
473         return FALSE;
474     }
475     if (collection->hdr.type != StoreTypeCollection)
476     {
477         SetLastError(E_INVALIDARG);
478         return FALSE;
479     }
480     if (sibling->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
481     {
482         SetLastError(E_INVALIDARG);
483         return FALSE;
484     }
485 
486     entry = CryptMemAlloc(sizeof(WINE_STORE_LIST_ENTRY));
487     if (entry)
488     {
489         InterlockedIncrement(&sibling->ref);
490         TRACE("sibling %p's ref count is %d\n", sibling, sibling->ref);
491         entry->store = sibling;
492         entry->dwUpdateFlags = dwUpdateFlags;
493         entry->dwPriority = dwPriority;
494         list_init(&entry->entry);
495         TRACE("%p: adding %p, priority %d\n", collection, entry, dwPriority);
496         EnterCriticalSection(&collection->cs);
497         if (dwPriority)
498         {
499             PWINE_STORE_LIST_ENTRY cursor;
500             BOOL added = FALSE;
501 
502             LIST_FOR_EACH_ENTRY(cursor, &collection->stores,
503              WINE_STORE_LIST_ENTRY, entry)
504             {
505                 if (cursor->dwPriority < dwPriority)
506                 {
507                     list_add_before(&cursor->entry, &entry->entry);
508                     added = TRUE;
509                     break;
510                 }
511             }
512             if (!added)
513                 list_add_tail(&collection->stores, &entry->entry);
514         }
515         else
516             list_add_tail(&collection->stores, &entry->entry);
517         LeaveCriticalSection(&collection->cs);
518         ret = TRUE;
519     }
520     else
521         ret = FALSE;
522     return ret;
523 }
524 
525 void WINAPI CertRemoveStoreFromCollection(HCERTSTORE hCollectionStore,
526  HCERTSTORE hSiblingStore)
527 {
528     PWINE_COLLECTIONSTORE collection = (PWINE_COLLECTIONSTORE)hCollectionStore;
529     WINECRYPT_CERTSTORE *sibling = (WINECRYPT_CERTSTORE *)hSiblingStore;
530     PWINE_STORE_LIST_ENTRY store, next;
531 
532     TRACE("(%p, %p)\n", hCollectionStore, hSiblingStore);
533 
534     if (!collection || !sibling)
535         return;
536     if (collection->hdr.dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
537     {
538         SetLastError(E_INVALIDARG);
539         return;
540     }
541     if (collection->hdr.type != StoreTypeCollection)
542         return;
543     if (sibling->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
544     {
545         SetLastError(E_INVALIDARG);
546         return;
547     }
548     EnterCriticalSection(&collection->cs);
549     LIST_FOR_EACH_ENTRY_SAFE(store, next, &collection->stores,
550      WINE_STORE_LIST_ENTRY, entry)
551     {
552         if (store->store == sibling)
553         {
554             list_remove(&store->entry);
555             CertCloseStore(store->store, 0);
556             CryptMemFree(store);
557             break;
558         }
559     }
560     LeaveCriticalSection(&collection->cs);
561 }
562 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.