ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

collectionstore.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 2004-2007 Juan Lang
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2.1 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this library; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00017  */
00018 #include <stdarg.h>
00019 #include "windef.h"
00020 #include "winbase.h"
00021 #include "wincrypt.h"
00022 #include "wine/debug.h"
00023 #include "wine/list.h"
00024 #include "crypt32_private.h"
00025 
00026 WINE_DEFAULT_DEBUG_CHANNEL(crypt);
00027 
00028 typedef struct _WINE_STORE_LIST_ENTRY
00029 {
00030     PWINECRYPT_CERTSTORE store;
00031     DWORD                dwUpdateFlags;
00032     DWORD                dwPriority;
00033     struct list          entry;
00034 } WINE_STORE_LIST_ENTRY, *PWINE_STORE_LIST_ENTRY;
00035 
00036 typedef struct _WINE_COLLECTIONSTORE
00037 {
00038     WINECRYPT_CERTSTORE hdr;
00039     CRITICAL_SECTION    cs;
00040     struct list         stores;
00041 } WINE_COLLECTIONSTORE, *PWINE_COLLECTIONSTORE;
00042 
00043 static void WINAPI CRYPT_CollectionCloseStore(HCERTSTORE store, DWORD dwFlags)
00044 {
00045     PWINE_COLLECTIONSTORE cs = store;
00046     PWINE_STORE_LIST_ENTRY entry, next;
00047 
00048     TRACE("(%p, %08x)\n", store, dwFlags);
00049 
00050     LIST_FOR_EACH_ENTRY_SAFE(entry, next, &cs->stores, WINE_STORE_LIST_ENTRY,
00051      entry)
00052     {
00053         TRACE("closing %p\n", entry);
00054         CertCloseStore(entry->store, dwFlags);
00055         CryptMemFree(entry);
00056     }
00057     cs->cs.DebugInfo->Spare[0] = 0;
00058     DeleteCriticalSection(&cs->cs);
00059     CRYPT_FreeStore(store);
00060 }
00061 
00062 static void *CRYPT_CollectionCreateContextFromChild(PWINE_COLLECTIONSTORE store,
00063  PWINE_STORE_LIST_ENTRY storeEntry, void *child, size_t contextSize,
00064  BOOL addRef)
00065 {
00066     void *ret = Context_CreateLinkContext(contextSize, child,
00067      sizeof(PWINE_STORE_LIST_ENTRY), addRef);
00068 
00069     if (ret)
00070         *(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(ret, contextSize)
00071          = storeEntry;
00072 
00073     return ret;
00074 }
00075 
00076 static BOOL CRYPT_CollectionAddContext(PWINE_COLLECTIONSTORE store,
00077  unsigned int contextFuncsOffset, void *context, void *toReplace, unsigned int contextSize,
00078  void **pChildContext)
00079 {
00080     BOOL ret;
00081     void *childContext = NULL;
00082     PWINE_STORE_LIST_ENTRY storeEntry = NULL;
00083 
00084     TRACE("(%p, %d, %p, %p, %d)\n", store, contextFuncsOffset, context,
00085      toReplace, contextSize);
00086 
00087     ret = FALSE;
00088     if (toReplace)
00089     {
00090         void *existingLinked = Context_GetLinkedContext(toReplace, contextSize);
00091         PCONTEXT_FUNCS contextFuncs;
00092 
00093         storeEntry = *(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(toReplace,
00094          contextSize);
00095         contextFuncs = (PCONTEXT_FUNCS)((LPBYTE)storeEntry->store +
00096          contextFuncsOffset);
00097         ret = contextFuncs->addContext(storeEntry->store, context,
00098          existingLinked, (const void **)&childContext);
00099     }
00100     else
00101     {
00102         PWINE_STORE_LIST_ENTRY entry, next;
00103 
00104         EnterCriticalSection(&store->cs);
00105         LIST_FOR_EACH_ENTRY_SAFE(entry, next, &store->stores,
00106          WINE_STORE_LIST_ENTRY, entry)
00107         {
00108             if (entry->dwUpdateFlags & CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG)
00109             {
00110                 PCONTEXT_FUNCS contextFuncs = (PCONTEXT_FUNCS)(
00111                  (LPBYTE)entry->store + contextFuncsOffset);
00112 
00113                 storeEntry = entry;
00114                 ret = contextFuncs->addContext(entry->store, context, NULL,
00115                  (const void **)&childContext);
00116                 break;
00117             }
00118         }
00119         LeaveCriticalSection(&store->cs);
00120         if (!storeEntry)
00121             SetLastError(E_ACCESSDENIED);
00122     }
00123     *pChildContext = childContext;
00124     return ret;
00125 }
00126 
00127 /* Advances a collection enumeration by one context, if possible, where
00128  * advancing means:
00129  * - calling the current store's enumeration function once, and returning
00130  *   the enumerated context if one is returned
00131  * - moving to the next store if the current store has no more items, and
00132  *   recursively calling itself to get the next item.
00133  * Returns NULL if the collection contains no more items or on error.
00134  * Assumes the collection store's lock is held.
00135  */
00136 static void *CRYPT_CollectionAdvanceEnum(PWINE_COLLECTIONSTORE store,
00137  PWINE_STORE_LIST_ENTRY storeEntry, const CONTEXT_FUNCS *contextFuncs,
00138  PCWINE_CONTEXT_INTERFACE contextInterface, void *pPrev, size_t contextSize)
00139 {
00140     void *ret, *child;
00141     struct list *storeNext = list_next(&store->stores, &storeEntry->entry);
00142 
00143     TRACE("(%p, %p, %p)\n", store, storeEntry, pPrev);
00144 
00145     if (pPrev)
00146     {
00147         /* Ref-counting funny business: "duplicate" (addref) the child, because
00148          * the free(pPrev) below can cause the ref count to become negative.
00149          */
00150         child = Context_GetLinkedContext(pPrev, contextSize);
00151         contextInterface->duplicate(child);
00152         child = contextFuncs->enumContext(storeEntry->store, child);
00153         contextInterface->free(pPrev);
00154         pPrev = NULL;
00155     }
00156     else
00157         child = contextFuncs->enumContext(storeEntry->store, NULL);
00158     if (child)
00159         ret = CRYPT_CollectionCreateContextFromChild(store, storeEntry, child,
00160          contextSize, FALSE);
00161     else
00162     {
00163         if (storeNext)
00164         {
00165             /* We always want the same function pointers (from certs, crls)
00166              * in the next store, so use the same offset into the next store.
00167              */
00168             size_t offset = (const BYTE *)contextFuncs - (LPBYTE)storeEntry->store;
00169             PWINE_STORE_LIST_ENTRY storeNextEntry =
00170              LIST_ENTRY(storeNext, WINE_STORE_LIST_ENTRY, entry);
00171             PCONTEXT_FUNCS storeNextContexts =
00172              (PCONTEXT_FUNCS)((LPBYTE)storeNextEntry->store + offset);
00173 
00174             ret = CRYPT_CollectionAdvanceEnum(store, storeNextEntry,
00175              storeNextContexts, contextInterface, NULL, contextSize);
00176         }
00177         else
00178         {
00179             SetLastError(CRYPT_E_NOT_FOUND);
00180             ret = NULL;
00181         }
00182     }
00183     TRACE("returning %p\n", ret);
00184     return ret;
00185 }
00186 
00187 static BOOL CRYPT_CollectionAddCert(PWINECRYPT_CERTSTORE store, void *cert,
00188  void *toReplace, const void **ppStoreContext)
00189 {
00190     BOOL ret;
00191     void *childContext = NULL;
00192     PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
00193 
00194     ret = CRYPT_CollectionAddContext(cs, offsetof(WINECRYPT_CERTSTORE, certs),
00195      cert, toReplace, sizeof(CERT_CONTEXT), &childContext);
00196     if (ppStoreContext && childContext)
00197     {
00198         PWINE_STORE_LIST_ENTRY storeEntry = *(PWINE_STORE_LIST_ENTRY *)
00199          Context_GetExtra(childContext, sizeof(CERT_CONTEXT));
00200         PCERT_CONTEXT context =
00201          CRYPT_CollectionCreateContextFromChild(cs, storeEntry, childContext,
00202          sizeof(CERT_CONTEXT), TRUE);
00203 
00204         if (context)
00205             context->hCertStore = store;
00206         *ppStoreContext = context;
00207     }
00208     CertFreeCertificateContext(childContext);
00209     return ret;
00210 }
00211 
00212 static void *CRYPT_CollectionEnumCert(PWINECRYPT_CERTSTORE store, void *pPrev)
00213 {
00214     PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
00215     void *ret;
00216 
00217     TRACE("(%p, %p)\n", store, pPrev);
00218 
00219     EnterCriticalSection(&cs->cs);
00220     if (pPrev)
00221     {
00222         PWINE_STORE_LIST_ENTRY storeEntry =
00223          *(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(pPrev,
00224          sizeof(CERT_CONTEXT));
00225 
00226         ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
00227          &storeEntry->store->certs, pCertInterface, pPrev,
00228          sizeof(CERT_CONTEXT));
00229     }
00230     else
00231     {
00232         if (!list_empty(&cs->stores))
00233         {
00234             PWINE_STORE_LIST_ENTRY storeEntry = LIST_ENTRY(cs->stores.next,
00235              WINE_STORE_LIST_ENTRY, entry);
00236 
00237             ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
00238              &storeEntry->store->certs, pCertInterface, NULL,
00239              sizeof(CERT_CONTEXT));
00240         }
00241         else
00242         {
00243             SetLastError(CRYPT_E_NOT_FOUND);
00244             ret = NULL;
00245         }
00246     }
00247     LeaveCriticalSection(&cs->cs);
00248     if (ret)
00249         ((PCERT_CONTEXT)ret)->hCertStore = store;
00250     TRACE("returning %p\n", ret);
00251     return ret;
00252 }
00253 
00254 static BOOL CRYPT_CollectionDeleteCert(PWINECRYPT_CERTSTORE store,
00255  void *pCertContext)
00256 {
00257     BOOL ret;
00258     PCCERT_CONTEXT linked;
00259 
00260     TRACE("(%p, %p)\n", store, pCertContext);
00261 
00262     /* Deleting the linked context results in its ref count getting
00263      * decreased, but the caller of this (CertDeleteCertificateFromStore) also
00264      * decreases pCertContext's ref count, by calling
00265      * CertFreeCertificateContext.  Increase ref count of linked context to
00266      * compensate.
00267      */
00268     linked = Context_GetLinkedContext(pCertContext, sizeof(CERT_CONTEXT));
00269     CertDuplicateCertificateContext(linked);
00270     ret = CertDeleteCertificateFromStore(linked);
00271     return ret;
00272 }
00273 
00274 static BOOL CRYPT_CollectionAddCRL(PWINECRYPT_CERTSTORE store, void *crl,
00275  void *toReplace, const void **ppStoreContext)
00276 {
00277     BOOL ret;
00278     void *childContext = NULL;
00279     PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
00280 
00281     ret = CRYPT_CollectionAddContext(cs, offsetof(WINECRYPT_CERTSTORE, crls),
00282      crl, toReplace, sizeof(CRL_CONTEXT), &childContext);
00283     if (ppStoreContext && childContext)
00284     {
00285         PWINE_STORE_LIST_ENTRY storeEntry = *(PWINE_STORE_LIST_ENTRY *)
00286          Context_GetExtra(childContext, sizeof(CRL_CONTEXT));
00287         PCRL_CONTEXT context =
00288          CRYPT_CollectionCreateContextFromChild(cs, storeEntry, childContext,
00289          sizeof(CRL_CONTEXT), TRUE);
00290 
00291         if (context)
00292             context->hCertStore = store;
00293         *ppStoreContext = context;
00294     }
00295     CertFreeCRLContext(childContext);
00296     return ret;
00297 }
00298 
00299 static void *CRYPT_CollectionEnumCRL(PWINECRYPT_CERTSTORE store, void *pPrev)
00300 {
00301     PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
00302     void *ret;
00303 
00304     TRACE("(%p, %p)\n", store, pPrev);
00305 
00306     EnterCriticalSection(&cs->cs);
00307     if (pPrev)
00308     {
00309         PWINE_STORE_LIST_ENTRY storeEntry =
00310          *(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(pPrev,
00311          sizeof(CRL_CONTEXT));
00312 
00313         ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
00314          &storeEntry->store->crls, pCRLInterface, pPrev, sizeof(CRL_CONTEXT));
00315     }
00316     else
00317     {
00318         if (!list_empty(&cs->stores))
00319         {
00320             PWINE_STORE_LIST_ENTRY storeEntry = LIST_ENTRY(cs->stores.next,
00321              WINE_STORE_LIST_ENTRY, entry);
00322 
00323             ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
00324              &storeEntry->store->crls, pCRLInterface, NULL,
00325              sizeof(CRL_CONTEXT));
00326         }
00327         else
00328         {
00329             SetLastError(CRYPT_E_NOT_FOUND);
00330             ret = NULL;
00331         }
00332     }
00333     LeaveCriticalSection(&cs->cs);
00334     if (ret)
00335         ((PCRL_CONTEXT)ret)->hCertStore = store;
00336     TRACE("returning %p\n", ret);
00337     return ret;
00338 }
00339 
00340 static BOOL CRYPT_CollectionDeleteCRL(PWINECRYPT_CERTSTORE store,
00341  void *pCrlContext)
00342 {
00343     BOOL ret;
00344     PCCRL_CONTEXT linked;
00345 
00346     TRACE("(%p, %p)\n", store, pCrlContext);
00347 
00348     /* Deleting the linked context results in its ref count getting
00349      * decreased, but the caller of this (CertDeleteCRLFromStore) also
00350      * decreases pCrlContext's ref count, by calling CertFreeCRLContext.
00351      * Increase ref count of linked context to compensate.
00352      */
00353     linked = Context_GetLinkedContext(pCrlContext, sizeof(CRL_CONTEXT));
00354     CertDuplicateCRLContext(linked);
00355     ret = CertDeleteCRLFromStore(linked);
00356     return ret;
00357 }
00358 
00359 static BOOL CRYPT_CollectionAddCTL(PWINECRYPT_CERTSTORE store, void *ctl,
00360  void *toReplace, const void **ppStoreContext)
00361 {
00362     BOOL ret;
00363     void *childContext = NULL;
00364     PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
00365 
00366     ret = CRYPT_CollectionAddContext(cs, offsetof(WINECRYPT_CERTSTORE, ctls),
00367      ctl, toReplace, sizeof(CTL_CONTEXT), &childContext);
00368     if (ppStoreContext && childContext)
00369     {
00370         PWINE_STORE_LIST_ENTRY storeEntry = *(PWINE_STORE_LIST_ENTRY *)
00371          Context_GetExtra(childContext, sizeof(CTL_CONTEXT));
00372         PCTL_CONTEXT context =
00373          CRYPT_CollectionCreateContextFromChild(cs, storeEntry, childContext,
00374          sizeof(CTL_CONTEXT), TRUE);
00375 
00376         if (context)
00377             context->hCertStore = store;
00378         *ppStoreContext = context;
00379     }
00380     CertFreeCTLContext(childContext);
00381     return ret;
00382 }
00383 
00384 static void *CRYPT_CollectionEnumCTL(PWINECRYPT_CERTSTORE store, void *pPrev)
00385 {
00386     PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
00387     void *ret;
00388 
00389     TRACE("(%p, %p)\n", store, pPrev);
00390 
00391     EnterCriticalSection(&cs->cs);
00392     if (pPrev)
00393     {
00394         PWINE_STORE_LIST_ENTRY storeEntry =
00395          *(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(pPrev,
00396          sizeof(CTL_CONTEXT));
00397 
00398         ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
00399          &storeEntry->store->ctls, pCTLInterface, pPrev, sizeof(CTL_CONTEXT));
00400     }
00401     else
00402     {
00403         if (!list_empty(&cs->stores))
00404         {
00405             PWINE_STORE_LIST_ENTRY storeEntry = LIST_ENTRY(cs->stores.next,
00406              WINE_STORE_LIST_ENTRY, entry);
00407 
00408             ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
00409              &storeEntry->store->ctls, pCTLInterface, NULL,
00410              sizeof(CTL_CONTEXT));
00411         }
00412         else
00413         {
00414             SetLastError(CRYPT_E_NOT_FOUND);
00415             ret = NULL;
00416         }
00417     }
00418     LeaveCriticalSection(&cs->cs);
00419     if (ret)
00420         ((PCTL_CONTEXT)ret)->hCertStore = store;
00421     TRACE("returning %p\n", ret);
00422     return ret;
00423 }
00424 
00425 static BOOL CRYPT_CollectionDeleteCTL(PWINECRYPT_CERTSTORE store,
00426  void *pCtlContext)
00427 {
00428     BOOL ret;
00429     PCCTL_CONTEXT linked;
00430 
00431     TRACE("(%p, %p)\n", store, pCtlContext);
00432 
00433     /* Deleting the linked context results in its ref count getting
00434      * decreased, but the caller of this (CertDeleteCTLFromStore) also
00435      * decreases pCtlContext's ref count, by calling CertFreeCTLContext.
00436      * Increase ref count of linked context to compensate.
00437      */
00438     linked = Context_GetLinkedContext(pCtlContext, sizeof(CTL_CONTEXT));
00439     CertDuplicateCTLContext(linked);
00440     ret = CertDeleteCTLFromStore(linked);
00441     return ret;
00442 }
00443 
00444 static BOOL WINAPI CRYPT_CollectionControl(HCERTSTORE hCertStore, DWORD dwFlags,
00445  DWORD dwCtrlType, void const *pvCtrlPara)
00446 {
00447     BOOL ret;
00448     PWINE_COLLECTIONSTORE store = hCertStore;
00449     PWINE_STORE_LIST_ENTRY entry;
00450 
00451     TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType,
00452      pvCtrlPara);
00453 
00454     if (!store)
00455         return TRUE;
00456     if (store->hdr.dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
00457     {
00458         SetLastError(E_INVALIDARG);
00459         return FALSE;
00460     }
00461     if (store->hdr.type != StoreTypeCollection)
00462     {
00463         SetLastError(E_INVALIDARG);
00464         return FALSE;
00465     }
00466 
00467     ret = TRUE;
00468     EnterCriticalSection(&store->cs);
00469     LIST_FOR_EACH_ENTRY(entry, &store->stores, WINE_STORE_LIST_ENTRY, entry)
00470     {
00471         if (entry->store->control)
00472         {
00473             ret = entry->store->control(entry->store, dwFlags, dwCtrlType,
00474              pvCtrlPara);
00475             if (!ret)
00476                 break;
00477         }
00478     }
00479     LeaveCriticalSection(&store->cs);
00480     return ret;
00481 }
00482 
00483 PWINECRYPT_CERTSTORE CRYPT_CollectionOpenStore(HCRYPTPROV hCryptProv,
00484  DWORD dwFlags, const void *pvPara)
00485 {
00486     PWINE_COLLECTIONSTORE store;
00487 
00488     if (dwFlags & CERT_STORE_DELETE_FLAG)
00489     {
00490         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00491         store = NULL;
00492     }
00493     else
00494     {
00495         store = CryptMemAlloc(sizeof(WINE_COLLECTIONSTORE));
00496         if (store)
00497         {
00498             memset(store, 0, sizeof(WINE_COLLECTIONSTORE));
00499             CRYPT_InitStore(&store->hdr, dwFlags, StoreTypeCollection);
00500             store->hdr.closeStore          = CRYPT_CollectionCloseStore;
00501             store->hdr.certs.addContext    = CRYPT_CollectionAddCert;
00502             store->hdr.certs.enumContext   = CRYPT_CollectionEnumCert;
00503             store->hdr.certs.deleteContext = CRYPT_CollectionDeleteCert;
00504             store->hdr.crls.addContext     = CRYPT_CollectionAddCRL;
00505             store->hdr.crls.enumContext    = CRYPT_CollectionEnumCRL;
00506             store->hdr.crls.deleteContext  = CRYPT_CollectionDeleteCRL;
00507             store->hdr.ctls.addContext     = CRYPT_CollectionAddCTL;
00508             store->hdr.ctls.enumContext    = CRYPT_CollectionEnumCTL;
00509             store->hdr.ctls.deleteContext  = CRYPT_CollectionDeleteCTL;
00510             store->hdr.control             = CRYPT_CollectionControl;
00511             InitializeCriticalSection(&store->cs);
00512             store->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PWINE_COLLECTIONSTORE->cs");
00513             list_init(&store->stores);
00514         }
00515     }
00516     return (PWINECRYPT_CERTSTORE)store;
00517 }
00518 
00519 BOOL WINAPI CertAddStoreToCollection(HCERTSTORE hCollectionStore,
00520  HCERTSTORE hSiblingStore, DWORD dwUpdateFlags, DWORD dwPriority)
00521 {
00522     PWINE_COLLECTIONSTORE collection = hCollectionStore;
00523     WINECRYPT_CERTSTORE *sibling = hSiblingStore;
00524     PWINE_STORE_LIST_ENTRY entry;
00525     BOOL ret;
00526 
00527     TRACE("(%p, %p, %08x, %d)\n", hCollectionStore, hSiblingStore,
00528      dwUpdateFlags, dwPriority);
00529 
00530     if (!collection || !sibling)
00531         return TRUE;
00532     if (collection->hdr.dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
00533     {
00534         SetLastError(E_INVALIDARG);
00535         return FALSE;
00536     }
00537     if (collection->hdr.type != StoreTypeCollection)
00538     {
00539         SetLastError(E_INVALIDARG);
00540         return FALSE;
00541     }
00542     if (sibling->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
00543     {
00544         SetLastError(E_INVALIDARG);
00545         return FALSE;
00546     }
00547 
00548     entry = CryptMemAlloc(sizeof(WINE_STORE_LIST_ENTRY));
00549     if (entry)
00550     {
00551         InterlockedIncrement(&sibling->ref);
00552         TRACE("sibling %p's ref count is %d\n", sibling, sibling->ref);
00553         entry->store = sibling;
00554         entry->dwUpdateFlags = dwUpdateFlags;
00555         entry->dwPriority = dwPriority;
00556         list_init(&entry->entry);
00557         TRACE("%p: adding %p, priority %d\n", collection, entry, dwPriority);
00558         EnterCriticalSection(&collection->cs);
00559         if (dwPriority)
00560         {
00561             PWINE_STORE_LIST_ENTRY cursor;
00562             BOOL added = FALSE;
00563 
00564             LIST_FOR_EACH_ENTRY(cursor, &collection->stores,
00565              WINE_STORE_LIST_ENTRY, entry)
00566             {
00567                 if (cursor->dwPriority < dwPriority)
00568                 {
00569                     list_add_before(&cursor->entry, &entry->entry);
00570                     added = TRUE;
00571                     break;
00572                 }
00573             }
00574             if (!added)
00575                 list_add_tail(&collection->stores, &entry->entry);
00576         }
00577         else
00578             list_add_tail(&collection->stores, &entry->entry);
00579         LeaveCriticalSection(&collection->cs);
00580         ret = TRUE;
00581     }
00582     else
00583         ret = FALSE;
00584     return ret;
00585 }
00586 
00587 void WINAPI CertRemoveStoreFromCollection(HCERTSTORE hCollectionStore,
00588  HCERTSTORE hSiblingStore)
00589 {
00590     PWINE_COLLECTIONSTORE collection = hCollectionStore;
00591     WINECRYPT_CERTSTORE *sibling = hSiblingStore;
00592     PWINE_STORE_LIST_ENTRY store, next;
00593 
00594     TRACE("(%p, %p)\n", hCollectionStore, hSiblingStore);
00595 
00596     if (!collection || !sibling)
00597         return;
00598     if (collection->hdr.dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
00599     {
00600         SetLastError(E_INVALIDARG);
00601         return;
00602     }
00603     if (collection->hdr.type != StoreTypeCollection)
00604         return;
00605     if (sibling->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
00606     {
00607         SetLastError(E_INVALIDARG);
00608         return;
00609     }
00610     EnterCriticalSection(&collection->cs);
00611     LIST_FOR_EACH_ENTRY_SAFE(store, next, &collection->stores,
00612      WINE_STORE_LIST_ENTRY, entry)
00613     {
00614         if (store->store == sibling)
00615         {
00616             list_remove(&store->entry);
00617             CertCloseStore(store->store, 0);
00618             CryptMemFree(store);
00619             break;
00620         }
00621     }
00622     LeaveCriticalSection(&collection->cs);
00623 }

Generated on Sat May 26 2012 04:21:46 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.