2 * Copyright 2002 Mike McCormack for CodeWeavers
3 * Copyright 2004-2006 Juan Lang
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 * - The concept of physical stores and locations isn't implemented. (This
21 * doesn't mean registry stores et al aren't implemented. See the PSDK for
22 * registering and enumerating physical stores and locations.)
23 * - Many flags, options and whatnot are unimplemented.
35 #include "wine/debug.h"
36 #include "crypt32_private.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(crypt
);
40 static const WINE_CONTEXT_INTERFACE gCertInterface
= {
41 (CreateContextFunc
)CertCreateCertificateContext
,
42 (AddContextToStoreFunc
)CertAddCertificateContextToStore
,
43 (AddEncodedContextToStoreFunc
)CertAddEncodedCertificateToStore
,
44 (EnumContextsInStoreFunc
)CertEnumCertificatesInStore
,
45 (EnumPropertiesFunc
)CertEnumCertificateContextProperties
,
46 (GetContextPropertyFunc
)CertGetCertificateContextProperty
,
47 (SetContextPropertyFunc
)CertSetCertificateContextProperty
,
48 (SerializeElementFunc
)CertSerializeCertificateStoreElement
,
49 (DeleteContextFunc
)CertDeleteCertificateFromStore
,
51 const WINE_CONTEXT_INTERFACE
*pCertInterface
= &gCertInterface
;
53 static const WINE_CONTEXT_INTERFACE gCRLInterface
= {
54 (CreateContextFunc
)CertCreateCRLContext
,
55 (AddContextToStoreFunc
)CertAddCRLContextToStore
,
56 (AddEncodedContextToStoreFunc
)CertAddEncodedCRLToStore
,
57 (EnumContextsInStoreFunc
)CertEnumCRLsInStore
,
58 (EnumPropertiesFunc
)CertEnumCRLContextProperties
,
59 (GetContextPropertyFunc
)CertGetCRLContextProperty
,
60 (SetContextPropertyFunc
)CertSetCRLContextProperty
,
61 (SerializeElementFunc
)CertSerializeCRLStoreElement
,
62 (DeleteContextFunc
)CertDeleteCRLFromStore
,
64 const WINE_CONTEXT_INTERFACE
*pCRLInterface
= &gCRLInterface
;
66 static const WINE_CONTEXT_INTERFACE gCTLInterface
= {
67 (CreateContextFunc
)CertCreateCTLContext
,
68 (AddContextToStoreFunc
)CertAddCTLContextToStore
,
69 (AddEncodedContextToStoreFunc
)CertAddEncodedCTLToStore
,
70 (EnumContextsInStoreFunc
)CertEnumCTLsInStore
,
71 (EnumPropertiesFunc
)CertEnumCTLContextProperties
,
72 (GetContextPropertyFunc
)CertGetCTLContextProperty
,
73 (SetContextPropertyFunc
)CertSetCTLContextProperty
,
74 (SerializeElementFunc
)CertSerializeCTLStoreElement
,
75 (DeleteContextFunc
)CertDeleteCTLFromStore
,
77 const WINE_CONTEXT_INTERFACE
*pCTLInterface
= &gCTLInterface
;
79 typedef struct _WINE_MEMSTORE
81 WINECRYPT_CERTSTORE hdr
;
88 void CRYPT_InitStore(WINECRYPT_CERTSTORE
*store
, DWORD dwFlags
, CertStoreType type
, const store_vtbl_t
*vtbl
)
91 store
->dwMagic
= WINE_CRYPTCERTSTORE_MAGIC
;
93 store
->dwOpenFlags
= dwFlags
;
95 store
->properties
= NULL
;
98 void CRYPT_FreeStore(WINECRYPT_CERTSTORE
*store
)
100 if (store
->properties
)
101 ContextPropertyList_Free(store
->properties
);
106 BOOL WINAPI
I_CertUpdateStore(HCERTSTORE store1
, HCERTSTORE store2
, DWORD unk0
,
109 static BOOL warned
= FALSE
;
110 const WINE_CONTEXT_INTERFACE
* const interfaces
[] = { pCertInterface
,
111 pCRLInterface
, pCTLInterface
};
114 TRACE("(%p, %p, %08lx, %08lx)\n", store1
, store2
, unk0
, unk1
);
117 FIXME("semi-stub\n");
121 /* Poor-man's resync: empty first store, then add everything from second
124 for (i
= 0; i
< ARRAY_SIZE(interfaces
); i
++)
129 context
= interfaces
[i
]->enumContextsInStore(store1
, NULL
);
131 interfaces
[i
]->deleteFromStore(context
);
134 context
= interfaces
[i
]->enumContextsInStore(store2
, context
);
136 interfaces
[i
]->addContextToStore(store1
, context
,
137 CERT_STORE_ADD_ALWAYS
, NULL
);
143 static BOOL
MemStore_addContext(WINE_MEMSTORE
*store
, struct list
*list
, context_t
*orig_context
,
144 context_t
*existing
, context_t
**ret_context
, BOOL use_link
)
148 context
= orig_context
->vtbl
->clone(orig_context
, &store
->hdr
, use_link
);
152 TRACE("adding %p\n", context
);
153 EnterCriticalSection(&store
->cs
);
155 context
->u
.entry
.prev
= existing
->u
.entry
.prev
;
156 context
->u
.entry
.next
= existing
->u
.entry
.next
;
157 context
->u
.entry
.prev
->next
= &context
->u
.entry
;
158 context
->u
.entry
.next
->prev
= &context
->u
.entry
;
159 list_init(&existing
->u
.entry
);
161 Context_Release(existing
);
163 list_add_head(list
, &context
->u
.entry
);
165 LeaveCriticalSection(&store
->cs
);
168 *ret_context
= context
;
170 Context_Release(context
);
174 static context_t
*MemStore_enumContext(WINE_MEMSTORE
*store
, struct list
*list
, context_t
*prev
)
179 EnterCriticalSection(&store
->cs
);
181 next
= list_next(list
, &prev
->u
.entry
);
182 Context_Release(prev
);
184 next
= list_next(list
, list
);
186 LeaveCriticalSection(&store
->cs
);
189 SetLastError(CRYPT_E_NOT_FOUND
);
193 ret
= LIST_ENTRY(next
, context_t
, u
.entry
);
198 static BOOL
MemStore_deleteContext(WINE_MEMSTORE
*store
, context_t
*context
)
200 BOOL in_list
= FALSE
;
202 EnterCriticalSection(&store
->cs
);
203 if (!list_empty(&context
->u
.entry
)) {
204 list_remove(&context
->u
.entry
);
205 list_init(&context
->u
.entry
);
208 LeaveCriticalSection(&store
->cs
);
210 if(in_list
&& !context
->ref
)
211 Context_Free(context
);
215 static void free_contexts(struct list
*list
)
217 context_t
*context
, *next
;
219 LIST_FOR_EACH_ENTRY_SAFE(context
, next
, list
, context_t
, u
.entry
)
221 TRACE("freeing %p\n", context
);
222 list_remove(&context
->u
.entry
);
223 Context_Free(context
);
227 static void MemStore_releaseContext(WINECRYPT_CERTSTORE
*store
, context_t
*context
)
229 /* Free the context only if it's not in a list. Otherwise it may be reused later. */
230 if(list_empty(&context
->u
.entry
))
231 Context_Free(context
);
234 static BOOL
MemStore_addCert(WINECRYPT_CERTSTORE
*store
, context_t
*cert
,
235 context_t
*toReplace
, context_t
**ppStoreContext
, BOOL use_link
)
237 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
239 TRACE("(%p, %p, %p, %p)\n", store
, cert
, toReplace
, ppStoreContext
);
240 return MemStore_addContext(ms
, &ms
->certs
, cert
, toReplace
, ppStoreContext
, use_link
);
243 static context_t
*MemStore_enumCert(WINECRYPT_CERTSTORE
*store
, context_t
*prev
)
245 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
247 TRACE("(%p, %p)\n", store
, prev
);
249 return MemStore_enumContext(ms
, &ms
->certs
, prev
);
252 static BOOL
MemStore_deleteCert(WINECRYPT_CERTSTORE
*store
, context_t
*context
)
254 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
256 TRACE("(%p, %p)\n", store
, context
);
258 return MemStore_deleteContext(ms
, context
);
261 static BOOL
MemStore_addCRL(WINECRYPT_CERTSTORE
*store
, context_t
*crl
,
262 context_t
*toReplace
, context_t
**ppStoreContext
, BOOL use_link
)
264 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
266 TRACE("(%p, %p, %p, %p)\n", store
, crl
, toReplace
, ppStoreContext
);
268 return MemStore_addContext(ms
, &ms
->crls
, crl
, toReplace
, ppStoreContext
, use_link
);
271 static context_t
*MemStore_enumCRL(WINECRYPT_CERTSTORE
*store
, context_t
*prev
)
273 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
275 TRACE("(%p, %p)\n", store
, prev
);
277 return MemStore_enumContext(ms
, &ms
->crls
, prev
);
280 static BOOL
MemStore_deleteCRL(WINECRYPT_CERTSTORE
*store
, context_t
*context
)
282 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
284 TRACE("(%p, %p)\n", store
, context
);
286 return MemStore_deleteContext(ms
, context
);
289 static BOOL
MemStore_addCTL(WINECRYPT_CERTSTORE
*store
, context_t
*ctl
,
290 context_t
*toReplace
, context_t
**ppStoreContext
, BOOL use_link
)
292 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
294 TRACE("(%p, %p, %p, %p)\n", store
, ctl
, toReplace
, ppStoreContext
);
296 return MemStore_addContext(ms
, &ms
->ctls
, ctl
, toReplace
, ppStoreContext
, use_link
);
299 static context_t
*MemStore_enumCTL(WINECRYPT_CERTSTORE
*store
, context_t
*prev
)
301 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
303 TRACE("(%p, %p)\n", store
, prev
);
305 return MemStore_enumContext(ms
, &ms
->ctls
, prev
);
308 static BOOL
MemStore_deleteCTL(WINECRYPT_CERTSTORE
*store
, context_t
*context
)
310 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
312 TRACE("(%p, %p)\n", store
, context
);
314 return MemStore_deleteContext(ms
, context
);
317 static void MemStore_addref(WINECRYPT_CERTSTORE
*store
)
319 LONG ref
= InterlockedIncrement(&store
->ref
);
320 TRACE("ref = %ld\n", ref
);
323 static DWORD
MemStore_release(WINECRYPT_CERTSTORE
*cert_store
, DWORD flags
)
325 WINE_MEMSTORE
*store
= (WINE_MEMSTORE
*)cert_store
;
328 if(flags
& ~CERT_CLOSE_STORE_CHECK_FLAG
)
329 FIXME("Unimplemented flags %lx\n", flags
);
331 ref
= InterlockedDecrement(&store
->hdr
.ref
);
332 TRACE("(%p) ref=%ld\n", store
, ref
);
334 return (flags
& CERT_CLOSE_STORE_CHECK_FLAG
) ? CRYPT_E_PENDING_CLOSE
: ERROR_SUCCESS
;
336 free_contexts(&store
->certs
);
337 free_contexts(&store
->crls
);
338 free_contexts(&store
->ctls
);
339 store
->cs
.DebugInfo
->Spare
[0] = 0;
340 DeleteCriticalSection(&store
->cs
);
341 CRYPT_FreeStore(&store
->hdr
);
342 return ERROR_SUCCESS
;
345 static BOOL
MemStore_control(WINECRYPT_CERTSTORE
*store
, DWORD dwFlags
,
346 DWORD dwCtrlType
, void const *pvCtrlPara
)
348 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
352 static const store_vtbl_t MemStoreVtbl
= {
355 MemStore_releaseContext
,
372 static WINECRYPT_CERTSTORE
*CRYPT_MemOpenStore(HCRYPTPROV hCryptProv
,
373 DWORD dwFlags
, const void *pvPara
)
375 WINE_MEMSTORE
*store
;
377 TRACE("(%Id, %08lx, %p)\n", hCryptProv
, dwFlags
, pvPara
);
379 if (dwFlags
& CERT_STORE_DELETE_FLAG
)
381 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
386 store
= CryptMemAlloc(sizeof(WINE_MEMSTORE
));
389 memset(store
, 0, sizeof(WINE_MEMSTORE
));
390 CRYPT_InitStore(&store
->hdr
, dwFlags
, StoreTypeMem
, &MemStoreVtbl
);
391 InitializeCriticalSection(&store
->cs
);
392 store
->cs
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": ContextList.cs");
393 list_init(&store
->certs
);
394 list_init(&store
->crls
);
395 list_init(&store
->ctls
);
396 /* Mem store doesn't need crypto provider, so close it */
397 if (hCryptProv
&& !(dwFlags
& CERT_STORE_NO_CRYPT_RELEASE_FLAG
))
398 CryptReleaseContext(hCryptProv
, 0);
401 return (WINECRYPT_CERTSTORE
*)store
;
404 static WINECRYPT_CERTSTORE
*CRYPT_SysRegOpenStoreW(HCRYPTPROV hCryptProv
,
405 DWORD dwFlags
, const void *pvPara
)
407 LPCWSTR storeName
= pvPara
;
409 WINECRYPT_CERTSTORE
*store
= NULL
;
413 TRACE("(%Id, %08lx, %s)\n", hCryptProv
, dwFlags
,
418 SetLastError(E_INVALIDARG
);
422 switch (dwFlags
& CERT_SYSTEM_STORE_LOCATION_MASK
)
424 case CERT_SYSTEM_STORE_LOCAL_MACHINE
:
425 root
= HKEY_LOCAL_MACHINE
;
426 base
= CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH
;
427 /* If the HKLM\Root certs are requested, expressing system certs into the registry */
428 if (!lstrcmpiW(storeName
, L
"Root"))
429 CRYPT_ImportSystemRootCertsToReg();
431 case CERT_SYSTEM_STORE_CURRENT_USER
:
432 root
= HKEY_CURRENT_USER
;
433 base
= CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH
;
435 case CERT_SYSTEM_STORE_CURRENT_SERVICE
:
436 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
439 FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE, %s: stub\n",
440 debugstr_w(storeName
));
442 case CERT_SYSTEM_STORE_SERVICES
:
443 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
446 FIXME("CERT_SYSTEM_STORE_SERVICES, %s: stub\n",
447 debugstr_w(storeName
));
449 case CERT_SYSTEM_STORE_USERS
:
450 /* hku\user sid\Software\Microsoft\SystemCertificates */
451 FIXME("CERT_SYSTEM_STORE_USERS, %s: stub\n",
452 debugstr_w(storeName
));
454 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY
:
455 root
= HKEY_CURRENT_USER
;
456 base
= CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH
;
458 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY
:
459 root
= HKEY_LOCAL_MACHINE
;
460 base
= CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH
;
462 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE
:
463 /* hklm\Software\Microsoft\EnterpriseCertificates */
464 FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, %s: stub\n",
465 debugstr_w(storeName
));
468 SetLastError(E_INVALIDARG
);
472 storePath
= CryptMemAlloc((lstrlenW(base
) + lstrlenW(storeName
) + 2) *
478 REGSAM sam
= dwFlags
& CERT_STORE_READONLY_FLAG
? KEY_READ
:
481 wsprintfW(storePath
, L
"%s\\%s", base
, storeName
);
482 if (dwFlags
& CERT_STORE_OPEN_EXISTING_FLAG
)
483 rc
= RegOpenKeyExW(root
, storePath
, 0, sam
, &key
);
488 rc
= RegCreateKeyExW(root
, storePath
, 0, NULL
, 0, sam
, NULL
,
490 if (!rc
&& dwFlags
& CERT_STORE_CREATE_NEW_FLAG
&&
491 disp
== REG_OPENED_EXISTING_KEY
)
494 rc
= ERROR_FILE_EXISTS
;
499 store
= CRYPT_RegOpenStore(hCryptProv
, dwFlags
, key
);
504 CryptMemFree(storePath
);
509 static WINECRYPT_CERTSTORE
*CRYPT_SysRegOpenStoreA(HCRYPTPROV hCryptProv
,
510 DWORD dwFlags
, const void *pvPara
)
513 WINECRYPT_CERTSTORE
*ret
= NULL
;
515 TRACE("(%Id, %08lx, %s)\n", hCryptProv
, dwFlags
,
520 SetLastError(ERROR_FILE_NOT_FOUND
);
523 len
= MultiByteToWideChar(CP_ACP
, 0, pvPara
, -1, NULL
, 0);
526 LPWSTR storeName
= CryptMemAlloc(len
* sizeof(WCHAR
));
530 MultiByteToWideChar(CP_ACP
, 0, pvPara
, -1, storeName
, len
);
531 ret
= CRYPT_SysRegOpenStoreW(hCryptProv
, dwFlags
, storeName
);
532 CryptMemFree(storeName
);
538 static WINECRYPT_CERTSTORE
*CRYPT_SysOpenStoreW(HCRYPTPROV hCryptProv
,
539 DWORD dwFlags
, const void *pvPara
)
541 HCERTSTORE store
= 0;
544 TRACE("(%Id, %08lx, %s)\n", hCryptProv
, dwFlags
,
549 SetLastError(ERROR_FILE_NOT_FOUND
);
552 /* This returns a different error than system registry stores if the
553 * location is invalid.
555 switch (dwFlags
& CERT_SYSTEM_STORE_LOCATION_MASK
)
557 case CERT_SYSTEM_STORE_LOCAL_MACHINE
:
558 case CERT_SYSTEM_STORE_CURRENT_USER
:
559 case CERT_SYSTEM_STORE_CURRENT_SERVICE
:
560 case CERT_SYSTEM_STORE_SERVICES
:
561 case CERT_SYSTEM_STORE_USERS
:
562 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY
:
563 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY
:
564 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE
:
568 SetLastError(ERROR_FILE_NOT_FOUND
);
573 HCERTSTORE regStore
= CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W
,
574 0, 0, dwFlags
, pvPara
);
578 store
= CertOpenStore(CERT_STORE_PROV_COLLECTION
, 0, 0,
579 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
580 CertAddStoreToCollection(store
, regStore
,
581 dwFlags
& CERT_STORE_READONLY_FLAG
? 0 :
582 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG
, 0);
583 CertCloseStore(regStore
, 0);
584 /* CERT_SYSTEM_STORE_CURRENT_USER returns both the HKCU and HKLM
587 if ((dwFlags
& CERT_SYSTEM_STORE_LOCATION_MASK
) ==
588 CERT_SYSTEM_STORE_CURRENT_USER
)
590 dwFlags
&= ~CERT_SYSTEM_STORE_CURRENT_USER
;
591 dwFlags
|= CERT_SYSTEM_STORE_LOCAL_MACHINE
;
592 regStore
= CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W
, 0,
596 CertAddStoreToCollection(store
, regStore
,
597 dwFlags
& CERT_STORE_READONLY_FLAG
? 0 :
598 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG
, 0);
599 CertCloseStore(regStore
, 0);
602 /* System store doesn't need crypto provider, so close it */
603 if (hCryptProv
&& !(dwFlags
& CERT_STORE_NO_CRYPT_RELEASE_FLAG
))
604 CryptReleaseContext(hCryptProv
, 0);
610 static WINECRYPT_CERTSTORE
*CRYPT_SysOpenStoreA(HCRYPTPROV hCryptProv
,
611 DWORD dwFlags
, const void *pvPara
)
614 WINECRYPT_CERTSTORE
*ret
= NULL
;
616 TRACE("(%Id, %08lx, %s)\n", hCryptProv
, dwFlags
,
621 SetLastError(ERROR_FILE_NOT_FOUND
);
624 len
= MultiByteToWideChar(CP_ACP
, 0, pvPara
, -1, NULL
, 0);
627 LPWSTR storeName
= CryptMemAlloc(len
* sizeof(WCHAR
));
631 MultiByteToWideChar(CP_ACP
, 0, pvPara
, -1, storeName
, len
);
632 ret
= CRYPT_SysOpenStoreW(hCryptProv
, dwFlags
, storeName
);
633 CryptMemFree(storeName
);
639 static void WINAPI
CRYPT_MsgCloseStore(HCERTSTORE hCertStore
, DWORD dwFlags
)
641 HCRYPTMSG msg
= hCertStore
;
643 TRACE("(%p, %08lx)\n", msg
, dwFlags
);
647 static void *msgProvFuncs
[] = {
651 static WINECRYPT_CERTSTORE
*CRYPT_MsgOpenStore(HCRYPTPROV hCryptProv
,
652 DWORD dwFlags
, const void *pvPara
)
654 WINECRYPT_CERTSTORE
*store
= NULL
;
655 HCRYPTMSG msg
= (HCRYPTMSG
)pvPara
;
656 WINECRYPT_CERTSTORE
*memStore
;
658 TRACE("(%Id, %08lx, %p)\n", hCryptProv
, dwFlags
, pvPara
);
660 memStore
= CertOpenStore(CERT_STORE_PROV_MEMORY
, 0, 0,
661 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
665 DWORD size
, count
, i
;
667 size
= sizeof(count
);
668 ret
= CryptMsgGetParam(msg
, CMSG_CERT_COUNT_PARAM
, 0, &count
, &size
);
669 for (i
= 0; ret
&& i
< count
; i
++)
672 ret
= CryptMsgGetParam(msg
, CMSG_CERT_PARAM
, i
, NULL
, &size
);
675 LPBYTE buf
= CryptMemAlloc(size
);
679 ret
= CryptMsgGetParam(msg
, CMSG_CERT_PARAM
, i
, buf
, &size
);
681 ret
= CertAddEncodedCertificateToStore(memStore
,
682 X509_ASN_ENCODING
, buf
, size
, CERT_STORE_ADD_ALWAYS
,
688 size
= sizeof(count
);
689 ret
= CryptMsgGetParam(msg
, CMSG_CRL_COUNT_PARAM
, 0, &count
, &size
);
690 for (i
= 0; ret
&& i
< count
; i
++)
693 ret
= CryptMsgGetParam(msg
, CMSG_CRL_PARAM
, i
, NULL
, &size
);
696 LPBYTE buf
= CryptMemAlloc(size
);
700 ret
= CryptMsgGetParam(msg
, CMSG_CRL_PARAM
, i
, buf
, &size
);
702 ret
= CertAddEncodedCRLToStore(memStore
,
703 X509_ASN_ENCODING
, buf
, size
, CERT_STORE_ADD_ALWAYS
,
711 CERT_STORE_PROV_INFO provInfo
= { 0 };
713 provInfo
.cbSize
= sizeof(provInfo
);
714 provInfo
.cStoreProvFunc
= ARRAY_SIZE(msgProvFuncs
);
715 provInfo
.rgpvStoreProvFunc
= msgProvFuncs
;
716 provInfo
.hStoreProv
= CryptMsgDuplicate(msg
);
717 store
= CRYPT_ProvCreateStore(dwFlags
, memStore
, &provInfo
);
718 /* Msg store doesn't need crypto provider, so close it */
719 if (hCryptProv
&& !(dwFlags
& CERT_STORE_NO_CRYPT_RELEASE_FLAG
))
720 CryptReleaseContext(hCryptProv
, 0);
723 CertCloseStore(memStore
, 0);
725 TRACE("returning %p\n", store
);
729 static WINECRYPT_CERTSTORE
*CRYPT_PKCSOpenStore(HCRYPTPROV hCryptProv
,
730 DWORD dwFlags
, const void *pvPara
)
733 WINECRYPT_CERTSTORE
*store
= NULL
;
734 const CRYPT_DATA_BLOB
*data
= pvPara
;
736 DWORD msgOpenFlags
= dwFlags
& CERT_STORE_NO_CRYPT_RELEASE_FLAG
? 0 :
737 CMSG_CRYPT_RELEASE_CONTEXT_FLAG
;
739 TRACE("(%Id, %08lx, %p)\n", hCryptProv
, dwFlags
, pvPara
);
741 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, msgOpenFlags
, CMSG_SIGNED
,
742 hCryptProv
, NULL
, NULL
);
743 ret
= CryptMsgUpdate(msg
, data
->pbData
, data
->cbData
, TRUE
);
747 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, msgOpenFlags
, 0,
748 hCryptProv
, NULL
, NULL
);
749 ret
= CryptMsgUpdate(msg
, data
->pbData
, data
->cbData
, TRUE
);
752 DWORD type
, size
= sizeof(type
);
754 /* Only signed messages are allowed, check type */
755 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, &type
, &size
);
756 if (ret
&& type
!= CMSG_SIGNED
)
758 SetLastError(CRYPT_E_INVALID_MSG_TYPE
);
764 store
= CRYPT_MsgOpenStore(0, dwFlags
, msg
);
766 TRACE("returning %p\n", store
);
770 static WINECRYPT_CERTSTORE
*CRYPT_SerializedOpenStore(HCRYPTPROV hCryptProv
,
771 DWORD dwFlags
, const void *pvPara
)
774 const CRYPT_DATA_BLOB
*data
= pvPara
;
776 TRACE("(%Id, %08lx, %p)\n", hCryptProv
, dwFlags
, pvPara
);
778 if (dwFlags
& CERT_STORE_DELETE_FLAG
)
780 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
784 store
= CertOpenStore(CERT_STORE_PROV_MEMORY
, 0, 0,
785 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
788 if (!CRYPT_ReadSerializedStoreFromBlob(data
, store
))
790 CertCloseStore(store
, 0);
794 TRACE("returning %p\n", store
);
795 return (WINECRYPT_CERTSTORE
*)store
;
798 static WINECRYPT_CERTSTORE
*CRYPT_PhysOpenStoreW(HCRYPTPROV hCryptProv
,
799 DWORD dwFlags
, const void *pvPara
)
801 if (dwFlags
& CERT_SYSTEM_STORE_RELOCATE_FLAG
)
802 FIXME("(%Id, %08lx, %p): stub\n", hCryptProv
, dwFlags
, pvPara
);
804 FIXME("(%Id, %08lx, %s): stub\n", hCryptProv
, dwFlags
,
809 HCERTSTORE WINAPI
CertOpenStore(LPCSTR lpszStoreProvider
,
810 DWORD dwMsgAndCertEncodingType
, HCRYPTPROV_LEGACY hCryptProv
, DWORD dwFlags
,
813 WINECRYPT_CERTSTORE
*hcs
;
814 StoreOpenFunc openFunc
= NULL
;
816 TRACE("(%s, %08lx, %08Ix, %08lx, %p)\n", debugstr_a(lpszStoreProvider
),
817 dwMsgAndCertEncodingType
, hCryptProv
, dwFlags
, pvPara
);
819 if (IS_INTOID(lpszStoreProvider
))
821 switch (LOWORD(lpszStoreProvider
))
823 case LOWORD(CERT_STORE_PROV_MSG
):
824 openFunc
= CRYPT_MsgOpenStore
;
826 case LOWORD(CERT_STORE_PROV_MEMORY
):
827 openFunc
= CRYPT_MemOpenStore
;
829 case LOWORD(CERT_STORE_PROV_FILE
):
830 openFunc
= CRYPT_FileOpenStore
;
832 case LOWORD(CERT_STORE_PROV_PKCS7
):
833 openFunc
= CRYPT_PKCSOpenStore
;
835 case LOWORD(CERT_STORE_PROV_SERIALIZED
):
836 openFunc
= CRYPT_SerializedOpenStore
;
838 case LOWORD(CERT_STORE_PROV_REG
):
839 openFunc
= CRYPT_RegOpenStore
;
841 case LOWORD(CERT_STORE_PROV_FILENAME_A
):
842 openFunc
= CRYPT_FileNameOpenStoreA
;
844 case LOWORD(CERT_STORE_PROV_FILENAME_W
):
845 openFunc
= CRYPT_FileNameOpenStoreW
;
847 case LOWORD(CERT_STORE_PROV_COLLECTION
):
848 openFunc
= CRYPT_CollectionOpenStore
;
850 case LOWORD(CERT_STORE_PROV_SYSTEM_A
):
851 openFunc
= CRYPT_SysOpenStoreA
;
853 case LOWORD(CERT_STORE_PROV_SYSTEM_W
):
854 openFunc
= CRYPT_SysOpenStoreW
;
856 case LOWORD(CERT_STORE_PROV_SYSTEM_REGISTRY_A
):
857 openFunc
= CRYPT_SysRegOpenStoreA
;
859 case LOWORD(CERT_STORE_PROV_SYSTEM_REGISTRY_W
):
860 openFunc
= CRYPT_SysRegOpenStoreW
;
862 case LOWORD(CERT_STORE_PROV_PHYSICAL_W
):
863 openFunc
= CRYPT_PhysOpenStoreW
;
866 if (LOWORD(lpszStoreProvider
))
867 FIXME("unimplemented type %d\n", LOWORD(lpszStoreProvider
));
870 else if (!stricmp(lpszStoreProvider
, sz_CERT_STORE_PROV_MEMORY
))
871 openFunc
= CRYPT_MemOpenStore
;
872 else if (!stricmp(lpszStoreProvider
, sz_CERT_STORE_PROV_FILENAME_W
))
873 openFunc
= CRYPT_FileOpenStore
;
874 else if (!stricmp(lpszStoreProvider
, sz_CERT_STORE_PROV_SYSTEM
))
875 openFunc
= CRYPT_SysOpenStoreW
;
876 else if (!stricmp(lpszStoreProvider
, sz_CERT_STORE_PROV_PKCS7
))
877 openFunc
= CRYPT_PKCSOpenStore
;
878 else if (!stricmp(lpszStoreProvider
, sz_CERT_STORE_PROV_SERIALIZED
))
879 openFunc
= CRYPT_SerializedOpenStore
;
880 else if (!stricmp(lpszStoreProvider
, sz_CERT_STORE_PROV_COLLECTION
))
881 openFunc
= CRYPT_CollectionOpenStore
;
882 else if (!stricmp(lpszStoreProvider
, sz_CERT_STORE_PROV_SYSTEM_REGISTRY
))
883 openFunc
= CRYPT_SysRegOpenStoreW
;
886 FIXME("unimplemented type %s\n", lpszStoreProvider
);
891 hcs
= CRYPT_ProvOpenStore(lpszStoreProvider
, dwMsgAndCertEncodingType
,
892 hCryptProv
, dwFlags
, pvPara
);
894 hcs
= openFunc(hCryptProv
, dwFlags
, pvPara
);
898 HCERTSTORE WINAPI
CertOpenSystemStoreA(HCRYPTPROV_LEGACY hProv
,
899 LPCSTR szSubSystemProtocol
)
901 if (!szSubSystemProtocol
)
903 SetLastError(E_INVALIDARG
);
906 return CertOpenStore(CERT_STORE_PROV_SYSTEM_A
, 0, hProv
,
907 CERT_SYSTEM_STORE_CURRENT_USER
, szSubSystemProtocol
);
910 HCERTSTORE WINAPI
CertOpenSystemStoreW(HCRYPTPROV_LEGACY hProv
,
911 LPCWSTR szSubSystemProtocol
)
913 if (!szSubSystemProtocol
)
915 SetLastError(E_INVALIDARG
);
918 return CertOpenStore(CERT_STORE_PROV_SYSTEM_W
, 0, hProv
,
919 CERT_SYSTEM_STORE_CURRENT_USER
, szSubSystemProtocol
);
922 PCCERT_CONTEXT WINAPI
CertEnumCertificatesInStore(HCERTSTORE hCertStore
, PCCERT_CONTEXT pPrev
)
924 cert_t
*prev
= pPrev
? cert_from_ptr(pPrev
) : NULL
, *ret
;
925 WINECRYPT_CERTSTORE
*hcs
= hCertStore
;
927 TRACE("(%p, %p)\n", hCertStore
, pPrev
);
930 else if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
933 ret
= (cert_t
*)hcs
->vtbl
->certs
.enumContext(hcs
, prev
? &prev
->base
: NULL
);
934 return ret
? &ret
->ctx
: NULL
;
937 BOOL WINAPI
CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext
)
939 WINECRYPT_CERTSTORE
*hcs
;
941 TRACE("(%p)\n", pCertContext
);
946 hcs
= pCertContext
->hCertStore
;
948 if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
951 return hcs
->vtbl
->certs
.delete(hcs
, &cert_from_ptr(pCertContext
)->base
);
954 BOOL WINAPI
CertAddCRLContextToStore(HCERTSTORE hCertStore
,
955 PCCRL_CONTEXT pCrlContext
, DWORD dwAddDisposition
,
956 PCCRL_CONTEXT
* ppStoreContext
)
958 WINECRYPT_CERTSTORE
*store
= hCertStore
;
960 PCCRL_CONTEXT toAdd
= NULL
, existing
= NULL
;
962 TRACE("(%p, %p, %08lx, %p)\n", hCertStore
, pCrlContext
,
963 dwAddDisposition
, ppStoreContext
);
965 /* Weird case to pass a test */
966 if (dwAddDisposition
== 0)
968 SetLastError(STATUS_ACCESS_VIOLATION
);
971 if (dwAddDisposition
!= CERT_STORE_ADD_ALWAYS
)
973 existing
= CertFindCRLInStore(hCertStore
, 0, 0, CRL_FIND_EXISTING
,
977 switch (dwAddDisposition
)
979 case CERT_STORE_ADD_ALWAYS
:
980 toAdd
= CertDuplicateCRLContext(pCrlContext
);
982 case CERT_STORE_ADD_NEW
:
985 TRACE("found matching CRL, not adding\n");
986 SetLastError(CRYPT_E_EXISTS
);
990 toAdd
= CertDuplicateCRLContext(pCrlContext
);
992 case CERT_STORE_ADD_NEWER
:
995 LONG newer
= CompareFileTime(&existing
->pCrlInfo
->ThisUpdate
,
996 &pCrlContext
->pCrlInfo
->ThisUpdate
);
999 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1002 TRACE("existing CRL is newer, not adding\n");
1003 SetLastError(CRYPT_E_EXISTS
);
1008 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1010 case CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES
:
1013 LONG newer
= CompareFileTime(&existing
->pCrlInfo
->ThisUpdate
,
1014 &pCrlContext
->pCrlInfo
->ThisUpdate
);
1018 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1019 Context_CopyProperties(toAdd
, existing
);
1023 TRACE("existing CRL is newer, not adding\n");
1024 SetLastError(CRYPT_E_EXISTS
);
1029 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1031 case CERT_STORE_ADD_REPLACE_EXISTING
:
1032 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1034 case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES
:
1035 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1037 Context_CopyProperties(toAdd
, existing
);
1039 case CERT_STORE_ADD_USE_EXISTING
:
1042 Context_CopyProperties(existing
, pCrlContext
);
1044 *ppStoreContext
= CertDuplicateCRLContext(existing
);
1047 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1050 FIXME("Unimplemented add disposition %ld\n", dwAddDisposition
);
1057 context_t
*ret_context
;
1058 ret
= store
->vtbl
->crls
.addContext(store
, context_from_ptr(toAdd
),
1059 existing
? context_from_ptr(existing
) : NULL
, ppStoreContext
? &ret_context
: NULL
, FALSE
);
1060 if (ret
&& ppStoreContext
)
1061 *ppStoreContext
= context_ptr(ret_context
);
1062 }else if (ppStoreContext
) {
1063 *ppStoreContext
= CertDuplicateCRLContext(toAdd
);
1065 CertFreeCRLContext(toAdd
);
1068 CertFreeCRLContext(existing
);
1070 TRACE("returning %d\n", ret
);
1074 BOOL WINAPI
CertDeleteCRLFromStore(PCCRL_CONTEXT pCrlContext
)
1076 WINECRYPT_CERTSTORE
*hcs
;
1079 TRACE("(%p)\n", pCrlContext
);
1084 hcs
= pCrlContext
->hCertStore
;
1086 if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1089 ret
= hcs
->vtbl
->crls
.delete(hcs
, &crl_from_ptr(pCrlContext
)->base
);
1091 ret
= CertFreeCRLContext(pCrlContext
);
1095 PCCRL_CONTEXT WINAPI
CertEnumCRLsInStore(HCERTSTORE hCertStore
, PCCRL_CONTEXT pPrev
)
1097 crl_t
*ret
, *prev
= pPrev
? crl_from_ptr(pPrev
) : NULL
;
1098 WINECRYPT_CERTSTORE
*hcs
= hCertStore
;
1100 TRACE("(%p, %p)\n", hCertStore
, pPrev
);
1103 else if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1106 ret
= (crl_t
*)hcs
->vtbl
->crls
.enumContext(hcs
, prev
? &prev
->base
: NULL
);
1107 return ret
? &ret
->ctx
: NULL
;
1110 HCERTSTORE WINAPI
CertDuplicateStore(HCERTSTORE hCertStore
)
1112 WINECRYPT_CERTSTORE
*hcs
= hCertStore
;
1114 TRACE("(%p)\n", hCertStore
);
1116 if (hcs
&& hcs
->dwMagic
== WINE_CRYPTCERTSTORE_MAGIC
)
1117 hcs
->vtbl
->addref(hcs
);
1121 BOOL WINAPI
CertCloseStore(HCERTSTORE hCertStore
, DWORD dwFlags
)
1123 WINECRYPT_CERTSTORE
*hcs
= hCertStore
;
1126 TRACE("(%p, %08lx)\n", hCertStore
, dwFlags
);
1131 if ( hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1134 res
= hcs
->vtbl
->release(hcs
, dwFlags
);
1135 if (res
!= ERROR_SUCCESS
) {
1143 BOOL WINAPI
CertControlStore(HCERTSTORE hCertStore
, DWORD dwFlags
,
1144 DWORD dwCtrlType
, void const *pvCtrlPara
)
1146 WINECRYPT_CERTSTORE
*hcs
= hCertStore
;
1149 TRACE("(%p, %08lx, %ld, %p)\n", hCertStore
, dwFlags
, dwCtrlType
,
1154 else if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1158 if (hcs
->vtbl
->control
)
1159 ret
= hcs
->vtbl
->control(hcs
, dwFlags
, dwCtrlType
, pvCtrlPara
);
1166 BOOL WINAPI
CertGetStoreProperty(HCERTSTORE hCertStore
, DWORD dwPropId
,
1167 void *pvData
, DWORD
*pcbData
)
1169 WINECRYPT_CERTSTORE
*store
= hCertStore
;
1172 TRACE("(%p, %ld, %p, %p)\n", hCertStore
, dwPropId
, pvData
, pcbData
);
1176 case CERT_ACCESS_STATE_PROP_ID
:
1179 *pcbData
= sizeof(DWORD
);
1182 else if (*pcbData
< sizeof(DWORD
))
1184 SetLastError(ERROR_MORE_DATA
);
1185 *pcbData
= sizeof(DWORD
);
1191 if (store
->type
!= StoreTypeMem
&&
1192 !(store
->dwOpenFlags
& CERT_STORE_READONLY_FLAG
))
1193 state
|= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG
;
1194 *(DWORD
*)pvData
= state
;
1199 if (store
->properties
)
1201 CRYPT_DATA_BLOB blob
;
1203 ret
= ContextPropertyList_FindProperty(store
->properties
, dwPropId
,
1208 *pcbData
= blob
.cbData
;
1209 else if (*pcbData
< blob
.cbData
)
1211 SetLastError(ERROR_MORE_DATA
);
1212 *pcbData
= blob
.cbData
;
1217 memcpy(pvData
, blob
.pbData
, blob
.cbData
);
1218 *pcbData
= blob
.cbData
;
1222 SetLastError(CRYPT_E_NOT_FOUND
);
1225 SetLastError(CRYPT_E_NOT_FOUND
);
1230 BOOL WINAPI
CertSetStoreProperty(HCERTSTORE hCertStore
, DWORD dwPropId
,
1231 DWORD dwFlags
, const void *pvData
)
1233 WINECRYPT_CERTSTORE
*store
= hCertStore
;
1236 TRACE("(%p, %ld, %08lx, %p)\n", hCertStore
, dwPropId
, dwFlags
, pvData
);
1238 if (!store
->properties
)
1239 store
->properties
= ContextPropertyList_Create();
1242 case CERT_ACCESS_STATE_PROP_ID
:
1243 SetLastError(E_INVALIDARG
);
1248 const CRYPT_DATA_BLOB
*blob
= pvData
;
1250 ret
= ContextPropertyList_SetProperty(store
->properties
, dwPropId
,
1251 blob
->pbData
, blob
->cbData
);
1255 ContextPropertyList_RemoveProperty(store
->properties
, dwPropId
);
1262 static LONG
CRYPT_OpenParentStore(DWORD dwFlags
,
1263 void *pvSystemStoreLocationPara
, HKEY
*key
)
1268 TRACE("(%08lx, %p)\n", dwFlags
, pvSystemStoreLocationPara
);
1270 switch (dwFlags
& CERT_SYSTEM_STORE_LOCATION_MASK
)
1272 case CERT_SYSTEM_STORE_LOCAL_MACHINE
:
1273 root
= HKEY_LOCAL_MACHINE
;
1274 base
= CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH
;
1276 case CERT_SYSTEM_STORE_CURRENT_USER
:
1277 root
= HKEY_CURRENT_USER
;
1278 base
= CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH
;
1280 case CERT_SYSTEM_STORE_CURRENT_SERVICE
:
1281 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
1282 * SystemCertificates
1284 FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE\n");
1285 return ERROR_FILE_NOT_FOUND
;
1286 case CERT_SYSTEM_STORE_SERVICES
:
1287 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
1288 * SystemCertificates
1290 FIXME("CERT_SYSTEM_STORE_SERVICES\n");
1291 return ERROR_FILE_NOT_FOUND
;
1292 case CERT_SYSTEM_STORE_USERS
:
1293 /* hku\user sid\Software\Microsoft\SystemCertificates */
1294 FIXME("CERT_SYSTEM_STORE_USERS\n");
1295 return ERROR_FILE_NOT_FOUND
;
1296 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY
:
1297 root
= HKEY_CURRENT_USER
;
1298 base
= CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH
;
1300 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY
:
1301 root
= HKEY_LOCAL_MACHINE
;
1302 base
= CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH
;
1304 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE
:
1305 /* hklm\Software\Microsoft\EnterpriseCertificates */
1306 FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE\n");
1307 return ERROR_FILE_NOT_FOUND
;
1309 return ERROR_FILE_NOT_FOUND
;
1312 return RegOpenKeyExW(root
, base
, 0, KEY_READ
, key
);
1315 BOOL WINAPI
CertEnumSystemStore(DWORD dwFlags
, void *pvSystemStoreLocationPara
,
1316 void *pvArg
, PFN_CERT_ENUM_SYSTEM_STORE pfnEnum
)
1321 CERT_SYSTEM_STORE_INFO info
= { sizeof(info
) };
1323 TRACE("(%08lx, %p, %p, %p)\n", dwFlags
, pvSystemStoreLocationPara
, pvArg
,
1326 rc
= CRYPT_OpenParentStore(dwFlags
, pvArg
, &key
);
1333 WCHAR name
[MAX_PATH
];
1334 DWORD size
= ARRAY_SIZE(name
);
1336 rc
= RegEnumKeyExW(key
, index
++, name
, &size
, NULL
, NULL
, NULL
,
1339 ret
= pfnEnum(name
, dwFlags
, &info
, NULL
, pvArg
);
1340 } while (ret
&& !rc
);
1341 if (ret
&& rc
!= ERROR_NO_MORE_ITEMS
)
1346 /* Include root store for the local machine location (it isn't in the
1349 if (ret
&& (dwFlags
& CERT_SYSTEM_STORE_LOCATION_MASK
) ==
1350 CERT_SYSTEM_STORE_LOCAL_MACHINE
)
1351 ret
= pfnEnum(L
"Root", dwFlags
, &info
, NULL
, pvArg
);
1355 BOOL WINAPI
CertEnumPhysicalStore(const void *pvSystemStore
, DWORD dwFlags
,
1356 void *pvArg
, PFN_CERT_ENUM_PHYSICAL_STORE pfnEnum
)
1358 if (dwFlags
& CERT_SYSTEM_STORE_RELOCATE_FLAG
)
1359 FIXME("(%p, %08lx, %p, %p): stub\n", pvSystemStore
, dwFlags
, pvArg
,
1362 FIXME("(%s, %08lx, %p, %p): stub\n", debugstr_w(pvSystemStore
),
1368 BOOL WINAPI
CertRegisterPhysicalStore(const void *pvSystemStore
, DWORD dwFlags
,
1369 LPCWSTR pwszStoreName
, PCERT_PHYSICAL_STORE_INFO pStoreInfo
, void *pvReserved
)
1371 if (dwFlags
& CERT_SYSTEM_STORE_RELOCATE_FLAG
)
1372 FIXME("(%p, %08lx, %s, %p, %p): stub\n", pvSystemStore
, dwFlags
,
1373 debugstr_w(pwszStoreName
), pStoreInfo
, pvReserved
);
1375 FIXME("(%s, %08lx, %s, %p, %p): stub\n", debugstr_w(pvSystemStore
),
1376 dwFlags
, debugstr_w(pwszStoreName
), pStoreInfo
, pvReserved
);
1380 BOOL WINAPI
CertUnregisterPhysicalStore(const void *pvSystemStore
, DWORD dwFlags
,
1381 LPCWSTR pwszStoreName
)
1383 FIXME("(%p, %08lx, %s): stub\n", pvSystemStore
, dwFlags
, debugstr_w(pwszStoreName
));
1387 BOOL WINAPI
CertRegisterSystemStore(const void *pvSystemStore
, DWORD dwFlags
,
1388 PCERT_SYSTEM_STORE_INFO pStoreInfo
, void *pvReserved
)
1392 if (dwFlags
& CERT_SYSTEM_STORE_RELOCATE_FLAG
)
1394 FIXME("(%p, %08lx, %p, %p): flag not supported\n", pvSystemStore
, dwFlags
, pStoreInfo
, pvReserved
);
1398 TRACE("(%s, %08lx, %p, %p)\n", debugstr_w(pvSystemStore
), dwFlags
, pStoreInfo
, pvReserved
);
1400 hstore
= CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W
, 0, 0, dwFlags
, pvSystemStore
);
1403 CertCloseStore(hstore
, 0);
1410 BOOL WINAPI
CertUnregisterSystemStore(const void *pvSystemStore
, DWORD dwFlags
)
1414 if (dwFlags
& CERT_SYSTEM_STORE_RELOCATE_FLAG
)
1416 FIXME("(%p, %08lx): flag not supported\n", pvSystemStore
, dwFlags
);
1419 TRACE("(%s, %08lx)\n", debugstr_w(pvSystemStore
), dwFlags
);
1421 hstore
= CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W
, 0, 0, dwFlags
| CERT_STORE_OPEN_EXISTING_FLAG
, pvSystemStore
);
1425 hstore
= CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W
, 0, 0, dwFlags
| CERT_STORE_DELETE_FLAG
, pvSystemStore
);
1426 if (hstore
== NULL
&& GetLastError() == 0)
1432 static void EmptyStore_addref(WINECRYPT_CERTSTORE
*store
)
1434 TRACE("(%p)\n", store
);
1437 static DWORD
EmptyStore_release(WINECRYPT_CERTSTORE
*store
, DWORD flags
)
1439 TRACE("(%p)\n", store
);
1440 return E_UNEXPECTED
;
1443 static void EmptyStore_releaseContext(WINECRYPT_CERTSTORE
*store
, context_t
*context
)
1445 Context_Free(context
);
1448 static BOOL
EmptyStore_add(WINECRYPT_CERTSTORE
*store
, context_t
*context
,
1449 context_t
*replace
, context_t
**ret_context
, BOOL use_link
)
1451 TRACE("(%p, %p, %p, %p)\n", store
, context
, replace
, ret_context
);
1453 /* FIXME: We should clone the context */
1455 Context_AddRef(context
);
1456 *ret_context
= context
;
1462 static context_t
*EmptyStore_enum(WINECRYPT_CERTSTORE
*store
, context_t
*prev
)
1464 TRACE("(%p, %p)\n", store
, prev
);
1466 SetLastError(CRYPT_E_NOT_FOUND
);
1470 static BOOL
EmptyStore_delete(WINECRYPT_CERTSTORE
*store
, context_t
*context
)
1475 static BOOL
EmptyStore_control(WINECRYPT_CERTSTORE
*store
, DWORD flags
, DWORD ctrl_type
, void const *ctrl_para
)
1479 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1483 static const store_vtbl_t EmptyStoreVtbl
= {
1486 EmptyStore_releaseContext
,
1503 WINECRYPT_CERTSTORE empty_store
;
1505 void init_empty_store(void)
1507 CRYPT_InitStore(&empty_store
, CERT_STORE_READONLY_FLAG
, StoreTypeEmpty
, &EmptyStoreVtbl
);