ntdll: Move the image address initialization to the Unix library.
[wine.git] / dlls / crypt32 / store.c
blob1c9ed910e403dcdd7eb30b4d06b31b1b38804cb9
1 /*
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
19 * FIXME:
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.
26 #include "config.h"
27 #include "wine/port.h"
29 #include <assert.h>
30 #include <stdarg.h>
31 #include "windef.h"
32 #include "winbase.h"
33 #include "winnls.h"
34 #include "winreg.h"
35 #include "winternl.h"
36 #include "winuser.h"
37 #include "wincrypt.h"
38 #include "wine/debug.h"
39 #include "wine/exception.h"
40 #include "crypt32_private.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(crypt);
44 static const WINE_CONTEXT_INTERFACE gCertInterface = {
45 (CreateContextFunc)CertCreateCertificateContext,
46 (AddContextToStoreFunc)CertAddCertificateContextToStore,
47 (AddEncodedContextToStoreFunc)CertAddEncodedCertificateToStore,
48 (EnumContextsInStoreFunc)CertEnumCertificatesInStore,
49 (EnumPropertiesFunc)CertEnumCertificateContextProperties,
50 (GetContextPropertyFunc)CertGetCertificateContextProperty,
51 (SetContextPropertyFunc)CertSetCertificateContextProperty,
52 (SerializeElementFunc)CertSerializeCertificateStoreElement,
53 (DeleteContextFunc)CertDeleteCertificateFromStore,
55 const WINE_CONTEXT_INTERFACE *pCertInterface = &gCertInterface;
57 static const WINE_CONTEXT_INTERFACE gCRLInterface = {
58 (CreateContextFunc)CertCreateCRLContext,
59 (AddContextToStoreFunc)CertAddCRLContextToStore,
60 (AddEncodedContextToStoreFunc)CertAddEncodedCRLToStore,
61 (EnumContextsInStoreFunc)CertEnumCRLsInStore,
62 (EnumPropertiesFunc)CertEnumCRLContextProperties,
63 (GetContextPropertyFunc)CertGetCRLContextProperty,
64 (SetContextPropertyFunc)CertSetCRLContextProperty,
65 (SerializeElementFunc)CertSerializeCRLStoreElement,
66 (DeleteContextFunc)CertDeleteCRLFromStore,
68 const WINE_CONTEXT_INTERFACE *pCRLInterface = &gCRLInterface;
70 static const WINE_CONTEXT_INTERFACE gCTLInterface = {
71 (CreateContextFunc)CertCreateCTLContext,
72 (AddContextToStoreFunc)CertAddCTLContextToStore,
73 (AddEncodedContextToStoreFunc)CertAddEncodedCTLToStore,
74 (EnumContextsInStoreFunc)CertEnumCTLsInStore,
75 (EnumPropertiesFunc)CertEnumCTLContextProperties,
76 (GetContextPropertyFunc)CertGetCTLContextProperty,
77 (SetContextPropertyFunc)CertSetCTLContextProperty,
78 (SerializeElementFunc)CertSerializeCTLStoreElement,
79 (DeleteContextFunc)CertDeleteCTLFromStore,
81 const WINE_CONTEXT_INTERFACE *pCTLInterface = &gCTLInterface;
83 typedef struct _WINE_MEMSTORE
85 WINECRYPT_CERTSTORE hdr;
86 CRITICAL_SECTION cs;
87 struct list certs;
88 struct list crls;
89 struct list ctls;
90 } WINE_MEMSTORE;
92 void CRYPT_InitStore(WINECRYPT_CERTSTORE *store, DWORD dwFlags, CertStoreType type, const store_vtbl_t *vtbl)
94 store->ref = 1;
95 store->dwMagic = WINE_CRYPTCERTSTORE_MAGIC;
96 store->type = type;
97 store->dwOpenFlags = dwFlags;
98 store->vtbl = vtbl;
99 store->properties = NULL;
102 void CRYPT_FreeStore(WINECRYPT_CERTSTORE *store)
104 if (store->properties)
105 ContextPropertyList_Free(store->properties);
106 store->dwMagic = 0;
107 CryptMemFree(store);
110 BOOL WINAPI I_CertUpdateStore(HCERTSTORE store1, HCERTSTORE store2, DWORD unk0,
111 DWORD unk1)
113 static BOOL warned = FALSE;
114 const WINE_CONTEXT_INTERFACE * const interfaces[] = { pCertInterface,
115 pCRLInterface, pCTLInterface };
116 DWORD i;
118 TRACE("(%p, %p, %08x, %08x)\n", store1, store2, unk0, unk1);
119 if (!warned)
121 FIXME("semi-stub\n");
122 warned = TRUE;
125 /* Poor-man's resync: empty first store, then add everything from second
126 * store to it.
128 for (i = 0; i < ARRAY_SIZE(interfaces); i++)
130 const void *context;
132 do {
133 context = interfaces[i]->enumContextsInStore(store1, NULL);
134 if (context)
135 interfaces[i]->deleteFromStore(context);
136 } while (context);
137 do {
138 context = interfaces[i]->enumContextsInStore(store2, context);
139 if (context)
140 interfaces[i]->addContextToStore(store1, context,
141 CERT_STORE_ADD_ALWAYS, NULL);
142 } while (context);
144 return TRUE;
147 static BOOL MemStore_addContext(WINE_MEMSTORE *store, struct list *list, context_t *orig_context,
148 context_t *existing, context_t **ret_context, BOOL use_link)
150 context_t *context;
152 context = orig_context->vtbl->clone(orig_context, &store->hdr, use_link);
153 if (!context)
154 return FALSE;
156 TRACE("adding %p\n", context);
157 EnterCriticalSection(&store->cs);
158 if (existing) {
159 context->u.entry.prev = existing->u.entry.prev;
160 context->u.entry.next = existing->u.entry.next;
161 context->u.entry.prev->next = &context->u.entry;
162 context->u.entry.next->prev = &context->u.entry;
163 list_init(&existing->u.entry);
164 if(!existing->ref)
165 Context_Release(existing);
166 }else {
167 list_add_head(list, &context->u.entry);
169 LeaveCriticalSection(&store->cs);
171 if(ret_context)
172 *ret_context = context;
173 else
174 Context_Release(context);
175 return TRUE;
178 static context_t *MemStore_enumContext(WINE_MEMSTORE *store, struct list *list, context_t *prev)
180 struct list *next;
181 context_t *ret;
183 EnterCriticalSection(&store->cs);
184 if (prev) {
185 next = list_next(list, &prev->u.entry);
186 Context_Release(prev);
187 }else {
188 next = list_next(list, list);
190 LeaveCriticalSection(&store->cs);
192 if (!next) {
193 SetLastError(CRYPT_E_NOT_FOUND);
194 return NULL;
197 ret = LIST_ENTRY(next, context_t, u.entry);
198 Context_AddRef(ret);
199 return ret;
202 static BOOL MemStore_deleteContext(WINE_MEMSTORE *store, context_t *context)
204 BOOL in_list = FALSE;
206 EnterCriticalSection(&store->cs);
207 if (!list_empty(&context->u.entry)) {
208 list_remove(&context->u.entry);
209 list_init(&context->u.entry);
210 in_list = TRUE;
212 LeaveCriticalSection(&store->cs);
214 if(in_list && !context->ref)
215 Context_Free(context);
216 return TRUE;
219 static void free_contexts(struct list *list)
221 context_t *context, *next;
223 LIST_FOR_EACH_ENTRY_SAFE(context, next, list, context_t, u.entry)
225 TRACE("freeing %p\n", context);
226 list_remove(&context->u.entry);
227 Context_Free(context);
231 static void MemStore_releaseContext(WINECRYPT_CERTSTORE *store, context_t *context)
233 /* Free the context only if it's not in a list. Otherwise it may be reused later. */
234 if(list_empty(&context->u.entry))
235 Context_Free(context);
238 static BOOL MemStore_addCert(WINECRYPT_CERTSTORE *store, context_t *cert,
239 context_t *toReplace, context_t **ppStoreContext, BOOL use_link)
241 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
243 TRACE("(%p, %p, %p, %p)\n", store, cert, toReplace, ppStoreContext);
244 return MemStore_addContext(ms, &ms->certs, cert, toReplace, ppStoreContext, use_link);
247 static context_t *MemStore_enumCert(WINECRYPT_CERTSTORE *store, context_t *prev)
249 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
251 TRACE("(%p, %p)\n", store, prev);
253 return MemStore_enumContext(ms, &ms->certs, prev);
256 static BOOL MemStore_deleteCert(WINECRYPT_CERTSTORE *store, context_t *context)
258 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
260 TRACE("(%p, %p)\n", store, context);
262 return MemStore_deleteContext(ms, context);
265 static BOOL MemStore_addCRL(WINECRYPT_CERTSTORE *store, context_t *crl,
266 context_t *toReplace, context_t **ppStoreContext, BOOL use_link)
268 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
270 TRACE("(%p, %p, %p, %p)\n", store, crl, toReplace, ppStoreContext);
272 return MemStore_addContext(ms, &ms->crls, crl, toReplace, ppStoreContext, use_link);
275 static context_t *MemStore_enumCRL(WINECRYPT_CERTSTORE *store, context_t *prev)
277 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
279 TRACE("(%p, %p)\n", store, prev);
281 return MemStore_enumContext(ms, &ms->crls, prev);
284 static BOOL MemStore_deleteCRL(WINECRYPT_CERTSTORE *store, context_t *context)
286 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
288 TRACE("(%p, %p)\n", store, context);
290 return MemStore_deleteContext(ms, context);
293 static BOOL MemStore_addCTL(WINECRYPT_CERTSTORE *store, context_t *ctl,
294 context_t *toReplace, context_t **ppStoreContext, BOOL use_link)
296 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
298 TRACE("(%p, %p, %p, %p)\n", store, ctl, toReplace, ppStoreContext);
300 return MemStore_addContext(ms, &ms->ctls, ctl, toReplace, ppStoreContext, use_link);
303 static context_t *MemStore_enumCTL(WINECRYPT_CERTSTORE *store, context_t *prev)
305 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
307 TRACE("(%p, %p)\n", store, prev);
309 return MemStore_enumContext(ms, &ms->ctls, prev);
312 static BOOL MemStore_deleteCTL(WINECRYPT_CERTSTORE *store, context_t *context)
314 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
316 TRACE("(%p, %p)\n", store, context);
318 return MemStore_deleteContext(ms, context);
321 static void MemStore_addref(WINECRYPT_CERTSTORE *store)
323 LONG ref = InterlockedIncrement(&store->ref);
324 TRACE("ref = %d\n", ref);
327 static DWORD MemStore_release(WINECRYPT_CERTSTORE *cert_store, DWORD flags)
329 WINE_MEMSTORE *store = (WINE_MEMSTORE*)cert_store;
330 LONG ref;
332 if(flags & ~CERT_CLOSE_STORE_CHECK_FLAG)
333 FIXME("Unimplemented flags %x\n", flags);
335 ref = InterlockedDecrement(&store->hdr.ref);
336 TRACE("(%p) ref=%d\n", store, ref);
337 if(ref)
338 return (flags & CERT_CLOSE_STORE_CHECK_FLAG) ? CRYPT_E_PENDING_CLOSE : ERROR_SUCCESS;
340 free_contexts(&store->certs);
341 free_contexts(&store->crls);
342 free_contexts(&store->ctls);
343 store->cs.DebugInfo->Spare[0] = 0;
344 DeleteCriticalSection(&store->cs);
345 CRYPT_FreeStore(&store->hdr);
346 return ERROR_SUCCESS;
349 static BOOL MemStore_control(WINECRYPT_CERTSTORE *store, DWORD dwFlags,
350 DWORD dwCtrlType, void const *pvCtrlPara)
352 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
353 return FALSE;
356 static const store_vtbl_t MemStoreVtbl = {
357 MemStore_addref,
358 MemStore_release,
359 MemStore_releaseContext,
360 MemStore_control,
362 MemStore_addCert,
363 MemStore_enumCert,
364 MemStore_deleteCert
365 }, {
366 MemStore_addCRL,
367 MemStore_enumCRL,
368 MemStore_deleteCRL
369 }, {
370 MemStore_addCTL,
371 MemStore_enumCTL,
372 MemStore_deleteCTL
376 static WINECRYPT_CERTSTORE *CRYPT_MemOpenStore(HCRYPTPROV hCryptProv,
377 DWORD dwFlags, const void *pvPara)
379 WINE_MEMSTORE *store;
381 TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
383 if (dwFlags & CERT_STORE_DELETE_FLAG)
385 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
386 store = NULL;
388 else
390 store = CryptMemAlloc(sizeof(WINE_MEMSTORE));
391 if (store)
393 memset(store, 0, sizeof(WINE_MEMSTORE));
394 CRYPT_InitStore(&store->hdr, dwFlags, StoreTypeMem, &MemStoreVtbl);
395 InitializeCriticalSection(&store->cs);
396 store->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ContextList.cs");
397 list_init(&store->certs);
398 list_init(&store->crls);
399 list_init(&store->ctls);
400 /* Mem store doesn't need crypto provider, so close it */
401 if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
402 CryptReleaseContext(hCryptProv, 0);
405 return (WINECRYPT_CERTSTORE*)store;
408 static const WCHAR rootW[] = { 'R','o','o','t',0 };
410 static WINECRYPT_CERTSTORE *CRYPT_SysRegOpenStoreW(HCRYPTPROV hCryptProv,
411 DWORD dwFlags, const void *pvPara)
413 static const WCHAR fmt[] = { '%','s','\\','%','s',0 };
414 LPCWSTR storeName = pvPara;
415 LPWSTR storePath;
416 WINECRYPT_CERTSTORE *store = NULL;
417 HKEY root;
418 LPCWSTR base;
420 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
421 debugstr_w(pvPara));
423 if (!pvPara)
425 SetLastError(E_INVALIDARG);
426 return NULL;
429 switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
431 case CERT_SYSTEM_STORE_LOCAL_MACHINE:
432 root = HKEY_LOCAL_MACHINE;
433 base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
434 /* If the HKLM\Root certs are requested, expressing system certs into the registry */
435 if (!lstrcmpiW(storeName, rootW))
436 CRYPT_ImportSystemRootCertsToReg();
437 break;
438 case CERT_SYSTEM_STORE_CURRENT_USER:
439 root = HKEY_CURRENT_USER;
440 base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
441 break;
442 case CERT_SYSTEM_STORE_CURRENT_SERVICE:
443 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
444 * SystemCertificates
446 FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE, %s: stub\n",
447 debugstr_w(storeName));
448 return NULL;
449 case CERT_SYSTEM_STORE_SERVICES:
450 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
451 * SystemCertificates
453 FIXME("CERT_SYSTEM_STORE_SERVICES, %s: stub\n",
454 debugstr_w(storeName));
455 return NULL;
456 case CERT_SYSTEM_STORE_USERS:
457 /* hku\user sid\Software\Microsoft\SystemCertificates */
458 FIXME("CERT_SYSTEM_STORE_USERS, %s: stub\n",
459 debugstr_w(storeName));
460 return NULL;
461 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY:
462 root = HKEY_CURRENT_USER;
463 base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
464 break;
465 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY:
466 root = HKEY_LOCAL_MACHINE;
467 base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
468 break;
469 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE:
470 /* hklm\Software\Microsoft\EnterpriseCertificates */
471 FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, %s: stub\n",
472 debugstr_w(storeName));
473 return NULL;
474 default:
475 SetLastError(E_INVALIDARG);
476 return NULL;
479 storePath = CryptMemAlloc((lstrlenW(base) + lstrlenW(storeName) + 2) *
480 sizeof(WCHAR));
481 if (storePath)
483 LONG rc;
484 HKEY key;
485 REGSAM sam = dwFlags & CERT_STORE_READONLY_FLAG ? KEY_READ :
486 KEY_ALL_ACCESS;
488 wsprintfW(storePath, fmt, base, storeName);
489 if (dwFlags & CERT_STORE_OPEN_EXISTING_FLAG)
490 rc = RegOpenKeyExW(root, storePath, 0, sam, &key);
491 else
493 DWORD disp;
495 rc = RegCreateKeyExW(root, storePath, 0, NULL, 0, sam, NULL,
496 &key, &disp);
497 if (!rc && dwFlags & CERT_STORE_CREATE_NEW_FLAG &&
498 disp == REG_OPENED_EXISTING_KEY)
500 RegCloseKey(key);
501 rc = ERROR_FILE_EXISTS;
504 if (!rc)
506 store = CRYPT_RegOpenStore(hCryptProv, dwFlags, key);
507 RegCloseKey(key);
509 else
510 SetLastError(rc);
511 CryptMemFree(storePath);
513 return store;
516 static WINECRYPT_CERTSTORE *CRYPT_SysRegOpenStoreA(HCRYPTPROV hCryptProv,
517 DWORD dwFlags, const void *pvPara)
519 int len;
520 WINECRYPT_CERTSTORE *ret = NULL;
522 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
523 debugstr_a(pvPara));
525 if (!pvPara)
527 SetLastError(ERROR_FILE_NOT_FOUND);
528 return NULL;
530 len = MultiByteToWideChar(CP_ACP, 0, pvPara, -1, NULL, 0);
531 if (len)
533 LPWSTR storeName = CryptMemAlloc(len * sizeof(WCHAR));
535 if (storeName)
537 MultiByteToWideChar(CP_ACP, 0, pvPara, -1, storeName, len);
538 ret = CRYPT_SysRegOpenStoreW(hCryptProv, dwFlags, storeName);
539 CryptMemFree(storeName);
542 return ret;
545 static WINECRYPT_CERTSTORE *CRYPT_SysOpenStoreW(HCRYPTPROV hCryptProv,
546 DWORD dwFlags, const void *pvPara)
548 HCERTSTORE store = 0;
549 BOOL ret;
551 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
552 debugstr_w(pvPara));
554 if (!pvPara)
556 SetLastError(ERROR_FILE_NOT_FOUND);
557 return NULL;
559 /* This returns a different error than system registry stores if the
560 * location is invalid.
562 switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
564 case CERT_SYSTEM_STORE_LOCAL_MACHINE:
565 case CERT_SYSTEM_STORE_CURRENT_USER:
566 case CERT_SYSTEM_STORE_CURRENT_SERVICE:
567 case CERT_SYSTEM_STORE_SERVICES:
568 case CERT_SYSTEM_STORE_USERS:
569 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY:
570 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY:
571 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE:
572 ret = TRUE;
573 break;
574 default:
575 SetLastError(ERROR_FILE_NOT_FOUND);
576 ret = FALSE;
578 if (ret)
580 HCERTSTORE regStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,
581 0, 0, dwFlags, pvPara);
583 if (regStore)
585 store = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
586 CERT_STORE_CREATE_NEW_FLAG, NULL);
587 CertAddStoreToCollection(store, regStore,
588 dwFlags & CERT_STORE_READONLY_FLAG ? 0 :
589 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
590 CertCloseStore(regStore, 0);
591 /* CERT_SYSTEM_STORE_CURRENT_USER returns both the HKCU and HKLM
592 * stores.
594 if ((dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) ==
595 CERT_SYSTEM_STORE_CURRENT_USER)
597 dwFlags &= ~CERT_SYSTEM_STORE_CURRENT_USER;
598 dwFlags |= CERT_SYSTEM_STORE_LOCAL_MACHINE;
599 regStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0,
600 0, dwFlags, pvPara);
601 if (regStore)
603 CertAddStoreToCollection(store, regStore,
604 dwFlags & CERT_STORE_READONLY_FLAG ? 0 :
605 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
606 CertCloseStore(regStore, 0);
609 /* System store doesn't need crypto provider, so close it */
610 if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
611 CryptReleaseContext(hCryptProv, 0);
614 return store;
617 static WINECRYPT_CERTSTORE *CRYPT_SysOpenStoreA(HCRYPTPROV hCryptProv,
618 DWORD dwFlags, const void *pvPara)
620 int len;
621 WINECRYPT_CERTSTORE *ret = NULL;
623 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
624 debugstr_a(pvPara));
626 if (!pvPara)
628 SetLastError(ERROR_FILE_NOT_FOUND);
629 return NULL;
631 len = MultiByteToWideChar(CP_ACP, 0, pvPara, -1, NULL, 0);
632 if (len)
634 LPWSTR storeName = CryptMemAlloc(len * sizeof(WCHAR));
636 if (storeName)
638 MultiByteToWideChar(CP_ACP, 0, pvPara, -1, storeName, len);
639 ret = CRYPT_SysOpenStoreW(hCryptProv, dwFlags, storeName);
640 CryptMemFree(storeName);
643 return ret;
646 static void WINAPI CRYPT_MsgCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
648 HCRYPTMSG msg = hCertStore;
650 TRACE("(%p, %08x)\n", msg, dwFlags);
651 CryptMsgClose(msg);
654 static void *msgProvFuncs[] = {
655 CRYPT_MsgCloseStore,
658 static WINECRYPT_CERTSTORE *CRYPT_MsgOpenStore(HCRYPTPROV hCryptProv,
659 DWORD dwFlags, const void *pvPara)
661 WINECRYPT_CERTSTORE *store = NULL;
662 HCRYPTMSG msg = (HCRYPTMSG)pvPara;
663 WINECRYPT_CERTSTORE *memStore;
665 TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
667 memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
668 CERT_STORE_CREATE_NEW_FLAG, NULL);
669 if (memStore)
671 BOOL ret;
672 DWORD size, count, i;
674 size = sizeof(count);
675 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &count, &size);
676 for (i = 0; ret && i < count; i++)
678 size = 0;
679 ret = CryptMsgGetParam(msg, CMSG_CERT_PARAM, i, NULL, &size);
680 if (ret)
682 LPBYTE buf = CryptMemAlloc(size);
684 if (buf)
686 ret = CryptMsgGetParam(msg, CMSG_CERT_PARAM, i, buf, &size);
687 if (ret)
688 ret = CertAddEncodedCertificateToStore(memStore,
689 X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_ALWAYS,
690 NULL);
691 CryptMemFree(buf);
695 size = sizeof(count);
696 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &count, &size);
697 for (i = 0; ret && i < count; i++)
699 size = 0;
700 ret = CryptMsgGetParam(msg, CMSG_CRL_PARAM, i, NULL, &size);
701 if (ret)
703 LPBYTE buf = CryptMemAlloc(size);
705 if (buf)
707 ret = CryptMsgGetParam(msg, CMSG_CRL_PARAM, i, buf, &size);
708 if (ret)
709 ret = CertAddEncodedCRLToStore(memStore,
710 X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_ALWAYS,
711 NULL);
712 CryptMemFree(buf);
716 if (ret)
718 CERT_STORE_PROV_INFO provInfo = { 0 };
720 provInfo.cbSize = sizeof(provInfo);
721 provInfo.cStoreProvFunc = ARRAY_SIZE(msgProvFuncs);
722 provInfo.rgpvStoreProvFunc = msgProvFuncs;
723 provInfo.hStoreProv = CryptMsgDuplicate(msg);
724 store = CRYPT_ProvCreateStore(dwFlags, memStore, &provInfo);
725 /* Msg store doesn't need crypto provider, so close it */
726 if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
727 CryptReleaseContext(hCryptProv, 0);
729 else
730 CertCloseStore(memStore, 0);
732 TRACE("returning %p\n", store);
733 return store;
736 static WINECRYPT_CERTSTORE *CRYPT_PKCSOpenStore(HCRYPTPROV hCryptProv,
737 DWORD dwFlags, const void *pvPara)
739 HCRYPTMSG msg;
740 WINECRYPT_CERTSTORE *store = NULL;
741 const CRYPT_DATA_BLOB *data = pvPara;
742 BOOL ret;
743 DWORD msgOpenFlags = dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG ? 0 :
744 CMSG_CRYPT_RELEASE_CONTEXT_FLAG;
746 TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
748 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, msgOpenFlags, CMSG_SIGNED,
749 hCryptProv, NULL, NULL);
750 ret = CryptMsgUpdate(msg, data->pbData, data->cbData, TRUE);
751 if (!ret)
753 CryptMsgClose(msg);
754 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, msgOpenFlags, 0,
755 hCryptProv, NULL, NULL);
756 ret = CryptMsgUpdate(msg, data->pbData, data->cbData, TRUE);
757 if (ret)
759 DWORD type, size = sizeof(type);
761 /* Only signed messages are allowed, check type */
762 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &type, &size);
763 if (ret && type != CMSG_SIGNED)
765 SetLastError(CRYPT_E_INVALID_MSG_TYPE);
766 ret = FALSE;
770 if (ret)
771 store = CRYPT_MsgOpenStore(0, dwFlags, msg);
772 CryptMsgClose(msg);
773 TRACE("returning %p\n", store);
774 return store;
777 static WINECRYPT_CERTSTORE *CRYPT_SerializedOpenStore(HCRYPTPROV hCryptProv,
778 DWORD dwFlags, const void *pvPara)
780 HCERTSTORE store;
781 const CRYPT_DATA_BLOB *data = pvPara;
783 TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
785 if (dwFlags & CERT_STORE_DELETE_FLAG)
787 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
788 return NULL;
791 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
792 CERT_STORE_CREATE_NEW_FLAG, NULL);
793 if (store)
795 if (!CRYPT_ReadSerializedStoreFromBlob(data, store))
797 CertCloseStore(store, 0);
798 store = NULL;
801 TRACE("returning %p\n", store);
802 return (WINECRYPT_CERTSTORE*)store;
805 static WINECRYPT_CERTSTORE *CRYPT_PhysOpenStoreW(HCRYPTPROV hCryptProv,
806 DWORD dwFlags, const void *pvPara)
808 if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG)
809 FIXME("(%ld, %08x, %p): stub\n", hCryptProv, dwFlags, pvPara);
810 else
811 FIXME("(%ld, %08x, %s): stub\n", hCryptProv, dwFlags,
812 debugstr_w(pvPara));
813 return NULL;
816 HCERTSTORE WINAPI CertOpenStore(LPCSTR lpszStoreProvider,
817 DWORD dwMsgAndCertEncodingType, HCRYPTPROV_LEGACY hCryptProv, DWORD dwFlags,
818 const void* pvPara)
820 WINECRYPT_CERTSTORE *hcs;
821 StoreOpenFunc openFunc = NULL;
823 TRACE("(%s, %08x, %08lx, %08x, %p)\n", debugstr_a(lpszStoreProvider),
824 dwMsgAndCertEncodingType, hCryptProv, dwFlags, pvPara);
826 if (IS_INTOID(lpszStoreProvider))
828 switch (LOWORD(lpszStoreProvider))
830 case LOWORD(CERT_STORE_PROV_MSG):
831 openFunc = CRYPT_MsgOpenStore;
832 break;
833 case LOWORD(CERT_STORE_PROV_MEMORY):
834 openFunc = CRYPT_MemOpenStore;
835 break;
836 case LOWORD(CERT_STORE_PROV_FILE):
837 openFunc = CRYPT_FileOpenStore;
838 break;
839 case LOWORD(CERT_STORE_PROV_PKCS7):
840 openFunc = CRYPT_PKCSOpenStore;
841 break;
842 case LOWORD(CERT_STORE_PROV_SERIALIZED):
843 openFunc = CRYPT_SerializedOpenStore;
844 break;
845 case LOWORD(CERT_STORE_PROV_REG):
846 openFunc = CRYPT_RegOpenStore;
847 break;
848 case LOWORD(CERT_STORE_PROV_FILENAME_A):
849 openFunc = CRYPT_FileNameOpenStoreA;
850 break;
851 case LOWORD(CERT_STORE_PROV_FILENAME_W):
852 openFunc = CRYPT_FileNameOpenStoreW;
853 break;
854 case LOWORD(CERT_STORE_PROV_COLLECTION):
855 openFunc = CRYPT_CollectionOpenStore;
856 break;
857 case LOWORD(CERT_STORE_PROV_SYSTEM_A):
858 openFunc = CRYPT_SysOpenStoreA;
859 break;
860 case LOWORD(CERT_STORE_PROV_SYSTEM_W):
861 openFunc = CRYPT_SysOpenStoreW;
862 break;
863 case LOWORD(CERT_STORE_PROV_SYSTEM_REGISTRY_A):
864 openFunc = CRYPT_SysRegOpenStoreA;
865 break;
866 case LOWORD(CERT_STORE_PROV_SYSTEM_REGISTRY_W):
867 openFunc = CRYPT_SysRegOpenStoreW;
868 break;
869 case LOWORD(CERT_STORE_PROV_PHYSICAL_W):
870 openFunc = CRYPT_PhysOpenStoreW;
871 break;
872 default:
873 if (LOWORD(lpszStoreProvider))
874 FIXME("unimplemented type %d\n", LOWORD(lpszStoreProvider));
877 else if (!_strnicmp(lpszStoreProvider, sz_CERT_STORE_PROV_MEMORY, -1))
878 openFunc = CRYPT_MemOpenStore;
879 else if (!_strnicmp(lpszStoreProvider, sz_CERT_STORE_PROV_FILENAME_W, -1))
880 openFunc = CRYPT_FileOpenStore;
881 else if (!_strnicmp(lpszStoreProvider, sz_CERT_STORE_PROV_SYSTEM, -1))
882 openFunc = CRYPT_SysOpenStoreW;
883 else if (!_strnicmp(lpszStoreProvider, sz_CERT_STORE_PROV_PKCS7, -1))
884 openFunc = CRYPT_PKCSOpenStore;
885 else if (!_strnicmp(lpszStoreProvider, sz_CERT_STORE_PROV_SERIALIZED, -1))
886 openFunc = CRYPT_SerializedOpenStore;
887 else if (!_strnicmp(lpszStoreProvider, sz_CERT_STORE_PROV_COLLECTION, -1))
888 openFunc = CRYPT_CollectionOpenStore;
889 else if (!_strnicmp(lpszStoreProvider, sz_CERT_STORE_PROV_SYSTEM_REGISTRY, -1))
890 openFunc = CRYPT_SysRegOpenStoreW;
891 else
893 FIXME("unimplemented type %s\n", lpszStoreProvider);
894 openFunc = NULL;
897 if (!openFunc)
898 hcs = CRYPT_ProvOpenStore(lpszStoreProvider, dwMsgAndCertEncodingType,
899 hCryptProv, dwFlags, pvPara);
900 else
901 hcs = openFunc(hCryptProv, dwFlags, pvPara);
902 return hcs;
905 HCERTSTORE WINAPI CertOpenSystemStoreA(HCRYPTPROV_LEGACY hProv,
906 LPCSTR szSubSystemProtocol)
908 if (!szSubSystemProtocol)
910 SetLastError(E_INVALIDARG);
911 return 0;
913 return CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, hProv,
914 CERT_SYSTEM_STORE_CURRENT_USER, szSubSystemProtocol);
917 HCERTSTORE WINAPI CertOpenSystemStoreW(HCRYPTPROV_LEGACY hProv,
918 LPCWSTR szSubSystemProtocol)
920 if (!szSubSystemProtocol)
922 SetLastError(E_INVALIDARG);
923 return 0;
925 return CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, hProv,
926 CERT_SYSTEM_STORE_CURRENT_USER, szSubSystemProtocol);
929 PCCERT_CONTEXT WINAPI CertEnumCertificatesInStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pPrev)
931 cert_t *prev = pPrev ? cert_from_ptr(pPrev) : NULL, *ret;
932 WINECRYPT_CERTSTORE *hcs = hCertStore;
934 TRACE("(%p, %p)\n", hCertStore, pPrev);
935 if (!hCertStore)
936 ret = NULL;
937 else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
938 ret = NULL;
939 else
940 ret = (cert_t*)hcs->vtbl->certs.enumContext(hcs, prev ? &prev->base : NULL);
941 return ret ? &ret->ctx : NULL;
944 BOOL WINAPI CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext)
946 WINECRYPT_CERTSTORE *hcs;
948 TRACE("(%p)\n", pCertContext);
950 if (!pCertContext)
951 return TRUE;
953 hcs = pCertContext->hCertStore;
955 if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
956 return FALSE;
958 return hcs->vtbl->certs.delete(hcs, &cert_from_ptr(pCertContext)->base);
961 BOOL WINAPI CertAddCRLContextToStore(HCERTSTORE hCertStore,
962 PCCRL_CONTEXT pCrlContext, DWORD dwAddDisposition,
963 PCCRL_CONTEXT* ppStoreContext)
965 WINECRYPT_CERTSTORE *store = hCertStore;
966 BOOL ret = TRUE;
967 PCCRL_CONTEXT toAdd = NULL, existing = NULL;
969 TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCrlContext,
970 dwAddDisposition, ppStoreContext);
972 /* Weird case to pass a test */
973 if (dwAddDisposition == 0)
975 SetLastError(STATUS_ACCESS_VIOLATION);
976 return FALSE;
978 if (dwAddDisposition != CERT_STORE_ADD_ALWAYS)
980 existing = CertFindCRLInStore(hCertStore, 0, 0, CRL_FIND_EXISTING,
981 pCrlContext, NULL);
984 switch (dwAddDisposition)
986 case CERT_STORE_ADD_ALWAYS:
987 toAdd = CertDuplicateCRLContext(pCrlContext);
988 break;
989 case CERT_STORE_ADD_NEW:
990 if (existing)
992 TRACE("found matching CRL, not adding\n");
993 SetLastError(CRYPT_E_EXISTS);
994 ret = FALSE;
996 else
997 toAdd = CertDuplicateCRLContext(pCrlContext);
998 break;
999 case CERT_STORE_ADD_NEWER:
1000 if (existing)
1002 LONG newer = CompareFileTime(&existing->pCrlInfo->ThisUpdate,
1003 &pCrlContext->pCrlInfo->ThisUpdate);
1005 if (newer < 0)
1006 toAdd = CertDuplicateCRLContext(pCrlContext);
1007 else
1009 TRACE("existing CRL is newer, not adding\n");
1010 SetLastError(CRYPT_E_EXISTS);
1011 ret = FALSE;
1014 else
1015 toAdd = CertDuplicateCRLContext(pCrlContext);
1016 break;
1017 case CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES:
1018 if (existing)
1020 LONG newer = CompareFileTime(&existing->pCrlInfo->ThisUpdate,
1021 &pCrlContext->pCrlInfo->ThisUpdate);
1023 if (newer < 0)
1025 toAdd = CertDuplicateCRLContext(pCrlContext);
1026 Context_CopyProperties(toAdd, existing);
1028 else
1030 TRACE("existing CRL is newer, not adding\n");
1031 SetLastError(CRYPT_E_EXISTS);
1032 ret = FALSE;
1035 else
1036 toAdd = CertDuplicateCRLContext(pCrlContext);
1037 break;
1038 case CERT_STORE_ADD_REPLACE_EXISTING:
1039 toAdd = CertDuplicateCRLContext(pCrlContext);
1040 break;
1041 case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES:
1042 toAdd = CertDuplicateCRLContext(pCrlContext);
1043 if (existing)
1044 Context_CopyProperties(toAdd, existing);
1045 break;
1046 case CERT_STORE_ADD_USE_EXISTING:
1047 if (existing)
1049 Context_CopyProperties(existing, pCrlContext);
1050 if (ppStoreContext)
1051 *ppStoreContext = CertDuplicateCRLContext(existing);
1053 else
1054 toAdd = CertDuplicateCRLContext(pCrlContext);
1055 break;
1056 default:
1057 FIXME("Unimplemented add disposition %d\n", dwAddDisposition);
1058 ret = FALSE;
1061 if (toAdd)
1063 if (store) {
1064 context_t *ret_context;
1065 ret = store->vtbl->crls.addContext(store, context_from_ptr(toAdd),
1066 existing ? context_from_ptr(existing) : NULL, ppStoreContext ? &ret_context : NULL, FALSE);
1067 if (ret && ppStoreContext)
1068 *ppStoreContext = context_ptr(ret_context);
1069 }else if (ppStoreContext) {
1070 *ppStoreContext = CertDuplicateCRLContext(toAdd);
1072 CertFreeCRLContext(toAdd);
1074 if (existing)
1075 CertFreeCRLContext(existing);
1077 TRACE("returning %d\n", ret);
1078 return ret;
1081 BOOL WINAPI CertDeleteCRLFromStore(PCCRL_CONTEXT pCrlContext)
1083 WINECRYPT_CERTSTORE *hcs;
1084 BOOL ret;
1086 TRACE("(%p)\n", pCrlContext);
1088 if (!pCrlContext)
1089 return TRUE;
1091 hcs = pCrlContext->hCertStore;
1093 if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
1094 return FALSE;
1096 ret = hcs->vtbl->crls.delete(hcs, &crl_from_ptr(pCrlContext)->base);
1097 if (ret)
1098 ret = CertFreeCRLContext(pCrlContext);
1099 return ret;
1102 PCCRL_CONTEXT WINAPI CertEnumCRLsInStore(HCERTSTORE hCertStore, PCCRL_CONTEXT pPrev)
1104 crl_t *ret, *prev = pPrev ? crl_from_ptr(pPrev) : NULL;
1105 WINECRYPT_CERTSTORE *hcs = hCertStore;
1107 TRACE("(%p, %p)\n", hCertStore, pPrev);
1108 if (!hCertStore)
1109 ret = NULL;
1110 else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
1111 ret = NULL;
1112 else
1113 ret = (crl_t*)hcs->vtbl->crls.enumContext(hcs, prev ? &prev->base : NULL);
1114 return ret ? &ret->ctx : NULL;
1117 HCERTSTORE WINAPI CertDuplicateStore(HCERTSTORE hCertStore)
1119 WINECRYPT_CERTSTORE *hcs = hCertStore;
1121 TRACE("(%p)\n", hCertStore);
1123 if (hcs && hcs->dwMagic == WINE_CRYPTCERTSTORE_MAGIC)
1124 hcs->vtbl->addref(hcs);
1125 return hCertStore;
1128 BOOL WINAPI CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
1130 WINECRYPT_CERTSTORE *hcs = hCertStore;
1131 DWORD res;
1133 TRACE("(%p, %08x)\n", hCertStore, dwFlags);
1135 if( ! hCertStore )
1136 return TRUE;
1138 if ( hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC )
1139 return FALSE;
1141 res = hcs->vtbl->release(hcs, dwFlags);
1142 if (res != ERROR_SUCCESS) {
1143 SetLastError(res);
1144 return FALSE;
1147 return TRUE;
1150 BOOL WINAPI CertControlStore(HCERTSTORE hCertStore, DWORD dwFlags,
1151 DWORD dwCtrlType, void const *pvCtrlPara)
1153 WINECRYPT_CERTSTORE *hcs = hCertStore;
1154 BOOL ret;
1156 TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType,
1157 pvCtrlPara);
1159 if (!hcs)
1160 ret = FALSE;
1161 else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
1162 ret = FALSE;
1163 else
1165 if (hcs->vtbl->control)
1166 ret = hcs->vtbl->control(hcs, dwFlags, dwCtrlType, pvCtrlPara);
1167 else
1168 ret = TRUE;
1170 return ret;
1173 BOOL WINAPI CertGetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId,
1174 void *pvData, DWORD *pcbData)
1176 WINECRYPT_CERTSTORE *store = hCertStore;
1177 BOOL ret = FALSE;
1179 TRACE("(%p, %d, %p, %p)\n", hCertStore, dwPropId, pvData, pcbData);
1181 switch (dwPropId)
1183 case CERT_ACCESS_STATE_PROP_ID:
1184 if (!pvData)
1186 *pcbData = sizeof(DWORD);
1187 ret = TRUE;
1189 else if (*pcbData < sizeof(DWORD))
1191 SetLastError(ERROR_MORE_DATA);
1192 *pcbData = sizeof(DWORD);
1194 else
1196 DWORD state = 0;
1198 if (store->type != StoreTypeMem &&
1199 !(store->dwOpenFlags & CERT_STORE_READONLY_FLAG))
1200 state |= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG;
1201 *(DWORD *)pvData = state;
1202 ret = TRUE;
1204 break;
1205 default:
1206 if (store->properties)
1208 CRYPT_DATA_BLOB blob;
1210 ret = ContextPropertyList_FindProperty(store->properties, dwPropId,
1211 &blob);
1212 if (ret)
1214 if (!pvData)
1215 *pcbData = blob.cbData;
1216 else if (*pcbData < blob.cbData)
1218 SetLastError(ERROR_MORE_DATA);
1219 *pcbData = blob.cbData;
1220 ret = FALSE;
1222 else
1224 memcpy(pvData, blob.pbData, blob.cbData);
1225 *pcbData = blob.cbData;
1228 else
1229 SetLastError(CRYPT_E_NOT_FOUND);
1231 else
1232 SetLastError(CRYPT_E_NOT_FOUND);
1234 return ret;
1237 BOOL WINAPI CertSetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId,
1238 DWORD dwFlags, const void *pvData)
1240 WINECRYPT_CERTSTORE *store = hCertStore;
1241 BOOL ret = FALSE;
1243 TRACE("(%p, %d, %08x, %p)\n", hCertStore, dwPropId, dwFlags, pvData);
1245 if (!store->properties)
1246 store->properties = ContextPropertyList_Create();
1247 switch (dwPropId)
1249 case CERT_ACCESS_STATE_PROP_ID:
1250 SetLastError(E_INVALIDARG);
1251 break;
1252 default:
1253 if (pvData)
1255 const CRYPT_DATA_BLOB *blob = pvData;
1257 ret = ContextPropertyList_SetProperty(store->properties, dwPropId,
1258 blob->pbData, blob->cbData);
1260 else
1262 ContextPropertyList_RemoveProperty(store->properties, dwPropId);
1263 ret = TRUE;
1266 return ret;
1269 static LONG CRYPT_OpenParentStore(DWORD dwFlags,
1270 void *pvSystemStoreLocationPara, HKEY *key)
1272 HKEY root;
1273 LPCWSTR base;
1275 TRACE("(%08x, %p)\n", dwFlags, pvSystemStoreLocationPara);
1277 switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
1279 case CERT_SYSTEM_STORE_LOCAL_MACHINE:
1280 root = HKEY_LOCAL_MACHINE;
1281 base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
1282 break;
1283 case CERT_SYSTEM_STORE_CURRENT_USER:
1284 root = HKEY_CURRENT_USER;
1285 base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
1286 break;
1287 case CERT_SYSTEM_STORE_CURRENT_SERVICE:
1288 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
1289 * SystemCertificates
1291 FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE\n");
1292 return ERROR_FILE_NOT_FOUND;
1293 case CERT_SYSTEM_STORE_SERVICES:
1294 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
1295 * SystemCertificates
1297 FIXME("CERT_SYSTEM_STORE_SERVICES\n");
1298 return ERROR_FILE_NOT_FOUND;
1299 case CERT_SYSTEM_STORE_USERS:
1300 /* hku\user sid\Software\Microsoft\SystemCertificates */
1301 FIXME("CERT_SYSTEM_STORE_USERS\n");
1302 return ERROR_FILE_NOT_FOUND;
1303 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY:
1304 root = HKEY_CURRENT_USER;
1305 base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
1306 break;
1307 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY:
1308 root = HKEY_LOCAL_MACHINE;
1309 base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
1310 break;
1311 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE:
1312 /* hklm\Software\Microsoft\EnterpriseCertificates */
1313 FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE\n");
1314 return ERROR_FILE_NOT_FOUND;
1315 default:
1316 return ERROR_FILE_NOT_FOUND;
1319 return RegOpenKeyExW(root, base, 0, KEY_READ, key);
1322 BOOL WINAPI CertEnumSystemStore(DWORD dwFlags, void *pvSystemStoreLocationPara,
1323 void *pvArg, PFN_CERT_ENUM_SYSTEM_STORE pfnEnum)
1325 BOOL ret = FALSE;
1326 LONG rc;
1327 HKEY key;
1328 CERT_SYSTEM_STORE_INFO info = { sizeof(info) };
1330 TRACE("(%08x, %p, %p, %p)\n", dwFlags, pvSystemStoreLocationPara, pvArg,
1331 pfnEnum);
1333 rc = CRYPT_OpenParentStore(dwFlags, pvArg, &key);
1334 if (!rc)
1336 DWORD index = 0;
1338 ret = TRUE;
1339 do {
1340 WCHAR name[MAX_PATH];
1341 DWORD size = ARRAY_SIZE(name);
1343 rc = RegEnumKeyExW(key, index++, name, &size, NULL, NULL, NULL,
1344 NULL);
1345 if (!rc)
1346 ret = pfnEnum(name, dwFlags, &info, NULL, pvArg);
1347 } while (ret && !rc);
1348 if (ret && rc != ERROR_NO_MORE_ITEMS)
1349 SetLastError(rc);
1351 else
1352 SetLastError(rc);
1353 /* Include root store for the local machine location (it isn't in the
1354 * registry)
1356 if (ret && (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) ==
1357 CERT_SYSTEM_STORE_LOCAL_MACHINE)
1358 ret = pfnEnum(rootW, dwFlags, &info, NULL, pvArg);
1359 return ret;
1362 BOOL WINAPI CertEnumPhysicalStore(const void *pvSystemStore, DWORD dwFlags,
1363 void *pvArg, PFN_CERT_ENUM_PHYSICAL_STORE pfnEnum)
1365 if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG)
1366 FIXME("(%p, %08x, %p, %p): stub\n", pvSystemStore, dwFlags, pvArg,
1367 pfnEnum);
1368 else
1369 FIXME("(%s, %08x, %p, %p): stub\n", debugstr_w(pvSystemStore),
1370 dwFlags, pvArg,
1371 pfnEnum);
1372 return FALSE;
1375 BOOL WINAPI CertRegisterPhysicalStore(const void *pvSystemStore, DWORD dwFlags,
1376 LPCWSTR pwszStoreName, PCERT_PHYSICAL_STORE_INFO pStoreInfo, void *pvReserved)
1378 if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG)
1379 FIXME("(%p, %08x, %s, %p, %p): stub\n", pvSystemStore, dwFlags,
1380 debugstr_w(pwszStoreName), pStoreInfo, pvReserved);
1381 else
1382 FIXME("(%s, %08x, %s, %p, %p): stub\n", debugstr_w(pvSystemStore),
1383 dwFlags, debugstr_w(pwszStoreName), pStoreInfo, pvReserved);
1384 return FALSE;
1387 BOOL WINAPI CertUnregisterPhysicalStore(const void *pvSystemStore, DWORD dwFlags,
1388 LPCWSTR pwszStoreName)
1390 FIXME("(%p, %08x, %s): stub\n", pvSystemStore, dwFlags, debugstr_w(pwszStoreName));
1391 return TRUE;
1394 BOOL WINAPI CertRegisterSystemStore(const void *pvSystemStore, DWORD dwFlags,
1395 PCERT_SYSTEM_STORE_INFO pStoreInfo, void *pvReserved)
1397 HCERTSTORE hstore;
1399 if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG )
1401 FIXME("(%p, %08x, %p, %p): flag not supported\n", pvSystemStore, dwFlags, pStoreInfo, pvReserved);
1402 return FALSE;
1405 TRACE("(%s, %08x, %p, %p)\n", debugstr_w(pvSystemStore), dwFlags, pStoreInfo, pvReserved);
1407 hstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0, 0, dwFlags, pvSystemStore);
1408 if (hstore)
1410 CertCloseStore(hstore, 0);
1411 return TRUE;
1414 return FALSE;
1417 BOOL WINAPI CertUnregisterSystemStore(const void *pvSystemStore, DWORD dwFlags)
1419 HCERTSTORE hstore;
1421 if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG)
1423 FIXME("(%p, %08x): flag not supported\n", pvSystemStore, dwFlags);
1424 return FALSE;
1426 TRACE("(%s, %08x)\n", debugstr_w(pvSystemStore), dwFlags);
1428 hstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0, 0, dwFlags | CERT_STORE_OPEN_EXISTING_FLAG, pvSystemStore);
1429 if (hstore == NULL)
1430 return FALSE;
1432 hstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0, 0, dwFlags | CERT_STORE_DELETE_FLAG, pvSystemStore);
1433 if (hstore == NULL && GetLastError() == 0)
1434 return TRUE;
1436 return FALSE;
1439 static void EmptyStore_addref(WINECRYPT_CERTSTORE *store)
1441 TRACE("(%p)\n", store);
1444 static DWORD EmptyStore_release(WINECRYPT_CERTSTORE *store, DWORD flags)
1446 TRACE("(%p)\n", store);
1447 return E_UNEXPECTED;
1450 static void EmptyStore_releaseContext(WINECRYPT_CERTSTORE *store, context_t *context)
1452 Context_Free(context);
1455 static BOOL EmptyStore_add(WINECRYPT_CERTSTORE *store, context_t *context,
1456 context_t *replace, context_t **ret_context, BOOL use_link)
1458 TRACE("(%p, %p, %p, %p)\n", store, context, replace, ret_context);
1460 /* FIXME: We should clone the context */
1461 if(ret_context) {
1462 Context_AddRef(context);
1463 *ret_context = context;
1466 return TRUE;
1469 static context_t *EmptyStore_enum(WINECRYPT_CERTSTORE *store, context_t *prev)
1471 TRACE("(%p, %p)\n", store, prev);
1473 SetLastError(CRYPT_E_NOT_FOUND);
1474 return NULL;
1477 static BOOL EmptyStore_delete(WINECRYPT_CERTSTORE *store, context_t *context)
1479 return TRUE;
1482 static BOOL EmptyStore_control(WINECRYPT_CERTSTORE *store, DWORD flags, DWORD ctrl_type, void const *ctrl_para)
1484 TRACE("()\n");
1486 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1487 return FALSE;
1490 static const store_vtbl_t EmptyStoreVtbl = {
1491 EmptyStore_addref,
1492 EmptyStore_release,
1493 EmptyStore_releaseContext,
1494 EmptyStore_control,
1496 EmptyStore_add,
1497 EmptyStore_enum,
1498 EmptyStore_delete
1499 }, {
1500 EmptyStore_add,
1501 EmptyStore_enum,
1502 EmptyStore_delete
1503 }, {
1504 EmptyStore_add,
1505 EmptyStore_enum,
1506 EmptyStore_delete
1510 WINECRYPT_CERTSTORE empty_store;
1512 void init_empty_store(void)
1514 CRYPT_InitStore(&empty_store, CERT_STORE_READONLY_FLAG, StoreTypeEmpty, &EmptyStoreVtbl);