wintrust: Don't prefer native version.
[wine/multimedia.git] / dlls / crypt32 / store.c
blob8a710a19f284aa47a29019cbe286b5a0d0120818
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 } WINE_MEMSTORE, *PWINE_MEMSTORE;
96 typedef struct _WINE_MSGSTOREINFO
98 DWORD dwOpenFlags;
99 HCERTSTORE memStore;
100 HCRYPTMSG msg;
101 } WINE_MSGSTOREINFO, *PWINE_MSGSTOREINFO;
103 void CRYPT_InitStore(WINECRYPT_CERTSTORE *store, DWORD dwFlags,
104 CertStoreType type)
106 store->ref = 1;
107 store->dwMagic = WINE_CRYPTCERTSTORE_MAGIC;
108 store->type = type;
109 store->dwOpenFlags = dwFlags;
110 store->properties = NULL;
113 void CRYPT_FreeStore(PWINECRYPT_CERTSTORE store)
115 if (store->properties)
116 ContextPropertyList_Free(store->properties);
117 CryptMemFree(store);
120 static BOOL CRYPT_MemAddCert(PWINECRYPT_CERTSTORE store, void *cert,
121 void *toReplace, const void **ppStoreContext)
123 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
124 PCERT_CONTEXT context;
126 TRACE("(%p, %p, %p, %p)\n", store, cert, toReplace, ppStoreContext);
128 context = (PCERT_CONTEXT)ContextList_Add(ms->certs, cert, toReplace);
129 if (context)
131 context->hCertStore = store;
132 if (ppStoreContext)
133 *ppStoreContext = CertDuplicateCertificateContext(context);
135 return context ? TRUE : FALSE;
138 static void *CRYPT_MemEnumCert(PWINECRYPT_CERTSTORE store, void *pPrev)
140 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
141 void *ret;
143 TRACE("(%p, %p)\n", store, pPrev);
145 ret = ContextList_Enum(ms->certs, pPrev);
146 if (!ret)
147 SetLastError(CRYPT_E_NOT_FOUND);
149 TRACE("returning %p\n", ret);
150 return ret;
153 static BOOL CRYPT_MemDeleteCert(PWINECRYPT_CERTSTORE store, void *pCertContext)
155 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
157 ContextList_Delete(ms->certs, pCertContext);
158 return TRUE;
161 static BOOL CRYPT_MemAddCrl(PWINECRYPT_CERTSTORE store, void *crl,
162 void *toReplace, const void **ppStoreContext)
164 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
165 PCRL_CONTEXT context;
167 TRACE("(%p, %p, %p, %p)\n", store, crl, toReplace, ppStoreContext);
169 context = (PCRL_CONTEXT)ContextList_Add(ms->crls, crl, toReplace);
170 if (context)
172 context->hCertStore = store;
173 if (ppStoreContext)
174 *ppStoreContext = CertDuplicateCRLContext(context);
176 return context ? TRUE : FALSE;
179 static void *CRYPT_MemEnumCrl(PWINECRYPT_CERTSTORE store, void *pPrev)
181 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
182 void *ret;
184 TRACE("(%p, %p)\n", store, pPrev);
186 ret = ContextList_Enum(ms->crls, pPrev);
187 if (!ret)
188 SetLastError(CRYPT_E_NOT_FOUND);
190 TRACE("returning %p\n", ret);
191 return ret;
194 static BOOL CRYPT_MemDeleteCrl(PWINECRYPT_CERTSTORE store, void *pCrlContext)
196 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
198 ContextList_Delete(ms->crls, pCrlContext);
199 return TRUE;
202 void CRYPT_EmptyStore(HCERTSTORE store)
204 PCCERT_CONTEXT cert;
205 PCCRL_CONTEXT crl;
207 do {
208 cert = CertEnumCertificatesInStore(store, NULL);
209 if (cert)
210 CertDeleteCertificateFromStore(cert);
211 } while (cert);
212 do {
213 crl = CertEnumCRLsInStore(store, NULL);
214 if (crl)
215 CertDeleteCRLFromStore(crl);
216 } while (crl);
219 static void WINAPI CRYPT_MemCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
221 WINE_MEMSTORE *store = (WINE_MEMSTORE *)hCertStore;
223 TRACE("(%p, %08x)\n", store, dwFlags);
224 if (dwFlags)
225 FIXME("Unimplemented flags: %08x\n", dwFlags);
227 ContextList_Free(store->certs);
228 ContextList_Free(store->crls);
229 CRYPT_FreeStore((PWINECRYPT_CERTSTORE)store);
232 static WINECRYPT_CERTSTORE *CRYPT_MemOpenStore(HCRYPTPROV hCryptProv,
233 DWORD dwFlags, const void *pvPara)
235 PWINE_MEMSTORE store;
237 TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
239 if (dwFlags & CERT_STORE_DELETE_FLAG)
241 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
242 store = NULL;
244 else
246 store = CryptMemAlloc(sizeof(WINE_MEMSTORE));
247 if (store)
249 memset(store, 0, sizeof(WINE_MEMSTORE));
250 CRYPT_InitStore(&store->hdr, dwFlags, StoreTypeMem);
251 store->hdr.closeStore = CRYPT_MemCloseStore;
252 store->hdr.certs.addContext = CRYPT_MemAddCert;
253 store->hdr.certs.enumContext = CRYPT_MemEnumCert;
254 store->hdr.certs.deleteContext = CRYPT_MemDeleteCert;
255 store->hdr.crls.addContext = CRYPT_MemAddCrl;
256 store->hdr.crls.enumContext = CRYPT_MemEnumCrl;
257 store->hdr.crls.deleteContext = CRYPT_MemDeleteCrl;
258 store->hdr.control = NULL;
259 store->certs = ContextList_Create(pCertInterface,
260 sizeof(CERT_CONTEXT));
261 store->crls = ContextList_Create(pCRLInterface,
262 sizeof(CRL_CONTEXT));
263 /* Mem store doesn't need crypto provider, so close it */
264 if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
265 CryptReleaseContext(hCryptProv, 0);
268 return (PWINECRYPT_CERTSTORE)store;
271 static PWINECRYPT_CERTSTORE CRYPT_SysRegOpenStoreW(HCRYPTPROV hCryptProv,
272 DWORD dwFlags, const void *pvPara)
274 static const WCHAR rootW[] = { 'R','o','o','t',0 };
275 static const WCHAR fmt[] = { '%','s','\\','%','s',0 };
276 LPCWSTR storeName = (LPCWSTR)pvPara;
277 LPWSTR storePath;
278 PWINECRYPT_CERTSTORE store = NULL;
279 HKEY root;
280 LPCWSTR base;
281 BOOL ret;
283 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
284 debugstr_w((LPCWSTR)pvPara));
286 if (!pvPara)
288 SetLastError(E_INVALIDARG);
289 return NULL;
291 if (!lstrcmpiW(storeName, rootW))
292 return CRYPT_RootOpenStore(hCryptProv, dwFlags);
294 ret = TRUE;
295 switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
297 case CERT_SYSTEM_STORE_LOCAL_MACHINE:
298 root = HKEY_LOCAL_MACHINE;
299 base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
300 break;
301 case CERT_SYSTEM_STORE_CURRENT_USER:
302 root = HKEY_CURRENT_USER;
303 base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
304 break;
305 case CERT_SYSTEM_STORE_CURRENT_SERVICE:
306 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
307 * SystemCertificates
309 FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE, %s: stub\n",
310 debugstr_w(storeName));
311 return NULL;
312 case CERT_SYSTEM_STORE_SERVICES:
313 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
314 * SystemCertificates
316 FIXME("CERT_SYSTEM_STORE_SERVICES, %s: stub\n",
317 debugstr_w(storeName));
318 return NULL;
319 case CERT_SYSTEM_STORE_USERS:
320 /* hku\user sid\Software\Microsoft\SystemCertificates */
321 FIXME("CERT_SYSTEM_STORE_USERS, %s: stub\n",
322 debugstr_w(storeName));
323 return NULL;
324 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY:
325 root = HKEY_CURRENT_USER;
326 base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
327 break;
328 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY:
329 root = HKEY_LOCAL_MACHINE;
330 base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
331 break;
332 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE:
333 /* hklm\Software\Microsoft\EnterpriseCertificates */
334 FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, %s: stub\n",
335 debugstr_w(storeName));
336 return NULL;
337 default:
338 SetLastError(E_INVALIDARG);
339 return NULL;
342 storePath = CryptMemAlloc((lstrlenW(base) + lstrlenW(storeName) + 2) *
343 sizeof(WCHAR));
344 if (storePath)
346 LONG rc;
347 HKEY key;
348 REGSAM sam = dwFlags & CERT_STORE_READONLY_FLAG ? KEY_READ :
349 KEY_ALL_ACCESS;
351 wsprintfW(storePath, fmt, base, storeName);
352 if (dwFlags & CERT_STORE_OPEN_EXISTING_FLAG)
353 rc = RegOpenKeyExW(root, storePath, 0, sam, &key);
354 else
356 DWORD disp;
358 rc = RegCreateKeyExW(root, storePath, 0, NULL, 0, sam, NULL,
359 &key, &disp);
360 if (!rc && dwFlags & CERT_STORE_CREATE_NEW_FLAG &&
361 disp == REG_OPENED_EXISTING_KEY)
363 RegCloseKey(key);
364 rc = ERROR_FILE_EXISTS;
367 if (!rc)
369 store = CRYPT_RegOpenStore(hCryptProv, dwFlags, key);
370 RegCloseKey(key);
372 else
373 SetLastError(rc);
374 CryptMemFree(storePath);
376 return store;
379 static PWINECRYPT_CERTSTORE CRYPT_SysRegOpenStoreA(HCRYPTPROV hCryptProv,
380 DWORD dwFlags, const void *pvPara)
382 int len;
383 PWINECRYPT_CERTSTORE ret = NULL;
385 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
386 debugstr_a((LPCSTR)pvPara));
388 if (!pvPara)
390 SetLastError(ERROR_FILE_NOT_FOUND);
391 return NULL;
393 len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, NULL, 0);
394 if (len)
396 LPWSTR storeName = CryptMemAlloc(len * sizeof(WCHAR));
398 if (storeName)
400 MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, storeName, len);
401 ret = CRYPT_SysRegOpenStoreW(hCryptProv, dwFlags, storeName);
402 CryptMemFree(storeName);
405 return ret;
408 static PWINECRYPT_CERTSTORE CRYPT_SysOpenStoreW(HCRYPTPROV hCryptProv,
409 DWORD dwFlags, const void *pvPara)
411 HCERTSTORE store = 0;
412 BOOL ret;
414 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
415 debugstr_w((LPCWSTR)pvPara));
417 if (!pvPara)
419 SetLastError(ERROR_FILE_NOT_FOUND);
420 return NULL;
422 /* This returns a different error than system registry stores if the
423 * location is invalid.
425 switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
427 case CERT_SYSTEM_STORE_LOCAL_MACHINE:
428 case CERT_SYSTEM_STORE_CURRENT_USER:
429 case CERT_SYSTEM_STORE_CURRENT_SERVICE:
430 case CERT_SYSTEM_STORE_SERVICES:
431 case CERT_SYSTEM_STORE_USERS:
432 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY:
433 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY:
434 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE:
435 ret = TRUE;
436 break;
437 default:
438 SetLastError(ERROR_FILE_NOT_FOUND);
439 ret = FALSE;
441 if (ret)
443 HCERTSTORE regStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,
444 0, 0, dwFlags, pvPara);
446 if (regStore)
448 store = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
449 CERT_STORE_CREATE_NEW_FLAG, NULL);
450 CertAddStoreToCollection(store, regStore,
451 dwFlags & CERT_STORE_READONLY_FLAG ? 0 :
452 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
453 CertCloseStore(regStore, 0);
454 /* CERT_SYSTEM_STORE_CURRENT_USER returns both the HKCU and HKLM
455 * stores.
457 if ((dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) ==
458 CERT_SYSTEM_STORE_CURRENT_USER)
460 dwFlags &= ~CERT_SYSTEM_STORE_CURRENT_USER;
461 dwFlags |= CERT_SYSTEM_STORE_LOCAL_MACHINE;
462 regStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0,
463 0, dwFlags, pvPara);
464 if (regStore)
466 CertAddStoreToCollection(store, regStore,
467 dwFlags & CERT_STORE_READONLY_FLAG ? 0 :
468 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
469 CertCloseStore(regStore, 0);
472 /* System store doesn't need crypto provider, so close it */
473 if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
474 CryptReleaseContext(hCryptProv, 0);
477 return (PWINECRYPT_CERTSTORE)store;
480 static PWINECRYPT_CERTSTORE CRYPT_SysOpenStoreA(HCRYPTPROV hCryptProv,
481 DWORD dwFlags, const void *pvPara)
483 int len;
484 PWINECRYPT_CERTSTORE ret = NULL;
486 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
487 debugstr_a((LPCSTR)pvPara));
489 if (!pvPara)
491 SetLastError(ERROR_FILE_NOT_FOUND);
492 return NULL;
494 len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, NULL, 0);
495 if (len)
497 LPWSTR storeName = CryptMemAlloc(len * sizeof(WCHAR));
499 if (storeName)
501 MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, storeName, len);
502 ret = CRYPT_SysOpenStoreW(hCryptProv, dwFlags, storeName);
503 CryptMemFree(storeName);
506 return ret;
509 static void WINAPI CRYPT_MsgCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
511 PWINE_MSGSTOREINFO store = (PWINE_MSGSTOREINFO)hCertStore;
513 TRACE("(%p, %08x)\n", store, dwFlags);
514 CertCloseStore(store->memStore, dwFlags);
515 CryptMsgClose(store->msg);
516 CryptMemFree(store);
519 static void *msgProvFuncs[] = {
520 CRYPT_MsgCloseStore,
521 NULL, /* CERT_STORE_PROV_READ_CERT_FUNC */
522 NULL, /* CERT_STORE_PROV_WRITE_CERT_FUNC */
523 NULL, /* CERT_STORE_PROV_DELETE_CERT_FUNC */
524 NULL, /* CERT_STORE_PROV_SET_CERT_PROPERTY_FUNC */
525 NULL, /* CERT_STORE_PROV_READ_CRL_FUNC */
526 NULL, /* CERT_STORE_PROV_WRITE_CRL_FUNC */
527 NULL, /* CERT_STORE_PROV_DELETE_CRL_FUNC */
528 NULL, /* CERT_STORE_PROV_SET_CRL_PROPERTY_FUNC */
529 NULL, /* CERT_STORE_PROV_READ_CTL_FUNC */
530 NULL, /* CERT_STORE_PROV_WRITE_CTL_FUNC */
531 NULL, /* CERT_STORE_PROV_DELETE_CTL_FUNC */
532 NULL, /* CERT_STORE_PROV_SET_CTL_PROPERTY_FUNC */
533 NULL, /* CERT_STORE_PROV_CONTROL_FUNC */
536 static PWINECRYPT_CERTSTORE CRYPT_MsgOpenStore(HCRYPTPROV hCryptProv,
537 DWORD dwFlags, const void *pvPara)
539 PWINECRYPT_CERTSTORE store = NULL;
540 HCRYPTMSG msg = (HCRYPTMSG)pvPara;
541 PWINECRYPT_CERTSTORE memStore;
543 TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
545 memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
546 CERT_STORE_CREATE_NEW_FLAG, NULL);
547 if (memStore)
549 BOOL ret;
550 DWORD size, count, i;
552 size = sizeof(count);
553 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &count, &size);
554 for (i = 0; ret && i < count; i++)
556 size = 0;
557 ret = CryptMsgGetParam(msg, CMSG_CERT_PARAM, i, NULL, &size);
558 if (ret)
560 LPBYTE buf = CryptMemAlloc(size);
562 if (buf)
564 ret = CryptMsgGetParam(msg, CMSG_CERT_PARAM, i, buf, &size);
565 if (ret)
566 ret = CertAddEncodedCertificateToStore(memStore,
567 X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_ALWAYS,
568 NULL);
569 CryptMemFree(buf);
573 size = sizeof(count);
574 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &count, &size);
575 for (i = 0; ret && i < count; i++)
577 size = 0;
578 ret = CryptMsgGetParam(msg, CMSG_CRL_PARAM, i, NULL, &size);
579 if (ret)
581 LPBYTE buf = CryptMemAlloc(size);
583 if (buf)
585 ret = CryptMsgGetParam(msg, CMSG_CRL_PARAM, i, buf, &size);
586 if (ret)
587 ret = CertAddEncodedCRLToStore(memStore,
588 X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_ALWAYS,
589 NULL);
590 CryptMemFree(buf);
594 if (ret)
596 PWINE_MSGSTOREINFO info = CryptMemAlloc(sizeof(WINE_MSGSTOREINFO));
598 if (info)
600 CERT_STORE_PROV_INFO provInfo = { 0 };
602 info->dwOpenFlags = dwFlags;
603 info->memStore = memStore;
604 info->msg = CryptMsgDuplicate(msg);
605 provInfo.cbSize = sizeof(provInfo);
606 provInfo.cStoreProvFunc = sizeof(msgProvFuncs) /
607 sizeof(msgProvFuncs[0]);
608 provInfo.rgpvStoreProvFunc = msgProvFuncs;
609 provInfo.hStoreProv = info;
610 store = CRYPT_ProvCreateStore(dwFlags, memStore,
611 &provInfo);
612 /* Msg store doesn't need crypto provider, so close it */
613 if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
614 CryptReleaseContext(hCryptProv, 0);
616 else
617 CertCloseStore(memStore, 0);
619 else
620 CertCloseStore(memStore, 0);
622 TRACE("returning %p\n", store);
623 return store;
626 static PWINECRYPT_CERTSTORE CRYPT_PKCSOpenStore(HCRYPTPROV hCryptProv,
627 DWORD dwFlags, const void *pvPara)
629 HCRYPTMSG msg;
630 PWINECRYPT_CERTSTORE store = NULL;
631 const CRYPT_DATA_BLOB *data = (const CRYPT_DATA_BLOB *)pvPara;
632 BOOL ret;
633 DWORD msgOpenFlags = dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG ? 0 :
634 CMSG_CRYPT_RELEASE_CONTEXT_FLAG;
636 TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
638 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, msgOpenFlags, CMSG_SIGNED,
639 hCryptProv, NULL, NULL);
640 ret = CryptMsgUpdate(msg, data->pbData, data->cbData, TRUE);
641 if (!ret)
643 CryptMsgClose(msg);
644 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, msgOpenFlags, 0,
645 hCryptProv, NULL, NULL);
646 ret = CryptMsgUpdate(msg, data->pbData, data->cbData, TRUE);
647 if (ret)
649 DWORD type, size = sizeof(type);
651 /* Only signed messages are allowed, check type */
652 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &type, &size);
653 if (ret && type != CMSG_SIGNED)
655 SetLastError(CRYPT_E_INVALID_MSG_TYPE);
656 ret = FALSE;
660 if (ret)
661 store = CRYPT_MsgOpenStore(0, dwFlags, msg);
662 CryptMsgClose(msg);
663 TRACE("returning %p\n", store);
664 return store;
667 static PWINECRYPT_CERTSTORE CRYPT_PhysOpenStoreW(HCRYPTPROV hCryptProv,
668 DWORD dwFlags, const void *pvPara)
670 if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG)
671 FIXME("(%ld, %08x, %p): stub\n", hCryptProv, dwFlags, pvPara);
672 else
673 FIXME("(%ld, %08x, %s): stub\n", hCryptProv, dwFlags,
674 debugstr_w((LPCWSTR)pvPara));
675 return NULL;
678 HCERTSTORE WINAPI CertOpenStore(LPCSTR lpszStoreProvider,
679 DWORD dwMsgAndCertEncodingType, HCRYPTPROV_LEGACY hCryptProv, DWORD dwFlags,
680 const void* pvPara)
682 WINECRYPT_CERTSTORE *hcs;
683 StoreOpenFunc openFunc = NULL;
685 TRACE("(%s, %08x, %08lx, %08x, %p)\n", debugstr_a(lpszStoreProvider),
686 dwMsgAndCertEncodingType, hCryptProv, dwFlags, pvPara);
688 if (!HIWORD(lpszStoreProvider))
690 switch (LOWORD(lpszStoreProvider))
692 case (int)CERT_STORE_PROV_MSG:
693 openFunc = CRYPT_MsgOpenStore;
694 break;
695 case (int)CERT_STORE_PROV_MEMORY:
696 openFunc = CRYPT_MemOpenStore;
697 break;
698 case (int)CERT_STORE_PROV_FILE:
699 openFunc = CRYPT_FileOpenStore;
700 break;
701 case (int)CERT_STORE_PROV_PKCS7:
702 openFunc = CRYPT_PKCSOpenStore;
703 break;
704 case (int)CERT_STORE_PROV_REG:
705 openFunc = CRYPT_RegOpenStore;
706 break;
707 case (int)CERT_STORE_PROV_FILENAME_A:
708 openFunc = CRYPT_FileNameOpenStoreA;
709 break;
710 case (int)CERT_STORE_PROV_FILENAME_W:
711 openFunc = CRYPT_FileNameOpenStoreW;
712 break;
713 case (int)CERT_STORE_PROV_COLLECTION:
714 openFunc = CRYPT_CollectionOpenStore;
715 break;
716 case (int)CERT_STORE_PROV_SYSTEM_A:
717 openFunc = CRYPT_SysOpenStoreA;
718 break;
719 case (int)CERT_STORE_PROV_SYSTEM_W:
720 openFunc = CRYPT_SysOpenStoreW;
721 break;
722 case (int)CERT_STORE_PROV_SYSTEM_REGISTRY_A:
723 openFunc = CRYPT_SysRegOpenStoreA;
724 break;
725 case (int)CERT_STORE_PROV_SYSTEM_REGISTRY_W:
726 openFunc = CRYPT_SysRegOpenStoreW;
727 break;
728 case (int)CERT_STORE_PROV_PHYSICAL_W:
729 openFunc = CRYPT_PhysOpenStoreW;
730 break;
731 default:
732 if (LOWORD(lpszStoreProvider))
733 FIXME("unimplemented type %d\n", LOWORD(lpszStoreProvider));
736 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_MEMORY))
737 openFunc = CRYPT_MemOpenStore;
738 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_FILENAME_W))
739 openFunc = CRYPT_FileOpenStore;
740 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_SYSTEM))
741 openFunc = CRYPT_SysOpenStoreW;
742 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_COLLECTION))
743 openFunc = CRYPT_CollectionOpenStore;
744 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_SYSTEM_REGISTRY))
745 openFunc = CRYPT_SysRegOpenStoreW;
746 else
748 FIXME("unimplemented type %s\n", lpszStoreProvider);
749 openFunc = NULL;
752 if (!openFunc)
753 hcs = CRYPT_ProvOpenStore(lpszStoreProvider, dwMsgAndCertEncodingType,
754 hCryptProv, dwFlags, pvPara);
755 else
756 hcs = openFunc(hCryptProv, dwFlags, pvPara);
757 return (HCERTSTORE)hcs;
760 HCERTSTORE WINAPI CertOpenSystemStoreA(HCRYPTPROV_LEGACY hProv,
761 LPCSTR szSubSystemProtocol)
763 if (!szSubSystemProtocol)
765 SetLastError(E_INVALIDARG);
766 return 0;
768 return CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, hProv,
769 CERT_SYSTEM_STORE_CURRENT_USER, szSubSystemProtocol);
772 HCERTSTORE WINAPI CertOpenSystemStoreW(HCRYPTPROV_LEGACY hProv,
773 LPCWSTR szSubSystemProtocol)
775 if (!szSubSystemProtocol)
777 SetLastError(E_INVALIDARG);
778 return 0;
780 return CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, hProv,
781 CERT_SYSTEM_STORE_CURRENT_USER, szSubSystemProtocol);
784 BOOL WINAPI CertSaveStore(HCERTSTORE hCertStore, DWORD dwMsgAndCertEncodingType,
785 DWORD dwSaveAs, DWORD dwSaveTo, void* pvSaveToPara, DWORD dwFlags)
787 FIXME("(%p,%d,%d,%d,%p,%08x) stub!\n", hCertStore,
788 dwMsgAndCertEncodingType, dwSaveAs, dwSaveTo, pvSaveToPara, dwFlags);
789 return TRUE;
792 #define CertContext_CopyProperties(to, from) \
793 Context_CopyProperties((to), (from), sizeof(CERT_CONTEXT))
795 BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore,
796 PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition,
797 PCCERT_CONTEXT *ppStoreContext)
799 PWINECRYPT_CERTSTORE store = (PWINECRYPT_CERTSTORE)hCertStore;
800 BOOL ret = TRUE;
801 PCCERT_CONTEXT toAdd = NULL, existing = NULL;
803 TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCertContext,
804 dwAddDisposition, ppStoreContext);
806 /* Weird case to pass a test */
807 if (dwAddDisposition == 0)
809 SetLastError(STATUS_ACCESS_VIOLATION);
810 return FALSE;
812 if (dwAddDisposition != CERT_STORE_ADD_ALWAYS)
814 BYTE hashToAdd[20];
815 DWORD size = sizeof(hashToAdd);
817 ret = CertGetCertificateContextProperty(pCertContext, CERT_HASH_PROP_ID,
818 hashToAdd, &size);
819 if (ret)
821 CRYPT_HASH_BLOB blob = { sizeof(hashToAdd), hashToAdd };
823 existing = CertFindCertificateInStore(hCertStore,
824 pCertContext->dwCertEncodingType, 0, CERT_FIND_SHA1_HASH, &blob,
825 NULL);
829 switch (dwAddDisposition)
831 case CERT_STORE_ADD_ALWAYS:
832 toAdd = CertDuplicateCertificateContext(pCertContext);
833 break;
834 case CERT_STORE_ADD_NEW:
835 if (existing)
837 TRACE("found matching certificate, not adding\n");
838 SetLastError(CRYPT_E_EXISTS);
839 ret = FALSE;
841 else
842 toAdd = CertDuplicateCertificateContext(pCertContext);
843 break;
844 case CERT_STORE_ADD_REPLACE_EXISTING:
845 toAdd = CertDuplicateCertificateContext(pCertContext);
846 break;
847 case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES:
848 toAdd = CertDuplicateCertificateContext(pCertContext);
849 if (existing)
850 CertContext_CopyProperties(toAdd, existing);
851 break;
852 case CERT_STORE_ADD_USE_EXISTING:
853 if (existing)
855 CertContext_CopyProperties(existing, pCertContext);
856 *ppStoreContext = CertDuplicateCertificateContext(existing);
858 else
859 toAdd = CertDuplicateCertificateContext(pCertContext);
860 break;
861 default:
862 FIXME("Unimplemented add disposition %d\n", dwAddDisposition);
863 ret = FALSE;
866 if (toAdd)
868 if (store)
869 ret = store->certs.addContext(store, (void *)toAdd,
870 (void *)existing, (const void **)ppStoreContext);
871 else if (ppStoreContext)
872 *ppStoreContext = CertDuplicateCertificateContext(toAdd);
873 CertFreeCertificateContext(toAdd);
875 CertFreeCertificateContext(existing);
877 TRACE("returning %d\n", ret);
878 return ret;
881 PCCERT_CONTEXT WINAPI CertEnumCertificatesInStore(HCERTSTORE hCertStore,
882 PCCERT_CONTEXT pPrev)
884 WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *)hCertStore;
885 PCCERT_CONTEXT ret;
887 TRACE("(%p, %p)\n", hCertStore, pPrev);
888 if (!hCertStore)
889 ret = NULL;
890 else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
891 ret = NULL;
892 else
893 ret = (PCCERT_CONTEXT)hcs->certs.enumContext(hcs, (void *)pPrev);
894 return ret;
897 BOOL WINAPI CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext)
899 BOOL ret;
901 TRACE("(%p)\n", pCertContext);
903 if (!pCertContext)
904 ret = TRUE;
905 else if (!pCertContext->hCertStore)
907 ret = TRUE;
908 CertFreeCertificateContext(pCertContext);
910 else
912 PWINECRYPT_CERTSTORE hcs =
913 (PWINECRYPT_CERTSTORE)pCertContext->hCertStore;
915 if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
916 ret = FALSE;
917 else
918 ret = hcs->certs.deleteContext(hcs, (void *)pCertContext);
919 CertFreeCertificateContext(pCertContext);
921 return ret;
924 #define CrlContext_CopyProperties(to, from) \
925 Context_CopyProperties((to), (from), sizeof(CRL_CONTEXT))
927 BOOL WINAPI CertAddCRLContextToStore(HCERTSTORE hCertStore,
928 PCCRL_CONTEXT pCrlContext, DWORD dwAddDisposition,
929 PCCRL_CONTEXT* ppStoreContext)
931 PWINECRYPT_CERTSTORE store = (PWINECRYPT_CERTSTORE)hCertStore;
932 BOOL ret = TRUE;
933 PCCRL_CONTEXT toAdd = NULL, existing = NULL;
935 TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCrlContext,
936 dwAddDisposition, ppStoreContext);
938 /* Weird case to pass a test */
939 if (dwAddDisposition == 0)
941 SetLastError(STATUS_ACCESS_VIOLATION);
942 return FALSE;
944 if (dwAddDisposition != CERT_STORE_ADD_ALWAYS)
946 existing = CertFindCRLInStore(hCertStore, 0, 0, CRL_FIND_EXISTING,
947 pCrlContext, NULL);
950 switch (dwAddDisposition)
952 case CERT_STORE_ADD_ALWAYS:
953 toAdd = CertDuplicateCRLContext(pCrlContext);
954 break;
955 case CERT_STORE_ADD_NEW:
956 if (existing)
958 TRACE("found matching CRL, not adding\n");
959 SetLastError(CRYPT_E_EXISTS);
960 ret = FALSE;
962 else
963 toAdd = CertDuplicateCRLContext(pCrlContext);
964 break;
965 case CERT_STORE_ADD_NEWER:
966 if (existing)
968 LONG newer = CompareFileTime(&existing->pCrlInfo->ThisUpdate,
969 &pCrlContext->pCrlInfo->ThisUpdate);
971 if (newer < 0)
972 toAdd = CertDuplicateCRLContext(pCrlContext);
973 else
975 TRACE("existing CRL is newer, not adding\n");
976 SetLastError(CRYPT_E_EXISTS);
977 ret = FALSE;
980 else
981 toAdd = CertDuplicateCRLContext(pCrlContext);
982 break;
983 case CERT_STORE_ADD_REPLACE_EXISTING:
984 toAdd = CertDuplicateCRLContext(pCrlContext);
985 break;
986 case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES:
987 toAdd = CertDuplicateCRLContext(pCrlContext);
988 if (existing)
989 CrlContext_CopyProperties(toAdd, existing);
990 break;
991 case CERT_STORE_ADD_USE_EXISTING:
992 if (existing)
993 CrlContext_CopyProperties(existing, pCrlContext);
994 break;
995 default:
996 FIXME("Unimplemented add disposition %d\n", dwAddDisposition);
997 ret = FALSE;
1000 if (toAdd)
1002 if (store)
1003 ret = store->crls.addContext(store, (void *)toAdd,
1004 (void *)existing, (const void **)ppStoreContext);
1005 else if (ppStoreContext)
1006 *ppStoreContext = CertDuplicateCRLContext(toAdd);
1007 CertFreeCRLContext(toAdd);
1009 CertFreeCRLContext(existing);
1011 TRACE("returning %d\n", ret);
1012 return ret;
1015 BOOL WINAPI CertDeleteCRLFromStore(PCCRL_CONTEXT pCrlContext)
1017 BOOL ret;
1019 TRACE("(%p)\n", pCrlContext);
1021 if (!pCrlContext)
1022 ret = TRUE;
1023 else if (!pCrlContext->hCertStore)
1025 ret = TRUE;
1026 CertFreeCRLContext(pCrlContext);
1028 else
1030 PWINECRYPT_CERTSTORE hcs =
1031 (PWINECRYPT_CERTSTORE)pCrlContext->hCertStore;
1033 if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
1034 ret = FALSE;
1035 else
1036 ret = hcs->crls.deleteContext(hcs, (void *)pCrlContext);
1037 CertFreeCRLContext(pCrlContext);
1039 return ret;
1042 PCCRL_CONTEXT WINAPI CertEnumCRLsInStore(HCERTSTORE hCertStore,
1043 PCCRL_CONTEXT pPrev)
1045 WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *)hCertStore;
1046 PCCRL_CONTEXT ret;
1048 TRACE("(%p, %p)\n", hCertStore, pPrev);
1049 if (!hCertStore)
1050 ret = NULL;
1051 else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
1052 ret = NULL;
1053 else
1054 ret = (PCCRL_CONTEXT)hcs->crls.enumContext(hcs, (void *)pPrev);
1055 return ret;
1058 PCCTL_CONTEXT WINAPI CertCreateCTLContext(DWORD dwCertEncodingType,
1059 const BYTE* pbCtlEncoded, DWORD cbCtlEncoded)
1061 FIXME("(%08x, %p, %08x): stub\n", dwCertEncodingType, pbCtlEncoded,
1062 cbCtlEncoded);
1063 return NULL;
1066 BOOL WINAPI CertAddEncodedCTLToStore(HCERTSTORE hCertStore,
1067 DWORD dwMsgAndCertEncodingType, const BYTE *pbCtlEncoded, DWORD cbCtlEncoded,
1068 DWORD dwAddDisposition, PCCTL_CONTEXT *ppCtlContext)
1070 FIXME("(%p, %08x, %p, %d, %08x, %p): stub\n", hCertStore,
1071 dwMsgAndCertEncodingType, pbCtlEncoded, cbCtlEncoded, dwAddDisposition,
1072 ppCtlContext);
1073 return FALSE;
1076 BOOL WINAPI CertAddCTLContextToStore(HCERTSTORE hCertStore,
1077 PCCTL_CONTEXT pCtlContext, DWORD dwAddDisposition,
1078 PCCTL_CONTEXT* ppStoreContext)
1080 FIXME("(%p, %p, %08x, %p): stub\n", hCertStore, pCtlContext,
1081 dwAddDisposition, ppStoreContext);
1082 return TRUE;
1085 PCCTL_CONTEXT WINAPI CertDuplicateCTLContext(PCCTL_CONTEXT pCtlContext)
1087 FIXME("(%p): stub\n", pCtlContext );
1088 return pCtlContext;
1091 BOOL WINAPI CertFreeCTLContext(PCCTL_CONTEXT pCtlContext)
1093 FIXME("(%p): stub\n", pCtlContext );
1094 return TRUE;
1097 BOOL WINAPI CertDeleteCTLFromStore(PCCTL_CONTEXT pCtlContext)
1099 FIXME("(%p): stub\n", pCtlContext);
1100 return TRUE;
1103 PCCTL_CONTEXT WINAPI CertEnumCTLsInStore(HCERTSTORE hCertStore,
1104 PCCTL_CONTEXT pPrev)
1106 FIXME("(%p, %p): stub\n", hCertStore, pPrev);
1107 return NULL;
1110 HCERTSTORE WINAPI CertDuplicateStore(HCERTSTORE hCertStore)
1112 WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *)hCertStore;
1114 TRACE("(%p)\n", hCertStore);
1116 if (hcs && hcs->dwMagic == WINE_CRYPTCERTSTORE_MAGIC)
1117 InterlockedIncrement(&hcs->ref);
1118 return hCertStore;
1121 BOOL WINAPI CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
1123 WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *) hCertStore;
1125 TRACE("(%p, %08x)\n", hCertStore, dwFlags);
1127 if( ! hCertStore )
1128 return TRUE;
1130 if ( hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC )
1131 return FALSE;
1133 if (InterlockedDecrement(&hcs->ref) == 0)
1135 TRACE("%p's ref count is 0, freeing\n", hcs);
1136 hcs->dwMagic = 0;
1137 hcs->closeStore(hcs, dwFlags);
1139 else
1140 TRACE("%p's ref count is %d\n", hcs, hcs->ref);
1141 return TRUE;
1144 BOOL WINAPI CertControlStore(HCERTSTORE hCertStore, DWORD dwFlags,
1145 DWORD dwCtrlType, void const *pvCtrlPara)
1147 WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *)hCertStore;
1148 BOOL ret;
1150 TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType,
1151 pvCtrlPara);
1153 if (!hcs)
1154 ret = FALSE;
1155 else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
1156 ret = FALSE;
1157 else
1159 if (hcs->control)
1160 ret = hcs->control(hCertStore, dwFlags, dwCtrlType, pvCtrlPara);
1161 else
1162 ret = TRUE;
1164 return ret;
1167 BOOL WINAPI CertGetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId,
1168 void *pvData, DWORD *pcbData)
1170 PWINECRYPT_CERTSTORE store = (PWINECRYPT_CERTSTORE)hCertStore;
1171 BOOL ret = FALSE;
1173 TRACE("(%p, %d, %p, %p)\n", hCertStore, dwPropId, pvData, pcbData);
1175 switch (dwPropId)
1177 case CERT_ACCESS_STATE_PROP_ID:
1178 if (!pvData)
1180 *pcbData = sizeof(DWORD);
1181 ret = TRUE;
1183 else if (*pcbData < sizeof(DWORD))
1185 SetLastError(ERROR_MORE_DATA);
1186 *pcbData = sizeof(DWORD);
1188 else
1190 DWORD state = 0;
1192 if (store->type != StoreTypeMem &&
1193 !(store->dwOpenFlags & CERT_STORE_READONLY_FLAG))
1194 state |= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG;
1195 *(DWORD *)pvData = state;
1196 ret = TRUE;
1198 break;
1199 default:
1200 if (store->properties)
1202 CRYPT_DATA_BLOB blob;
1204 ret = ContextPropertyList_FindProperty(store->properties, dwPropId,
1205 &blob);
1206 if (ret)
1208 if (!pvData)
1209 *pcbData = blob.cbData;
1210 else if (*pcbData < blob.cbData)
1212 SetLastError(ERROR_MORE_DATA);
1213 *pcbData = blob.cbData;
1214 ret = FALSE;
1216 else
1218 memcpy(pvData, blob.pbData, blob.cbData);
1219 *pcbData = blob.cbData;
1222 else
1223 SetLastError(CRYPT_E_NOT_FOUND);
1225 else
1226 SetLastError(CRYPT_E_NOT_FOUND);
1228 return ret;
1231 BOOL WINAPI CertSetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId,
1232 DWORD dwFlags, const void *pvData)
1234 PWINECRYPT_CERTSTORE store = (PWINECRYPT_CERTSTORE)hCertStore;
1235 BOOL ret = FALSE;
1237 TRACE("(%p, %d, %08x, %p)\n", hCertStore, dwPropId, dwFlags, pvData);
1239 if (!store->properties)
1240 store->properties = ContextPropertyList_Create();
1241 switch (dwPropId)
1243 case CERT_ACCESS_STATE_PROP_ID:
1244 SetLastError(E_INVALIDARG);
1245 break;
1246 default:
1247 if (pvData)
1249 const CRYPT_DATA_BLOB *blob = (const CRYPT_DATA_BLOB *)pvData;
1251 ret = ContextPropertyList_SetProperty(store->properties, dwPropId,
1252 blob->pbData, blob->cbData);
1254 else
1256 ContextPropertyList_RemoveProperty(store->properties, dwPropId);
1257 ret = TRUE;
1260 return ret;
1263 DWORD WINAPI CertEnumCTLContextProperties(PCCTL_CONTEXT pCTLContext,
1264 DWORD dwPropId)
1266 FIXME("(%p, %d): stub\n", pCTLContext, dwPropId);
1267 return 0;
1270 BOOL WINAPI CertGetCTLContextProperty(PCCTL_CONTEXT pCTLContext,
1271 DWORD dwPropId, void *pvData, DWORD *pcbData)
1273 FIXME("(%p, %d, %p, %p): stub\n", pCTLContext, dwPropId, pvData, pcbData);
1274 return FALSE;
1277 BOOL WINAPI CertSetCTLContextProperty(PCCTL_CONTEXT pCTLContext,
1278 DWORD dwPropId, DWORD dwFlags, const void *pvData)
1280 FIXME("(%p, %d, %08x, %p): stub\n", pCTLContext, dwPropId, dwFlags,
1281 pvData);
1282 return FALSE;
1285 static LONG CRYPT_OpenParentStore(DWORD dwFlags,
1286 void *pvSystemStoreLocationPara, HKEY *key)
1288 HKEY root;
1289 LPCWSTR base;
1291 TRACE("(%08x, %p)\n", dwFlags, pvSystemStoreLocationPara);
1293 switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
1295 case CERT_SYSTEM_STORE_LOCAL_MACHINE:
1296 root = HKEY_LOCAL_MACHINE;
1297 base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
1298 break;
1299 case CERT_SYSTEM_STORE_CURRENT_USER:
1300 root = HKEY_CURRENT_USER;
1301 base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
1302 break;
1303 case CERT_SYSTEM_STORE_CURRENT_SERVICE:
1304 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
1305 * SystemCertificates
1307 FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE\n");
1308 return ERROR_FILE_NOT_FOUND;
1309 case CERT_SYSTEM_STORE_SERVICES:
1310 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
1311 * SystemCertificates
1313 FIXME("CERT_SYSTEM_STORE_SERVICES\n");
1314 return ERROR_FILE_NOT_FOUND;
1315 case CERT_SYSTEM_STORE_USERS:
1316 /* hku\user sid\Software\Microsoft\SystemCertificates */
1317 FIXME("CERT_SYSTEM_STORE_USERS\n");
1318 return ERROR_FILE_NOT_FOUND;
1319 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY:
1320 root = HKEY_CURRENT_USER;
1321 base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
1322 break;
1323 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY:
1324 root = HKEY_LOCAL_MACHINE;
1325 base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
1326 break;
1327 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE:
1328 /* hklm\Software\Microsoft\EnterpriseCertificates */
1329 FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE\n");
1330 return ERROR_FILE_NOT_FOUND;
1331 default:
1332 return ERROR_FILE_NOT_FOUND;
1335 return RegOpenKeyExW(root, base, 0, KEY_READ, key);
1338 BOOL WINAPI CertEnumSystemStore(DWORD dwFlags, void *pvSystemStoreLocationPara,
1339 void *pvArg, PFN_CERT_ENUM_SYSTEM_STORE pfnEnum)
1341 BOOL ret = FALSE;
1342 LONG rc;
1343 HKEY key;
1345 TRACE("(%08x, %p, %p, %p)\n", dwFlags, pvSystemStoreLocationPara, pvArg,
1346 pfnEnum);
1348 rc = CRYPT_OpenParentStore(dwFlags, pvArg, &key);
1349 if (!rc)
1351 DWORD index = 0;
1352 CERT_SYSTEM_STORE_INFO info = { sizeof(info) };
1354 ret = TRUE;
1355 do {
1356 WCHAR name[MAX_PATH];
1357 DWORD size = sizeof(name) / sizeof(name[0]);
1359 rc = RegEnumKeyExW(key, index++, name, &size, NULL, NULL, NULL,
1360 NULL);
1361 if (!rc)
1362 ret = pfnEnum(name, 0, &info, NULL, pvArg);
1363 } while (ret && !rc);
1364 if (ret && rc != ERROR_NO_MORE_ITEMS)
1365 SetLastError(rc);
1367 else
1368 SetLastError(rc);
1369 return ret;