Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencollectionstore.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
1.7.6.1
|