2006-04-16 19:15:04 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2002 Mike McCormack for CodeWeavers
|
|
|
|
* Copyright 2004-2006 Juan Lang
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
2006-07-06 10:19:03 +00:00
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
2006-04-16 19:15:04 +00:00
|
|
|
*
|
|
|
|
* FIXME:
|
|
|
|
* - The concept of physical stores and locations isn't implemented. (This
|
|
|
|
* doesn't mean registry stores et al aren't implemented. See the PSDK for
|
|
|
|
* registering and enumerating physical stores and locations.)
|
|
|
|
* - Many flags, options and whatnot are unimplemented.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "crypt32_private.h"
|
|
|
|
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
|
|
|
|
|
|
|
|
static const WINE_CONTEXT_INTERFACE gCertInterface = {
|
|
|
|
(CreateContextFunc)CertCreateCertificateContext,
|
|
|
|
(AddContextToStoreFunc)CertAddCertificateContextToStore,
|
|
|
|
(AddEncodedContextToStoreFunc)CertAddEncodedCertificateToStore,
|
2006-07-06 10:19:03 +00:00
|
|
|
(DuplicateContextFunc)CertDuplicateCertificateContext,
|
2006-04-16 19:15:04 +00:00
|
|
|
(EnumContextsInStoreFunc)CertEnumCertificatesInStore,
|
2006-07-06 10:19:03 +00:00
|
|
|
(EnumPropertiesFunc)CertEnumCertificateContextProperties,
|
2006-04-16 19:15:04 +00:00
|
|
|
(GetContextPropertyFunc)CertGetCertificateContextProperty,
|
|
|
|
(SetContextPropertyFunc)CertSetCertificateContextProperty,
|
|
|
|
(SerializeElementFunc)CertSerializeCertificateStoreElement,
|
2008-05-10 18:43:43 +00:00
|
|
|
(FreeContextFunc)CertFreeCertificateContext,
|
|
|
|
(DeleteContextFunc)CertDeleteCertificateFromStore,
|
|
|
|
};
|
|
|
|
PCWINE_CONTEXT_INTERFACE pCertInterface = &gCertInterface;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
static const WINE_CONTEXT_INTERFACE gCRLInterface = {
|
|
|
|
(CreateContextFunc)CertCreateCRLContext,
|
|
|
|
(AddContextToStoreFunc)CertAddCRLContextToStore,
|
|
|
|
(AddEncodedContextToStoreFunc)CertAddEncodedCRLToStore,
|
|
|
|
(DuplicateContextFunc)CertDuplicateCRLContext,
|
|
|
|
(EnumContextsInStoreFunc)CertEnumCRLsInStore,
|
|
|
|
(EnumPropertiesFunc)CertEnumCRLContextProperties,
|
|
|
|
(GetContextPropertyFunc)CertGetCRLContextProperty,
|
|
|
|
(SetContextPropertyFunc)CertSetCRLContextProperty,
|
|
|
|
(SerializeElementFunc)CertSerializeCRLStoreElement,
|
|
|
|
(FreeContextFunc)CertFreeCRLContext,
|
|
|
|
(DeleteContextFunc)CertDeleteCRLFromStore,
|
|
|
|
};
|
|
|
|
PCWINE_CONTEXT_INTERFACE pCRLInterface = &gCRLInterface;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
static const WINE_CONTEXT_INTERFACE gCTLInterface = {
|
|
|
|
(CreateContextFunc)CertCreateCTLContext,
|
|
|
|
(AddContextToStoreFunc)CertAddCTLContextToStore,
|
|
|
|
(AddEncodedContextToStoreFunc)CertAddEncodedCTLToStore,
|
|
|
|
(DuplicateContextFunc)CertDuplicateCTLContext,
|
|
|
|
(EnumContextsInStoreFunc)CertEnumCTLsInStore,
|
|
|
|
(EnumPropertiesFunc)CertEnumCTLContextProperties,
|
|
|
|
(GetContextPropertyFunc)CertGetCTLContextProperty,
|
|
|
|
(SetContextPropertyFunc)CertSetCTLContextProperty,
|
|
|
|
(SerializeElementFunc)CertSerializeCTLStoreElement,
|
|
|
|
(FreeContextFunc)CertFreeCTLContext,
|
|
|
|
(DeleteContextFunc)CertDeleteCTLFromStore,
|
|
|
|
};
|
|
|
|
PCWINE_CONTEXT_INTERFACE pCTLInterface = &gCTLInterface;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
typedef struct _WINE_MEMSTORE
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
WINECRYPT_CERTSTORE hdr;
|
|
|
|
struct ContextList *certs;
|
|
|
|
struct ContextList *crls;
|
2008-09-14 11:32:55 +00:00
|
|
|
struct ContextList *ctls;
|
2008-05-10 18:43:43 +00:00
|
|
|
} WINE_MEMSTORE, *PWINE_MEMSTORE;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
void CRYPT_InitStore(WINECRYPT_CERTSTORE *store, DWORD dwFlags,
|
|
|
|
CertStoreType type)
|
|
|
|
{
|
|
|
|
store->ref = 1;
|
|
|
|
store->dwMagic = WINE_CRYPTCERTSTORE_MAGIC;
|
|
|
|
store->type = type;
|
|
|
|
store->dwOpenFlags = dwFlags;
|
|
|
|
store->properties = NULL;
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
void CRYPT_FreeStore(PWINECRYPT_CERTSTORE store)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
if (store->properties)
|
|
|
|
ContextPropertyList_Free(store->properties);
|
|
|
|
CryptMemFree(store);
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
BOOL WINAPI I_CertUpdateStore(HCERTSTORE store1, HCERTSTORE store2, DWORD unk0,
|
|
|
|
DWORD unk1)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
static BOOL warned = FALSE;
|
|
|
|
const WINE_CONTEXT_INTERFACE * const interfaces[] = { pCertInterface,
|
|
|
|
pCRLInterface, pCTLInterface };
|
|
|
|
DWORD i;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
TRACE("(%p, %p, %08x, %08x)\n", store1, store2, unk0, unk1);
|
|
|
|
if (!warned)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
FIXME("semi-stub\n");
|
|
|
|
warned = TRUE;
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
/* Poor-man's resync: empty first store, then add everything from second
|
|
|
|
* store to it.
|
|
|
|
*/
|
|
|
|
for (i = 0; i < sizeof(interfaces) / sizeof(interfaces[0]); i++)
|
|
|
|
{
|
|
|
|
const void *context;
|
|
|
|
|
|
|
|
do {
|
|
|
|
context = interfaces[i]->enumContextsInStore(store1, NULL);
|
|
|
|
if (context)
|
|
|
|
interfaces[i]->deleteFromStore(context);
|
|
|
|
} while (context);
|
|
|
|
do {
|
|
|
|
context = interfaces[i]->enumContextsInStore(store2, context);
|
|
|
|
if (context)
|
|
|
|
interfaces[i]->addContextToStore(store1, context,
|
|
|
|
CERT_STORE_ADD_ALWAYS, NULL);
|
|
|
|
} while (context);
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
2008-05-10 18:43:43 +00:00
|
|
|
return TRUE;
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
static BOOL CRYPT_MemAddCert(PWINECRYPT_CERTSTORE store, void *cert,
|
|
|
|
void *toReplace, const void **ppStoreContext)
|
2006-07-06 10:19:03 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
|
|
|
|
PCERT_CONTEXT context;
|
2006-07-06 10:19:03 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
TRACE("(%p, %p, %p, %p)\n", store, cert, toReplace, ppStoreContext);
|
2006-07-06 10:19:03 +00:00
|
|
|
|
2008-12-27 11:03:19 +00:00
|
|
|
context = ContextList_Add(ms->certs, cert, toReplace);
|
2008-05-10 18:43:43 +00:00
|
|
|
if (context)
|
|
|
|
{
|
|
|
|
context->hCertStore = store;
|
|
|
|
if (ppStoreContext)
|
|
|
|
*ppStoreContext = CertDuplicateCertificateContext(context);
|
|
|
|
}
|
2013-04-03 22:43:22 +00:00
|
|
|
return context != 0;
|
2006-07-06 10:19:03 +00:00
|
|
|
}
|
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
static void *CRYPT_MemEnumCert(PWINECRYPT_CERTSTORE store, void *pPrev)
|
2006-07-06 10:19:03 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
|
|
|
|
void *ret;
|
|
|
|
|
|
|
|
TRACE("(%p, %p)\n", store, pPrev);
|
2006-07-06 10:19:03 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
ret = ContextList_Enum(ms->certs, pPrev);
|
|
|
|
if (!ret)
|
|
|
|
SetLastError(CRYPT_E_NOT_FOUND);
|
2006-07-06 10:19:03 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
TRACE("returning %p\n", ret);
|
|
|
|
return ret;
|
2006-07-06 10:19:03 +00:00
|
|
|
}
|
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
static BOOL CRYPT_MemDeleteCert(PWINECRYPT_CERTSTORE store, void *pCertContext)
|
2006-07-06 10:19:03 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
|
2009-11-15 22:58:08 +00:00
|
|
|
BOOL ret;
|
2006-07-06 10:19:03 +00:00
|
|
|
|
2009-11-15 22:58:08 +00:00
|
|
|
if (ContextList_Remove(ms->certs, pCertContext))
|
|
|
|
ret = CertFreeCertificateContext(pCertContext);
|
|
|
|
else
|
|
|
|
ret = TRUE;
|
|
|
|
return ret;
|
2006-07-06 10:19:03 +00:00
|
|
|
}
|
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
static BOOL CRYPT_MemAddCrl(PWINECRYPT_CERTSTORE store, void *crl,
|
|
|
|
void *toReplace, const void **ppStoreContext)
|
2006-07-06 10:19:03 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
|
|
|
|
PCRL_CONTEXT context;
|
2006-07-06 10:19:03 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
TRACE("(%p, %p, %p, %p)\n", store, crl, toReplace, ppStoreContext);
|
2006-07-06 10:19:03 +00:00
|
|
|
|
2008-12-27 11:03:19 +00:00
|
|
|
context = ContextList_Add(ms->crls, crl, toReplace);
|
2008-05-10 18:43:43 +00:00
|
|
|
if (context)
|
|
|
|
{
|
|
|
|
context->hCertStore = store;
|
|
|
|
if (ppStoreContext)
|
|
|
|
*ppStoreContext = CertDuplicateCRLContext(context);
|
|
|
|
}
|
2013-04-03 22:43:22 +00:00
|
|
|
return context != 0;
|
2006-07-06 10:19:03 +00:00
|
|
|
}
|
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
static void *CRYPT_MemEnumCrl(PWINECRYPT_CERTSTORE store, void *pPrev)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
|
|
|
|
void *ret;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
TRACE("(%p, %p)\n", store, pPrev);
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
ret = ContextList_Enum(ms->crls, pPrev);
|
|
|
|
if (!ret)
|
|
|
|
SetLastError(CRYPT_E_NOT_FOUND);
|
|
|
|
|
|
|
|
TRACE("returning %p\n", ret);
|
2006-04-16 19:15:04 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
static BOOL CRYPT_MemDeleteCrl(PWINECRYPT_CERTSTORE store, void *pCrlContext)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
|
2009-11-15 22:58:08 +00:00
|
|
|
BOOL ret;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2009-11-15 22:58:08 +00:00
|
|
|
if (ContextList_Remove(ms->crls, pCrlContext))
|
|
|
|
ret = CertFreeCRLContext(pCrlContext);
|
|
|
|
else
|
|
|
|
ret = TRUE;
|
|
|
|
return ret;
|
2008-05-10 18:43:43 +00:00
|
|
|
}
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2008-09-14 11:32:55 +00:00
|
|
|
static BOOL CRYPT_MemAddCtl(PWINECRYPT_CERTSTORE store, void *ctl,
|
|
|
|
void *toReplace, const void **ppStoreContext)
|
|
|
|
{
|
|
|
|
WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
|
|
|
|
PCTL_CONTEXT context;
|
|
|
|
|
|
|
|
TRACE("(%p, %p, %p, %p)\n", store, ctl, toReplace, ppStoreContext);
|
|
|
|
|
2008-12-27 11:03:19 +00:00
|
|
|
context = ContextList_Add(ms->ctls, ctl, toReplace);
|
2008-09-14 11:32:55 +00:00
|
|
|
if (context)
|
|
|
|
{
|
|
|
|
context->hCertStore = store;
|
|
|
|
if (ppStoreContext)
|
|
|
|
*ppStoreContext = CertDuplicateCTLContext(context);
|
|
|
|
}
|
2013-04-03 22:43:22 +00:00
|
|
|
return context != 0;
|
2008-09-14 11:32:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void *CRYPT_MemEnumCtl(PWINECRYPT_CERTSTORE store, void *pPrev)
|
|
|
|
{
|
|
|
|
WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
|
|
|
|
void *ret;
|
|
|
|
|
|
|
|
TRACE("(%p, %p)\n", store, pPrev);
|
|
|
|
|
|
|
|
ret = ContextList_Enum(ms->ctls, pPrev);
|
|
|
|
if (!ret)
|
|
|
|
SetLastError(CRYPT_E_NOT_FOUND);
|
|
|
|
|
|
|
|
TRACE("returning %p\n", ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static BOOL CRYPT_MemDeleteCtl(PWINECRYPT_CERTSTORE store, void *pCtlContext)
|
|
|
|
{
|
|
|
|
WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
|
2009-11-15 22:58:08 +00:00
|
|
|
BOOL ret;
|
2008-09-14 11:32:55 +00:00
|
|
|
|
2009-11-15 22:58:08 +00:00
|
|
|
if (ContextList_Remove(ms->ctls, pCtlContext))
|
|
|
|
ret = CertFreeCTLContext(pCtlContext);
|
|
|
|
else
|
|
|
|
ret = TRUE;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static BOOL WINAPI CRYPT_MemControl(HCERTSTORE hCertStore, DWORD dwFlags,
|
|
|
|
DWORD dwCtrlType, void const *pvCtrlPara)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
return FALSE;
|
2008-09-14 11:32:55 +00:00
|
|
|
}
|
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
static void WINAPI CRYPT_MemCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
|
|
|
|
{
|
2009-01-31 14:28:46 +00:00
|
|
|
WINE_MEMSTORE *store = hCertStore;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
TRACE("(%p, %08x)\n", store, dwFlags);
|
|
|
|
if (dwFlags)
|
|
|
|
FIXME("Unimplemented flags: %08x\n", dwFlags);
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
ContextList_Free(store->certs);
|
|
|
|
ContextList_Free(store->crls);
|
2008-09-14 11:32:55 +00:00
|
|
|
ContextList_Free(store->ctls);
|
2008-05-10 18:43:43 +00:00
|
|
|
CRYPT_FreeStore((PWINECRYPT_CERTSTORE)store);
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
static WINECRYPT_CERTSTORE *CRYPT_MemOpenStore(HCRYPTPROV hCryptProv,
|
2006-04-16 19:15:04 +00:00
|
|
|
DWORD dwFlags, const void *pvPara)
|
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
PWINE_MEMSTORE store;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2007-04-26 13:37:57 +00:00
|
|
|
TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
|
2006-04-16 19:15:04 +00:00
|
|
|
|
|
|
|
if (dwFlags & CERT_STORE_DELETE_FLAG)
|
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
store = NULL;
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
store = CryptMemAlloc(sizeof(WINE_MEMSTORE));
|
|
|
|
if (store)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
memset(store, 0, sizeof(WINE_MEMSTORE));
|
|
|
|
CRYPT_InitStore(&store->hdr, dwFlags, StoreTypeMem);
|
|
|
|
store->hdr.closeStore = CRYPT_MemCloseStore;
|
|
|
|
store->hdr.certs.addContext = CRYPT_MemAddCert;
|
|
|
|
store->hdr.certs.enumContext = CRYPT_MemEnumCert;
|
|
|
|
store->hdr.certs.deleteContext = CRYPT_MemDeleteCert;
|
|
|
|
store->hdr.crls.addContext = CRYPT_MemAddCrl;
|
|
|
|
store->hdr.crls.enumContext = CRYPT_MemEnumCrl;
|
|
|
|
store->hdr.crls.deleteContext = CRYPT_MemDeleteCrl;
|
2008-09-14 11:32:55 +00:00
|
|
|
store->hdr.ctls.addContext = CRYPT_MemAddCtl;
|
|
|
|
store->hdr.ctls.enumContext = CRYPT_MemEnumCtl;
|
|
|
|
store->hdr.ctls.deleteContext = CRYPT_MemDeleteCtl;
|
2009-11-15 22:58:08 +00:00
|
|
|
store->hdr.control = CRYPT_MemControl;
|
2008-05-10 18:43:43 +00:00
|
|
|
store->certs = ContextList_Create(pCertInterface,
|
|
|
|
sizeof(CERT_CONTEXT));
|
|
|
|
store->crls = ContextList_Create(pCRLInterface,
|
|
|
|
sizeof(CRL_CONTEXT));
|
2008-09-14 11:32:55 +00:00
|
|
|
store->ctls = ContextList_Create(pCTLInterface,
|
|
|
|
sizeof(CTL_CONTEXT));
|
2008-05-10 18:43:43 +00:00
|
|
|
/* Mem store doesn't need crypto provider, so close it */
|
|
|
|
if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
|
|
|
|
CryptReleaseContext(hCryptProv, 0);
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
}
|
2008-05-10 18:43:43 +00:00
|
|
|
return (PWINECRYPT_CERTSTORE)store;
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
|
2009-01-31 14:28:46 +00:00
|
|
|
static const WCHAR rootW[] = { 'R','o','o','t',0 };
|
|
|
|
|
2006-04-16 19:15:04 +00:00
|
|
|
static PWINECRYPT_CERTSTORE CRYPT_SysRegOpenStoreW(HCRYPTPROV hCryptProv,
|
|
|
|
DWORD dwFlags, const void *pvPara)
|
|
|
|
{
|
|
|
|
static const WCHAR fmt[] = { '%','s','\\','%','s',0 };
|
2009-01-31 14:28:46 +00:00
|
|
|
LPCWSTR storeName = pvPara;
|
2006-04-16 19:15:04 +00:00
|
|
|
LPWSTR storePath;
|
|
|
|
PWINECRYPT_CERTSTORE store = NULL;
|
|
|
|
HKEY root;
|
|
|
|
LPCWSTR base;
|
|
|
|
|
2007-04-26 13:37:57 +00:00
|
|
|
TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
|
2009-01-31 14:28:46 +00:00
|
|
|
debugstr_w(pvPara));
|
2006-04-16 19:15:04 +00:00
|
|
|
|
|
|
|
if (!pvPara)
|
|
|
|
{
|
2006-07-06 10:19:03 +00:00
|
|
|
SetLastError(E_INVALIDARG);
|
2006-04-16 19:15:04 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2009-01-31 14:28:46 +00:00
|
|
|
/* FIXME: In Windows, the root store (even the current user location) is
|
|
|
|
* protected: adding to it or removing from it present a user interface,
|
|
|
|
* and the keys are owned by the system process, not the current user.
|
|
|
|
* Wine's registry doesn't implement access controls, so a similar
|
|
|
|
* mechanism isn't possible yet.
|
|
|
|
*/
|
|
|
|
if ((dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) ==
|
|
|
|
CERT_SYSTEM_STORE_LOCAL_MACHINE && !lstrcmpiW(storeName, rootW))
|
2008-05-10 18:43:43 +00:00
|
|
|
return CRYPT_RootOpenStore(hCryptProv, dwFlags);
|
2006-04-16 19:15:04 +00:00
|
|
|
|
|
|
|
switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
|
|
|
|
{
|
|
|
|
case CERT_SYSTEM_STORE_LOCAL_MACHINE:
|
|
|
|
root = HKEY_LOCAL_MACHINE;
|
|
|
|
base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
|
|
|
|
break;
|
|
|
|
case CERT_SYSTEM_STORE_CURRENT_USER:
|
|
|
|
root = HKEY_CURRENT_USER;
|
|
|
|
base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
|
|
|
|
break;
|
|
|
|
case CERT_SYSTEM_STORE_CURRENT_SERVICE:
|
|
|
|
/* hklm\Software\Microsoft\Cryptography\Services\servicename\
|
|
|
|
* SystemCertificates
|
|
|
|
*/
|
|
|
|
FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE, %s: stub\n",
|
|
|
|
debugstr_w(storeName));
|
|
|
|
return NULL;
|
|
|
|
case CERT_SYSTEM_STORE_SERVICES:
|
|
|
|
/* hklm\Software\Microsoft\Cryptography\Services\servicename\
|
|
|
|
* SystemCertificates
|
|
|
|
*/
|
|
|
|
FIXME("CERT_SYSTEM_STORE_SERVICES, %s: stub\n",
|
|
|
|
debugstr_w(storeName));
|
|
|
|
return NULL;
|
|
|
|
case CERT_SYSTEM_STORE_USERS:
|
|
|
|
/* hku\user sid\Software\Microsoft\SystemCertificates */
|
|
|
|
FIXME("CERT_SYSTEM_STORE_USERS, %s: stub\n",
|
|
|
|
debugstr_w(storeName));
|
|
|
|
return NULL;
|
|
|
|
case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY:
|
|
|
|
root = HKEY_CURRENT_USER;
|
|
|
|
base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
|
|
|
|
break;
|
|
|
|
case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY:
|
|
|
|
root = HKEY_LOCAL_MACHINE;
|
|
|
|
base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
|
|
|
|
break;
|
|
|
|
case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE:
|
|
|
|
/* hklm\Software\Microsoft\EnterpriseCertificates */
|
|
|
|
FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, %s: stub\n",
|
|
|
|
debugstr_w(storeName));
|
|
|
|
return NULL;
|
|
|
|
default:
|
2006-07-06 10:19:03 +00:00
|
|
|
SetLastError(E_INVALIDARG);
|
2006-04-16 19:15:04 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
storePath = CryptMemAlloc((lstrlenW(base) + lstrlenW(storeName) + 2) *
|
|
|
|
sizeof(WCHAR));
|
|
|
|
if (storePath)
|
|
|
|
{
|
|
|
|
LONG rc;
|
|
|
|
HKEY key;
|
|
|
|
REGSAM sam = dwFlags & CERT_STORE_READONLY_FLAG ? KEY_READ :
|
|
|
|
KEY_ALL_ACCESS;
|
|
|
|
|
|
|
|
wsprintfW(storePath, fmt, base, storeName);
|
|
|
|
if (dwFlags & CERT_STORE_OPEN_EXISTING_FLAG)
|
|
|
|
rc = RegOpenKeyExW(root, storePath, 0, sam, &key);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DWORD disp;
|
|
|
|
|
|
|
|
rc = RegCreateKeyExW(root, storePath, 0, NULL, 0, sam, NULL,
|
|
|
|
&key, &disp);
|
|
|
|
if (!rc && dwFlags & CERT_STORE_CREATE_NEW_FLAG &&
|
|
|
|
disp == REG_OPENED_EXISTING_KEY)
|
|
|
|
{
|
|
|
|
RegCloseKey(key);
|
|
|
|
rc = ERROR_FILE_EXISTS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!rc)
|
|
|
|
{
|
|
|
|
store = CRYPT_RegOpenStore(hCryptProv, dwFlags, key);
|
|
|
|
RegCloseKey(key);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SetLastError(rc);
|
|
|
|
CryptMemFree(storePath);
|
|
|
|
}
|
|
|
|
return store;
|
|
|
|
}
|
|
|
|
|
|
|
|
static PWINECRYPT_CERTSTORE CRYPT_SysRegOpenStoreA(HCRYPTPROV hCryptProv,
|
|
|
|
DWORD dwFlags, const void *pvPara)
|
|
|
|
{
|
|
|
|
int len;
|
|
|
|
PWINECRYPT_CERTSTORE ret = NULL;
|
|
|
|
|
2007-04-26 13:37:57 +00:00
|
|
|
TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
|
2009-01-31 14:28:46 +00:00
|
|
|
debugstr_a(pvPara));
|
2006-04-16 19:15:04 +00:00
|
|
|
|
|
|
|
if (!pvPara)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_FILE_NOT_FOUND);
|
|
|
|
return NULL;
|
|
|
|
}
|
2009-01-31 14:28:46 +00:00
|
|
|
len = MultiByteToWideChar(CP_ACP, 0, pvPara, -1, NULL, 0);
|
2006-04-16 19:15:04 +00:00
|
|
|
if (len)
|
|
|
|
{
|
|
|
|
LPWSTR storeName = CryptMemAlloc(len * sizeof(WCHAR));
|
|
|
|
|
|
|
|
if (storeName)
|
|
|
|
{
|
2009-01-31 14:28:46 +00:00
|
|
|
MultiByteToWideChar(CP_ACP, 0, pvPara, -1, storeName, len);
|
2006-04-16 19:15:04 +00:00
|
|
|
ret = CRYPT_SysRegOpenStoreW(hCryptProv, dwFlags, storeName);
|
|
|
|
CryptMemFree(storeName);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static PWINECRYPT_CERTSTORE CRYPT_SysOpenStoreW(HCRYPTPROV hCryptProv,
|
|
|
|
DWORD dwFlags, const void *pvPara)
|
|
|
|
{
|
|
|
|
HCERTSTORE store = 0;
|
|
|
|
BOOL ret;
|
|
|
|
|
2007-04-26 13:37:57 +00:00
|
|
|
TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
|
2009-01-31 14:28:46 +00:00
|
|
|
debugstr_w(pvPara));
|
2006-04-16 19:15:04 +00:00
|
|
|
|
|
|
|
if (!pvPara)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_FILE_NOT_FOUND);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
/* This returns a different error than system registry stores if the
|
|
|
|
* location is invalid.
|
|
|
|
*/
|
|
|
|
switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
|
|
|
|
{
|
|
|
|
case CERT_SYSTEM_STORE_LOCAL_MACHINE:
|
|
|
|
case CERT_SYSTEM_STORE_CURRENT_USER:
|
|
|
|
case CERT_SYSTEM_STORE_CURRENT_SERVICE:
|
|
|
|
case CERT_SYSTEM_STORE_SERVICES:
|
|
|
|
case CERT_SYSTEM_STORE_USERS:
|
|
|
|
case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY:
|
|
|
|
case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY:
|
|
|
|
case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE:
|
|
|
|
ret = TRUE;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
SetLastError(ERROR_FILE_NOT_FOUND);
|
|
|
|
ret = FALSE;
|
|
|
|
}
|
|
|
|
if (ret)
|
|
|
|
{
|
|
|
|
HCERTSTORE regStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,
|
2008-05-10 18:43:43 +00:00
|
|
|
0, 0, dwFlags, pvPara);
|
2006-04-16 19:15:04 +00:00
|
|
|
|
|
|
|
if (regStore)
|
|
|
|
{
|
|
|
|
store = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
|
|
|
|
CERT_STORE_CREATE_NEW_FLAG, NULL);
|
|
|
|
CertAddStoreToCollection(store, regStore,
|
|
|
|
dwFlags & CERT_STORE_READONLY_FLAG ? 0 :
|
|
|
|
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
|
|
|
|
CertCloseStore(regStore, 0);
|
|
|
|
/* CERT_SYSTEM_STORE_CURRENT_USER returns both the HKCU and HKLM
|
|
|
|
* stores.
|
|
|
|
*/
|
|
|
|
if ((dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) ==
|
|
|
|
CERT_SYSTEM_STORE_CURRENT_USER)
|
|
|
|
{
|
|
|
|
dwFlags &= ~CERT_SYSTEM_STORE_CURRENT_USER;
|
|
|
|
dwFlags |= CERT_SYSTEM_STORE_LOCAL_MACHINE;
|
|
|
|
regStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0,
|
2008-05-10 18:43:43 +00:00
|
|
|
0, dwFlags, pvPara);
|
2006-04-16 19:15:04 +00:00
|
|
|
if (regStore)
|
|
|
|
{
|
|
|
|
CertAddStoreToCollection(store, regStore,
|
|
|
|
dwFlags & CERT_STORE_READONLY_FLAG ? 0 :
|
|
|
|
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
|
|
|
|
CertCloseStore(regStore, 0);
|
|
|
|
}
|
|
|
|
}
|
2008-05-10 18:43:43 +00:00
|
|
|
/* System store doesn't need crypto provider, so close it */
|
|
|
|
if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
|
|
|
|
CryptReleaseContext(hCryptProv, 0);
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
}
|
2009-01-31 14:28:46 +00:00
|
|
|
return store;
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static PWINECRYPT_CERTSTORE CRYPT_SysOpenStoreA(HCRYPTPROV hCryptProv,
|
|
|
|
DWORD dwFlags, const void *pvPara)
|
|
|
|
{
|
|
|
|
int len;
|
|
|
|
PWINECRYPT_CERTSTORE ret = NULL;
|
|
|
|
|
2007-04-26 13:37:57 +00:00
|
|
|
TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
|
2009-01-31 14:28:46 +00:00
|
|
|
debugstr_a(pvPara));
|
2006-04-16 19:15:04 +00:00
|
|
|
|
|
|
|
if (!pvPara)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_FILE_NOT_FOUND);
|
|
|
|
return NULL;
|
|
|
|
}
|
2009-01-31 14:28:46 +00:00
|
|
|
len = MultiByteToWideChar(CP_ACP, 0, pvPara, -1, NULL, 0);
|
2006-04-16 19:15:04 +00:00
|
|
|
if (len)
|
|
|
|
{
|
|
|
|
LPWSTR storeName = CryptMemAlloc(len * sizeof(WCHAR));
|
|
|
|
|
|
|
|
if (storeName)
|
|
|
|
{
|
2009-01-31 14:28:46 +00:00
|
|
|
MultiByteToWideChar(CP_ACP, 0, pvPara, -1, storeName, len);
|
2008-05-10 18:43:43 +00:00
|
|
|
ret = CRYPT_SysOpenStoreW(hCryptProv, dwFlags, storeName);
|
|
|
|
CryptMemFree(storeName);
|
|
|
|
}
|
2007-04-26 13:37:57 +00:00
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
static void WINAPI CRYPT_MsgCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
|
|
|
|
{
|
|
|
|
HCRYPTMSG msg = hCertStore;
|
|
|
|
|
|
|
|
TRACE("(%p, %08x)\n", msg, dwFlags);
|
|
|
|
CryptMsgClose(msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *msgProvFuncs[] = {
|
|
|
|
CRYPT_MsgCloseStore,
|
2007-04-26 13:37:57 +00:00
|
|
|
};
|
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
static PWINECRYPT_CERTSTORE CRYPT_MsgOpenStore(HCRYPTPROV hCryptProv,
|
2007-04-26 13:37:57 +00:00
|
|
|
DWORD dwFlags, const void *pvPara)
|
|
|
|
{
|
|
|
|
PWINECRYPT_CERTSTORE store = NULL;
|
2008-05-10 18:43:43 +00:00
|
|
|
HCRYPTMSG msg = (HCRYPTMSG)pvPara;
|
|
|
|
PWINECRYPT_CERTSTORE memStore;
|
2007-04-26 13:37:57 +00:00
|
|
|
|
|
|
|
TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
|
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
|
|
|
|
CERT_STORE_CREATE_NEW_FLAG, NULL);
|
|
|
|
if (memStore)
|
2007-04-26 13:37:57 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
BOOL ret;
|
|
|
|
DWORD size, count, i;
|
2007-04-26 13:37:57 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
size = sizeof(count);
|
|
|
|
ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &count, &size);
|
|
|
|
for (i = 0; ret && i < count; i++)
|
|
|
|
{
|
|
|
|
size = 0;
|
|
|
|
ret = CryptMsgGetParam(msg, CMSG_CERT_PARAM, i, NULL, &size);
|
|
|
|
if (ret)
|
|
|
|
{
|
|
|
|
LPBYTE buf = CryptMemAlloc(size);
|
2007-04-26 13:37:57 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
if (buf)
|
|
|
|
{
|
|
|
|
ret = CryptMsgGetParam(msg, CMSG_CERT_PARAM, i, buf, &size);
|
|
|
|
if (ret)
|
|
|
|
ret = CertAddEncodedCertificateToStore(memStore,
|
|
|
|
X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_ALWAYS,
|
|
|
|
NULL);
|
|
|
|
CryptMemFree(buf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
size = sizeof(count);
|
|
|
|
ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &count, &size);
|
|
|
|
for (i = 0; ret && i < count; i++)
|
2007-04-26 13:37:57 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
size = 0;
|
|
|
|
ret = CryptMsgGetParam(msg, CMSG_CRL_PARAM, i, NULL, &size);
|
|
|
|
if (ret)
|
2007-04-26 13:37:57 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
LPBYTE buf = CryptMemAlloc(size);
|
2007-04-26 13:37:57 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
if (buf)
|
2007-04-26 13:37:57 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
ret = CryptMsgGetParam(msg, CMSG_CRL_PARAM, i, buf, &size);
|
|
|
|
if (ret)
|
|
|
|
ret = CertAddEncodedCRLToStore(memStore,
|
|
|
|
X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_ALWAYS,
|
|
|
|
NULL);
|
|
|
|
CryptMemFree(buf);
|
2007-04-26 13:37:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2008-05-10 18:43:43 +00:00
|
|
|
if (ret)
|
|
|
|
{
|
|
|
|
CERT_STORE_PROV_INFO provInfo = { 0 };
|
|
|
|
|
|
|
|
provInfo.cbSize = sizeof(provInfo);
|
|
|
|
provInfo.cStoreProvFunc = sizeof(msgProvFuncs) /
|
|
|
|
sizeof(msgProvFuncs[0]);
|
|
|
|
provInfo.rgpvStoreProvFunc = msgProvFuncs;
|
|
|
|
provInfo.hStoreProv = CryptMsgDuplicate(msg);
|
|
|
|
store = CRYPT_ProvCreateStore(dwFlags, memStore, &provInfo);
|
|
|
|
/* Msg store doesn't need crypto provider, so close it */
|
|
|
|
if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
|
|
|
|
CryptReleaseContext(hCryptProv, 0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
CertCloseStore(memStore, 0);
|
2007-04-26 13:37:57 +00:00
|
|
|
}
|
|
|
|
TRACE("returning %p\n", store);
|
|
|
|
return store;
|
|
|
|
}
|
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
static PWINECRYPT_CERTSTORE CRYPT_PKCSOpenStore(HCRYPTPROV hCryptProv,
|
2006-07-21 11:13:18 +00:00
|
|
|
DWORD dwFlags, const void *pvPara)
|
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
HCRYPTMSG msg;
|
|
|
|
PWINECRYPT_CERTSTORE store = NULL;
|
2009-01-31 14:28:46 +00:00
|
|
|
const CRYPT_DATA_BLOB *data = pvPara;
|
2008-05-10 18:43:43 +00:00
|
|
|
BOOL ret;
|
|
|
|
DWORD msgOpenFlags = dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG ? 0 :
|
|
|
|
CMSG_CRYPT_RELEASE_CONTEXT_FLAG;
|
2006-07-21 11:13:18 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
|
2006-07-21 11:13:18 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, msgOpenFlags, CMSG_SIGNED,
|
|
|
|
hCryptProv, NULL, NULL);
|
|
|
|
ret = CryptMsgUpdate(msg, data->pbData, data->cbData, TRUE);
|
|
|
|
if (!ret)
|
2006-07-21 11:13:18 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
CryptMsgClose(msg);
|
|
|
|
msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, msgOpenFlags, 0,
|
|
|
|
hCryptProv, NULL, NULL);
|
|
|
|
ret = CryptMsgUpdate(msg, data->pbData, data->cbData, TRUE);
|
|
|
|
if (ret)
|
2006-07-21 11:13:18 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
DWORD type, size = sizeof(type);
|
|
|
|
|
|
|
|
/* Only signed messages are allowed, check type */
|
|
|
|
ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &type, &size);
|
|
|
|
if (ret && type != CMSG_SIGNED)
|
|
|
|
{
|
|
|
|
SetLastError(CRYPT_E_INVALID_MSG_TYPE);
|
|
|
|
ret = FALSE;
|
|
|
|
}
|
2006-07-21 11:13:18 +00:00
|
|
|
}
|
|
|
|
}
|
2008-05-10 18:43:43 +00:00
|
|
|
if (ret)
|
|
|
|
store = CRYPT_MsgOpenStore(0, dwFlags, msg);
|
|
|
|
CryptMsgClose(msg);
|
|
|
|
TRACE("returning %p\n", store);
|
|
|
|
return store;
|
2006-07-21 11:13:18 +00:00
|
|
|
}
|
|
|
|
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
static PWINECRYPT_CERTSTORE CRYPT_SerializedOpenStore(HCRYPTPROV hCryptProv,
|
|
|
|
DWORD dwFlags, const void *pvPara)
|
|
|
|
{
|
|
|
|
HCERTSTORE store;
|
|
|
|
const CRYPT_DATA_BLOB *data = pvPara;
|
|
|
|
|
|
|
|
TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
|
|
|
|
|
|
|
|
if (dwFlags & CERT_STORE_DELETE_FLAG)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
|
|
|
|
CERT_STORE_CREATE_NEW_FLAG, NULL);
|
|
|
|
if (store)
|
|
|
|
{
|
|
|
|
if (!CRYPT_ReadSerializedStoreFromBlob(data, store))
|
|
|
|
{
|
|
|
|
CertCloseStore(store, 0);
|
|
|
|
store = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
TRACE("returning %p\n", store);
|
|
|
|
return (PWINECRYPT_CERTSTORE)store;
|
|
|
|
}
|
|
|
|
|
2006-07-21 11:13:18 +00:00
|
|
|
static PWINECRYPT_CERTSTORE CRYPT_PhysOpenStoreW(HCRYPTPROV hCryptProv,
|
|
|
|
DWORD dwFlags, const void *pvPara)
|
|
|
|
{
|
|
|
|
if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG)
|
2007-04-26 13:37:57 +00:00
|
|
|
FIXME("(%ld, %08x, %p): stub\n", hCryptProv, dwFlags, pvPara);
|
2006-07-21 11:13:18 +00:00
|
|
|
else
|
2007-04-26 13:37:57 +00:00
|
|
|
FIXME("(%ld, %08x, %s): stub\n", hCryptProv, dwFlags,
|
2009-01-31 14:28:46 +00:00
|
|
|
debugstr_w(pvPara));
|
2006-07-21 11:13:18 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2006-04-16 19:15:04 +00:00
|
|
|
HCERTSTORE WINAPI CertOpenStore(LPCSTR lpszStoreProvider,
|
2008-05-10 18:43:43 +00:00
|
|
|
DWORD dwMsgAndCertEncodingType, HCRYPTPROV_LEGACY hCryptProv, DWORD dwFlags,
|
2006-04-16 19:15:04 +00:00
|
|
|
const void* pvPara)
|
|
|
|
{
|
|
|
|
WINECRYPT_CERTSTORE *hcs;
|
|
|
|
StoreOpenFunc openFunc = NULL;
|
|
|
|
|
2007-04-26 13:37:57 +00:00
|
|
|
TRACE("(%s, %08x, %08lx, %08x, %p)\n", debugstr_a(lpszStoreProvider),
|
2006-04-16 19:15:04 +00:00
|
|
|
dwMsgAndCertEncodingType, hCryptProv, dwFlags, pvPara);
|
|
|
|
|
2010-03-03 20:55:13 +00:00
|
|
|
if (IS_INTOID(lpszStoreProvider))
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
|
|
|
switch (LOWORD(lpszStoreProvider))
|
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
case LOWORD(CERT_STORE_PROV_MSG):
|
|
|
|
openFunc = CRYPT_MsgOpenStore;
|
|
|
|
break;
|
|
|
|
case LOWORD(CERT_STORE_PROV_MEMORY):
|
2006-04-16 19:15:04 +00:00
|
|
|
openFunc = CRYPT_MemOpenStore;
|
|
|
|
break;
|
2008-05-10 18:43:43 +00:00
|
|
|
case LOWORD(CERT_STORE_PROV_FILE):
|
2007-04-26 13:37:57 +00:00
|
|
|
openFunc = CRYPT_FileOpenStore;
|
|
|
|
break;
|
2008-05-10 18:43:43 +00:00
|
|
|
case LOWORD(CERT_STORE_PROV_PKCS7):
|
|
|
|
openFunc = CRYPT_PKCSOpenStore;
|
|
|
|
break;
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
case LOWORD(CERT_STORE_PROV_SERIALIZED):
|
|
|
|
openFunc = CRYPT_SerializedOpenStore;
|
|
|
|
break;
|
2008-05-10 18:43:43 +00:00
|
|
|
case LOWORD(CERT_STORE_PROV_REG):
|
2006-04-16 19:15:04 +00:00
|
|
|
openFunc = CRYPT_RegOpenStore;
|
|
|
|
break;
|
2008-05-10 18:43:43 +00:00
|
|
|
case LOWORD(CERT_STORE_PROV_FILENAME_A):
|
2006-07-21 11:13:18 +00:00
|
|
|
openFunc = CRYPT_FileNameOpenStoreA;
|
|
|
|
break;
|
2008-05-10 18:43:43 +00:00
|
|
|
case LOWORD(CERT_STORE_PROV_FILENAME_W):
|
2006-07-21 11:13:18 +00:00
|
|
|
openFunc = CRYPT_FileNameOpenStoreW;
|
|
|
|
break;
|
2008-05-10 18:43:43 +00:00
|
|
|
case LOWORD(CERT_STORE_PROV_COLLECTION):
|
2006-04-16 19:15:04 +00:00
|
|
|
openFunc = CRYPT_CollectionOpenStore;
|
|
|
|
break;
|
2008-05-10 18:43:43 +00:00
|
|
|
case LOWORD(CERT_STORE_PROV_SYSTEM_A):
|
2006-04-16 19:15:04 +00:00
|
|
|
openFunc = CRYPT_SysOpenStoreA;
|
|
|
|
break;
|
2008-05-10 18:43:43 +00:00
|
|
|
case LOWORD(CERT_STORE_PROV_SYSTEM_W):
|
2006-04-16 19:15:04 +00:00
|
|
|
openFunc = CRYPT_SysOpenStoreW;
|
|
|
|
break;
|
2008-05-10 18:43:43 +00:00
|
|
|
case LOWORD(CERT_STORE_PROV_SYSTEM_REGISTRY_A):
|
2006-04-16 19:15:04 +00:00
|
|
|
openFunc = CRYPT_SysRegOpenStoreA;
|
|
|
|
break;
|
2008-05-10 18:43:43 +00:00
|
|
|
case LOWORD(CERT_STORE_PROV_SYSTEM_REGISTRY_W):
|
2006-04-16 19:15:04 +00:00
|
|
|
openFunc = CRYPT_SysRegOpenStoreW;
|
|
|
|
break;
|
2008-05-10 18:43:43 +00:00
|
|
|
case LOWORD(CERT_STORE_PROV_PHYSICAL_W):
|
2006-07-21 11:13:18 +00:00
|
|
|
openFunc = CRYPT_PhysOpenStoreW;
|
|
|
|
break;
|
2006-04-16 19:15:04 +00:00
|
|
|
default:
|
|
|
|
if (LOWORD(lpszStoreProvider))
|
|
|
|
FIXME("unimplemented type %d\n", LOWORD(lpszStoreProvider));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_MEMORY))
|
|
|
|
openFunc = CRYPT_MemOpenStore;
|
2007-04-26 13:37:57 +00:00
|
|
|
else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_FILENAME_W))
|
|
|
|
openFunc = CRYPT_FileOpenStore;
|
2006-04-16 19:15:04 +00:00
|
|
|
else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_SYSTEM))
|
|
|
|
openFunc = CRYPT_SysOpenStoreW;
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_PKCS7))
|
|
|
|
openFunc = CRYPT_PKCSOpenStore;
|
|
|
|
else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_SERIALIZED))
|
|
|
|
openFunc = CRYPT_SerializedOpenStore;
|
2006-04-16 19:15:04 +00:00
|
|
|
else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_COLLECTION))
|
|
|
|
openFunc = CRYPT_CollectionOpenStore;
|
|
|
|
else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_SYSTEM_REGISTRY))
|
|
|
|
openFunc = CRYPT_SysRegOpenStoreW;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
FIXME("unimplemented type %s\n", lpszStoreProvider);
|
|
|
|
openFunc = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!openFunc)
|
|
|
|
hcs = CRYPT_ProvOpenStore(lpszStoreProvider, dwMsgAndCertEncodingType,
|
|
|
|
hCryptProv, dwFlags, pvPara);
|
|
|
|
else
|
|
|
|
hcs = openFunc(hCryptProv, dwFlags, pvPara);
|
2009-01-31 14:28:46 +00:00
|
|
|
return hcs;
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
HCERTSTORE WINAPI CertOpenSystemStoreA(HCRYPTPROV_LEGACY hProv,
|
2006-04-16 19:15:04 +00:00
|
|
|
LPCSTR szSubSystemProtocol)
|
|
|
|
{
|
|
|
|
if (!szSubSystemProtocol)
|
|
|
|
{
|
2006-07-06 10:19:03 +00:00
|
|
|
SetLastError(E_INVALIDARG);
|
2006-04-16 19:15:04 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, hProv,
|
|
|
|
CERT_SYSTEM_STORE_CURRENT_USER, szSubSystemProtocol);
|
|
|
|
}
|
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
HCERTSTORE WINAPI CertOpenSystemStoreW(HCRYPTPROV_LEGACY hProv,
|
2006-04-16 19:15:04 +00:00
|
|
|
LPCWSTR szSubSystemProtocol)
|
|
|
|
{
|
|
|
|
if (!szSubSystemProtocol)
|
|
|
|
{
|
2006-07-06 10:19:03 +00:00
|
|
|
SetLastError(E_INVALIDARG);
|
2006-04-16 19:15:04 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, hProv,
|
|
|
|
CERT_SYSTEM_STORE_CURRENT_USER, szSubSystemProtocol);
|
|
|
|
}
|
|
|
|
|
2006-07-06 10:19:03 +00:00
|
|
|
#define CertContext_CopyProperties(to, from) \
|
|
|
|
Context_CopyProperties((to), (from), sizeof(CERT_CONTEXT))
|
|
|
|
|
|
|
|
BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore,
|
|
|
|
PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition,
|
|
|
|
PCCERT_CONTEXT *ppStoreContext)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2009-01-31 14:28:46 +00:00
|
|
|
PWINECRYPT_CERTSTORE store = hCertStore;
|
2006-07-06 10:19:03 +00:00
|
|
|
BOOL ret = TRUE;
|
|
|
|
PCCERT_CONTEXT toAdd = NULL, existing = NULL;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2007-04-26 13:37:57 +00:00
|
|
|
TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCertContext,
|
2006-07-06 10:19:03 +00:00
|
|
|
dwAddDisposition, ppStoreContext);
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2010-05-29 13:14:05 +00:00
|
|
|
switch (dwAddDisposition)
|
|
|
|
{
|
|
|
|
case CERT_STORE_ADD_ALWAYS:
|
|
|
|
break;
|
|
|
|
case CERT_STORE_ADD_NEW:
|
|
|
|
case CERT_STORE_ADD_REPLACE_EXISTING:
|
|
|
|
case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES:
|
|
|
|
case CERT_STORE_ADD_USE_EXISTING:
|
|
|
|
case CERT_STORE_ADD_NEWER:
|
|
|
|
case CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES:
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2006-07-06 10:19:03 +00:00
|
|
|
BYTE hashToAdd[20];
|
|
|
|
DWORD size = sizeof(hashToAdd);
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2006-07-06 10:19:03 +00:00
|
|
|
ret = CertGetCertificateContextProperty(pCertContext, CERT_HASH_PROP_ID,
|
|
|
|
hashToAdd, &size);
|
|
|
|
if (ret)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2006-07-06 10:19:03 +00:00
|
|
|
CRYPT_HASH_BLOB blob = { sizeof(hashToAdd), hashToAdd };
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2006-07-06 10:19:03 +00:00
|
|
|
existing = CertFindCertificateInStore(hCertStore,
|
|
|
|
pCertContext->dwCertEncodingType, 0, CERT_FIND_SHA1_HASH, &blob,
|
|
|
|
NULL);
|
|
|
|
}
|
2010-05-29 13:14:05 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
FIXME("Unimplemented add disposition %d\n", dwAddDisposition);
|
|
|
|
SetLastError(E_INVALIDARG);
|
|
|
|
ret = FALSE;
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
|
2006-07-06 10:19:03 +00:00
|
|
|
switch (dwAddDisposition)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2006-07-06 10:19:03 +00:00
|
|
|
case CERT_STORE_ADD_ALWAYS:
|
|
|
|
toAdd = CertDuplicateCertificateContext(pCertContext);
|
|
|
|
break;
|
|
|
|
case CERT_STORE_ADD_NEW:
|
|
|
|
if (existing)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2006-07-06 10:19:03 +00:00
|
|
|
TRACE("found matching certificate, not adding\n");
|
|
|
|
SetLastError(CRYPT_E_EXISTS);
|
|
|
|
ret = FALSE;
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
else
|
2006-07-06 10:19:03 +00:00
|
|
|
toAdd = CertDuplicateCertificateContext(pCertContext);
|
|
|
|
break;
|
|
|
|
case CERT_STORE_ADD_REPLACE_EXISTING:
|
|
|
|
toAdd = CertDuplicateCertificateContext(pCertContext);
|
|
|
|
break;
|
|
|
|
case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES:
|
|
|
|
toAdd = CertDuplicateCertificateContext(pCertContext);
|
|
|
|
if (existing)
|
|
|
|
CertContext_CopyProperties(toAdd, existing);
|
|
|
|
break;
|
|
|
|
case CERT_STORE_ADD_USE_EXISTING:
|
|
|
|
if (existing)
|
2008-05-10 18:43:43 +00:00
|
|
|
{
|
2006-07-06 10:19:03 +00:00
|
|
|
CertContext_CopyProperties(existing, pCertContext);
|
2010-01-03 11:59:38 +00:00
|
|
|
if (ppStoreContext)
|
|
|
|
*ppStoreContext = CertDuplicateCertificateContext(existing);
|
2008-05-10 18:43:43 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
toAdd = CertDuplicateCertificateContext(pCertContext);
|
|
|
|
break;
|
|
|
|
case CERT_STORE_ADD_NEWER:
|
|
|
|
if (existing)
|
|
|
|
{
|
|
|
|
if (CompareFileTime(&existing->pCertInfo->NotBefore,
|
|
|
|
&pCertContext->pCertInfo->NotBefore) >= 0)
|
|
|
|
{
|
|
|
|
TRACE("existing certificate is newer, not adding\n");
|
|
|
|
SetLastError(CRYPT_E_EXISTS);
|
|
|
|
ret = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
toAdd = CertDuplicateCertificateContext(pCertContext);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
toAdd = CertDuplicateCertificateContext(pCertContext);
|
2006-07-06 10:19:03 +00:00
|
|
|
break;
|
2009-01-19 16:16:15 +00:00
|
|
|
case CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES:
|
|
|
|
if (existing)
|
|
|
|
{
|
|
|
|
if (CompareFileTime(&existing->pCertInfo->NotBefore,
|
|
|
|
&pCertContext->pCertInfo->NotBefore) >= 0)
|
|
|
|
{
|
|
|
|
TRACE("existing certificate is newer, not adding\n");
|
|
|
|
SetLastError(CRYPT_E_EXISTS);
|
|
|
|
ret = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
toAdd = CertDuplicateCertificateContext(pCertContext);
|
|
|
|
CertContext_CopyProperties(toAdd, existing);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
toAdd = CertDuplicateCertificateContext(pCertContext);
|
|
|
|
break;
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
2006-07-06 10:19:03 +00:00
|
|
|
|
|
|
|
if (toAdd)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2006-07-06 10:19:03 +00:00
|
|
|
if (store)
|
|
|
|
ret = store->certs.addContext(store, (void *)toAdd,
|
|
|
|
(void *)existing, (const void **)ppStoreContext);
|
|
|
|
else if (ppStoreContext)
|
|
|
|
*ppStoreContext = CertDuplicateCertificateContext(toAdd);
|
|
|
|
CertFreeCertificateContext(toAdd);
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
2006-07-06 10:19:03 +00:00
|
|
|
CertFreeCertificateContext(existing);
|
|
|
|
|
2006-04-16 19:15:04 +00:00
|
|
|
TRACE("returning %d\n", ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2006-07-06 10:19:03 +00:00
|
|
|
PCCERT_CONTEXT WINAPI CertEnumCertificatesInStore(HCERTSTORE hCertStore,
|
|
|
|
PCCERT_CONTEXT pPrev)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2009-01-31 14:28:46 +00:00
|
|
|
WINECRYPT_CERTSTORE *hcs = hCertStore;
|
2006-07-06 10:19:03 +00:00
|
|
|
PCCERT_CONTEXT ret;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2006-07-06 10:19:03 +00:00
|
|
|
TRACE("(%p, %p)\n", hCertStore, pPrev);
|
|
|
|
if (!hCertStore)
|
|
|
|
ret = NULL;
|
|
|
|
else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
|
|
|
|
ret = NULL;
|
|
|
|
else
|
|
|
|
ret = (PCCERT_CONTEXT)hcs->certs.enumContext(hcs, (void *)pPrev);
|
2006-04-16 19:15:04 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2006-07-06 10:19:03 +00:00
|
|
|
BOOL WINAPI CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
|
|
|
BOOL ret;
|
|
|
|
|
2006-07-06 10:19:03 +00:00
|
|
|
TRACE("(%p)\n", pCertContext);
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2006-07-06 10:19:03 +00:00
|
|
|
if (!pCertContext)
|
|
|
|
ret = TRUE;
|
|
|
|
else if (!pCertContext->hCertStore)
|
2009-11-15 22:58:08 +00:00
|
|
|
ret = CertFreeCertificateContext(pCertContext);
|
2006-04-16 19:15:04 +00:00
|
|
|
else
|
|
|
|
{
|
2009-01-31 14:28:46 +00:00
|
|
|
PWINECRYPT_CERTSTORE hcs = pCertContext->hCertStore;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2006-07-06 10:19:03 +00:00
|
|
|
if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
|
2006-04-16 19:15:04 +00:00
|
|
|
ret = FALSE;
|
2006-07-06 10:19:03 +00:00
|
|
|
else
|
|
|
|
ret = hcs->certs.deleteContext(hcs, (void *)pCertContext);
|
2009-09-26 10:46:37 +00:00
|
|
|
if (ret)
|
2009-11-15 22:58:08 +00:00
|
|
|
ret = CertFreeCertificateContext(pCertContext);
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2006-07-06 10:19:03 +00:00
|
|
|
#define CrlContext_CopyProperties(to, from) \
|
|
|
|
Context_CopyProperties((to), (from), sizeof(CRL_CONTEXT))
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2006-07-06 10:19:03 +00:00
|
|
|
BOOL WINAPI CertAddCRLContextToStore(HCERTSTORE hCertStore,
|
|
|
|
PCCRL_CONTEXT pCrlContext, DWORD dwAddDisposition,
|
|
|
|
PCCRL_CONTEXT* ppStoreContext)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2009-01-31 14:28:46 +00:00
|
|
|
PWINECRYPT_CERTSTORE store = hCertStore;
|
2006-07-06 10:19:03 +00:00
|
|
|
BOOL ret = TRUE;
|
|
|
|
PCCRL_CONTEXT toAdd = NULL, existing = NULL;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2007-04-26 13:37:57 +00:00
|
|
|
TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCrlContext,
|
2006-04-16 19:15:04 +00:00
|
|
|
dwAddDisposition, ppStoreContext);
|
|
|
|
|
2006-07-06 10:19:03 +00:00
|
|
|
/* Weird case to pass a test */
|
|
|
|
if (dwAddDisposition == 0)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2006-07-06 10:19:03 +00:00
|
|
|
SetLastError(STATUS_ACCESS_VIOLATION);
|
2006-04-16 19:15:04 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
2006-07-06 10:19:03 +00:00
|
|
|
if (dwAddDisposition != CERT_STORE_ADD_ALWAYS)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2006-07-06 10:19:03 +00:00
|
|
|
existing = CertFindCRLInStore(hCertStore, 0, 0, CRL_FIND_EXISTING,
|
|
|
|
pCrlContext, NULL);
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
|
2006-07-06 10:19:03 +00:00
|
|
|
switch (dwAddDisposition)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2006-07-06 10:19:03 +00:00
|
|
|
case CERT_STORE_ADD_ALWAYS:
|
|
|
|
toAdd = CertDuplicateCRLContext(pCrlContext);
|
|
|
|
break;
|
|
|
|
case CERT_STORE_ADD_NEW:
|
|
|
|
if (existing)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2006-07-06 10:19:03 +00:00
|
|
|
TRACE("found matching CRL, not adding\n");
|
|
|
|
SetLastError(CRYPT_E_EXISTS);
|
|
|
|
ret = FALSE;
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
else
|
2006-07-06 10:19:03 +00:00
|
|
|
toAdd = CertDuplicateCRLContext(pCrlContext);
|
|
|
|
break;
|
|
|
|
case CERT_STORE_ADD_NEWER:
|
|
|
|
if (existing)
|
|
|
|
{
|
|
|
|
LONG newer = CompareFileTime(&existing->pCrlInfo->ThisUpdate,
|
|
|
|
&pCrlContext->pCrlInfo->ThisUpdate);
|
|
|
|
|
|
|
|
if (newer < 0)
|
|
|
|
toAdd = CertDuplicateCRLContext(pCrlContext);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
TRACE("existing CRL is newer, not adding\n");
|
|
|
|
SetLastError(CRYPT_E_EXISTS);
|
|
|
|
ret = FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
toAdd = CertDuplicateCRLContext(pCrlContext);
|
|
|
|
break;
|
2009-01-19 16:16:15 +00:00
|
|
|
case CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES:
|
|
|
|
if (existing)
|
|
|
|
{
|
|
|
|
LONG newer = CompareFileTime(&existing->pCrlInfo->ThisUpdate,
|
|
|
|
&pCrlContext->pCrlInfo->ThisUpdate);
|
|
|
|
|
|
|
|
if (newer < 0)
|
|
|
|
{
|
|
|
|
toAdd = CertDuplicateCRLContext(pCrlContext);
|
|
|
|
CrlContext_CopyProperties(toAdd, existing);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
TRACE("existing CRL is newer, not adding\n");
|
|
|
|
SetLastError(CRYPT_E_EXISTS);
|
|
|
|
ret = FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
toAdd = CertDuplicateCRLContext(pCrlContext);
|
|
|
|
break;
|
2006-07-06 10:19:03 +00:00
|
|
|
case CERT_STORE_ADD_REPLACE_EXISTING:
|
|
|
|
toAdd = CertDuplicateCRLContext(pCrlContext);
|
|
|
|
break;
|
|
|
|
case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES:
|
|
|
|
toAdd = CertDuplicateCRLContext(pCrlContext);
|
|
|
|
if (existing)
|
|
|
|
CrlContext_CopyProperties(toAdd, existing);
|
|
|
|
break;
|
|
|
|
case CERT_STORE_ADD_USE_EXISTING:
|
|
|
|
if (existing)
|
2010-01-03 11:59:38 +00:00
|
|
|
{
|
2006-07-06 10:19:03 +00:00
|
|
|
CrlContext_CopyProperties(existing, pCrlContext);
|
2010-01-03 11:59:38 +00:00
|
|
|
if (ppStoreContext)
|
|
|
|
*ppStoreContext = CertDuplicateCRLContext(existing);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
toAdd = CertDuplicateCRLContext(pCrlContext);
|
2006-07-06 10:19:03 +00:00
|
|
|
break;
|
|
|
|
default:
|
2007-04-26 13:37:57 +00:00
|
|
|
FIXME("Unimplemented add disposition %d\n", dwAddDisposition);
|
2006-07-06 10:19:03 +00:00
|
|
|
ret = FALSE;
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
|
2006-07-06 10:19:03 +00:00
|
|
|
if (toAdd)
|
|
|
|
{
|
|
|
|
if (store)
|
|
|
|
ret = store->crls.addContext(store, (void *)toAdd,
|
|
|
|
(void *)existing, (const void **)ppStoreContext);
|
|
|
|
else if (ppStoreContext)
|
|
|
|
*ppStoreContext = CertDuplicateCRLContext(toAdd);
|
|
|
|
CertFreeCRLContext(toAdd);
|
|
|
|
}
|
|
|
|
CertFreeCRLContext(existing);
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2006-07-06 10:19:03 +00:00
|
|
|
TRACE("returning %d\n", ret);
|
2006-04-16 19:15:04 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2006-07-06 10:19:03 +00:00
|
|
|
BOOL WINAPI CertDeleteCRLFromStore(PCCRL_CONTEXT pCrlContext)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
|
|
|
BOOL ret;
|
|
|
|
|
2006-07-06 10:19:03 +00:00
|
|
|
TRACE("(%p)\n", pCrlContext);
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2006-07-06 10:19:03 +00:00
|
|
|
if (!pCrlContext)
|
2006-04-16 19:15:04 +00:00
|
|
|
ret = TRUE;
|
2006-07-06 10:19:03 +00:00
|
|
|
else if (!pCrlContext->hCertStore)
|
2009-11-15 22:58:08 +00:00
|
|
|
ret = CertFreeCRLContext(pCrlContext);
|
2006-04-16 19:15:04 +00:00
|
|
|
else
|
|
|
|
{
|
2009-01-31 14:28:46 +00:00
|
|
|
PWINECRYPT_CERTSTORE hcs = pCrlContext->hCertStore;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
|
|
|
if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
|
|
|
|
ret = FALSE;
|
|
|
|
else
|
2006-07-06 10:19:03 +00:00
|
|
|
ret = hcs->crls.deleteContext(hcs, (void *)pCrlContext);
|
2009-11-15 22:58:08 +00:00
|
|
|
if (ret)
|
|
|
|
ret = CertFreeCRLContext(pCrlContext);
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
PCCRL_CONTEXT WINAPI CertEnumCRLsInStore(HCERTSTORE hCertStore,
|
|
|
|
PCCRL_CONTEXT pPrev)
|
|
|
|
{
|
2009-01-31 14:28:46 +00:00
|
|
|
WINECRYPT_CERTSTORE *hcs = hCertStore;
|
2006-07-06 10:19:03 +00:00
|
|
|
PCCRL_CONTEXT ret;
|
|
|
|
|
|
|
|
TRACE("(%p, %p)\n", hCertStore, pPrev);
|
|
|
|
if (!hCertStore)
|
|
|
|
ret = NULL;
|
|
|
|
else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
|
|
|
|
ret = NULL;
|
|
|
|
else
|
|
|
|
ret = (PCCRL_CONTEXT)hcs->crls.enumContext(hcs, (void *)pPrev);
|
|
|
|
return ret;
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
HCERTSTORE WINAPI CertDuplicateStore(HCERTSTORE hCertStore)
|
|
|
|
{
|
2009-01-31 14:28:46 +00:00
|
|
|
WINECRYPT_CERTSTORE *hcs = hCertStore;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
|
|
|
TRACE("(%p)\n", hCertStore);
|
|
|
|
|
|
|
|
if (hcs && hcs->dwMagic == WINE_CRYPTCERTSTORE_MAGIC)
|
|
|
|
InterlockedIncrement(&hcs->ref);
|
|
|
|
return hCertStore;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL WINAPI CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
|
|
|
|
{
|
2009-01-31 14:28:46 +00:00
|
|
|
WINECRYPT_CERTSTORE *hcs = hCertStore;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2007-04-26 13:37:57 +00:00
|
|
|
TRACE("(%p, %08x)\n", hCertStore, dwFlags);
|
2006-04-16 19:15:04 +00:00
|
|
|
|
|
|
|
if( ! hCertStore )
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
if ( hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC )
|
|
|
|
return FALSE;
|
|
|
|
|
2009-11-15 22:58:08 +00:00
|
|
|
if (hcs->ref <= 0)
|
|
|
|
ERR("%p's ref count is %d\n", hcs, hcs->ref);
|
2006-04-16 19:15:04 +00:00
|
|
|
if (InterlockedDecrement(&hcs->ref) == 0)
|
|
|
|
{
|
|
|
|
TRACE("%p's ref count is 0, freeing\n", hcs);
|
|
|
|
hcs->dwMagic = 0;
|
|
|
|
hcs->closeStore(hcs, dwFlags);
|
|
|
|
}
|
|
|
|
else
|
2007-04-26 13:37:57 +00:00
|
|
|
TRACE("%p's ref count is %d\n", hcs, hcs->ref);
|
2006-04-16 19:15:04 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL WINAPI CertControlStore(HCERTSTORE hCertStore, DWORD dwFlags,
|
|
|
|
DWORD dwCtrlType, void const *pvCtrlPara)
|
|
|
|
{
|
2009-01-31 14:28:46 +00:00
|
|
|
WINECRYPT_CERTSTORE *hcs = hCertStore;
|
2006-04-16 19:15:04 +00:00
|
|
|
BOOL ret;
|
|
|
|
|
2007-04-26 13:37:57 +00:00
|
|
|
TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType,
|
2006-04-16 19:15:04 +00:00
|
|
|
pvCtrlPara);
|
|
|
|
|
|
|
|
if (!hcs)
|
|
|
|
ret = FALSE;
|
|
|
|
else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
|
|
|
|
ret = FALSE;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (hcs->control)
|
|
|
|
ret = hcs->control(hCertStore, dwFlags, dwCtrlType, pvCtrlPara);
|
|
|
|
else
|
|
|
|
ret = TRUE;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
BOOL WINAPI CertGetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId,
|
|
|
|
void *pvData, DWORD *pcbData)
|
|
|
|
{
|
2009-01-31 14:28:46 +00:00
|
|
|
PWINECRYPT_CERTSTORE store = hCertStore;
|
2008-05-10 18:43:43 +00:00
|
|
|
BOOL ret = FALSE;
|
|
|
|
|
|
|
|
TRACE("(%p, %d, %p, %p)\n", hCertStore, dwPropId, pvData, pcbData);
|
|
|
|
|
|
|
|
switch (dwPropId)
|
|
|
|
{
|
|
|
|
case CERT_ACCESS_STATE_PROP_ID:
|
|
|
|
if (!pvData)
|
|
|
|
{
|
|
|
|
*pcbData = sizeof(DWORD);
|
|
|
|
ret = TRUE;
|
|
|
|
}
|
|
|
|
else if (*pcbData < sizeof(DWORD))
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_MORE_DATA);
|
|
|
|
*pcbData = sizeof(DWORD);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DWORD state = 0;
|
|
|
|
|
|
|
|
if (store->type != StoreTypeMem &&
|
|
|
|
!(store->dwOpenFlags & CERT_STORE_READONLY_FLAG))
|
|
|
|
state |= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG;
|
|
|
|
*(DWORD *)pvData = state;
|
|
|
|
ret = TRUE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if (store->properties)
|
|
|
|
{
|
|
|
|
CRYPT_DATA_BLOB blob;
|
|
|
|
|
|
|
|
ret = ContextPropertyList_FindProperty(store->properties, dwPropId,
|
|
|
|
&blob);
|
|
|
|
if (ret)
|
|
|
|
{
|
|
|
|
if (!pvData)
|
|
|
|
*pcbData = blob.cbData;
|
|
|
|
else if (*pcbData < blob.cbData)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_MORE_DATA);
|
|
|
|
*pcbData = blob.cbData;
|
|
|
|
ret = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
memcpy(pvData, blob.pbData, blob.cbData);
|
|
|
|
*pcbData = blob.cbData;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SetLastError(CRYPT_E_NOT_FOUND);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SetLastError(CRYPT_E_NOT_FOUND);
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL WINAPI CertSetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId,
|
|
|
|
DWORD dwFlags, const void *pvData)
|
|
|
|
{
|
2009-01-31 14:28:46 +00:00
|
|
|
PWINECRYPT_CERTSTORE store = hCertStore;
|
2008-05-10 18:43:43 +00:00
|
|
|
BOOL ret = FALSE;
|
|
|
|
|
|
|
|
TRACE("(%p, %d, %08x, %p)\n", hCertStore, dwPropId, dwFlags, pvData);
|
|
|
|
|
|
|
|
if (!store->properties)
|
|
|
|
store->properties = ContextPropertyList_Create();
|
|
|
|
switch (dwPropId)
|
|
|
|
{
|
|
|
|
case CERT_ACCESS_STATE_PROP_ID:
|
|
|
|
SetLastError(E_INVALIDARG);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if (pvData)
|
|
|
|
{
|
2009-01-31 14:28:46 +00:00
|
|
|
const CRYPT_DATA_BLOB *blob = pvData;
|
2008-05-10 18:43:43 +00:00
|
|
|
|
|
|
|
ret = ContextPropertyList_SetProperty(store->properties, dwPropId,
|
|
|
|
blob->pbData, blob->cbData);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ContextPropertyList_RemoveProperty(store->properties, dwPropId);
|
|
|
|
ret = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static LONG CRYPT_OpenParentStore(DWORD dwFlags,
|
|
|
|
void *pvSystemStoreLocationPara, HKEY *key)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
HKEY root;
|
|
|
|
LPCWSTR base;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
TRACE("(%08x, %p)\n", dwFlags, pvSystemStoreLocationPara);
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
case CERT_SYSTEM_STORE_LOCAL_MACHINE:
|
|
|
|
root = HKEY_LOCAL_MACHINE;
|
|
|
|
base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
|
|
|
|
break;
|
|
|
|
case CERT_SYSTEM_STORE_CURRENT_USER:
|
|
|
|
root = HKEY_CURRENT_USER;
|
|
|
|
base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
|
|
|
|
break;
|
|
|
|
case CERT_SYSTEM_STORE_CURRENT_SERVICE:
|
|
|
|
/* hklm\Software\Microsoft\Cryptography\Services\servicename\
|
|
|
|
* SystemCertificates
|
|
|
|
*/
|
|
|
|
FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE\n");
|
|
|
|
return ERROR_FILE_NOT_FOUND;
|
|
|
|
case CERT_SYSTEM_STORE_SERVICES:
|
|
|
|
/* hklm\Software\Microsoft\Cryptography\Services\servicename\
|
|
|
|
* SystemCertificates
|
|
|
|
*/
|
|
|
|
FIXME("CERT_SYSTEM_STORE_SERVICES\n");
|
|
|
|
return ERROR_FILE_NOT_FOUND;
|
|
|
|
case CERT_SYSTEM_STORE_USERS:
|
|
|
|
/* hku\user sid\Software\Microsoft\SystemCertificates */
|
|
|
|
FIXME("CERT_SYSTEM_STORE_USERS\n");
|
|
|
|
return ERROR_FILE_NOT_FOUND;
|
|
|
|
case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY:
|
|
|
|
root = HKEY_CURRENT_USER;
|
|
|
|
base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
|
|
|
|
break;
|
|
|
|
case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY:
|
|
|
|
root = HKEY_LOCAL_MACHINE;
|
|
|
|
base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
|
|
|
|
break;
|
|
|
|
case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE:
|
|
|
|
/* hklm\Software\Microsoft\EnterpriseCertificates */
|
|
|
|
FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE\n");
|
|
|
|
return ERROR_FILE_NOT_FOUND;
|
|
|
|
default:
|
|
|
|
return ERROR_FILE_NOT_FOUND;
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
return RegOpenKeyExW(root, base, 0, KEY_READ, key);
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
BOOL WINAPI CertEnumSystemStore(DWORD dwFlags, void *pvSystemStoreLocationPara,
|
|
|
|
void *pvArg, PFN_CERT_ENUM_SYSTEM_STORE pfnEnum)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
BOOL ret = FALSE;
|
|
|
|
LONG rc;
|
|
|
|
HKEY key;
|
2009-01-31 14:28:46 +00:00
|
|
|
CERT_SYSTEM_STORE_INFO info = { sizeof(info) };
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
TRACE("(%08x, %p, %p, %p)\n", dwFlags, pvSystemStoreLocationPara, pvArg,
|
|
|
|
pfnEnum);
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
rc = CRYPT_OpenParentStore(dwFlags, pvArg, &key);
|
|
|
|
if (!rc)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
DWORD index = 0;
|
|
|
|
|
|
|
|
ret = TRUE;
|
|
|
|
do {
|
|
|
|
WCHAR name[MAX_PATH];
|
|
|
|
DWORD size = sizeof(name) / sizeof(name[0]);
|
|
|
|
|
|
|
|
rc = RegEnumKeyExW(key, index++, name, &size, NULL, NULL, NULL,
|
|
|
|
NULL);
|
|
|
|
if (!rc)
|
2008-12-27 11:03:19 +00:00
|
|
|
ret = pfnEnum(name, dwFlags, &info, NULL, pvArg);
|
2008-05-10 18:43:43 +00:00
|
|
|
} while (ret && !rc);
|
|
|
|
if (ret && rc != ERROR_NO_MORE_ITEMS)
|
|
|
|
SetLastError(rc);
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
2008-05-10 18:43:43 +00:00
|
|
|
else
|
|
|
|
SetLastError(rc);
|
2009-01-31 14:28:46 +00:00
|
|
|
/* Include root store for the local machine location (it isn't in the
|
|
|
|
* registry)
|
|
|
|
*/
|
|
|
|
if (ret && (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) ==
|
|
|
|
CERT_SYSTEM_STORE_LOCAL_MACHINE)
|
|
|
|
ret = pfnEnum(rootW, dwFlags, &info, NULL, pvArg);
|
2008-05-10 18:43:43 +00:00
|
|
|
return ret;
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
2008-12-27 11:03:19 +00:00
|
|
|
|
|
|
|
BOOL WINAPI CertEnumPhysicalStore(const void *pvSystemStore, DWORD dwFlags,
|
|
|
|
void *pvArg, PFN_CERT_ENUM_PHYSICAL_STORE pfnEnum)
|
|
|
|
{
|
|
|
|
if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG)
|
|
|
|
FIXME("(%p, %08x, %p, %p): stub\n", pvSystemStore, dwFlags, pvArg,
|
|
|
|
pfnEnum);
|
|
|
|
else
|
2009-01-31 14:28:46 +00:00
|
|
|
FIXME("(%s, %08x, %p, %p): stub\n", debugstr_w(pvSystemStore),
|
2008-12-27 11:03:19 +00:00
|
|
|
dwFlags, pvArg,
|
|
|
|
pfnEnum);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2012-01-23 15:45:15 +00:00
|
|
|
|
|
|
|
BOOL WINAPI CertRegisterPhysicalStore(const void *pvSystemStore, DWORD dwFlags,
|
|
|
|
LPCWSTR pwszStoreName, PCERT_PHYSICAL_STORE_INFO pStoreInfo, void *pvReserved)
|
|
|
|
{
|
|
|
|
if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG)
|
|
|
|
FIXME("(%p, %08x, %s, %p, %p): stub\n", pvSystemStore, dwFlags,
|
|
|
|
debugstr_w(pwszStoreName), pStoreInfo, pvReserved);
|
|
|
|
else
|
|
|
|
FIXME("(%s, %08x, %s, %p, %p): stub\n", debugstr_w(pvSystemStore),
|
|
|
|
dwFlags, debugstr_w(pwszStoreName), pStoreInfo, pvReserved);
|
|
|
|
return FALSE;
|
|
|
|
}
|