📄 store.c
字号:
toReplace, contextSize);
ret = FALSE;
if (toReplace)
{
void *existingLinked = Context_GetLinkedContext(toReplace, contextSize);
PCONTEXT_STORE contextStore;
storeEntry = *(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(toReplace,
contextSize);
contextStore = (PCONTEXT_STORE)((LPBYTE)storeEntry->store +
contextStoreOffset);
ret = contextStore->addContext(storeEntry->store, context,
existingLinked, (const void **)&childContext);
}
else
{
PWINE_STORE_LIST_ENTRY entry, next;
EnterCriticalSection(&store->cs);
LIST_FOR_EACH_ENTRY_SAFE(entry, next, &store->stores,
WINE_STORE_LIST_ENTRY, entry)
{
if (entry->dwUpdateFlags & CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG)
{
PCONTEXT_STORE contextStore = (PCONTEXT_STORE)(
(LPBYTE)entry->store + contextStoreOffset);
storeEntry = entry;
ret = contextStore->addContext(entry->store, context, NULL,
(const void **)&childContext);
break;
}
}
LeaveCriticalSection(&store->cs);
if (!storeEntry)
SetLastError(E_ACCESSDENIED);
}
*pChildContext = childContext;
return ret;
}
/* Advances a collection enumeration by one context, if possible, where
* advancing means:
* - calling the current store's enumeration function once, and returning
* the enumerated context if one is returned
* - moving to the next store if the current store has no more items, and
* recursively calling itself to get the next item.
* Returns NULL if the collection contains no more items or on error.
* Assumes the collection store's lock is held.
*/
static void *CRYPT_CollectionAdvanceEnum(PWINE_COLLECTIONSTORE store,
PWINE_STORE_LIST_ENTRY storeEntry, size_t contextStoreOffset,
PCWINE_CONTEXT_INTERFACE contextInterface, void *pPrev, size_t contextSize)
{
void *ret, *child;
struct list *storeNext = list_next(&store->stores, &storeEntry->entry);
PCONTEXT_STORE contextStore = (PCONTEXT_STORE)((LPBYTE)storeEntry->store +
contextStoreOffset);
TRACE("(%p, %p, %p)\n", store, storeEntry, pPrev);
if (pPrev)
{
/* Ref-counting funny business: "duplicate" (addref) the child, because
* the free(pPrev) below can cause the ref count to become negative.
*/
child = Context_GetLinkedContext(pPrev, contextSize);
contextInterface->duplicate(child);
child = contextStore->enumContext(storeEntry->store, child);
contextInterface->free(pPrev);
pPrev = NULL;
}
else
child = storeEntry->store->certs.enumContext(storeEntry->store, NULL);
if (child)
ret = CRYPT_CollectionCreateContextFromChild(store, storeEntry, child,
contextSize, FALSE);
else
{
if (storeNext)
ret = CRYPT_CollectionAdvanceEnum(store, LIST_ENTRY(storeNext,
WINE_STORE_LIST_ENTRY, entry), contextStoreOffset,
contextInterface, NULL, contextSize);
else
{
SetLastError(CRYPT_E_NOT_FOUND);
ret = NULL;
}
}
TRACE("returning %p\n", ret);
return ret;
}
static BOOL CRYPT_CollectionAddCert(PWINECRYPT_CERTSTORE store, void *cert,
void *toReplace, const void **ppStoreContext)
{
BOOL ret;
void *childContext = NULL;
PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
ret = CRYPT_CollectionAddContext(cs, offsetof(WINECRYPT_CERTSTORE, certs),
cert, toReplace, sizeof(CERT_CONTEXT), &childContext);
if (ppStoreContext && childContext)
{
PWINE_STORE_LIST_ENTRY storeEntry = *(PWINE_STORE_LIST_ENTRY *)
Context_GetExtra(childContext, sizeof(CERT_CONTEXT));
PCERT_CONTEXT context =
CRYPT_CollectionCreateContextFromChild(cs, storeEntry, childContext,
sizeof(CERT_CONTEXT), TRUE);
if (context)
context->hCertStore = store;
*ppStoreContext = context;
}
CertFreeCertificateContext((PCCERT_CONTEXT)childContext);
return ret;
}
static void *CRYPT_CollectionEnumCert(PWINECRYPT_CERTSTORE store, void *pPrev)
{
PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
void *ret;
TRACE("(%p, %p)\n", store, pPrev);
EnterCriticalSection(&cs->cs);
if (pPrev)
{
PWINE_STORE_LIST_ENTRY storeEntry =
*(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(pPrev,
sizeof(CERT_CONTEXT));
ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
offsetof(WINECRYPT_CERTSTORE, certs), pCertInterface, pPrev,
sizeof(CERT_CONTEXT));
}
else
{
if (!list_empty(&cs->stores))
{
PWINE_STORE_LIST_ENTRY storeEntry = LIST_ENTRY(cs->stores.next,
WINE_STORE_LIST_ENTRY, entry);
ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
offsetof(WINECRYPT_CERTSTORE, certs), pCertInterface, NULL,
sizeof(CERT_CONTEXT));
}
else
{
SetLastError(CRYPT_E_NOT_FOUND);
ret = NULL;
}
}
LeaveCriticalSection(&cs->cs);
if (ret)
((PCERT_CONTEXT)ret)->hCertStore = store;
TRACE("returning %p\n", ret);
return ret;
}
static BOOL CRYPT_CollectionDeleteCert(PWINECRYPT_CERTSTORE store,
void *pCertContext)
{
BOOL ret;
TRACE("(%p, %p)\n", store, pCertContext);
ret = CertDeleteCertificateFromStore((PCCERT_CONTEXT)
Context_GetLinkedContext(pCertContext, sizeof(CERT_CONTEXT)));
return ret;
}
static BOOL CRYPT_CollectionAddCRL(PWINECRYPT_CERTSTORE store, void *crl,
void *toReplace, const void **ppStoreContext)
{
BOOL ret;
void *childContext = NULL;
PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
ret = CRYPT_CollectionAddContext(cs, offsetof(WINECRYPT_CERTSTORE, crls),
crl, toReplace, sizeof(CRL_CONTEXT), &childContext);
if (ppStoreContext && childContext)
{
PWINE_STORE_LIST_ENTRY storeEntry = *(PWINE_STORE_LIST_ENTRY *)
Context_GetExtra(childContext, sizeof(CRL_CONTEXT));
PCRL_CONTEXT context =
CRYPT_CollectionCreateContextFromChild(cs, storeEntry, childContext,
sizeof(CRL_CONTEXT), TRUE);
if (context)
context->hCertStore = store;
*ppStoreContext = context;
}
CertFreeCRLContext((PCCRL_CONTEXT)childContext);
return ret;
}
static void *CRYPT_CollectionEnumCRL(PWINECRYPT_CERTSTORE store, void *pPrev)
{
PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
void *ret;
TRACE("(%p, %p)\n", store, pPrev);
EnterCriticalSection(&cs->cs);
if (pPrev)
{
PWINE_STORE_LIST_ENTRY storeEntry =
*(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(pPrev,
sizeof(CRL_CONTEXT));
ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
offsetof(WINECRYPT_CERTSTORE, crls), pCRLInterface, pPrev,
sizeof(CRL_CONTEXT));
}
else
{
if (!list_empty(&cs->stores))
{
PWINE_STORE_LIST_ENTRY storeEntry = LIST_ENTRY(cs->stores.next,
WINE_STORE_LIST_ENTRY, entry);
ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
offsetof(WINECRYPT_CERTSTORE, crls), pCRLInterface, NULL,
sizeof(CRL_CONTEXT));
}
else
{
SetLastError(CRYPT_E_NOT_FOUND);
ret = NULL;
}
}
LeaveCriticalSection(&cs->cs);
if (ret)
((PCRL_CONTEXT)ret)->hCertStore = store;
TRACE("returning %p\n", ret);
return ret;
}
static BOOL CRYPT_CollectionDeleteCRL(PWINECRYPT_CERTSTORE store,
void *pCrlContext)
{
BOOL ret;
TRACE("(%p, %p)\n", store, pCrlContext);
ret = CertDeleteCRLFromStore((PCCRL_CONTEXT)
Context_GetLinkedContext(pCrlContext, sizeof(CRL_CONTEXT)));
return ret;
}
static WINECRYPT_CERTSTORE *CRYPT_CollectionOpenStore(HCRYPTPROV hCryptProv,
DWORD dwFlags, const void *pvPara)
{
PWINE_COLLECTIONSTORE store;
if (dwFlags & CERT_STORE_DELETE_FLAG)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
store = NULL;
}
else
{
store = CryptMemAlloc(sizeof(WINE_COLLECTIONSTORE));
if (store)
{
memset(store, 0, sizeof(WINE_COLLECTIONSTORE));
CRYPT_InitStore(&store->hdr, hCryptProv, dwFlags,
StoreTypeCollection);
store->hdr.closeStore = CRYPT_CollectionCloseStore;
store->hdr.certs.addContext = CRYPT_CollectionAddCert;
store->hdr.certs.enumContext = CRYPT_CollectionEnumCert;
store->hdr.certs.deleteContext = CRYPT_CollectionDeleteCert;
store->hdr.crls.addContext = CRYPT_CollectionAddCRL;
store->hdr.crls.enumContext = CRYPT_CollectionEnumCRL;
store->hdr.crls.deleteContext = CRYPT_CollectionDeleteCRL;
InitializeCriticalSection(&store->cs);
store->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PWINE_COLLECTIONSTORE->cs");
list_init(&store->stores);
}
}
return (PWINECRYPT_CERTSTORE)store;
}
static void WINAPI CRYPT_ProvCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
{
PWINE_PROVIDERSTORE store = (PWINE_PROVIDERSTORE)hCertStore;
TRACE("(%p, %08x)\n", store, dwFlags);
if (store->provCloseStore)
store->provCloseStore(store->hStoreProv, dwFlags);
if (!(store->dwStoreProvFlags & CERT_STORE_PROV_EXTERNAL_FLAG))
CertCloseStore(store->memStore, dwFlags);
CryptMemFree(store);
}
static BOOL CRYPT_ProvAddCert(PWINECRYPT_CERTSTORE store, void *cert,
void *toReplace, const void **ppStoreContext)
{
PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
BOOL ret;
TRACE("(%p, %p, %p, %p)\n", store, cert, toReplace, ppStoreContext);
if (toReplace)
ret = ps->memStore->certs.addContext(ps->memStore, cert, toReplace,
(const void **)ppStoreContext);
else
{
ret = TRUE;
if (ps->provWriteCert)
ret = ps->provWriteCert(ps->hStoreProv, (PCCERT_CONTEXT)cert,
CERT_STORE_PROV_WRITE_ADD_FLAG);
if (ret)
ret = ps->memStore->certs.addContext(ps->memStore, cert, NULL,
(const void **)ppStoreContext);
}
/* dirty trick: replace the returned context's hCertStore with
* store.
*/
if (ppStoreContext)
(*(PCERT_CONTEXT *)ppStoreContext)->hCertStore = store;
return ret;
}
static void *CRYPT_ProvEnumCert(PWINECRYPT_CERTSTORE store, void *pPrev)
{
PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
void *ret;
ret = ps->memStore->certs.enumContext(ps->memStore, pPrev);
if (ret)
{
/* same dirty trick: replace the returned context's hCertStore with
* store.
*/
((PCERT_CONTEXT)ret)->hCertStore = store;
}
return ret;
}
static BOOL CRYPT_ProvDeleteCert(PWINECRYPT_CERTSTORE store, void *cert)
{
PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
BOOL ret = TRUE;
TRACE("(%p, %p)\n", store, cert);
if (ps->provDeleteCert)
ret = ps->provDeleteCert(ps->hStoreProv, cert, 0);
if (ret)
ret = ps->memStore->certs.deleteContext(ps->memStore, cert);
return ret;
}
static BOOL CRYPT_ProvAddCRL(PWINECRYPT_CERTSTORE store, void *crl,
void *toReplace, const void **ppStoreContext)
{
PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
BOOL ret;
TRACE("(%p, %p, %p, %p)\n", store, crl, toReplace, ppStoreContext);
if (toReplace)
ret = ps->memStore->crls.addContext(ps->memStore, crl, toReplace,
(const void **)ppStoreContext);
else
{
if (ps->hdr.dwOpenFlags & CERT_STORE_READONLY_FLAG)
{
SetLastError(ERROR_ACCESS_DENIED);
ret = FALSE;
}
else
{
ret = TRUE;
if (ps->provWriteCrl)
ret = ps->provWriteCrl(ps->hStoreProv, (PCCRL_CONTEXT)crl,
CERT_STORE_PROV_WRITE_ADD_FLAG);
if (ret)
ret = ps->memStore->crls.addContext(ps->memStore, crl, NULL,
(const void **)ppStoreContext);
}
}
/* dirty trick: replace the returned context's hCertStore with
* store.
*/
if (ppStoreContext)
(*(PCRL_CONTEXT *)ppStoreContext)->hCertStore = store;
return ret;
}
static void *CRYPT_ProvEnumCRL(PWINECRYPT_CERTSTORE store, void *pPrev)
{
PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
void *ret;
ret = ps->memStore->crls.enumContext(ps->memStore, pPrev);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -