user32: Fix SPI_SETMOUSESPEED handling, the parameter is not a pointer.
[wine/wine64.git] / dlls / crypt32 / store.c
blob3b42893d3dd1ae9ee95eaaec7c18446bec5c41d5
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 "winuser.h"
36 #include "wincrypt.h"
37 #include "wine/debug.h"
38 #include "wine/list.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 (DuplicateContextFunc)CertDuplicateCertificateContext,
49 (EnumContextsInStoreFunc)CertEnumCertificatesInStore,
50 (EnumPropertiesFunc)CertEnumCertificateContextProperties,
51 (GetContextPropertyFunc)CertGetCertificateContextProperty,
52 (SetContextPropertyFunc)CertSetCertificateContextProperty,
53 (SerializeElementFunc)CertSerializeCertificateStoreElement,
54 (FreeContextFunc)CertFreeCertificateContext,
55 (DeleteContextFunc)CertDeleteCertificateFromStore,
57 PCWINE_CONTEXT_INTERFACE pCertInterface = &gCertInterface;
59 static const WINE_CONTEXT_INTERFACE gCRLInterface = {
60 (CreateContextFunc)CertCreateCRLContext,
61 (AddContextToStoreFunc)CertAddCRLContextToStore,
62 (AddEncodedContextToStoreFunc)CertAddEncodedCRLToStore,
63 (DuplicateContextFunc)CertDuplicateCRLContext,
64 (EnumContextsInStoreFunc)CertEnumCRLsInStore,
65 (EnumPropertiesFunc)CertEnumCRLContextProperties,
66 (GetContextPropertyFunc)CertGetCRLContextProperty,
67 (SetContextPropertyFunc)CertSetCRLContextProperty,
68 (SerializeElementFunc)CertSerializeCRLStoreElement,
69 (FreeContextFunc)CertFreeCRLContext,
70 (DeleteContextFunc)CertDeleteCRLFromStore,
72 PCWINE_CONTEXT_INTERFACE pCRLInterface = &gCRLInterface;
74 static const WINE_CONTEXT_INTERFACE gCTLInterface = {
75 (CreateContextFunc)CertCreateCTLContext,
76 (AddContextToStoreFunc)CertAddCTLContextToStore,
77 (AddEncodedContextToStoreFunc)CertAddEncodedCTLToStore,
78 (DuplicateContextFunc)CertDuplicateCTLContext,
79 (EnumContextsInStoreFunc)CertEnumCTLsInStore,
80 (EnumPropertiesFunc)CertEnumCTLContextProperties,
81 (GetContextPropertyFunc)CertGetCTLContextProperty,
82 (SetContextPropertyFunc)CertSetCTLContextProperty,
83 (SerializeElementFunc)CertSerializeCTLStoreElement,
84 (FreeContextFunc)CertFreeCTLContext,
85 (DeleteContextFunc)CertDeleteCTLFromStore,
87 PCWINE_CONTEXT_INTERFACE pCTLInterface = &gCTLInterface;
89 typedef struct _WINE_MEMSTORE
91 WINECRYPT_CERTSTORE hdr;
92 struct ContextList *certs;
93 struct ContextList *crls;
94 struct ContextList *ctls;
95 } WINE_MEMSTORE, *PWINE_MEMSTORE;
97 void CRYPT_InitStore(WINECRYPT_CERTSTORE *store, DWORD dwFlags,
98 CertStoreType type)
100 store->ref = 1;
101 store->dwMagic = WINE_CRYPTCERTSTORE_MAGIC;
102 store->type = type;
103 store->dwOpenFlags = dwFlags;
104 store->properties = NULL;
107 void CRYPT_FreeStore(PWINECRYPT_CERTSTORE store)
109 if (store->properties)
110 ContextPropertyList_Free(store->properties);
111 CryptMemFree(store);
114 BOOL WINAPI I_CertUpdateStore(HCERTSTORE store1, HCERTSTORE store2, DWORD unk0,
115 DWORD unk1)
117 static BOOL warned = FALSE;
118 const WINE_CONTEXT_INTERFACE * const interfaces[] = { pCertInterface,
119 pCRLInterface, pCTLInterface };
120 DWORD i;
122 TRACE("(%p, %p, %08x, %08x)\n", store1, store2, unk0, unk1);
123 if (!warned)
125 FIXME("semi-stub\n");
126 warned = TRUE;
129 /* Poor-man's resync: empty first store, then add everything from second
130 * store to it.
132 for (i = 0; i < sizeof(interfaces) / sizeof(interfaces[0]); i++)
134 const void *context;
136 do {
137 context = interfaces[i]->enumContextsInStore(store1, NULL);
138 if (context)
139 interfaces[i]->deleteFromStore(context);
140 } while (context);
141 do {
142 context = interfaces[i]->enumContextsInStore(store2, context);
143 if (context)
144 interfaces[i]->addContextToStore(store1, context,
145 CERT_STORE_ADD_ALWAYS, NULL);
146 } while (context);
148 return TRUE;
151 static BOOL CRYPT_MemAddCert(PWINECRYPT_CERTSTORE store, void *cert,
152 void *toReplace, const void **ppStoreContext)
154 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
155 PCERT_CONTEXT context;
157 TRACE("(%p, %p, %p, %p)\n", store, cert, toReplace, ppStoreContext);
159 context = ContextList_Add(ms->certs, cert, toReplace);
160 if (context)
162 context->hCertStore = store;
163 if (ppStoreContext)
164 *ppStoreContext = CertDuplicateCertificateContext(context);
166 return context ? TRUE : FALSE;
169 static void *CRYPT_MemEnumCert(PWINECRYPT_CERTSTORE store, void *pPrev)
171 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
172 void *ret;
174 TRACE("(%p, %p)\n", store, pPrev);
176 ret = ContextList_Enum(ms->certs, pPrev);
177 if (!ret)
178 SetLastError(CRYPT_E_NOT_FOUND);
180 TRACE("returning %p\n", ret);
181 return ret;
184 static BOOL CRYPT_MemDeleteCert(PWINECRYPT_CERTSTORE store, void *pCertContext)
186 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
188 ContextList_Delete(ms->certs, pCertContext);
189 return TRUE;
192 static BOOL CRYPT_MemAddCrl(PWINECRYPT_CERTSTORE store, void *crl,
193 void *toReplace, const void **ppStoreContext)
195 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
196 PCRL_CONTEXT context;
198 TRACE("(%p, %p, %p, %p)\n", store, crl, toReplace, ppStoreContext);
200 context = ContextList_Add(ms->crls, crl, toReplace);
201 if (context)
203 context->hCertStore = store;
204 if (ppStoreContext)
205 *ppStoreContext = CertDuplicateCRLContext(context);
207 return context ? TRUE : FALSE;
210 static void *CRYPT_MemEnumCrl(PWINECRYPT_CERTSTORE store, void *pPrev)
212 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
213 void *ret;
215 TRACE("(%p, %p)\n", store, pPrev);
217 ret = ContextList_Enum(ms->crls, pPrev);
218 if (!ret)
219 SetLastError(CRYPT_E_NOT_FOUND);
221 TRACE("returning %p\n", ret);
222 return ret;
225 static BOOL CRYPT_MemDeleteCrl(PWINECRYPT_CERTSTORE store, void *pCrlContext)
227 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
229 ContextList_Delete(ms->crls, pCrlContext);
230 return TRUE;
233 static BOOL CRYPT_MemAddCtl(PWINECRYPT_CERTSTORE store, void *ctl,
234 void *toReplace, const void **ppStoreContext)
236 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
237 PCTL_CONTEXT context;
239 TRACE("(%p, %p, %p, %p)\n", store, ctl, toReplace, ppStoreContext);
241 context = ContextList_Add(ms->ctls, ctl, toReplace);
242 if (context)
244 context->hCertStore = store;
245 if (ppStoreContext)
246 *ppStoreContext = CertDuplicateCTLContext(context);
248 return context ? TRUE : FALSE;
251 static void *CRYPT_MemEnumCtl(PWINECRYPT_CERTSTORE store, void *pPrev)
253 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
254 void *ret;
256 TRACE("(%p, %p)\n", store, pPrev);
258 ret = ContextList_Enum(ms->ctls, pPrev);
259 if (!ret)
260 SetLastError(CRYPT_E_NOT_FOUND);
262 TRACE("returning %p\n", ret);
263 return ret;
266 static BOOL CRYPT_MemDeleteCtl(PWINECRYPT_CERTSTORE store, void *pCtlContext)
268 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
270 ContextList_Delete(ms->ctls, pCtlContext);
271 return TRUE;
274 static void WINAPI CRYPT_MemCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
276 WINE_MEMSTORE *store = (WINE_MEMSTORE *)hCertStore;
278 TRACE("(%p, %08x)\n", store, dwFlags);
279 if (dwFlags)
280 FIXME("Unimplemented flags: %08x\n", dwFlags);
282 ContextList_Free(store->certs);
283 ContextList_Free(store->crls);
284 ContextList_Free(store->ctls);
285 CRYPT_FreeStore((PWINECRYPT_CERTSTORE)store);
288 static WINECRYPT_CERTSTORE *CRYPT_MemOpenStore(HCRYPTPROV hCryptProv,
289 DWORD dwFlags, const void *pvPara)
291 PWINE_MEMSTORE store;
293 TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
295 if (dwFlags & CERT_STORE_DELETE_FLAG)
297 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
298 store = NULL;
300 else
302 store = CryptMemAlloc(sizeof(WINE_MEMSTORE));
303 if (store)
305 memset(store, 0, sizeof(WINE_MEMSTORE));
306 CRYPT_InitStore(&store->hdr, dwFlags, StoreTypeMem);
307 store->hdr.closeStore = CRYPT_MemCloseStore;
308 store->hdr.certs.addContext = CRYPT_MemAddCert;
309 store->hdr.certs.enumContext = CRYPT_MemEnumCert;
310 store->hdr.certs.deleteContext = CRYPT_MemDeleteCert;
311 store->hdr.crls.addContext = CRYPT_MemAddCrl;
312 store->hdr.crls.enumContext = CRYPT_MemEnumCrl;
313 store->hdr.crls.deleteContext = CRYPT_MemDeleteCrl;
314 store->hdr.ctls.addContext = CRYPT_MemAddCtl;
315 store->hdr.ctls.enumContext = CRYPT_MemEnumCtl;
316 store->hdr.ctls.deleteContext = CRYPT_MemDeleteCtl;
317 store->hdr.control = NULL;
318 store->certs = ContextList_Create(pCertInterface,
319 sizeof(CERT_CONTEXT));
320 store->crls = ContextList_Create(pCRLInterface,
321 sizeof(CRL_CONTEXT));
322 store->ctls = ContextList_Create(pCTLInterface,
323 sizeof(CTL_CONTEXT));
324 /* Mem store doesn't need crypto provider, so close it */
325 if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
326 CryptReleaseContext(hCryptProv, 0);
329 return (PWINECRYPT_CERTSTORE)store;
332 static PWINECRYPT_CERTSTORE CRYPT_SysRegOpenStoreW(HCRYPTPROV hCryptProv,
333 DWORD dwFlags, const void *pvPara)
335 static const WCHAR rootW[] = { 'R','o','o','t',0 };
336 static const WCHAR fmt[] = { '%','s','\\','%','s',0 };
337 LPCWSTR storeName = (LPCWSTR)pvPara;
338 LPWSTR storePath;
339 PWINECRYPT_CERTSTORE store = NULL;
340 HKEY root;
341 LPCWSTR base;
343 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
344 debugstr_w((LPCWSTR)pvPara));
346 if (!pvPara)
348 SetLastError(E_INVALIDARG);
349 return NULL;
351 if (!lstrcmpiW(storeName, rootW))
352 return CRYPT_RootOpenStore(hCryptProv, dwFlags);
354 switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
356 case CERT_SYSTEM_STORE_LOCAL_MACHINE:
357 root = HKEY_LOCAL_MACHINE;
358 base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
359 break;
360 case CERT_SYSTEM_STORE_CURRENT_USER:
361 root = HKEY_CURRENT_USER;
362 base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
363 break;
364 case CERT_SYSTEM_STORE_CURRENT_SERVICE:
365 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
366 * SystemCertificates
368 FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE, %s: stub\n",
369 debugstr_w(storeName));
370 return NULL;
371 case CERT_SYSTEM_STORE_SERVICES:
372 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
373 * SystemCertificates
375 FIXME("CERT_SYSTEM_STORE_SERVICES, %s: stub\n",
376 debugstr_w(storeName));
377 return NULL;
378 case CERT_SYSTEM_STORE_USERS:
379 /* hku\user sid\Software\Microsoft\SystemCertificates */
380 FIXME("CERT_SYSTEM_STORE_USERS, %s: stub\n",
381 debugstr_w(storeName));
382 return NULL;
383 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY:
384 root = HKEY_CURRENT_USER;
385 base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
386 break;
387 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY:
388 root = HKEY_LOCAL_MACHINE;
389 base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
390 break;
391 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE:
392 /* hklm\Software\Microsoft\EnterpriseCertificates */
393 FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, %s: stub\n",
394 debugstr_w(storeName));
395 return NULL;
396 default:
397 SetLastError(E_INVALIDARG);
398 return NULL;
401 storePath = CryptMemAlloc((lstrlenW(base) + lstrlenW(storeName) + 2) *
402 sizeof(WCHAR));
403 if (storePath)
405 LONG rc;
406 HKEY key;
407 REGSAM sam = dwFlags & CERT_STORE_READONLY_FLAG ? KEY_READ :
408 KEY_ALL_ACCESS;
410 wsprintfW(storePath, fmt, base, storeName);
411 if (dwFlags & CERT_STORE_OPEN_EXISTING_FLAG)
412 rc = RegOpenKeyExW(root, storePath, 0, sam, &key);
413 else
415 DWORD disp;
417 rc = RegCreateKeyExW(root, storePath, 0, NULL, 0, sam, NULL,
418 &key, &disp);
419 if (!rc && dwFlags & CERT_STORE_CREATE_NEW_FLAG &&
420 disp == REG_OPENED_EXISTING_KEY)
422 RegCloseKey(key);
423 rc = ERROR_FILE_EXISTS;
426 if (!rc)
428 store = CRYPT_RegOpenStore(hCryptProv, dwFlags, key);
429 RegCloseKey(key);
431 else
432 SetLastError(rc);
433 CryptMemFree(storePath);
435 return store;
438 static PWINECRYPT_CERTSTORE CRYPT_SysRegOpenStoreA(HCRYPTPROV hCryptProv,
439 DWORD dwFlags, const void *pvPara)
441 int len;
442 PWINECRYPT_CERTSTORE ret = NULL;
444 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
445 debugstr_a((LPCSTR)pvPara));
447 if (!pvPara)
449 SetLastError(ERROR_FILE_NOT_FOUND);
450 return NULL;
452 len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, NULL, 0);
453 if (len)
455 LPWSTR storeName = CryptMemAlloc(len * sizeof(WCHAR));
457 if (storeName)
459 MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, storeName, len);
460 ret = CRYPT_SysRegOpenStoreW(hCryptProv, dwFlags, storeName);
461 CryptMemFree(storeName);
464 return ret;
467 static PWINECRYPT_CERTSTORE CRYPT_SysOpenStoreW(HCRYPTPROV hCryptProv,
468 DWORD dwFlags, const void *pvPara)
470 HCERTSTORE store = 0;
471 BOOL ret;
473 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
474 debugstr_w((LPCWSTR)pvPara));
476 if (!pvPara)
478 SetLastError(ERROR_FILE_NOT_FOUND);
479 return NULL;
481 /* This returns a different error than system registry stores if the
482 * location is invalid.
484 switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
486 case CERT_SYSTEM_STORE_LOCAL_MACHINE:
487 case CERT_SYSTEM_STORE_CURRENT_USER:
488 case CERT_SYSTEM_STORE_CURRENT_SERVICE:
489 case CERT_SYSTEM_STORE_SERVICES:
490 case CERT_SYSTEM_STORE_USERS:
491 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY:
492 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY:
493 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE:
494 ret = TRUE;
495 break;
496 default:
497 SetLastError(ERROR_FILE_NOT_FOUND);
498 ret = FALSE;
500 if (ret)
502 HCERTSTORE regStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,
503 0, 0, dwFlags, pvPara);
505 if (regStore)
507 store = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
508 CERT_STORE_CREATE_NEW_FLAG, NULL);
509 CertAddStoreToCollection(store, regStore,
510 dwFlags & CERT_STORE_READONLY_FLAG ? 0 :
511 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
512 CertCloseStore(regStore, 0);
513 /* CERT_SYSTEM_STORE_CURRENT_USER returns both the HKCU and HKLM
514 * stores.
516 if ((dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) ==
517 CERT_SYSTEM_STORE_CURRENT_USER)
519 dwFlags &= ~CERT_SYSTEM_STORE_CURRENT_USER;
520 dwFlags |= CERT_SYSTEM_STORE_LOCAL_MACHINE;
521 regStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0,
522 0, dwFlags, pvPara);
523 if (regStore)
525 CertAddStoreToCollection(store, regStore,
526 dwFlags & CERT_STORE_READONLY_FLAG ? 0 :
527 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
528 CertCloseStore(regStore, 0);
531 /* System store doesn't need crypto provider, so close it */
532 if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
533 CryptReleaseContext(hCryptProv, 0);
536 return (PWINECRYPT_CERTSTORE)store;
539 static PWINECRYPT_CERTSTORE CRYPT_SysOpenStoreA(HCRYPTPROV hCryptProv,
540 DWORD dwFlags, const void *pvPara)
542 int len;
543 PWINECRYPT_CERTSTORE ret = NULL;
545 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
546 debugstr_a((LPCSTR)pvPara));
548 if (!pvPara)
550 SetLastError(ERROR_FILE_NOT_FOUND);
551 return NULL;
553 len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, NULL, 0);
554 if (len)
556 LPWSTR storeName = CryptMemAlloc(len * sizeof(WCHAR));
558 if (storeName)
560 MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, storeName, len);
561 ret = CRYPT_SysOpenStoreW(hCryptProv, dwFlags, storeName);
562 CryptMemFree(storeName);
565 return ret;
568 static void WINAPI CRYPT_MsgCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
570 HCRYPTMSG msg = hCertStore;
572 TRACE("(%p, %08x)\n", msg, dwFlags);
573 CryptMsgClose(msg);
576 static void *msgProvFuncs[] = {
577 CRYPT_MsgCloseStore,
580 static PWINECRYPT_CERTSTORE CRYPT_MsgOpenStore(HCRYPTPROV hCryptProv,
581 DWORD dwFlags, const void *pvPara)
583 PWINECRYPT_CERTSTORE store = NULL;
584 HCRYPTMSG msg = (HCRYPTMSG)pvPara;
585 PWINECRYPT_CERTSTORE memStore;
587 TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
589 memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
590 CERT_STORE_CREATE_NEW_FLAG, NULL);
591 if (memStore)
593 BOOL ret;
594 DWORD size, count, i;
596 size = sizeof(count);
597 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &count, &size);
598 for (i = 0; ret && i < count; i++)
600 size = 0;
601 ret = CryptMsgGetParam(msg, CMSG_CERT_PARAM, i, NULL, &size);
602 if (ret)
604 LPBYTE buf = CryptMemAlloc(size);
606 if (buf)
608 ret = CryptMsgGetParam(msg, CMSG_CERT_PARAM, i, buf, &size);
609 if (ret)
610 ret = CertAddEncodedCertificateToStore(memStore,
611 X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_ALWAYS,
612 NULL);
613 CryptMemFree(buf);
617 size = sizeof(count);
618 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &count, &size);
619 for (i = 0; ret && i < count; i++)
621 size = 0;
622 ret = CryptMsgGetParam(msg, CMSG_CRL_PARAM, i, NULL, &size);
623 if (ret)
625 LPBYTE buf = CryptMemAlloc(size);
627 if (buf)
629 ret = CryptMsgGetParam(msg, CMSG_CRL_PARAM, i, buf, &size);
630 if (ret)
631 ret = CertAddEncodedCRLToStore(memStore,
632 X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_ALWAYS,
633 NULL);
634 CryptMemFree(buf);
638 if (ret)
640 CERT_STORE_PROV_INFO provInfo = { 0 };
642 provInfo.cbSize = sizeof(provInfo);
643 provInfo.cStoreProvFunc = sizeof(msgProvFuncs) /
644 sizeof(msgProvFuncs[0]);
645 provInfo.rgpvStoreProvFunc = msgProvFuncs;
646 provInfo.hStoreProv = CryptMsgDuplicate(msg);
647 store = CRYPT_ProvCreateStore(dwFlags, memStore, &provInfo);
648 /* Msg store doesn't need crypto provider, so close it */
649 if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
650 CryptReleaseContext(hCryptProv, 0);
652 else
653 CertCloseStore(memStore, 0);
655 TRACE("returning %p\n", store);
656 return store;
659 static PWINECRYPT_CERTSTORE CRYPT_PKCSOpenStore(HCRYPTPROV hCryptProv,
660 DWORD dwFlags, const void *pvPara)
662 HCRYPTMSG msg;
663 PWINECRYPT_CERTSTORE store = NULL;
664 const CRYPT_DATA_BLOB *data = (const CRYPT_DATA_BLOB *)pvPara;
665 BOOL ret;
666 DWORD msgOpenFlags = dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG ? 0 :
667 CMSG_CRYPT_RELEASE_CONTEXT_FLAG;
669 TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
671 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, msgOpenFlags, CMSG_SIGNED,
672 hCryptProv, NULL, NULL);
673 ret = CryptMsgUpdate(msg, data->pbData, data->cbData, TRUE);
674 if (!ret)
676 CryptMsgClose(msg);
677 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, msgOpenFlags, 0,
678 hCryptProv, NULL, NULL);
679 ret = CryptMsgUpdate(msg, data->pbData, data->cbData, TRUE);
680 if (ret)
682 DWORD type, size = sizeof(type);
684 /* Only signed messages are allowed, check type */
685 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &type, &size);
686 if (ret && type != CMSG_SIGNED)
688 SetLastError(CRYPT_E_INVALID_MSG_TYPE);
689 ret = FALSE;
693 if (ret)
694 store = CRYPT_MsgOpenStore(0, dwFlags, msg);
695 CryptMsgClose(msg);
696 TRACE("returning %p\n", store);
697 return store;
700 static PWINECRYPT_CERTSTORE CRYPT_PhysOpenStoreW(HCRYPTPROV hCryptProv,
701 DWORD dwFlags, const void *pvPara)
703 if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG)
704 FIXME("(%ld, %08x, %p): stub\n", hCryptProv, dwFlags, pvPara);
705 else
706 FIXME("(%ld, %08x, %s): stub\n", hCryptProv, dwFlags,
707 debugstr_w((LPCWSTR)pvPara));
708 return NULL;
711 HCERTSTORE WINAPI CertOpenStore(LPCSTR lpszStoreProvider,
712 DWORD dwMsgAndCertEncodingType, HCRYPTPROV_LEGACY hCryptProv, DWORD dwFlags,
713 const void* pvPara)
715 WINECRYPT_CERTSTORE *hcs;
716 StoreOpenFunc openFunc = NULL;
718 TRACE("(%s, %08x, %08lx, %08x, %p)\n", debugstr_a(lpszStoreProvider),
719 dwMsgAndCertEncodingType, hCryptProv, dwFlags, pvPara);
721 if (!HIWORD(lpszStoreProvider))
723 switch (LOWORD(lpszStoreProvider))
725 case LOWORD(CERT_STORE_PROV_MSG):
726 openFunc = CRYPT_MsgOpenStore;
727 break;
728 case LOWORD(CERT_STORE_PROV_MEMORY):
729 openFunc = CRYPT_MemOpenStore;
730 break;
731 case LOWORD(CERT_STORE_PROV_FILE):
732 openFunc = CRYPT_FileOpenStore;
733 break;
734 case LOWORD(CERT_STORE_PROV_PKCS7):
735 openFunc = CRYPT_PKCSOpenStore;
736 break;
737 case LOWORD(CERT_STORE_PROV_REG):
738 openFunc = CRYPT_RegOpenStore;
739 break;
740 case LOWORD(CERT_STORE_PROV_FILENAME_A):
741 openFunc = CRYPT_FileNameOpenStoreA;
742 break;
743 case LOWORD(CERT_STORE_PROV_FILENAME_W):
744 openFunc = CRYPT_FileNameOpenStoreW;
745 break;
746 case LOWORD(CERT_STORE_PROV_COLLECTION):
747 openFunc = CRYPT_CollectionOpenStore;
748 break;
749 case LOWORD(CERT_STORE_PROV_SYSTEM_A):
750 openFunc = CRYPT_SysOpenStoreA;
751 break;
752 case LOWORD(CERT_STORE_PROV_SYSTEM_W):
753 openFunc = CRYPT_SysOpenStoreW;
754 break;
755 case LOWORD(CERT_STORE_PROV_SYSTEM_REGISTRY_A):
756 openFunc = CRYPT_SysRegOpenStoreA;
757 break;
758 case LOWORD(CERT_STORE_PROV_SYSTEM_REGISTRY_W):
759 openFunc = CRYPT_SysRegOpenStoreW;
760 break;
761 case LOWORD(CERT_STORE_PROV_PHYSICAL_W):
762 openFunc = CRYPT_PhysOpenStoreW;
763 break;
764 default:
765 if (LOWORD(lpszStoreProvider))
766 FIXME("unimplemented type %d\n", LOWORD(lpszStoreProvider));
769 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_MEMORY))
770 openFunc = CRYPT_MemOpenStore;
771 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_FILENAME_W))
772 openFunc = CRYPT_FileOpenStore;
773 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_SYSTEM))
774 openFunc = CRYPT_SysOpenStoreW;
775 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_COLLECTION))
776 openFunc = CRYPT_CollectionOpenStore;
777 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_SYSTEM_REGISTRY))
778 openFunc = CRYPT_SysRegOpenStoreW;
779 else
781 FIXME("unimplemented type %s\n", lpszStoreProvider);
782 openFunc = NULL;
785 if (!openFunc)
786 hcs = CRYPT_ProvOpenStore(lpszStoreProvider, dwMsgAndCertEncodingType,
787 hCryptProv, dwFlags, pvPara);
788 else
789 hcs = openFunc(hCryptProv, dwFlags, pvPara);
790 return (HCERTSTORE)hcs;
793 HCERTSTORE WINAPI CertOpenSystemStoreA(HCRYPTPROV_LEGACY hProv,
794 LPCSTR szSubSystemProtocol)
796 if (!szSubSystemProtocol)
798 SetLastError(E_INVALIDARG);
799 return 0;
801 return CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, hProv,
802 CERT_SYSTEM_STORE_CURRENT_USER, szSubSystemProtocol);
805 HCERTSTORE WINAPI CertOpenSystemStoreW(HCRYPTPROV_LEGACY hProv,
806 LPCWSTR szSubSystemProtocol)
808 if (!szSubSystemProtocol)
810 SetLastError(E_INVALIDARG);
811 return 0;
813 return CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, hProv,
814 CERT_SYSTEM_STORE_CURRENT_USER, szSubSystemProtocol);
817 #define CertContext_CopyProperties(to, from) \
818 Context_CopyProperties((to), (from), sizeof(CERT_CONTEXT))
820 BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore,
821 PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition,
822 PCCERT_CONTEXT *ppStoreContext)
824 PWINECRYPT_CERTSTORE store = (PWINECRYPT_CERTSTORE)hCertStore;
825 BOOL ret = TRUE;
826 PCCERT_CONTEXT toAdd = NULL, existing = NULL;
828 TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCertContext,
829 dwAddDisposition, ppStoreContext);
831 if (dwAddDisposition != CERT_STORE_ADD_ALWAYS)
833 BYTE hashToAdd[20];
834 DWORD size = sizeof(hashToAdd);
836 ret = CertGetCertificateContextProperty(pCertContext, CERT_HASH_PROP_ID,
837 hashToAdd, &size);
838 if (ret)
840 CRYPT_HASH_BLOB blob = { sizeof(hashToAdd), hashToAdd };
842 existing = CertFindCertificateInStore(hCertStore,
843 pCertContext->dwCertEncodingType, 0, CERT_FIND_SHA1_HASH, &blob,
844 NULL);
848 switch (dwAddDisposition)
850 case CERT_STORE_ADD_ALWAYS:
851 toAdd = CertDuplicateCertificateContext(pCertContext);
852 break;
853 case CERT_STORE_ADD_NEW:
854 if (existing)
856 TRACE("found matching certificate, not adding\n");
857 SetLastError(CRYPT_E_EXISTS);
858 ret = FALSE;
860 else
861 toAdd = CertDuplicateCertificateContext(pCertContext);
862 break;
863 case CERT_STORE_ADD_REPLACE_EXISTING:
864 toAdd = CertDuplicateCertificateContext(pCertContext);
865 break;
866 case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES:
867 toAdd = CertDuplicateCertificateContext(pCertContext);
868 if (existing)
869 CertContext_CopyProperties(toAdd, existing);
870 break;
871 case CERT_STORE_ADD_USE_EXISTING:
872 if (existing)
874 CertContext_CopyProperties(existing, pCertContext);
875 *ppStoreContext = CertDuplicateCertificateContext(existing);
877 else
878 toAdd = CertDuplicateCertificateContext(pCertContext);
879 break;
880 case CERT_STORE_ADD_NEWER:
881 if (existing)
883 if (CompareFileTime(&existing->pCertInfo->NotBefore,
884 &pCertContext->pCertInfo->NotBefore) >= 0)
886 TRACE("existing certificate is newer, not adding\n");
887 SetLastError(CRYPT_E_EXISTS);
888 ret = FALSE;
890 else
891 toAdd = CertDuplicateCertificateContext(pCertContext);
893 else
894 toAdd = CertDuplicateCertificateContext(pCertContext);
895 break;
896 case CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES:
897 if (existing)
899 if (CompareFileTime(&existing->pCertInfo->NotBefore,
900 &pCertContext->pCertInfo->NotBefore) >= 0)
902 TRACE("existing certificate is newer, not adding\n");
903 SetLastError(CRYPT_E_EXISTS);
904 ret = FALSE;
906 else
908 toAdd = CertDuplicateCertificateContext(pCertContext);
909 CertContext_CopyProperties(toAdd, existing);
912 else
913 toAdd = CertDuplicateCertificateContext(pCertContext);
914 break;
915 default:
916 FIXME("Unimplemented add disposition %d\n", dwAddDisposition);
917 SetLastError(E_INVALIDARG);
918 ret = FALSE;
921 if (toAdd)
923 if (store)
924 ret = store->certs.addContext(store, (void *)toAdd,
925 (void *)existing, (const void **)ppStoreContext);
926 else if (ppStoreContext)
927 *ppStoreContext = CertDuplicateCertificateContext(toAdd);
928 CertFreeCertificateContext(toAdd);
930 CertFreeCertificateContext(existing);
932 TRACE("returning %d\n", ret);
933 return ret;
936 PCCERT_CONTEXT WINAPI CertEnumCertificatesInStore(HCERTSTORE hCertStore,
937 PCCERT_CONTEXT pPrev)
939 WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *)hCertStore;
940 PCCERT_CONTEXT ret;
942 TRACE("(%p, %p)\n", hCertStore, pPrev);
943 if (!hCertStore)
944 ret = NULL;
945 else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
946 ret = NULL;
947 else
948 ret = (PCCERT_CONTEXT)hcs->certs.enumContext(hcs, (void *)pPrev);
949 return ret;
952 BOOL WINAPI CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext)
954 BOOL ret;
956 TRACE("(%p)\n", pCertContext);
958 if (!pCertContext)
959 ret = TRUE;
960 else if (!pCertContext->hCertStore)
962 ret = TRUE;
963 CertFreeCertificateContext(pCertContext);
965 else
967 PWINECRYPT_CERTSTORE hcs =
968 (PWINECRYPT_CERTSTORE)pCertContext->hCertStore;
970 if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
971 ret = FALSE;
972 else
973 ret = hcs->certs.deleteContext(hcs, (void *)pCertContext);
974 CertFreeCertificateContext(pCertContext);
976 return ret;
979 #define CrlContext_CopyProperties(to, from) \
980 Context_CopyProperties((to), (from), sizeof(CRL_CONTEXT))
982 BOOL WINAPI CertAddCRLContextToStore(HCERTSTORE hCertStore,
983 PCCRL_CONTEXT pCrlContext, DWORD dwAddDisposition,
984 PCCRL_CONTEXT* ppStoreContext)
986 PWINECRYPT_CERTSTORE store = (PWINECRYPT_CERTSTORE)hCertStore;
987 BOOL ret = TRUE;
988 PCCRL_CONTEXT toAdd = NULL, existing = NULL;
990 TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCrlContext,
991 dwAddDisposition, ppStoreContext);
993 /* Weird case to pass a test */
994 if (dwAddDisposition == 0)
996 SetLastError(STATUS_ACCESS_VIOLATION);
997 return FALSE;
999 if (dwAddDisposition != CERT_STORE_ADD_ALWAYS)
1001 existing = CertFindCRLInStore(hCertStore, 0, 0, CRL_FIND_EXISTING,
1002 pCrlContext, NULL);
1005 switch (dwAddDisposition)
1007 case CERT_STORE_ADD_ALWAYS:
1008 toAdd = CertDuplicateCRLContext(pCrlContext);
1009 break;
1010 case CERT_STORE_ADD_NEW:
1011 if (existing)
1013 TRACE("found matching CRL, not adding\n");
1014 SetLastError(CRYPT_E_EXISTS);
1015 ret = FALSE;
1017 else
1018 toAdd = CertDuplicateCRLContext(pCrlContext);
1019 break;
1020 case CERT_STORE_ADD_NEWER:
1021 if (existing)
1023 LONG newer = CompareFileTime(&existing->pCrlInfo->ThisUpdate,
1024 &pCrlContext->pCrlInfo->ThisUpdate);
1026 if (newer < 0)
1027 toAdd = CertDuplicateCRLContext(pCrlContext);
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_NEWER_INHERIT_PROPERTIES:
1039 if (existing)
1041 LONG newer = CompareFileTime(&existing->pCrlInfo->ThisUpdate,
1042 &pCrlContext->pCrlInfo->ThisUpdate);
1044 if (newer < 0)
1046 toAdd = CertDuplicateCRLContext(pCrlContext);
1047 CrlContext_CopyProperties(toAdd, existing);
1049 else
1051 TRACE("existing CRL is newer, not adding\n");
1052 SetLastError(CRYPT_E_EXISTS);
1053 ret = FALSE;
1056 else
1057 toAdd = CertDuplicateCRLContext(pCrlContext);
1058 break;
1059 case CERT_STORE_ADD_REPLACE_EXISTING:
1060 toAdd = CertDuplicateCRLContext(pCrlContext);
1061 break;
1062 case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES:
1063 toAdd = CertDuplicateCRLContext(pCrlContext);
1064 if (existing)
1065 CrlContext_CopyProperties(toAdd, existing);
1066 break;
1067 case CERT_STORE_ADD_USE_EXISTING:
1068 if (existing)
1069 CrlContext_CopyProperties(existing, pCrlContext);
1070 break;
1071 default:
1072 FIXME("Unimplemented add disposition %d\n", dwAddDisposition);
1073 ret = FALSE;
1076 if (toAdd)
1078 if (store)
1079 ret = store->crls.addContext(store, (void *)toAdd,
1080 (void *)existing, (const void **)ppStoreContext);
1081 else if (ppStoreContext)
1082 *ppStoreContext = CertDuplicateCRLContext(toAdd);
1083 CertFreeCRLContext(toAdd);
1085 CertFreeCRLContext(existing);
1087 TRACE("returning %d\n", ret);
1088 return ret;
1091 BOOL WINAPI CertDeleteCRLFromStore(PCCRL_CONTEXT pCrlContext)
1093 BOOL ret;
1095 TRACE("(%p)\n", pCrlContext);
1097 if (!pCrlContext)
1098 ret = TRUE;
1099 else if (!pCrlContext->hCertStore)
1101 ret = TRUE;
1102 CertFreeCRLContext(pCrlContext);
1104 else
1106 PWINECRYPT_CERTSTORE hcs =
1107 (PWINECRYPT_CERTSTORE)pCrlContext->hCertStore;
1109 if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
1110 ret = FALSE;
1111 else
1112 ret = hcs->crls.deleteContext(hcs, (void *)pCrlContext);
1113 CertFreeCRLContext(pCrlContext);
1115 return ret;
1118 PCCRL_CONTEXT WINAPI CertEnumCRLsInStore(HCERTSTORE hCertStore,
1119 PCCRL_CONTEXT pPrev)
1121 WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *)hCertStore;
1122 PCCRL_CONTEXT ret;
1124 TRACE("(%p, %p)\n", hCertStore, pPrev);
1125 if (!hCertStore)
1126 ret = NULL;
1127 else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
1128 ret = NULL;
1129 else
1130 ret = (PCCRL_CONTEXT)hcs->crls.enumContext(hcs, (void *)pPrev);
1131 return ret;
1134 HCERTSTORE WINAPI CertDuplicateStore(HCERTSTORE hCertStore)
1136 WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *)hCertStore;
1138 TRACE("(%p)\n", hCertStore);
1140 if (hcs && hcs->dwMagic == WINE_CRYPTCERTSTORE_MAGIC)
1141 InterlockedIncrement(&hcs->ref);
1142 return hCertStore;
1145 BOOL WINAPI CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
1147 WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *) hCertStore;
1149 TRACE("(%p, %08x)\n", hCertStore, dwFlags);
1151 if( ! hCertStore )
1152 return TRUE;
1154 if ( hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC )
1155 return FALSE;
1157 if (InterlockedDecrement(&hcs->ref) == 0)
1159 TRACE("%p's ref count is 0, freeing\n", hcs);
1160 hcs->dwMagic = 0;
1161 hcs->closeStore(hcs, dwFlags);
1163 else
1164 TRACE("%p's ref count is %d\n", hcs, hcs->ref);
1165 return TRUE;
1168 BOOL WINAPI CertControlStore(HCERTSTORE hCertStore, DWORD dwFlags,
1169 DWORD dwCtrlType, void const *pvCtrlPara)
1171 WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *)hCertStore;
1172 BOOL ret;
1174 TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType,
1175 pvCtrlPara);
1177 if (!hcs)
1178 ret = FALSE;
1179 else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
1180 ret = FALSE;
1181 else
1183 if (hcs->control)
1184 ret = hcs->control(hCertStore, dwFlags, dwCtrlType, pvCtrlPara);
1185 else
1186 ret = TRUE;
1188 return ret;
1191 BOOL WINAPI CertGetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId,
1192 void *pvData, DWORD *pcbData)
1194 PWINECRYPT_CERTSTORE store = (PWINECRYPT_CERTSTORE)hCertStore;
1195 BOOL ret = FALSE;
1197 TRACE("(%p, %d, %p, %p)\n", hCertStore, dwPropId, pvData, pcbData);
1199 switch (dwPropId)
1201 case CERT_ACCESS_STATE_PROP_ID:
1202 if (!pvData)
1204 *pcbData = sizeof(DWORD);
1205 ret = TRUE;
1207 else if (*pcbData < sizeof(DWORD))
1209 SetLastError(ERROR_MORE_DATA);
1210 *pcbData = sizeof(DWORD);
1212 else
1214 DWORD state = 0;
1216 if (store->type != StoreTypeMem &&
1217 !(store->dwOpenFlags & CERT_STORE_READONLY_FLAG))
1218 state |= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG;
1219 *(DWORD *)pvData = state;
1220 ret = TRUE;
1222 break;
1223 default:
1224 if (store->properties)
1226 CRYPT_DATA_BLOB blob;
1228 ret = ContextPropertyList_FindProperty(store->properties, dwPropId,
1229 &blob);
1230 if (ret)
1232 if (!pvData)
1233 *pcbData = blob.cbData;
1234 else if (*pcbData < blob.cbData)
1236 SetLastError(ERROR_MORE_DATA);
1237 *pcbData = blob.cbData;
1238 ret = FALSE;
1240 else
1242 memcpy(pvData, blob.pbData, blob.cbData);
1243 *pcbData = blob.cbData;
1246 else
1247 SetLastError(CRYPT_E_NOT_FOUND);
1249 else
1250 SetLastError(CRYPT_E_NOT_FOUND);
1252 return ret;
1255 BOOL WINAPI CertSetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId,
1256 DWORD dwFlags, const void *pvData)
1258 PWINECRYPT_CERTSTORE store = (PWINECRYPT_CERTSTORE)hCertStore;
1259 BOOL ret = FALSE;
1261 TRACE("(%p, %d, %08x, %p)\n", hCertStore, dwPropId, dwFlags, pvData);
1263 if (!store->properties)
1264 store->properties = ContextPropertyList_Create();
1265 switch (dwPropId)
1267 case CERT_ACCESS_STATE_PROP_ID:
1268 SetLastError(E_INVALIDARG);
1269 break;
1270 default:
1271 if (pvData)
1273 const CRYPT_DATA_BLOB *blob = (const CRYPT_DATA_BLOB *)pvData;
1275 ret = ContextPropertyList_SetProperty(store->properties, dwPropId,
1276 blob->pbData, blob->cbData);
1278 else
1280 ContextPropertyList_RemoveProperty(store->properties, dwPropId);
1281 ret = TRUE;
1284 return ret;
1287 static LONG CRYPT_OpenParentStore(DWORD dwFlags,
1288 void *pvSystemStoreLocationPara, HKEY *key)
1290 HKEY root;
1291 LPCWSTR base;
1293 TRACE("(%08x, %p)\n", dwFlags, pvSystemStoreLocationPara);
1295 switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
1297 case CERT_SYSTEM_STORE_LOCAL_MACHINE:
1298 root = HKEY_LOCAL_MACHINE;
1299 base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
1300 break;
1301 case CERT_SYSTEM_STORE_CURRENT_USER:
1302 root = HKEY_CURRENT_USER;
1303 base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
1304 break;
1305 case CERT_SYSTEM_STORE_CURRENT_SERVICE:
1306 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
1307 * SystemCertificates
1309 FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE\n");
1310 return ERROR_FILE_NOT_FOUND;
1311 case CERT_SYSTEM_STORE_SERVICES:
1312 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
1313 * SystemCertificates
1315 FIXME("CERT_SYSTEM_STORE_SERVICES\n");
1316 return ERROR_FILE_NOT_FOUND;
1317 case CERT_SYSTEM_STORE_USERS:
1318 /* hku\user sid\Software\Microsoft\SystemCertificates */
1319 FIXME("CERT_SYSTEM_STORE_USERS\n");
1320 return ERROR_FILE_NOT_FOUND;
1321 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY:
1322 root = HKEY_CURRENT_USER;
1323 base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
1324 break;
1325 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY:
1326 root = HKEY_LOCAL_MACHINE;
1327 base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
1328 break;
1329 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE:
1330 /* hklm\Software\Microsoft\EnterpriseCertificates */
1331 FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE\n");
1332 return ERROR_FILE_NOT_FOUND;
1333 default:
1334 return ERROR_FILE_NOT_FOUND;
1337 return RegOpenKeyExW(root, base, 0, KEY_READ, key);
1340 BOOL WINAPI CertEnumSystemStore(DWORD dwFlags, void *pvSystemStoreLocationPara,
1341 void *pvArg, PFN_CERT_ENUM_SYSTEM_STORE pfnEnum)
1343 BOOL ret = FALSE;
1344 LONG rc;
1345 HKEY key;
1347 TRACE("(%08x, %p, %p, %p)\n", dwFlags, pvSystemStoreLocationPara, pvArg,
1348 pfnEnum);
1350 rc = CRYPT_OpenParentStore(dwFlags, pvArg, &key);
1351 if (!rc)
1353 DWORD index = 0;
1354 CERT_SYSTEM_STORE_INFO info = { sizeof(info) };
1356 ret = TRUE;
1357 do {
1358 WCHAR name[MAX_PATH];
1359 DWORD size = sizeof(name) / sizeof(name[0]);
1361 rc = RegEnumKeyExW(key, index++, name, &size, NULL, NULL, NULL,
1362 NULL);
1363 if (!rc)
1364 ret = pfnEnum(name, dwFlags, &info, NULL, pvArg);
1365 } while (ret && !rc);
1366 if (ret && rc != ERROR_NO_MORE_ITEMS)
1367 SetLastError(rc);
1369 else
1370 SetLastError(rc);
1371 return ret;
1374 BOOL WINAPI CertEnumPhysicalStore(const void *pvSystemStore, DWORD dwFlags,
1375 void *pvArg, PFN_CERT_ENUM_PHYSICAL_STORE pfnEnum)
1377 if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG)
1378 FIXME("(%p, %08x, %p, %p): stub\n", pvSystemStore, dwFlags, pvArg,
1379 pfnEnum);
1380 else
1381 FIXME("(%s, %08x, %p, %p): stub\n", debugstr_w((LPCWSTR)pvSystemStore),
1382 dwFlags, pvArg,
1383 pfnEnum);
1384 return FALSE;