wininet: Avoid accessing uninitialized memory in HttpSendRequestExW.
[wine/multimedia.git] / dlls / crypt32 / store.c
blob8acc6f68b1280471350a3dfee2cc21c7a87c6ca6
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 = 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 const WCHAR rootW[] = { 'R','o','o','t',0 };
334 static PWINECRYPT_CERTSTORE CRYPT_SysRegOpenStoreW(HCRYPTPROV hCryptProv,
335 DWORD dwFlags, const void *pvPara)
337 static const WCHAR fmt[] = { '%','s','\\','%','s',0 };
338 LPCWSTR storeName = pvPara;
339 LPWSTR storePath;
340 PWINECRYPT_CERTSTORE store = NULL;
341 HKEY root;
342 LPCWSTR base;
344 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
345 debugstr_w(pvPara));
347 if (!pvPara)
349 SetLastError(E_INVALIDARG);
350 return NULL;
352 /* FIXME: In Windows, the root store (even the current user location) is
353 * protected: adding to it or removing from it present a user interface,
354 * and the keys are owned by the system process, not the current user.
355 * Wine's registry doesn't implement access controls, so a similar
356 * mechanism isn't possible yet.
358 if ((dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) ==
359 CERT_SYSTEM_STORE_LOCAL_MACHINE && !lstrcmpiW(storeName, rootW))
360 return CRYPT_RootOpenStore(hCryptProv, dwFlags);
362 switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
364 case CERT_SYSTEM_STORE_LOCAL_MACHINE:
365 root = HKEY_LOCAL_MACHINE;
366 base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
367 break;
368 case CERT_SYSTEM_STORE_CURRENT_USER:
369 root = HKEY_CURRENT_USER;
370 base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
371 break;
372 case CERT_SYSTEM_STORE_CURRENT_SERVICE:
373 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
374 * SystemCertificates
376 FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE, %s: stub\n",
377 debugstr_w(storeName));
378 return NULL;
379 case CERT_SYSTEM_STORE_SERVICES:
380 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
381 * SystemCertificates
383 FIXME("CERT_SYSTEM_STORE_SERVICES, %s: stub\n",
384 debugstr_w(storeName));
385 return NULL;
386 case CERT_SYSTEM_STORE_USERS:
387 /* hku\user sid\Software\Microsoft\SystemCertificates */
388 FIXME("CERT_SYSTEM_STORE_USERS, %s: stub\n",
389 debugstr_w(storeName));
390 return NULL;
391 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY:
392 root = HKEY_CURRENT_USER;
393 base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
394 break;
395 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY:
396 root = HKEY_LOCAL_MACHINE;
397 base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
398 break;
399 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE:
400 /* hklm\Software\Microsoft\EnterpriseCertificates */
401 FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, %s: stub\n",
402 debugstr_w(storeName));
403 return NULL;
404 default:
405 SetLastError(E_INVALIDARG);
406 return NULL;
409 storePath = CryptMemAlloc((lstrlenW(base) + lstrlenW(storeName) + 2) *
410 sizeof(WCHAR));
411 if (storePath)
413 LONG rc;
414 HKEY key;
415 REGSAM sam = dwFlags & CERT_STORE_READONLY_FLAG ? KEY_READ :
416 KEY_ALL_ACCESS;
418 wsprintfW(storePath, fmt, base, storeName);
419 if (dwFlags & CERT_STORE_OPEN_EXISTING_FLAG)
420 rc = RegOpenKeyExW(root, storePath, 0, sam, &key);
421 else
423 DWORD disp;
425 rc = RegCreateKeyExW(root, storePath, 0, NULL, 0, sam, NULL,
426 &key, &disp);
427 if (!rc && dwFlags & CERT_STORE_CREATE_NEW_FLAG &&
428 disp == REG_OPENED_EXISTING_KEY)
430 RegCloseKey(key);
431 rc = ERROR_FILE_EXISTS;
434 if (!rc)
436 store = CRYPT_RegOpenStore(hCryptProv, dwFlags, key);
437 RegCloseKey(key);
439 else
440 SetLastError(rc);
441 CryptMemFree(storePath);
443 return store;
446 static PWINECRYPT_CERTSTORE CRYPT_SysRegOpenStoreA(HCRYPTPROV hCryptProv,
447 DWORD dwFlags, const void *pvPara)
449 int len;
450 PWINECRYPT_CERTSTORE ret = NULL;
452 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
453 debugstr_a(pvPara));
455 if (!pvPara)
457 SetLastError(ERROR_FILE_NOT_FOUND);
458 return NULL;
460 len = MultiByteToWideChar(CP_ACP, 0, pvPara, -1, NULL, 0);
461 if (len)
463 LPWSTR storeName = CryptMemAlloc(len * sizeof(WCHAR));
465 if (storeName)
467 MultiByteToWideChar(CP_ACP, 0, pvPara, -1, storeName, len);
468 ret = CRYPT_SysRegOpenStoreW(hCryptProv, dwFlags, storeName);
469 CryptMemFree(storeName);
472 return ret;
475 static PWINECRYPT_CERTSTORE CRYPT_SysOpenStoreW(HCRYPTPROV hCryptProv,
476 DWORD dwFlags, const void *pvPara)
478 HCERTSTORE store = 0;
479 BOOL ret;
481 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
482 debugstr_w(pvPara));
484 if (!pvPara)
486 SetLastError(ERROR_FILE_NOT_FOUND);
487 return NULL;
489 /* This returns a different error than system registry stores if the
490 * location is invalid.
492 switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
494 case CERT_SYSTEM_STORE_LOCAL_MACHINE:
495 case CERT_SYSTEM_STORE_CURRENT_USER:
496 case CERT_SYSTEM_STORE_CURRENT_SERVICE:
497 case CERT_SYSTEM_STORE_SERVICES:
498 case CERT_SYSTEM_STORE_USERS:
499 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY:
500 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY:
501 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE:
502 ret = TRUE;
503 break;
504 default:
505 SetLastError(ERROR_FILE_NOT_FOUND);
506 ret = FALSE;
508 if (ret)
510 HCERTSTORE regStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,
511 0, 0, dwFlags, pvPara);
513 if (regStore)
515 store = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
516 CERT_STORE_CREATE_NEW_FLAG, NULL);
517 CertAddStoreToCollection(store, regStore,
518 dwFlags & CERT_STORE_READONLY_FLAG ? 0 :
519 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
520 CertCloseStore(regStore, 0);
521 /* CERT_SYSTEM_STORE_CURRENT_USER returns both the HKCU and HKLM
522 * stores.
524 if ((dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) ==
525 CERT_SYSTEM_STORE_CURRENT_USER)
527 dwFlags &= ~CERT_SYSTEM_STORE_CURRENT_USER;
528 dwFlags |= CERT_SYSTEM_STORE_LOCAL_MACHINE;
529 regStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0,
530 0, dwFlags, pvPara);
531 if (regStore)
533 CertAddStoreToCollection(store, regStore,
534 dwFlags & CERT_STORE_READONLY_FLAG ? 0 :
535 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
536 CertCloseStore(regStore, 0);
539 /* System store doesn't need crypto provider, so close it */
540 if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
541 CryptReleaseContext(hCryptProv, 0);
544 return store;
547 static PWINECRYPT_CERTSTORE CRYPT_SysOpenStoreA(HCRYPTPROV hCryptProv,
548 DWORD dwFlags, const void *pvPara)
550 int len;
551 PWINECRYPT_CERTSTORE ret = NULL;
553 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
554 debugstr_a(pvPara));
556 if (!pvPara)
558 SetLastError(ERROR_FILE_NOT_FOUND);
559 return NULL;
561 len = MultiByteToWideChar(CP_ACP, 0, pvPara, -1, NULL, 0);
562 if (len)
564 LPWSTR storeName = CryptMemAlloc(len * sizeof(WCHAR));
566 if (storeName)
568 MultiByteToWideChar(CP_ACP, 0, pvPara, -1, storeName, len);
569 ret = CRYPT_SysOpenStoreW(hCryptProv, dwFlags, storeName);
570 CryptMemFree(storeName);
573 return ret;
576 static void WINAPI CRYPT_MsgCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
578 HCRYPTMSG msg = hCertStore;
580 TRACE("(%p, %08x)\n", msg, dwFlags);
581 CryptMsgClose(msg);
584 static void *msgProvFuncs[] = {
585 CRYPT_MsgCloseStore,
588 static PWINECRYPT_CERTSTORE CRYPT_MsgOpenStore(HCRYPTPROV hCryptProv,
589 DWORD dwFlags, const void *pvPara)
591 PWINECRYPT_CERTSTORE store = NULL;
592 HCRYPTMSG msg = (HCRYPTMSG)pvPara;
593 PWINECRYPT_CERTSTORE memStore;
595 TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
597 memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
598 CERT_STORE_CREATE_NEW_FLAG, NULL);
599 if (memStore)
601 BOOL ret;
602 DWORD size, count, i;
604 size = sizeof(count);
605 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &count, &size);
606 for (i = 0; ret && i < count; i++)
608 size = 0;
609 ret = CryptMsgGetParam(msg, CMSG_CERT_PARAM, i, NULL, &size);
610 if (ret)
612 LPBYTE buf = CryptMemAlloc(size);
614 if (buf)
616 ret = CryptMsgGetParam(msg, CMSG_CERT_PARAM, i, buf, &size);
617 if (ret)
618 ret = CertAddEncodedCertificateToStore(memStore,
619 X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_ALWAYS,
620 NULL);
621 CryptMemFree(buf);
625 size = sizeof(count);
626 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &count, &size);
627 for (i = 0; ret && i < count; i++)
629 size = 0;
630 ret = CryptMsgGetParam(msg, CMSG_CRL_PARAM, i, NULL, &size);
631 if (ret)
633 LPBYTE buf = CryptMemAlloc(size);
635 if (buf)
637 ret = CryptMsgGetParam(msg, CMSG_CRL_PARAM, i, buf, &size);
638 if (ret)
639 ret = CertAddEncodedCRLToStore(memStore,
640 X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_ALWAYS,
641 NULL);
642 CryptMemFree(buf);
646 if (ret)
648 CERT_STORE_PROV_INFO provInfo = { 0 };
650 provInfo.cbSize = sizeof(provInfo);
651 provInfo.cStoreProvFunc = sizeof(msgProvFuncs) /
652 sizeof(msgProvFuncs[0]);
653 provInfo.rgpvStoreProvFunc = msgProvFuncs;
654 provInfo.hStoreProv = CryptMsgDuplicate(msg);
655 store = CRYPT_ProvCreateStore(dwFlags, memStore, &provInfo);
656 /* Msg store doesn't need crypto provider, so close it */
657 if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
658 CryptReleaseContext(hCryptProv, 0);
660 else
661 CertCloseStore(memStore, 0);
663 TRACE("returning %p\n", store);
664 return store;
667 static PWINECRYPT_CERTSTORE CRYPT_PKCSOpenStore(HCRYPTPROV hCryptProv,
668 DWORD dwFlags, const void *pvPara)
670 HCRYPTMSG msg;
671 PWINECRYPT_CERTSTORE store = NULL;
672 const CRYPT_DATA_BLOB *data = pvPara;
673 BOOL ret;
674 DWORD msgOpenFlags = dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG ? 0 :
675 CMSG_CRYPT_RELEASE_CONTEXT_FLAG;
677 TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
679 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, msgOpenFlags, CMSG_SIGNED,
680 hCryptProv, NULL, NULL);
681 ret = CryptMsgUpdate(msg, data->pbData, data->cbData, TRUE);
682 if (!ret)
684 CryptMsgClose(msg);
685 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, msgOpenFlags, 0,
686 hCryptProv, NULL, NULL);
687 ret = CryptMsgUpdate(msg, data->pbData, data->cbData, TRUE);
688 if (ret)
690 DWORD type, size = sizeof(type);
692 /* Only signed messages are allowed, check type */
693 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &type, &size);
694 if (ret && type != CMSG_SIGNED)
696 SetLastError(CRYPT_E_INVALID_MSG_TYPE);
697 ret = FALSE;
701 if (ret)
702 store = CRYPT_MsgOpenStore(0, dwFlags, msg);
703 CryptMsgClose(msg);
704 TRACE("returning %p\n", store);
705 return store;
708 static PWINECRYPT_CERTSTORE CRYPT_PhysOpenStoreW(HCRYPTPROV hCryptProv,
709 DWORD dwFlags, const void *pvPara)
711 if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG)
712 FIXME("(%ld, %08x, %p): stub\n", hCryptProv, dwFlags, pvPara);
713 else
714 FIXME("(%ld, %08x, %s): stub\n", hCryptProv, dwFlags,
715 debugstr_w(pvPara));
716 return NULL;
719 HCERTSTORE WINAPI CertOpenStore(LPCSTR lpszStoreProvider,
720 DWORD dwMsgAndCertEncodingType, HCRYPTPROV_LEGACY hCryptProv, DWORD dwFlags,
721 const void* pvPara)
723 WINECRYPT_CERTSTORE *hcs;
724 StoreOpenFunc openFunc = NULL;
726 TRACE("(%s, %08x, %08lx, %08x, %p)\n", debugstr_a(lpszStoreProvider),
727 dwMsgAndCertEncodingType, hCryptProv, dwFlags, pvPara);
729 if (!HIWORD(lpszStoreProvider))
731 switch (LOWORD(lpszStoreProvider))
733 case LOWORD(CERT_STORE_PROV_MSG):
734 openFunc = CRYPT_MsgOpenStore;
735 break;
736 case LOWORD(CERT_STORE_PROV_MEMORY):
737 openFunc = CRYPT_MemOpenStore;
738 break;
739 case LOWORD(CERT_STORE_PROV_FILE):
740 openFunc = CRYPT_FileOpenStore;
741 break;
742 case LOWORD(CERT_STORE_PROV_PKCS7):
743 openFunc = CRYPT_PKCSOpenStore;
744 break;
745 case LOWORD(CERT_STORE_PROV_REG):
746 openFunc = CRYPT_RegOpenStore;
747 break;
748 case LOWORD(CERT_STORE_PROV_FILENAME_A):
749 openFunc = CRYPT_FileNameOpenStoreA;
750 break;
751 case LOWORD(CERT_STORE_PROV_FILENAME_W):
752 openFunc = CRYPT_FileNameOpenStoreW;
753 break;
754 case LOWORD(CERT_STORE_PROV_COLLECTION):
755 openFunc = CRYPT_CollectionOpenStore;
756 break;
757 case LOWORD(CERT_STORE_PROV_SYSTEM_A):
758 openFunc = CRYPT_SysOpenStoreA;
759 break;
760 case LOWORD(CERT_STORE_PROV_SYSTEM_W):
761 openFunc = CRYPT_SysOpenStoreW;
762 break;
763 case LOWORD(CERT_STORE_PROV_SYSTEM_REGISTRY_A):
764 openFunc = CRYPT_SysRegOpenStoreA;
765 break;
766 case LOWORD(CERT_STORE_PROV_SYSTEM_REGISTRY_W):
767 openFunc = CRYPT_SysRegOpenStoreW;
768 break;
769 case LOWORD(CERT_STORE_PROV_PHYSICAL_W):
770 openFunc = CRYPT_PhysOpenStoreW;
771 break;
772 default:
773 if (LOWORD(lpszStoreProvider))
774 FIXME("unimplemented type %d\n", LOWORD(lpszStoreProvider));
777 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_MEMORY))
778 openFunc = CRYPT_MemOpenStore;
779 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_FILENAME_W))
780 openFunc = CRYPT_FileOpenStore;
781 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_SYSTEM))
782 openFunc = CRYPT_SysOpenStoreW;
783 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_COLLECTION))
784 openFunc = CRYPT_CollectionOpenStore;
785 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_SYSTEM_REGISTRY))
786 openFunc = CRYPT_SysRegOpenStoreW;
787 else
789 FIXME("unimplemented type %s\n", lpszStoreProvider);
790 openFunc = NULL;
793 if (!openFunc)
794 hcs = CRYPT_ProvOpenStore(lpszStoreProvider, dwMsgAndCertEncodingType,
795 hCryptProv, dwFlags, pvPara);
796 else
797 hcs = openFunc(hCryptProv, dwFlags, pvPara);
798 return hcs;
801 HCERTSTORE WINAPI CertOpenSystemStoreA(HCRYPTPROV_LEGACY hProv,
802 LPCSTR szSubSystemProtocol)
804 if (!szSubSystemProtocol)
806 SetLastError(E_INVALIDARG);
807 return 0;
809 return CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, hProv,
810 CERT_SYSTEM_STORE_CURRENT_USER, szSubSystemProtocol);
813 HCERTSTORE WINAPI CertOpenSystemStoreW(HCRYPTPROV_LEGACY hProv,
814 LPCWSTR szSubSystemProtocol)
816 if (!szSubSystemProtocol)
818 SetLastError(E_INVALIDARG);
819 return 0;
821 return CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, hProv,
822 CERT_SYSTEM_STORE_CURRENT_USER, szSubSystemProtocol);
825 #define CertContext_CopyProperties(to, from) \
826 Context_CopyProperties((to), (from), sizeof(CERT_CONTEXT))
828 BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore,
829 PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition,
830 PCCERT_CONTEXT *ppStoreContext)
832 PWINECRYPT_CERTSTORE store = hCertStore;
833 BOOL ret = TRUE;
834 PCCERT_CONTEXT toAdd = NULL, existing = NULL;
836 TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCertContext,
837 dwAddDisposition, ppStoreContext);
839 if (dwAddDisposition != CERT_STORE_ADD_ALWAYS)
841 BYTE hashToAdd[20];
842 DWORD size = sizeof(hashToAdd);
844 ret = CertGetCertificateContextProperty(pCertContext, CERT_HASH_PROP_ID,
845 hashToAdd, &size);
846 if (ret)
848 CRYPT_HASH_BLOB blob = { sizeof(hashToAdd), hashToAdd };
850 existing = CertFindCertificateInStore(hCertStore,
851 pCertContext->dwCertEncodingType, 0, CERT_FIND_SHA1_HASH, &blob,
852 NULL);
856 switch (dwAddDisposition)
858 case CERT_STORE_ADD_ALWAYS:
859 toAdd = CertDuplicateCertificateContext(pCertContext);
860 break;
861 case CERT_STORE_ADD_NEW:
862 if (existing)
864 TRACE("found matching certificate, not adding\n");
865 SetLastError(CRYPT_E_EXISTS);
866 ret = FALSE;
868 else
869 toAdd = CertDuplicateCertificateContext(pCertContext);
870 break;
871 case CERT_STORE_ADD_REPLACE_EXISTING:
872 toAdd = CertDuplicateCertificateContext(pCertContext);
873 break;
874 case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES:
875 toAdd = CertDuplicateCertificateContext(pCertContext);
876 if (existing)
877 CertContext_CopyProperties(toAdd, existing);
878 break;
879 case CERT_STORE_ADD_USE_EXISTING:
880 if (existing)
882 CertContext_CopyProperties(existing, pCertContext);
883 *ppStoreContext = CertDuplicateCertificateContext(existing);
885 else
886 toAdd = CertDuplicateCertificateContext(pCertContext);
887 break;
888 case CERT_STORE_ADD_NEWER:
889 if (existing)
891 if (CompareFileTime(&existing->pCertInfo->NotBefore,
892 &pCertContext->pCertInfo->NotBefore) >= 0)
894 TRACE("existing certificate is newer, not adding\n");
895 SetLastError(CRYPT_E_EXISTS);
896 ret = FALSE;
898 else
899 toAdd = CertDuplicateCertificateContext(pCertContext);
901 else
902 toAdd = CertDuplicateCertificateContext(pCertContext);
903 break;
904 case CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES:
905 if (existing)
907 if (CompareFileTime(&existing->pCertInfo->NotBefore,
908 &pCertContext->pCertInfo->NotBefore) >= 0)
910 TRACE("existing certificate is newer, not adding\n");
911 SetLastError(CRYPT_E_EXISTS);
912 ret = FALSE;
914 else
916 toAdd = CertDuplicateCertificateContext(pCertContext);
917 CertContext_CopyProperties(toAdd, existing);
920 else
921 toAdd = CertDuplicateCertificateContext(pCertContext);
922 break;
923 default:
924 FIXME("Unimplemented add disposition %d\n", dwAddDisposition);
925 SetLastError(E_INVALIDARG);
926 ret = FALSE;
929 if (toAdd)
931 if (store)
932 ret = store->certs.addContext(store, (void *)toAdd,
933 (void *)existing, (const void **)ppStoreContext);
934 else if (ppStoreContext)
935 *ppStoreContext = CertDuplicateCertificateContext(toAdd);
936 CertFreeCertificateContext(toAdd);
938 CertFreeCertificateContext(existing);
940 TRACE("returning %d\n", ret);
941 return ret;
944 PCCERT_CONTEXT WINAPI CertEnumCertificatesInStore(HCERTSTORE hCertStore,
945 PCCERT_CONTEXT pPrev)
947 WINECRYPT_CERTSTORE *hcs = hCertStore;
948 PCCERT_CONTEXT ret;
950 TRACE("(%p, %p)\n", hCertStore, pPrev);
951 if (!hCertStore)
952 ret = NULL;
953 else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
954 ret = NULL;
955 else
956 ret = (PCCERT_CONTEXT)hcs->certs.enumContext(hcs, (void *)pPrev);
957 return ret;
960 BOOL WINAPI CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext)
962 BOOL ret;
964 TRACE("(%p)\n", pCertContext);
966 if (!pCertContext)
967 ret = TRUE;
968 else if (!pCertContext->hCertStore)
970 ret = TRUE;
971 CertFreeCertificateContext(pCertContext);
973 else
975 PWINECRYPT_CERTSTORE hcs = pCertContext->hCertStore;
977 if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
978 ret = FALSE;
979 else
980 ret = hcs->certs.deleteContext(hcs, (void *)pCertContext);
981 if (ret)
982 CertFreeCertificateContext(pCertContext);
984 return ret;
987 #define CrlContext_CopyProperties(to, from) \
988 Context_CopyProperties((to), (from), sizeof(CRL_CONTEXT))
990 BOOL WINAPI CertAddCRLContextToStore(HCERTSTORE hCertStore,
991 PCCRL_CONTEXT pCrlContext, DWORD dwAddDisposition,
992 PCCRL_CONTEXT* ppStoreContext)
994 PWINECRYPT_CERTSTORE store = hCertStore;
995 BOOL ret = TRUE;
996 PCCRL_CONTEXT toAdd = NULL, existing = NULL;
998 TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCrlContext,
999 dwAddDisposition, ppStoreContext);
1001 /* Weird case to pass a test */
1002 if (dwAddDisposition == 0)
1004 SetLastError(STATUS_ACCESS_VIOLATION);
1005 return FALSE;
1007 if (dwAddDisposition != CERT_STORE_ADD_ALWAYS)
1009 existing = CertFindCRLInStore(hCertStore, 0, 0, CRL_FIND_EXISTING,
1010 pCrlContext, NULL);
1013 switch (dwAddDisposition)
1015 case CERT_STORE_ADD_ALWAYS:
1016 toAdd = CertDuplicateCRLContext(pCrlContext);
1017 break;
1018 case CERT_STORE_ADD_NEW:
1019 if (existing)
1021 TRACE("found matching CRL, not adding\n");
1022 SetLastError(CRYPT_E_EXISTS);
1023 ret = FALSE;
1025 else
1026 toAdd = CertDuplicateCRLContext(pCrlContext);
1027 break;
1028 case CERT_STORE_ADD_NEWER:
1029 if (existing)
1031 LONG newer = CompareFileTime(&existing->pCrlInfo->ThisUpdate,
1032 &pCrlContext->pCrlInfo->ThisUpdate);
1034 if (newer < 0)
1035 toAdd = CertDuplicateCRLContext(pCrlContext);
1036 else
1038 TRACE("existing CRL is newer, not adding\n");
1039 SetLastError(CRYPT_E_EXISTS);
1040 ret = FALSE;
1043 else
1044 toAdd = CertDuplicateCRLContext(pCrlContext);
1045 break;
1046 case CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES:
1047 if (existing)
1049 LONG newer = CompareFileTime(&existing->pCrlInfo->ThisUpdate,
1050 &pCrlContext->pCrlInfo->ThisUpdate);
1052 if (newer < 0)
1054 toAdd = CertDuplicateCRLContext(pCrlContext);
1055 CrlContext_CopyProperties(toAdd, existing);
1057 else
1059 TRACE("existing CRL is newer, not adding\n");
1060 SetLastError(CRYPT_E_EXISTS);
1061 ret = FALSE;
1064 else
1065 toAdd = CertDuplicateCRLContext(pCrlContext);
1066 break;
1067 case CERT_STORE_ADD_REPLACE_EXISTING:
1068 toAdd = CertDuplicateCRLContext(pCrlContext);
1069 break;
1070 case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES:
1071 toAdd = CertDuplicateCRLContext(pCrlContext);
1072 if (existing)
1073 CrlContext_CopyProperties(toAdd, existing);
1074 break;
1075 case CERT_STORE_ADD_USE_EXISTING:
1076 if (existing)
1077 CrlContext_CopyProperties(existing, pCrlContext);
1078 break;
1079 default:
1080 FIXME("Unimplemented add disposition %d\n", dwAddDisposition);
1081 ret = FALSE;
1084 if (toAdd)
1086 if (store)
1087 ret = store->crls.addContext(store, (void *)toAdd,
1088 (void *)existing, (const void **)ppStoreContext);
1089 else if (ppStoreContext)
1090 *ppStoreContext = CertDuplicateCRLContext(toAdd);
1091 CertFreeCRLContext(toAdd);
1093 CertFreeCRLContext(existing);
1095 TRACE("returning %d\n", ret);
1096 return ret;
1099 BOOL WINAPI CertDeleteCRLFromStore(PCCRL_CONTEXT pCrlContext)
1101 BOOL ret;
1103 TRACE("(%p)\n", pCrlContext);
1105 if (!pCrlContext)
1106 ret = TRUE;
1107 else if (!pCrlContext->hCertStore)
1109 ret = TRUE;
1110 CertFreeCRLContext(pCrlContext);
1112 else
1114 PWINECRYPT_CERTSTORE hcs = pCrlContext->hCertStore;
1116 if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
1117 ret = FALSE;
1118 else
1119 ret = hcs->crls.deleteContext(hcs, (void *)pCrlContext);
1120 CertFreeCRLContext(pCrlContext);
1122 return ret;
1125 PCCRL_CONTEXT WINAPI CertEnumCRLsInStore(HCERTSTORE hCertStore,
1126 PCCRL_CONTEXT pPrev)
1128 WINECRYPT_CERTSTORE *hcs = hCertStore;
1129 PCCRL_CONTEXT ret;
1131 TRACE("(%p, %p)\n", hCertStore, pPrev);
1132 if (!hCertStore)
1133 ret = NULL;
1134 else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
1135 ret = NULL;
1136 else
1137 ret = (PCCRL_CONTEXT)hcs->crls.enumContext(hcs, (void *)pPrev);
1138 return ret;
1141 HCERTSTORE WINAPI CertDuplicateStore(HCERTSTORE hCertStore)
1143 WINECRYPT_CERTSTORE *hcs = hCertStore;
1145 TRACE("(%p)\n", hCertStore);
1147 if (hcs && hcs->dwMagic == WINE_CRYPTCERTSTORE_MAGIC)
1148 InterlockedIncrement(&hcs->ref);
1149 return hCertStore;
1152 BOOL WINAPI CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
1154 WINECRYPT_CERTSTORE *hcs = hCertStore;
1156 TRACE("(%p, %08x)\n", hCertStore, dwFlags);
1158 if( ! hCertStore )
1159 return TRUE;
1161 if ( hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC )
1162 return FALSE;
1164 if (InterlockedDecrement(&hcs->ref) == 0)
1166 TRACE("%p's ref count is 0, freeing\n", hcs);
1167 hcs->dwMagic = 0;
1168 hcs->closeStore(hcs, dwFlags);
1170 else
1171 TRACE("%p's ref count is %d\n", hcs, hcs->ref);
1172 return TRUE;
1175 BOOL WINAPI CertControlStore(HCERTSTORE hCertStore, DWORD dwFlags,
1176 DWORD dwCtrlType, void const *pvCtrlPara)
1178 WINECRYPT_CERTSTORE *hcs = hCertStore;
1179 BOOL ret;
1181 TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType,
1182 pvCtrlPara);
1184 if (!hcs)
1185 ret = FALSE;
1186 else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
1187 ret = FALSE;
1188 else
1190 if (hcs->control)
1191 ret = hcs->control(hCertStore, dwFlags, dwCtrlType, pvCtrlPara);
1192 else
1193 ret = TRUE;
1195 return ret;
1198 BOOL WINAPI CertGetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId,
1199 void *pvData, DWORD *pcbData)
1201 PWINECRYPT_CERTSTORE store = hCertStore;
1202 BOOL ret = FALSE;
1204 TRACE("(%p, %d, %p, %p)\n", hCertStore, dwPropId, pvData, pcbData);
1206 switch (dwPropId)
1208 case CERT_ACCESS_STATE_PROP_ID:
1209 if (!pvData)
1211 *pcbData = sizeof(DWORD);
1212 ret = TRUE;
1214 else if (*pcbData < sizeof(DWORD))
1216 SetLastError(ERROR_MORE_DATA);
1217 *pcbData = sizeof(DWORD);
1219 else
1221 DWORD state = 0;
1223 if (store->type != StoreTypeMem &&
1224 !(store->dwOpenFlags & CERT_STORE_READONLY_FLAG))
1225 state |= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG;
1226 *(DWORD *)pvData = state;
1227 ret = TRUE;
1229 break;
1230 default:
1231 if (store->properties)
1233 CRYPT_DATA_BLOB blob;
1235 ret = ContextPropertyList_FindProperty(store->properties, dwPropId,
1236 &blob);
1237 if (ret)
1239 if (!pvData)
1240 *pcbData = blob.cbData;
1241 else if (*pcbData < blob.cbData)
1243 SetLastError(ERROR_MORE_DATA);
1244 *pcbData = blob.cbData;
1245 ret = FALSE;
1247 else
1249 memcpy(pvData, blob.pbData, blob.cbData);
1250 *pcbData = blob.cbData;
1253 else
1254 SetLastError(CRYPT_E_NOT_FOUND);
1256 else
1257 SetLastError(CRYPT_E_NOT_FOUND);
1259 return ret;
1262 BOOL WINAPI CertSetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId,
1263 DWORD dwFlags, const void *pvData)
1265 PWINECRYPT_CERTSTORE store = hCertStore;
1266 BOOL ret = FALSE;
1268 TRACE("(%p, %d, %08x, %p)\n", hCertStore, dwPropId, dwFlags, pvData);
1270 if (!store->properties)
1271 store->properties = ContextPropertyList_Create();
1272 switch (dwPropId)
1274 case CERT_ACCESS_STATE_PROP_ID:
1275 SetLastError(E_INVALIDARG);
1276 break;
1277 default:
1278 if (pvData)
1280 const CRYPT_DATA_BLOB *blob = pvData;
1282 ret = ContextPropertyList_SetProperty(store->properties, dwPropId,
1283 blob->pbData, blob->cbData);
1285 else
1287 ContextPropertyList_RemoveProperty(store->properties, dwPropId);
1288 ret = TRUE;
1291 return ret;
1294 static LONG CRYPT_OpenParentStore(DWORD dwFlags,
1295 void *pvSystemStoreLocationPara, HKEY *key)
1297 HKEY root;
1298 LPCWSTR base;
1300 TRACE("(%08x, %p)\n", dwFlags, pvSystemStoreLocationPara);
1302 switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
1304 case CERT_SYSTEM_STORE_LOCAL_MACHINE:
1305 root = HKEY_LOCAL_MACHINE;
1306 base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
1307 break;
1308 case CERT_SYSTEM_STORE_CURRENT_USER:
1309 root = HKEY_CURRENT_USER;
1310 base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
1311 break;
1312 case CERT_SYSTEM_STORE_CURRENT_SERVICE:
1313 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
1314 * SystemCertificates
1316 FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE\n");
1317 return ERROR_FILE_NOT_FOUND;
1318 case CERT_SYSTEM_STORE_SERVICES:
1319 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
1320 * SystemCertificates
1322 FIXME("CERT_SYSTEM_STORE_SERVICES\n");
1323 return ERROR_FILE_NOT_FOUND;
1324 case CERT_SYSTEM_STORE_USERS:
1325 /* hku\user sid\Software\Microsoft\SystemCertificates */
1326 FIXME("CERT_SYSTEM_STORE_USERS\n");
1327 return ERROR_FILE_NOT_FOUND;
1328 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY:
1329 root = HKEY_CURRENT_USER;
1330 base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
1331 break;
1332 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY:
1333 root = HKEY_LOCAL_MACHINE;
1334 base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
1335 break;
1336 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE:
1337 /* hklm\Software\Microsoft\EnterpriseCertificates */
1338 FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE\n");
1339 return ERROR_FILE_NOT_FOUND;
1340 default:
1341 return ERROR_FILE_NOT_FOUND;
1344 return RegOpenKeyExW(root, base, 0, KEY_READ, key);
1347 BOOL WINAPI CertEnumSystemStore(DWORD dwFlags, void *pvSystemStoreLocationPara,
1348 void *pvArg, PFN_CERT_ENUM_SYSTEM_STORE pfnEnum)
1350 BOOL ret = FALSE;
1351 LONG rc;
1352 HKEY key;
1353 CERT_SYSTEM_STORE_INFO info = { sizeof(info) };
1355 TRACE("(%08x, %p, %p, %p)\n", dwFlags, pvSystemStoreLocationPara, pvArg,
1356 pfnEnum);
1358 rc = CRYPT_OpenParentStore(dwFlags, pvArg, &key);
1359 if (!rc)
1361 DWORD index = 0;
1363 ret = TRUE;
1364 do {
1365 WCHAR name[MAX_PATH];
1366 DWORD size = sizeof(name) / sizeof(name[0]);
1368 rc = RegEnumKeyExW(key, index++, name, &size, NULL, NULL, NULL,
1369 NULL);
1370 if (!rc)
1371 ret = pfnEnum(name, dwFlags, &info, NULL, pvArg);
1372 } while (ret && !rc);
1373 if (ret && rc != ERROR_NO_MORE_ITEMS)
1374 SetLastError(rc);
1376 else
1377 SetLastError(rc);
1378 /* Include root store for the local machine location (it isn't in the
1379 * registry)
1381 if (ret && (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) ==
1382 CERT_SYSTEM_STORE_LOCAL_MACHINE)
1383 ret = pfnEnum(rootW, dwFlags, &info, NULL, pvArg);
1384 return ret;
1387 BOOL WINAPI CertEnumPhysicalStore(const void *pvSystemStore, DWORD dwFlags,
1388 void *pvArg, PFN_CERT_ENUM_PHYSICAL_STORE pfnEnum)
1390 if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG)
1391 FIXME("(%p, %08x, %p, %p): stub\n", pvSystemStore, dwFlags, pvArg,
1392 pfnEnum);
1393 else
1394 FIXME("(%s, %08x, %p, %p): stub\n", debugstr_w(pvSystemStore),
1395 dwFlags, pvArg,
1396 pfnEnum);
1397 return FALSE;