store.c
来自「一个类似windows」· C语言 代码 · 共 1,949 行 · 第 1/5 页
C
1,949 行
*ppStoreContext =
CertDuplicateCertificateContext((PCCERT_CONTEXT)entry);
ret = TRUE;
}
else
ret = FALSE;
}
else
ret = FALSE;
TRACE("returning %d\n", ret);
return ret;
}
static PWINE_CERT_CONTEXT CRYPT_MemEnumCert(PWINECRYPT_CERTSTORE store,
PWINE_CERT_CONTEXT pPrev)
{
WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
PWINE_CERT_LIST_ENTRY prevEntry = (PWINE_CERT_LIST_ENTRY)pPrev;
PWINE_CERT_CONTEXT ret;
struct list *listNext;
TRACE("(%p, %p)\n", store, pPrev);
EnterCriticalSection(&ms->cs);
if (prevEntry)
{
listNext = list_next(&ms->certs, &prevEntry->entry);
CertFreeCertificateContext((PCCERT_CONTEXT)pPrev);
}
else
listNext = list_next(&ms->certs, &ms->certs);
if (listNext)
ret = (PWINE_CERT_CONTEXT)CertDuplicateCertificateContext(
(PCCERT_CONTEXT)LIST_ENTRY(listNext, WINE_CERT_LIST_ENTRY, entry));
else
{
SetLastError(CRYPT_E_NOT_FOUND);
ret = NULL;
}
LeaveCriticalSection(&ms->cs);
TRACE("returning %p\n", ret);
return ret;
}
static BOOL WINAPI CRYPT_MemDeleteCert(HCERTSTORE hCertStore,
PCCERT_CONTEXT pCertContext, DWORD dwFlags)
{
WINE_MEMSTORE *store = (WINE_MEMSTORE *)hCertStore;
PWINE_CERT_LIST_ENTRY cert = (PWINE_CERT_LIST_ENTRY)pCertContext;
BOOL ret;
/* The passed-in context is itself a list entry, so just remove it. */
EnterCriticalSection(&store->cs);
list_remove(&cert->entry);
ret = CertFreeCertificateContext(pCertContext);
LeaveCriticalSection(&store->cs);
return ret;
}
static void CRYPT_MemEmptyStore(PWINE_MEMSTORE store)
{
PWINE_CERT_LIST_ENTRY cert, next;
EnterCriticalSection(&store->cs);
LIST_FOR_EACH_ENTRY_SAFE(cert, next, &store->certs, WINE_CERT_LIST_ENTRY,
entry)
{
TRACE("removing %p\n", cert);
list_remove(&cert->entry);
CertFreeCertificateContext((PCCERT_CONTEXT)cert);
}
LeaveCriticalSection(&store->cs);
}
static void WINAPI CRYPT_MemCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
{
WINE_MEMSTORE *store = (WINE_MEMSTORE *)hCertStore;
TRACE("(%p, %08lx)\n", store, dwFlags);
if (dwFlags)
FIXME("Unimplemented flags: %08lx\n", dwFlags);
CRYPT_MemEmptyStore(store);
DeleteCriticalSection(&store->cs);
CryptMemFree(store);
}
static WINECRYPT_CERTSTORE *CRYPT_MemOpenStore(HCRYPTPROV hCryptProv,
DWORD dwFlags, const void *pvPara)
{
PWINE_MEMSTORE store;
TRACE("(%ld, %08lx, %p)\n", hCryptProv, dwFlags, pvPara);
if (dwFlags & CERT_STORE_DELETE_FLAG)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
store = NULL;
}
else
{
store = CryptMemAlloc(sizeof(WINE_MEMSTORE));
if (store)
{
memset(store, 0, sizeof(WINE_MEMSTORE));
CRYPT_InitStore(&store->hdr, hCryptProv, dwFlags, StoreTypeMem);
store->hdr.closeStore = CRYPT_MemCloseStore;
store->hdr.addCert = CRYPT_MemAddCert;
store->hdr.enumCert = CRYPT_MemEnumCert;
store->hdr.deleteCert = CRYPT_MemDeleteCert;
store->hdr.control = NULL;
InitializeCriticalSection(&store->cs);
list_init(&store->certs);
}
}
return (PWINECRYPT_CERTSTORE)store;
}
static BOOL CRYPT_CollectionAddCert(PWINECRYPT_CERTSTORE store,
PWINE_CERT_CONTEXT cert, DWORD dwAddDisposition,
PCCERT_CONTEXT *ppStoreContext)
{
PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
PWINE_STORE_LIST_ENTRY entry, next;
BOOL ret;
TRACE("(%p, %p, %ld, %p)\n", store, cert, dwAddDisposition, ppStoreContext);
ret = FALSE;
EnterCriticalSection(&cs->cs);
LIST_FOR_EACH_ENTRY_SAFE(entry, next, &cs->stores, WINE_STORE_LIST_ENTRY,
entry)
{
if (entry->dwUpdateFlags & CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG)
{
ret = entry->store->addCert(entry->store, cert, dwAddDisposition,
ppStoreContext);
break;
}
}
LeaveCriticalSection(&cs->cs);
SetLastError(ret ? ERROR_SUCCESS : HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED));
return ret;
}
static void WINAPI CRYPT_CollectionCloseStore(HCERTSTORE store, DWORD dwFlags)
{
PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
PWINE_STORE_LIST_ENTRY entry, next;
TRACE("(%p, %08lx)\n", store, dwFlags);
LIST_FOR_EACH_ENTRY_SAFE(entry, next, &cs->stores, WINE_STORE_LIST_ENTRY,
entry)
{
TRACE("closing %p\n", entry);
CertCloseStore((HCERTSTORE)entry->store, dwFlags);
CryptMemFree(entry);
}
DeleteCriticalSection(&cs->cs);
CryptMemFree(cs);
}
/* Advances a collection enumeration by one cert, if possible, where advancing
* means:
* - calling the current store's enumeration function once, and returning
* the enumerated cert 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 PWINE_COLLECTION_CERT_CONTEXT CRYPT_CollectionAdvanceEnum(
PWINE_COLLECTIONSTORE store, PWINE_STORE_LIST_ENTRY storeEntry,
PWINE_COLLECTION_CERT_CONTEXT pPrev)
{
PWINE_COLLECTION_CERT_CONTEXT ret;
PWINE_CERT_CONTEXT child;
struct list *storeNext = list_next(&store->stores, &storeEntry->entry);
TRACE("(%p, %p, %p)\n", store, storeEntry, pPrev);
if (pPrev)
{
/* Ref-counting funny business: "duplicate" (addref) the child, because
* the CertFreeCertificateContext(pPrev) below can cause the ref count
* to become negative. See comment below as well.
*/
child = ((PWINE_COLLECTION_CERT_CONTEXT)pPrev)->cert.linked;
CertDuplicateCertificateContext((PCCERT_CONTEXT)child);
child = storeEntry->store->enumCert((HCERTSTORE)storeEntry->store,
child);
CertFreeCertificateContext((PCCERT_CONTEXT)pPrev);
pPrev = NULL;
}
else
child = storeEntry->store->enumCert((HCERTSTORE)storeEntry->store,
NULL);
if (child)
{
ret = CryptMemAlloc(sizeof(WINE_COLLECTION_CERT_CONTEXT));
if (ret)
{
CRYPT_InitCertRef((PWINE_CERT_CONTEXT_LINK)ret, child, store);
/* enumCert already addref'd once, and CRYPT_InitCertRef does again,
* so free child once to get the ref count right. (Not doing so
* will leak memory if the caller calls CertFreeCertificateContext
* rather than CertEnumCertificatesInStore.)
*/
CertFreeCertificateContext((PCCERT_CONTEXT)child);
ret->storeEntry = storeEntry;
}
else
CertFreeCertificateContext((PCCERT_CONTEXT)child);
}
else
{
if (storeNext)
{
storeEntry = LIST_ENTRY(storeNext, WINE_STORE_LIST_ENTRY, entry);
ret = CRYPT_CollectionAdvanceEnum(store, storeEntry, NULL);
}
else
{
SetLastError(CRYPT_E_NOT_FOUND);
ret = NULL;
}
}
TRACE("returning %p\n", ret);
return ret;
}
static PWINE_CERT_CONTEXT CRYPT_CollectionEnumCert(PWINECRYPT_CERTSTORE store,
PWINE_CERT_CONTEXT pPrev)
{
PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
PWINE_COLLECTION_CERT_CONTEXT prevEntry =
(PWINE_COLLECTION_CERT_CONTEXT)pPrev, ret;
TRACE("(%p, %p)\n", store, pPrev);
if (prevEntry)
{
EnterCriticalSection(&cs->cs);
ret = CRYPT_CollectionAdvanceEnum(cs, prevEntry->storeEntry, prevEntry);
LeaveCriticalSection(&cs->cs);
}
else
{
EnterCriticalSection(&cs->cs);
if (!list_empty(&cs->stores))
{
PWINE_STORE_LIST_ENTRY storeEntry;
storeEntry = LIST_ENTRY(cs->stores.next, WINE_STORE_LIST_ENTRY,
entry);
ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry, NULL);
}
else
{
SetLastError(CRYPT_E_NOT_FOUND);
ret = NULL;
}
LeaveCriticalSection(&cs->cs);
}
TRACE("returning %p\n", ret);
return (PWINE_CERT_CONTEXT)ret;
}
static BOOL WINAPI CRYPT_CollectionDeleteCert(HCERTSTORE hCertStore,
PCCERT_CONTEXT pCertContext, DWORD dwFlags)
{
PWINE_COLLECTION_CERT_CONTEXT context =
(PWINE_COLLECTION_CERT_CONTEXT)pCertContext;
BOOL ret;
TRACE("(%p, %p, %08lx)\n", hCertStore, pCertContext, dwFlags);
ret = CertDeleteCertificateFromStore((PCCERT_CONTEXT)context->cert.linked);
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.addCert = CRYPT_CollectionAddCert;
store->hdr.enumCert = CRYPT_CollectionEnumCert;
store->hdr.deleteCert = CRYPT_CollectionDeleteCert;
InitializeCriticalSection(&store->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, %08lx)\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,
PWINE_CERT_CONTEXT cert, DWORD dwAddDisposition,
PCCERT_CONTEXT *ppStoreContext)
{
PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
BOOL ret;
TRACE("(%p, %p, %ld, %p)\n", store, cert, dwAddDisposition, ppStoreContext);
if (ps->hdr.dwOpenFlags & CERT_STORE_READONLY_FLAG)
{
SetLastError(ERROR_ACCESS_DENIED);
ret = FALSE;
}
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->addCert(ps->memStore, cert,
dwAddDisposition, ppStoreContext);
/* dirty trick: replace the returned context's hCertStore with
* store.
*/
if (ppStoreContext)
(*(PCERT_CONTEXT *)ppStoreContext)->hCertStore = store;
}
}
return ret;
}
static PWINE_CERT_CONTEXT CRYPT_ProvEnumCert(PWINECRYPT_CERTSTORE store,
PWINE_CERT_CONTEXT pPrev)
{
PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
PWINE_CERT_CONTEXT ret;
ret = ps->memStore->enumCert(ps->memStore, pPrev);
if (ret)
{
/* same dirty trick: replace the returned context's hCertStore with
* store.
*/
ret->cert.hCertStore = store;
}
return ret;
}
static BOOL WINAPI CRYPT_ProvDeleteCert(HCERTSTORE hCertStore,
PCCERT_CONTEXT cert, DWORD dwFlags)
{
PWINE_PROVIDERSTORE store = (PWINE_PROVIDERSTORE)hCertStore;
BOOL ret = TRUE;
TRACE("(%p, %p, %08lx)\n", hCertStore, cert, dwFlags);
if (store->provDeleteCert)
ret = store->provDeleteCert(store->hStoreProv, cert, dwFlags);
if (ret)
ret = store->memStore->deleteCert(store->memStore, cert, dwFlags);
return ret;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?