crypt32: Keep reference to store in contexts.
This commit is contained in:
parent
610c863e75
commit
9fb1e4d675
|
@ -124,7 +124,7 @@ static context_t *Cert_clone(context_t *context, WINECRYPT_CERTSTORE *store, BOO
|
|||
cert_t *cert;
|
||||
|
||||
if(use_link) {
|
||||
cert = (cert_t*)Context_CreateLinkContext(sizeof(CERT_CONTEXT), context);
|
||||
cert = (cert_t*)Context_CreateLinkContext(sizeof(CERT_CONTEXT), context, store);
|
||||
if(!cert)
|
||||
return NULL;
|
||||
}else {
|
||||
|
@ -133,7 +133,7 @@ static context_t *Cert_clone(context_t *context, WINECRYPT_CERTSTORE *store, BOO
|
|||
DWORD size = 0;
|
||||
BOOL res;
|
||||
|
||||
new_context = Context_CreateDataContext(sizeof(CERT_CONTEXT), &cert_vtbl);
|
||||
new_context = Context_CreateDataContext(sizeof(CERT_CONTEXT), &cert_vtbl, store);
|
||||
if(!new_context)
|
||||
return NULL;
|
||||
cert = cert_from_ptr(new_context);
|
||||
|
@ -270,12 +270,10 @@ BOOL WINAPI add_cert_to_store(WINECRYPT_CERTSTORE *store, const CERT_CONTEXT *ce
|
|||
if(inherit_props)
|
||||
Context_CopyProperties(context_ptr(new_context), existing);
|
||||
|
||||
if(ret_context) {
|
||||
Context_AddRef(new_context);
|
||||
if(ret_context)
|
||||
*ret_context = context_ptr(new_context);
|
||||
}else if(new_context) {
|
||||
else if(new_context)
|
||||
Context_Release(new_context);
|
||||
}
|
||||
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
|
@ -335,7 +333,7 @@ PCCERT_CONTEXT WINAPI CertCreateCertificateContext(DWORD dwCertEncodingType,
|
|||
{
|
||||
BYTE *data = NULL;
|
||||
|
||||
cert = Context_CreateDataContext(sizeof(CERT_CONTEXT), &cert_vtbl);
|
||||
cert = Context_CreateDataContext(sizeof(CERT_CONTEXT), &cert_vtbl, &empty_store);
|
||||
if (!cert)
|
||||
goto end;
|
||||
data = CryptMemAlloc(cbCertEncoded);
|
||||
|
|
|
@ -71,6 +71,12 @@ static DWORD Collection_release(WINECRYPT_CERTSTORE *store, DWORD flags)
|
|||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static void Collection_releaseContext(WINECRYPT_CERTSTORE *store, context_t *context)
|
||||
{
|
||||
/* We don't cache context links, so just free them. */
|
||||
Context_Free(context);
|
||||
}
|
||||
|
||||
static context_t *CRYPT_CollectionCreateContextFromChild(WINE_COLLECTIONSTORE *store,
|
||||
WINE_STORE_LIST_ENTRY *storeEntry, context_t *child)
|
||||
{
|
||||
|
@ -256,14 +262,11 @@ static BOOL Collection_deleteCert(WINECRYPT_CERTSTORE *store, context_t *context
|
|||
{
|
||||
cert_t *cert = (cert_t*)context;
|
||||
cert_t *linked;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p, %p)\n", store, cert);
|
||||
|
||||
linked = (cert_t*)context->linked;
|
||||
ret = CertDeleteCertificateFromStore(&linked->ctx);
|
||||
Context_Release(&cert->base);
|
||||
return ret;
|
||||
return CertDeleteCertificateFromStore(&linked->ctx);
|
||||
}
|
||||
|
||||
static BOOL Collection_addCRL(WINECRYPT_CERTSTORE *store, context_t *crl,
|
||||
|
@ -327,14 +330,11 @@ static context_t *Collection_enumCRL(WINECRYPT_CERTSTORE *store, context_t *prev
|
|||
static BOOL Collection_deleteCRL(WINECRYPT_CERTSTORE *store, context_t *context)
|
||||
{
|
||||
crl_t *crl = (crl_t*)context, *linked;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p, %p)\n", store, crl);
|
||||
|
||||
linked = (crl_t*)context->linked;
|
||||
ret = CertDeleteCRLFromStore(&linked->ctx);
|
||||
Context_Release(&crl->base);
|
||||
return ret;
|
||||
return CertDeleteCRLFromStore(&linked->ctx);
|
||||
}
|
||||
|
||||
static BOOL Collection_addCTL(WINECRYPT_CERTSTORE *store, context_t *ctl,
|
||||
|
@ -398,14 +398,11 @@ static context_t *Collection_enumCTL(WINECRYPT_CERTSTORE *store, context_t *prev
|
|||
static BOOL Collection_deleteCTL(WINECRYPT_CERTSTORE *store, context_t *context)
|
||||
{
|
||||
ctl_t *ctl = (ctl_t*)context, *linked;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p, %p)\n", store, ctl);
|
||||
|
||||
linked = (ctl_t*)context->linked;
|
||||
ret = CertDeleteCTLFromStore(&linked->ctx);
|
||||
Context_Release(&ctl->base);
|
||||
return ret;
|
||||
return CertDeleteCTLFromStore(&linked->ctx);
|
||||
}
|
||||
|
||||
static BOOL Collection_control(WINECRYPT_CERTSTORE *cert_store, DWORD dwFlags,
|
||||
|
@ -448,6 +445,7 @@ static BOOL Collection_control(WINECRYPT_CERTSTORE *cert_store, DWORD dwFlags,
|
|||
static const store_vtbl_t CollectionStoreVtbl = {
|
||||
Collection_addref,
|
||||
Collection_release,
|
||||
Collection_releaseContext,
|
||||
Collection_control,
|
||||
{
|
||||
Collection_addCert,
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(context);
|
||||
|
||||
void *Context_CreateDataContext(size_t contextSize, const context_vtbl_t *vtbl)
|
||||
void *Context_CreateDataContext(size_t contextSize, const context_vtbl_t *vtbl, WINECRYPT_CERTSTORE *store)
|
||||
{
|
||||
context_t *context;
|
||||
|
||||
|
@ -33,9 +33,6 @@ void *Context_CreateDataContext(size_t contextSize, const context_vtbl_t *vtbl)
|
|||
if (!context)
|
||||
return NULL;
|
||||
|
||||
context->vtbl = vtbl;
|
||||
context->ref = 1;
|
||||
context->linked = NULL;
|
||||
context->properties = ContextPropertyList_Create();
|
||||
if (!context->properties)
|
||||
{
|
||||
|
@ -43,11 +40,18 @@ void *Context_CreateDataContext(size_t contextSize, const context_vtbl_t *vtbl)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
context->vtbl = vtbl;
|
||||
context->ref = 1;
|
||||
context->linked = NULL;
|
||||
|
||||
store->vtbl->addref(store);
|
||||
context->store = store;
|
||||
|
||||
TRACE("returning %p\n", context);
|
||||
return context_ptr(context);
|
||||
}
|
||||
|
||||
context_t *Context_CreateLinkContext(unsigned int contextSize, context_t *linked)
|
||||
context_t *Context_CreateLinkContext(unsigned int contextSize, context_t *linked, WINECRYPT_CERTSTORE *store)
|
||||
{
|
||||
context_t *context;
|
||||
|
||||
|
@ -64,36 +68,54 @@ context_t *Context_CreateLinkContext(unsigned int contextSize, context_t *linked
|
|||
context->properties = linked->properties;
|
||||
Context_AddRef(linked);
|
||||
|
||||
store->vtbl->addref(store);
|
||||
context->store = store;
|
||||
|
||||
TRACE("returning %p\n", context);
|
||||
return context;
|
||||
}
|
||||
|
||||
void Context_AddRef(context_t *context)
|
||||
{
|
||||
InterlockedIncrement(&context->ref);
|
||||
LONG ref = InterlockedIncrement(&context->ref);
|
||||
|
||||
TRACE("(%p) ref=%d\n", context, context->ref);
|
||||
|
||||
if(ref == 1) {
|
||||
/* This is the first external (non-store) reference. Increase store ref cnt. */
|
||||
context->store->vtbl->addref(context->store);
|
||||
}
|
||||
}
|
||||
|
||||
void Context_Free(context_t *context)
|
||||
{
|
||||
TRACE("(%p)\n", context);
|
||||
|
||||
assert(!context->ref);
|
||||
|
||||
if (!context->linked) {
|
||||
ContextPropertyList_Free(context->properties);
|
||||
context->vtbl->free(context);
|
||||
}else {
|
||||
Context_Release(context->linked);
|
||||
}
|
||||
|
||||
CryptMemFree(context);
|
||||
}
|
||||
|
||||
void Context_Release(context_t *context)
|
||||
{
|
||||
if (context->ref <= 0)
|
||||
{
|
||||
ERR("%p's ref count is %d\n", context, context->ref);
|
||||
LONG ref = InterlockedDecrement(&context->ref);
|
||||
|
||||
TRACE("(%p) ref=%d\n", context, ref);
|
||||
assert(ref >= 0);
|
||||
|
||||
if (!ref) {
|
||||
/* This is the last reference, but the context still may be in a store.
|
||||
* We release our store reference, but leave it up to store to free or keep the context. */
|
||||
context->store->vtbl->releaseContext(context->store, context);
|
||||
context->store->vtbl->release(context->store, 0);
|
||||
}
|
||||
if (InterlockedDecrement(&context->ref) == 0)
|
||||
{
|
||||
TRACE("freeing %p\n", context);
|
||||
if (!context->linked)
|
||||
{
|
||||
ContextPropertyList_Free(context->properties);
|
||||
context->vtbl->free(context);
|
||||
} else {
|
||||
Context_Release(context->linked);
|
||||
}
|
||||
CryptMemFree(context);
|
||||
}
|
||||
else
|
||||
TRACE("%p's ref count is %d\n", context, context->ref);
|
||||
}
|
||||
|
||||
void Context_CopyProperties(const void *to, const void *from)
|
||||
|
|
|
@ -46,7 +46,7 @@ static context_t *CRL_clone(context_t *context, WINECRYPT_CERTSTORE *store, BOOL
|
|||
return NULL;
|
||||
}
|
||||
|
||||
crl = (crl_t*)Context_CreateLinkContext(sizeof(CRL_CONTEXT), context);
|
||||
crl = (crl_t*)Context_CreateLinkContext(sizeof(CRL_CONTEXT), context, store);
|
||||
if(!crl)
|
||||
return NULL;
|
||||
|
||||
|
@ -82,7 +82,7 @@ PCCRL_CONTEXT WINAPI CertCreateCRLContext(DWORD dwCertEncodingType,
|
|||
{
|
||||
BYTE *data = NULL;
|
||||
|
||||
crl = Context_CreateDataContext(sizeof(CRL_CONTEXT), &crl_vtbl);
|
||||
crl = Context_CreateDataContext(sizeof(CRL_CONTEXT), &crl_vtbl, &empty_store);
|
||||
if (!crl)
|
||||
goto end;
|
||||
data = CryptMemAlloc(cbCrlEncoded);
|
||||
|
|
|
@ -174,6 +174,7 @@ typedef struct {
|
|||
struct _context_t {
|
||||
const context_vtbl_t *vtbl;
|
||||
LONG ref;
|
||||
struct WINE_CRYPTCERTSTORE *store;
|
||||
struct _context_t *linked;
|
||||
CONTEXT_PROPERTY_LIST *properties;
|
||||
union {
|
||||
|
@ -297,6 +298,7 @@ typedef enum _CertStoreType {
|
|||
typedef struct {
|
||||
void (*addref)(struct WINE_CRYPTCERTSTORE*);
|
||||
DWORD (*release)(struct WINE_CRYPTCERTSTORE*,DWORD);
|
||||
void (*releaseContext)(struct WINE_CRYPTCERTSTORE*,context_t*);
|
||||
BOOL (*control)(struct WINE_CRYPTCERTSTORE*,DWORD,DWORD,void const*);
|
||||
CONTEXT_FUNCS certs;
|
||||
CONTEXT_FUNCS crls;
|
||||
|
@ -387,24 +389,21 @@ DWORD cert_name_to_str_with_indent(DWORD dwCertEncodingType, DWORD indent,
|
|||
* which should be one of CERT_CONTEXT, CRL_CONTEXT, or CTL_CONTEXT.
|
||||
* Free with Context_Release.
|
||||
*/
|
||||
void *Context_CreateDataContext(size_t contextSize, const context_vtbl_t *vtbl) DECLSPEC_HIDDEN;
|
||||
void *Context_CreateDataContext(size_t contextSize, const context_vtbl_t *vtbl, struct WINE_CRYPTCERTSTORE*) DECLSPEC_HIDDEN;
|
||||
|
||||
/* Creates a new link context. The context refers to linked
|
||||
* rather than owning its own properties. If addRef is TRUE (which ordinarily
|
||||
* it should be) linked is addref'd.
|
||||
* Free with Context_Release.
|
||||
*/
|
||||
context_t *Context_CreateLinkContext(unsigned contextSize, context_t *linked) DECLSPEC_HIDDEN;
|
||||
context_t *Context_CreateLinkContext(unsigned contextSize, context_t *linked, struct WINE_CRYPTCERTSTORE*) DECLSPEC_HIDDEN;
|
||||
|
||||
/* Copies properties from fromContext to toContext. */
|
||||
void Context_CopyProperties(const void *to, const void *from) DECLSPEC_HIDDEN;
|
||||
|
||||
void Context_AddRef(context_t*) DECLSPEC_HIDDEN;
|
||||
|
||||
/* Decrements context's ref count. If context is a link context, releases its
|
||||
* linked context as well.
|
||||
*/
|
||||
void Context_Release(context_t *context) DECLSPEC_HIDDEN;
|
||||
void Context_Free(context_t*) DECLSPEC_HIDDEN;
|
||||
|
||||
/**
|
||||
* Context property list functions
|
||||
|
|
|
@ -48,7 +48,7 @@ static context_t *CTL_clone(context_t *context, WINECRYPT_CERTSTORE *store, BOOL
|
|||
return NULL;
|
||||
}
|
||||
|
||||
ctl = (ctl_t*)Context_CreateLinkContext(sizeof(CTL_CONTEXT), context);
|
||||
ctl = (ctl_t*)Context_CreateLinkContext(sizeof(CTL_CONTEXT), context, store);
|
||||
if(!ctl)
|
||||
return NULL;
|
||||
|
||||
|
@ -440,7 +440,7 @@ PCCTL_CONTEXT WINAPI CertCreateCTLContext(DWORD dwMsgAndCertEncodingType,
|
|||
&ctlInfo, &size);
|
||||
if (ret)
|
||||
{
|
||||
ctl = Context_CreateDataContext(sizeof(CTL_CONTEXT), &ctl_vtbl);
|
||||
ctl = Context_CreateDataContext(sizeof(CTL_CONTEXT), &ctl_vtbl, &empty_store);
|
||||
if (ctl)
|
||||
{
|
||||
BYTE *data = CryptMemAlloc(cbCtlEncoded);
|
||||
|
|
|
@ -15,7 +15,10 @@
|
|||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wincrypt.h"
|
||||
|
@ -68,6 +71,13 @@ static DWORD ProvStore_release(WINECRYPT_CERTSTORE *cert_store, DWORD flags)
|
|||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static void ProvStore_releaseContext(WINECRYPT_CERTSTORE *store, context_t *context)
|
||||
{
|
||||
/* As long as we don't have contexts properly stored (and hack around hCertStore
|
||||
in add* and enum* functions), this function should never be called. */
|
||||
assert(0);
|
||||
}
|
||||
|
||||
static BOOL ProvStore_addCert(WINECRYPT_CERTSTORE *store, context_t *cert,
|
||||
context_t *toReplace, context_t **ppStoreContext, BOOL use_link)
|
||||
{
|
||||
|
@ -277,6 +287,7 @@ static BOOL ProvStore_control(WINECRYPT_CERTSTORE *cert_store, DWORD dwFlags, DW
|
|||
static const store_vtbl_t ProvStoreVtbl = {
|
||||
ProvStore_addref,
|
||||
ProvStore_release,
|
||||
ProvStore_releaseContext,
|
||||
ProvStore_control,
|
||||
{
|
||||
ProvStore_addCert,
|
||||
|
|
|
@ -160,17 +160,17 @@ static BOOL MemStore_addContext(WINE_MEMSTORE *store, struct list *list, context
|
|||
context->u.entry.prev->next = &context->u.entry;
|
||||
context->u.entry.next->prev = &context->u.entry;
|
||||
list_init(&existing->u.entry);
|
||||
Context_Release(existing);
|
||||
if(!existing->ref)
|
||||
Context_Release(existing);
|
||||
}else {
|
||||
list_add_head(list, &context->u.entry);
|
||||
}
|
||||
LeaveCriticalSection(&store->cs);
|
||||
|
||||
if(ret_context) {
|
||||
Context_AddRef(context);
|
||||
if(ret_context)
|
||||
*ret_context = context;
|
||||
}
|
||||
|
||||
else
|
||||
Context_Release(context);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -210,8 +210,8 @@ static BOOL MemStore_deleteContext(WINE_MEMSTORE *store, context_t *context)
|
|||
}
|
||||
LeaveCriticalSection(&store->cs);
|
||||
|
||||
if(in_list)
|
||||
Context_Release(context);
|
||||
if(in_list && !context->ref)
|
||||
Context_Free(context);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -223,10 +223,17 @@ static void free_contexts(struct list *list)
|
|||
{
|
||||
TRACE("freeing %p\n", context);
|
||||
list_remove(&context->u.entry);
|
||||
Context_Release(context);
|
||||
Context_Free(context);
|
||||
}
|
||||
}
|
||||
|
||||
static void MemStore_releaseContext(WINECRYPT_CERTSTORE *store, context_t *context)
|
||||
{
|
||||
/* Free the context only if it's not in a list. Otherwise it may be reused later. */
|
||||
if(list_empty(&context->u.entry))
|
||||
Context_Free(context);
|
||||
}
|
||||
|
||||
static BOOL MemStore_addCert(WINECRYPT_CERTSTORE *store, context_t *cert,
|
||||
context_t *toReplace, context_t **ppStoreContext, BOOL use_link)
|
||||
{
|
||||
|
@ -348,6 +355,7 @@ static BOOL MemStore_control(WINECRYPT_CERTSTORE *store, DWORD dwFlags,
|
|||
static const store_vtbl_t MemStoreVtbl = {
|
||||
MemStore_addref,
|
||||
MemStore_release,
|
||||
MemStore_releaseContext,
|
||||
MemStore_control,
|
||||
{
|
||||
MemStore_addCert,
|
||||
|
@ -1401,6 +1409,11 @@ static DWORD EmptyStore_release(WINECRYPT_CERTSTORE *store, DWORD flags)
|
|||
return E_UNEXPECTED;
|
||||
}
|
||||
|
||||
static void EmptyStore_releaseContext(WINECRYPT_CERTSTORE *store, context_t *context)
|
||||
{
|
||||
Context_Free(context);
|
||||
}
|
||||
|
||||
static BOOL EmptyStore_add(WINECRYPT_CERTSTORE *store, context_t *context,
|
||||
context_t *replace, context_t **ret_context, BOOL use_link)
|
||||
{
|
||||
|
@ -1439,6 +1452,7 @@ static BOOL EmptyStore_control(WINECRYPT_CERTSTORE *store, DWORD flags, DWORD ct
|
|||
static const store_vtbl_t EmptyStoreVtbl = {
|
||||
EmptyStore_addref,
|
||||
EmptyStore_release,
|
||||
EmptyStore_releaseContext,
|
||||
EmptyStore_control,
|
||||
{
|
||||
EmptyStore_add,
|
||||
|
|
|
@ -93,6 +93,26 @@ static const BYTE bigCert2[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
|
|||
0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
|
||||
0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
|
||||
0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
|
||||
static const BYTE signedCTLWithCTLInnerContent[] = {
|
||||
0x30,0x82,0x01,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
|
||||
0xa0,0x82,0x01,0x00,0x30,0x81,0xfd,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,
|
||||
0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x30,0x06,0x09,
|
||||
0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x0a,0x01,0xa0,0x23,0x30,0x21,0x30,0x00,
|
||||
0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
|
||||
0x30,0x5a,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,
|
||||
0x00,0x31,0x81,0xb5,0x30,0x81,0xb2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
|
||||
0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
|
||||
0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
|
||||
0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0xa0,0x3b,0x30,0x18,0x06,0x09,0x2a,0x86,
|
||||
0x48,0x86,0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2b,0x06,0x01,0x04,
|
||||
0x01,0x82,0x37,0x0a,0x01,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
|
||||
0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x54,0x71,0xbc,0xe1,0x56,0x31,0xa2,0xf9,
|
||||
0x65,0x70,0x34,0xf8,0xe2,0xe9,0xb4,0xf4,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
|
||||
0x40,0x2f,0x1b,0x9f,0x5a,0x4a,0x15,0x73,0xfa,0xb1,0x93,0x3d,0x09,0x52,0xdf,
|
||||
0x6b,0x98,0x4b,0x13,0x5e,0xe7,0xbf,0x65,0xf4,0x9c,0xc2,0xb1,0x77,0x09,0xb1,
|
||||
0x66,0x4d,0x72,0x0d,0xb1,0x1a,0x50,0x20,0xe0,0x57,0xa2,0x39,0xc7,0xcd,0x7f,
|
||||
0x8e,0xe7,0x5f,0x76,0x2b,0xd1,0x6a,0x82,0xb3,0x30,0x25,0x61,0xf6,0x25,0x23,
|
||||
0x57,0x6c,0x0b,0x47,0xb8 };
|
||||
|
||||
|
||||
static BOOL (WINAPI *pCertAddStoreToCollection)(HCERTSTORE,HCERTSTORE,DWORD,DWORD);
|
||||
|
@ -2571,6 +2591,9 @@ static void testEmptyStore(void)
|
|||
|
||||
static void testCloseStore(void)
|
||||
{
|
||||
const CERT_CONTEXT *cert;
|
||||
const CRL_CONTEXT *crl;
|
||||
const CTL_CONTEXT *ctl;
|
||||
HCERTSTORE store, store2;
|
||||
BOOL res;
|
||||
|
||||
|
@ -2592,6 +2615,71 @@ static void testCloseStore(void)
|
|||
|
||||
res = CertCloseStore(store2, CERT_CLOSE_STORE_CHECK_FLAG);
|
||||
ok(res, "CertCloseStore failed\n");
|
||||
|
||||
store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
|
||||
ok(store != NULL, "CertOpenStore failed\n");
|
||||
|
||||
res = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, bigCert,
|
||||
sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &cert);
|
||||
ok(res, "CertAddEncodedCertificateToStore failed\n");
|
||||
|
||||
/* There is still a reference from cert */
|
||||
res = CertCloseStore(store, CERT_CLOSE_STORE_CHECK_FLAG);
|
||||
ok(!res && GetLastError() == CRYPT_E_PENDING_CLOSE, "CertCloseStore failed\n");
|
||||
|
||||
res = CertFreeCertificateContext(cert);
|
||||
ok(res, "CertFreeCertificateContext failed\n");
|
||||
|
||||
store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
|
||||
ok(store != NULL, "CertOpenStore failed\n");
|
||||
|
||||
res = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
|
||||
sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, &crl);
|
||||
ok(res, "CertAddEncodedCRLToStore failed\n");
|
||||
|
||||
/* There is still a reference from CRL */
|
||||
res = CertCloseStore(store, CERT_CLOSE_STORE_CHECK_FLAG);
|
||||
ok(!res && GetLastError() == CRYPT_E_PENDING_CLOSE, "CertCloseStore failed\n");
|
||||
|
||||
res = CertFreeCRLContext(crl);
|
||||
ok(res, "CertFreeCRLContext failed\n");
|
||||
|
||||
store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
|
||||
ok(store != NULL, "CertOpenStore failed\n");
|
||||
|
||||
res = CertAddEncodedCTLToStore(store, X509_ASN_ENCODING, signedCTLWithCTLInnerContent,
|
||||
sizeof(signedCTLWithCTLInnerContent), CERT_STORE_ADD_ALWAYS, &ctl);
|
||||
ok(res, "CertAddEncodedCTLToStore failed\n");
|
||||
|
||||
/* There is still a reference from CTL */
|
||||
res = CertCloseStore(store, CERT_CLOSE_STORE_CHECK_FLAG);
|
||||
ok(!res && GetLastError() == CRYPT_E_PENDING_CLOSE, "CertCloseStore returned: %x(%u)\n", res, GetLastError());
|
||||
|
||||
res = CertFreeCTLContext(ctl);
|
||||
ok(res, "CertFreeCTLContext failed\n");
|
||||
|
||||
/* Add all kinds of contexts, then release external references and make sure that store is properly closed. */
|
||||
store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
|
||||
ok(store != NULL, "CertOpenStore failed\n");
|
||||
|
||||
res = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, bigCert,
|
||||
sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &cert);
|
||||
ok(res, "CertAddEncodedCertificateToStore failed\n");
|
||||
|
||||
res = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
|
||||
sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, &crl);
|
||||
ok(res, "CertAddEncodedCRLToStore failed\n");
|
||||
|
||||
res = CertAddEncodedCTLToStore(store, X509_ASN_ENCODING, signedCTLWithCTLInnerContent,
|
||||
sizeof(signedCTLWithCTLInnerContent), CERT_STORE_ADD_ALWAYS, &ctl);
|
||||
ok(res, "CertAddEncodedCTLToStore failed\n");
|
||||
|
||||
CertFreeCertificateContext(cert);
|
||||
CertFreeCRLContext(crl);
|
||||
CertFreeCTLContext(ctl);
|
||||
|
||||
res = CertCloseStore(store, CERT_CLOSE_STORE_CHECK_FLAG);
|
||||
ok(res, "CertCloseStore failed\n");
|
||||
}
|
||||
|
||||
static void test_I_UpdateStore(void)
|
||||
|
|
Loading…
Reference in New Issue