secur32: Constify some variables.
[wine/testsucceed.git] / dlls / crypt32 / store.c
blobfd7ec8ac5f1587f92caa731886423e6b37089949
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 /* FIXME: this isn't complete for the Root store, in which the top-level
272 * self-signed CA certs reside. Adding a cert to the Root store should present
273 * the user with a dialog indicating the consequences of doing so, and asking
274 * the user to confirm whether the cert should be added.
276 static PWINECRYPT_CERTSTORE CRYPT_SysRegOpenStoreW(HCRYPTPROV hCryptProv,
277 DWORD dwFlags, const void *pvPara)
279 static const WCHAR fmt[] = { '%','s','\\','%','s',0 };
280 LPCWSTR storeName = (LPCWSTR)pvPara;
281 LPWSTR storePath;
282 PWINECRYPT_CERTSTORE store = NULL;
283 HKEY root;
284 LPCWSTR base;
285 BOOL ret;
287 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
288 debugstr_w((LPCWSTR)pvPara));
290 if (!pvPara)
292 SetLastError(E_INVALIDARG);
293 return NULL;
296 ret = TRUE;
297 switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
299 case CERT_SYSTEM_STORE_LOCAL_MACHINE:
300 root = HKEY_LOCAL_MACHINE;
301 base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
302 break;
303 case CERT_SYSTEM_STORE_CURRENT_USER:
304 root = HKEY_CURRENT_USER;
305 base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
306 break;
307 case CERT_SYSTEM_STORE_CURRENT_SERVICE:
308 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
309 * SystemCertificates
311 FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE, %s: stub\n",
312 debugstr_w(storeName));
313 return NULL;
314 case CERT_SYSTEM_STORE_SERVICES:
315 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
316 * SystemCertificates
318 FIXME("CERT_SYSTEM_STORE_SERVICES, %s: stub\n",
319 debugstr_w(storeName));
320 return NULL;
321 case CERT_SYSTEM_STORE_USERS:
322 /* hku\user sid\Software\Microsoft\SystemCertificates */
323 FIXME("CERT_SYSTEM_STORE_USERS, %s: stub\n",
324 debugstr_w(storeName));
325 return NULL;
326 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY:
327 root = HKEY_CURRENT_USER;
328 base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
329 break;
330 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY:
331 root = HKEY_LOCAL_MACHINE;
332 base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
333 break;
334 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE:
335 /* hklm\Software\Microsoft\EnterpriseCertificates */
336 FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, %s: stub\n",
337 debugstr_w(storeName));
338 return NULL;
339 default:
340 SetLastError(E_INVALIDARG);
341 return NULL;
344 storePath = CryptMemAlloc((lstrlenW(base) + lstrlenW(storeName) + 2) *
345 sizeof(WCHAR));
346 if (storePath)
348 LONG rc;
349 HKEY key;
350 REGSAM sam = dwFlags & CERT_STORE_READONLY_FLAG ? KEY_READ :
351 KEY_ALL_ACCESS;
353 wsprintfW(storePath, fmt, base, storeName);
354 if (dwFlags & CERT_STORE_OPEN_EXISTING_FLAG)
355 rc = RegOpenKeyExW(root, storePath, 0, sam, &key);
356 else
358 DWORD disp;
360 rc = RegCreateKeyExW(root, storePath, 0, NULL, 0, sam, NULL,
361 &key, &disp);
362 if (!rc && dwFlags & CERT_STORE_CREATE_NEW_FLAG &&
363 disp == REG_OPENED_EXISTING_KEY)
365 RegCloseKey(key);
366 rc = ERROR_FILE_EXISTS;
369 if (!rc)
371 store = CRYPT_RegOpenStore(hCryptProv, dwFlags, key);
372 RegCloseKey(key);
374 else
375 SetLastError(rc);
376 CryptMemFree(storePath);
378 return store;
381 static PWINECRYPT_CERTSTORE CRYPT_SysRegOpenStoreA(HCRYPTPROV hCryptProv,
382 DWORD dwFlags, const void *pvPara)
384 int len;
385 PWINECRYPT_CERTSTORE ret = NULL;
387 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
388 debugstr_a((LPCSTR)pvPara));
390 if (!pvPara)
392 SetLastError(ERROR_FILE_NOT_FOUND);
393 return NULL;
395 len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, NULL, 0);
396 if (len)
398 LPWSTR storeName = CryptMemAlloc(len * sizeof(WCHAR));
400 if (storeName)
402 MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, storeName, len);
403 ret = CRYPT_SysRegOpenStoreW(hCryptProv, dwFlags, storeName);
404 CryptMemFree(storeName);
407 return ret;
410 static PWINECRYPT_CERTSTORE CRYPT_SysOpenStoreW(HCRYPTPROV hCryptProv,
411 DWORD dwFlags, const void *pvPara)
413 HCERTSTORE store = 0;
414 BOOL ret;
416 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
417 debugstr_w((LPCWSTR)pvPara));
419 if (!pvPara)
421 SetLastError(ERROR_FILE_NOT_FOUND);
422 return NULL;
424 /* This returns a different error than system registry stores if the
425 * location is invalid.
427 switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
429 case CERT_SYSTEM_STORE_LOCAL_MACHINE:
430 case CERT_SYSTEM_STORE_CURRENT_USER:
431 case CERT_SYSTEM_STORE_CURRENT_SERVICE:
432 case CERT_SYSTEM_STORE_SERVICES:
433 case CERT_SYSTEM_STORE_USERS:
434 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY:
435 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY:
436 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE:
437 ret = TRUE;
438 break;
439 default:
440 SetLastError(ERROR_FILE_NOT_FOUND);
441 ret = FALSE;
443 if (ret)
445 HCERTSTORE regStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,
446 0, 0, dwFlags, pvPara);
448 if (regStore)
450 store = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
451 CERT_STORE_CREATE_NEW_FLAG, NULL);
452 CertAddStoreToCollection(store, regStore,
453 dwFlags & CERT_STORE_READONLY_FLAG ? 0 :
454 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
455 CertCloseStore(regStore, 0);
456 /* CERT_SYSTEM_STORE_CURRENT_USER returns both the HKCU and HKLM
457 * stores.
459 if ((dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) ==
460 CERT_SYSTEM_STORE_CURRENT_USER)
462 dwFlags &= ~CERT_SYSTEM_STORE_CURRENT_USER;
463 dwFlags |= CERT_SYSTEM_STORE_LOCAL_MACHINE;
464 regStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0,
465 0, dwFlags, pvPara);
466 if (regStore)
468 CertAddStoreToCollection(store, regStore,
469 dwFlags & CERT_STORE_READONLY_FLAG ? 0 :
470 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
471 CertCloseStore(regStore, 0);
474 /* System store doesn't need crypto provider, so close it */
475 if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
476 CryptReleaseContext(hCryptProv, 0);
479 return (PWINECRYPT_CERTSTORE)store;
482 static PWINECRYPT_CERTSTORE CRYPT_SysOpenStoreA(HCRYPTPROV hCryptProv,
483 DWORD dwFlags, const void *pvPara)
485 int len;
486 PWINECRYPT_CERTSTORE ret = NULL;
488 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
489 debugstr_a((LPCSTR)pvPara));
491 if (!pvPara)
493 SetLastError(ERROR_FILE_NOT_FOUND);
494 return NULL;
496 len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, NULL, 0);
497 if (len)
499 LPWSTR storeName = CryptMemAlloc(len * sizeof(WCHAR));
501 if (storeName)
503 MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, storeName, len);
504 ret = CRYPT_SysOpenStoreW(hCryptProv, dwFlags, storeName);
505 CryptMemFree(storeName);
508 return ret;
511 static void WINAPI CRYPT_MsgCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
513 PWINE_MSGSTOREINFO store = (PWINE_MSGSTOREINFO)hCertStore;
515 TRACE("(%p, %08x)\n", store, dwFlags);
516 CertCloseStore(store->memStore, dwFlags);
517 CryptMsgClose(store->msg);
518 CryptMemFree(store);
521 static void *msgProvFuncs[] = {
522 CRYPT_MsgCloseStore,
523 NULL, /* CERT_STORE_PROV_READ_CERT_FUNC */
524 NULL, /* CERT_STORE_PROV_WRITE_CERT_FUNC */
525 NULL, /* CERT_STORE_PROV_DELETE_CERT_FUNC */
526 NULL, /* CERT_STORE_PROV_SET_CERT_PROPERTY_FUNC */
527 NULL, /* CERT_STORE_PROV_READ_CRL_FUNC */
528 NULL, /* CERT_STORE_PROV_WRITE_CRL_FUNC */
529 NULL, /* CERT_STORE_PROV_DELETE_CRL_FUNC */
530 NULL, /* CERT_STORE_PROV_SET_CRL_PROPERTY_FUNC */
531 NULL, /* CERT_STORE_PROV_READ_CTL_FUNC */
532 NULL, /* CERT_STORE_PROV_WRITE_CTL_FUNC */
533 NULL, /* CERT_STORE_PROV_DELETE_CTL_FUNC */
534 NULL, /* CERT_STORE_PROV_SET_CTL_PROPERTY_FUNC */
535 NULL, /* CERT_STORE_PROV_CONTROL_FUNC */
538 static PWINECRYPT_CERTSTORE CRYPT_MsgOpenStore(HCRYPTPROV hCryptProv,
539 DWORD dwFlags, const void *pvPara)
541 PWINECRYPT_CERTSTORE store = NULL;
542 HCRYPTMSG msg = (HCRYPTMSG)pvPara;
543 PWINECRYPT_CERTSTORE memStore;
545 TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
547 memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
548 CERT_STORE_CREATE_NEW_FLAG, NULL);
549 if (memStore)
551 BOOL ret;
552 DWORD size, count, i;
554 size = sizeof(count);
555 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &count, &size);
556 for (i = 0; ret && i < count; i++)
558 size = 0;
559 ret = CryptMsgGetParam(msg, CMSG_CERT_PARAM, i, NULL, &size);
560 if (ret)
562 LPBYTE buf = CryptMemAlloc(size);
564 if (buf)
566 ret = CryptMsgGetParam(msg, CMSG_CERT_PARAM, i, buf, &size);
567 if (ret)
568 ret = CertAddEncodedCertificateToStore(memStore,
569 X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_ALWAYS,
570 NULL);
571 CryptMemFree(buf);
575 size = sizeof(count);
576 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &count, &size);
577 for (i = 0; ret && i < count; i++)
579 size = 0;
580 ret = CryptMsgGetParam(msg, CMSG_CRL_PARAM, i, NULL, &size);
581 if (ret)
583 LPBYTE buf = CryptMemAlloc(size);
585 if (buf)
587 ret = CryptMsgGetParam(msg, CMSG_CRL_PARAM, i, buf, &size);
588 if (ret)
589 ret = CertAddEncodedCRLToStore(memStore,
590 X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_ALWAYS,
591 NULL);
592 CryptMemFree(buf);
596 if (ret)
598 PWINE_MSGSTOREINFO info = CryptMemAlloc(sizeof(WINE_MSGSTOREINFO));
600 if (info)
602 CERT_STORE_PROV_INFO provInfo = { 0 };
604 info->dwOpenFlags = dwFlags;
605 info->memStore = memStore;
606 info->msg = CryptMsgDuplicate(msg);
607 provInfo.cbSize = sizeof(provInfo);
608 provInfo.cStoreProvFunc = sizeof(msgProvFuncs) /
609 sizeof(msgProvFuncs[0]);
610 provInfo.rgpvStoreProvFunc = msgProvFuncs;
611 provInfo.hStoreProv = info;
612 store = CRYPT_ProvCreateStore(dwFlags, memStore,
613 &provInfo);
614 /* Msg store doesn't need crypto provider, so close it */
615 if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
616 CryptReleaseContext(hCryptProv, 0);
618 else
619 CertCloseStore(memStore, 0);
621 else
622 CertCloseStore(memStore, 0);
624 TRACE("returning %p\n", store);
625 return store;
628 static PWINECRYPT_CERTSTORE CRYPT_PKCSOpenStore(HCRYPTPROV hCryptProv,
629 DWORD dwFlags, const void *pvPara)
631 HCRYPTMSG msg;
632 PWINECRYPT_CERTSTORE store = NULL;
633 const CRYPT_DATA_BLOB *data = (const CRYPT_DATA_BLOB *)pvPara;
634 BOOL ret;
635 DWORD msgOpenFlags = dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG ? 0 :
636 CMSG_CRYPT_RELEASE_CONTEXT_FLAG;
638 TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
640 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, msgOpenFlags, CMSG_SIGNED,
641 hCryptProv, NULL, NULL);
642 ret = CryptMsgUpdate(msg, data->pbData, data->cbData, TRUE);
643 if (!ret)
645 CryptMsgClose(msg);
646 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, msgOpenFlags, 0,
647 hCryptProv, NULL, NULL);
648 ret = CryptMsgUpdate(msg, data->pbData, data->cbData, TRUE);
649 if (ret)
651 DWORD type, size = sizeof(type);
653 /* Only signed messages are allowed, check type */
654 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &type, &size);
655 if (ret && type != CMSG_SIGNED)
657 SetLastError(CRYPT_E_INVALID_MSG_TYPE);
658 ret = FALSE;
662 if (ret)
663 store = CRYPT_MsgOpenStore(0, dwFlags, msg);
664 CryptMsgClose(msg);
665 TRACE("returning %p\n", store);
666 return store;
669 static PWINECRYPT_CERTSTORE CRYPT_PhysOpenStoreW(HCRYPTPROV hCryptProv,
670 DWORD dwFlags, const void *pvPara)
672 if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG)
673 FIXME("(%ld, %08x, %p): stub\n", hCryptProv, dwFlags, pvPara);
674 else
675 FIXME("(%ld, %08x, %s): stub\n", hCryptProv, dwFlags,
676 debugstr_w((LPCWSTR)pvPara));
677 return NULL;
680 HCERTSTORE WINAPI CertOpenStore(LPCSTR lpszStoreProvider,
681 DWORD dwMsgAndCertEncodingType, HCRYPTPROV_LEGACY hCryptProv, DWORD dwFlags,
682 const void* pvPara)
684 WINECRYPT_CERTSTORE *hcs;
685 StoreOpenFunc openFunc = NULL;
687 TRACE("(%s, %08x, %08lx, %08x, %p)\n", debugstr_a(lpszStoreProvider),
688 dwMsgAndCertEncodingType, hCryptProv, dwFlags, pvPara);
690 if (!HIWORD(lpszStoreProvider))
692 switch (LOWORD(lpszStoreProvider))
694 case (int)CERT_STORE_PROV_MSG:
695 openFunc = CRYPT_MsgOpenStore;
696 break;
697 case (int)CERT_STORE_PROV_MEMORY:
698 openFunc = CRYPT_MemOpenStore;
699 break;
700 case (int)CERT_STORE_PROV_FILE:
701 openFunc = CRYPT_FileOpenStore;
702 break;
703 case (int)CERT_STORE_PROV_PKCS7:
704 openFunc = CRYPT_PKCSOpenStore;
705 break;
706 case (int)CERT_STORE_PROV_REG:
707 openFunc = CRYPT_RegOpenStore;
708 break;
709 case (int)CERT_STORE_PROV_FILENAME_A:
710 openFunc = CRYPT_FileNameOpenStoreA;
711 break;
712 case (int)CERT_STORE_PROV_FILENAME_W:
713 openFunc = CRYPT_FileNameOpenStoreW;
714 break;
715 case (int)CERT_STORE_PROV_COLLECTION:
716 openFunc = CRYPT_CollectionOpenStore;
717 break;
718 case (int)CERT_STORE_PROV_SYSTEM_A:
719 openFunc = CRYPT_SysOpenStoreA;
720 break;
721 case (int)CERT_STORE_PROV_SYSTEM_W:
722 openFunc = CRYPT_SysOpenStoreW;
723 break;
724 case (int)CERT_STORE_PROV_SYSTEM_REGISTRY_A:
725 openFunc = CRYPT_SysRegOpenStoreA;
726 break;
727 case (int)CERT_STORE_PROV_SYSTEM_REGISTRY_W:
728 openFunc = CRYPT_SysRegOpenStoreW;
729 break;
730 case (int)CERT_STORE_PROV_PHYSICAL_W:
731 openFunc = CRYPT_PhysOpenStoreW;
732 break;
733 default:
734 if (LOWORD(lpszStoreProvider))
735 FIXME("unimplemented type %d\n", LOWORD(lpszStoreProvider));
738 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_MEMORY))
739 openFunc = CRYPT_MemOpenStore;
740 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_FILENAME_W))
741 openFunc = CRYPT_FileOpenStore;
742 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_SYSTEM))
743 openFunc = CRYPT_SysOpenStoreW;
744 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_COLLECTION))
745 openFunc = CRYPT_CollectionOpenStore;
746 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_SYSTEM_REGISTRY))
747 openFunc = CRYPT_SysRegOpenStoreW;
748 else
750 FIXME("unimplemented type %s\n", lpszStoreProvider);
751 openFunc = NULL;
754 if (!openFunc)
755 hcs = CRYPT_ProvOpenStore(lpszStoreProvider, dwMsgAndCertEncodingType,
756 hCryptProv, dwFlags, pvPara);
757 else
758 hcs = openFunc(hCryptProv, dwFlags, pvPara);
759 return (HCERTSTORE)hcs;
762 HCERTSTORE WINAPI CertOpenSystemStoreA(HCRYPTPROV_LEGACY hProv,
763 LPCSTR szSubSystemProtocol)
765 if (!szSubSystemProtocol)
767 SetLastError(E_INVALIDARG);
768 return 0;
770 return CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, hProv,
771 CERT_SYSTEM_STORE_CURRENT_USER, szSubSystemProtocol);
774 HCERTSTORE WINAPI CertOpenSystemStoreW(HCRYPTPROV_LEGACY hProv,
775 LPCWSTR szSubSystemProtocol)
777 if (!szSubSystemProtocol)
779 SetLastError(E_INVALIDARG);
780 return 0;
782 return CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, hProv,
783 CERT_SYSTEM_STORE_CURRENT_USER, szSubSystemProtocol);
786 BOOL WINAPI CertSaveStore(HCERTSTORE hCertStore, DWORD dwMsgAndCertEncodingType,
787 DWORD dwSaveAs, DWORD dwSaveTo, void* pvSaveToPara, DWORD dwFlags)
789 FIXME("(%p,%d,%d,%d,%p,%08x) stub!\n", hCertStore,
790 dwMsgAndCertEncodingType, dwSaveAs, dwSaveTo, pvSaveToPara, dwFlags);
791 return TRUE;
794 #define CertContext_CopyProperties(to, from) \
795 Context_CopyProperties((to), (from), sizeof(CERT_CONTEXT))
797 BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore,
798 PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition,
799 PCCERT_CONTEXT *ppStoreContext)
801 PWINECRYPT_CERTSTORE store = (PWINECRYPT_CERTSTORE)hCertStore;
802 BOOL ret = TRUE;
803 PCCERT_CONTEXT toAdd = NULL, existing = NULL;
805 TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCertContext,
806 dwAddDisposition, ppStoreContext);
808 /* Weird case to pass a test */
809 if (dwAddDisposition == 0)
811 SetLastError(STATUS_ACCESS_VIOLATION);
812 return FALSE;
814 if (dwAddDisposition != CERT_STORE_ADD_ALWAYS)
816 BYTE hashToAdd[20];
817 DWORD size = sizeof(hashToAdd);
819 ret = CertGetCertificateContextProperty(pCertContext, CERT_HASH_PROP_ID,
820 hashToAdd, &size);
821 if (ret)
823 CRYPT_HASH_BLOB blob = { sizeof(hashToAdd), hashToAdd };
825 existing = CertFindCertificateInStore(hCertStore,
826 pCertContext->dwCertEncodingType, 0, CERT_FIND_SHA1_HASH, &blob,
827 NULL);
831 switch (dwAddDisposition)
833 case CERT_STORE_ADD_ALWAYS:
834 toAdd = CertDuplicateCertificateContext(pCertContext);
835 break;
836 case CERT_STORE_ADD_NEW:
837 if (existing)
839 TRACE("found matching certificate, not adding\n");
840 SetLastError(CRYPT_E_EXISTS);
841 ret = FALSE;
843 else
844 toAdd = CertDuplicateCertificateContext(pCertContext);
845 break;
846 case CERT_STORE_ADD_REPLACE_EXISTING:
847 toAdd = CertDuplicateCertificateContext(pCertContext);
848 break;
849 case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES:
850 toAdd = CertDuplicateCertificateContext(pCertContext);
851 if (existing)
852 CertContext_CopyProperties(toAdd, existing);
853 break;
854 case CERT_STORE_ADD_USE_EXISTING:
855 if (existing)
857 CertContext_CopyProperties(existing, pCertContext);
858 *ppStoreContext = CertDuplicateCertificateContext(existing);
860 else
861 toAdd = CertDuplicateCertificateContext(pCertContext);
862 break;
863 default:
864 FIXME("Unimplemented add disposition %d\n", dwAddDisposition);
865 ret = FALSE;
868 if (toAdd)
870 if (store)
871 ret = store->certs.addContext(store, (void *)toAdd,
872 (void *)existing, (const void **)ppStoreContext);
873 else if (ppStoreContext)
874 *ppStoreContext = CertDuplicateCertificateContext(toAdd);
875 CertFreeCertificateContext(toAdd);
877 CertFreeCertificateContext(existing);
879 TRACE("returning %d\n", ret);
880 return ret;
883 PCCERT_CONTEXT WINAPI CertEnumCertificatesInStore(HCERTSTORE hCertStore,
884 PCCERT_CONTEXT pPrev)
886 WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *)hCertStore;
887 PCCERT_CONTEXT ret;
889 TRACE("(%p, %p)\n", hCertStore, pPrev);
890 if (!hCertStore)
891 ret = NULL;
892 else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
893 ret = NULL;
894 else
895 ret = (PCCERT_CONTEXT)hcs->certs.enumContext(hcs, (void *)pPrev);
896 return ret;
899 BOOL WINAPI CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext)
901 BOOL ret;
903 TRACE("(%p)\n", pCertContext);
905 if (!pCertContext)
906 ret = TRUE;
907 else if (!pCertContext->hCertStore)
909 ret = TRUE;
910 CertFreeCertificateContext(pCertContext);
912 else
914 PWINECRYPT_CERTSTORE hcs =
915 (PWINECRYPT_CERTSTORE)pCertContext->hCertStore;
917 if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
918 ret = FALSE;
919 else
920 ret = hcs->certs.deleteContext(hcs, (void *)pCertContext);
921 CertFreeCertificateContext(pCertContext);
923 return ret;
926 #define CrlContext_CopyProperties(to, from) \
927 Context_CopyProperties((to), (from), sizeof(CRL_CONTEXT))
929 BOOL WINAPI CertAddCRLContextToStore(HCERTSTORE hCertStore,
930 PCCRL_CONTEXT pCrlContext, DWORD dwAddDisposition,
931 PCCRL_CONTEXT* ppStoreContext)
933 PWINECRYPT_CERTSTORE store = (PWINECRYPT_CERTSTORE)hCertStore;
934 BOOL ret = TRUE;
935 PCCRL_CONTEXT toAdd = NULL, existing = NULL;
937 TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCrlContext,
938 dwAddDisposition, ppStoreContext);
940 /* Weird case to pass a test */
941 if (dwAddDisposition == 0)
943 SetLastError(STATUS_ACCESS_VIOLATION);
944 return FALSE;
946 if (dwAddDisposition != CERT_STORE_ADD_ALWAYS)
948 existing = CertFindCRLInStore(hCertStore, 0, 0, CRL_FIND_EXISTING,
949 pCrlContext, NULL);
952 switch (dwAddDisposition)
954 case CERT_STORE_ADD_ALWAYS:
955 toAdd = CertDuplicateCRLContext(pCrlContext);
956 break;
957 case CERT_STORE_ADD_NEW:
958 if (existing)
960 TRACE("found matching CRL, not adding\n");
961 SetLastError(CRYPT_E_EXISTS);
962 ret = FALSE;
964 else
965 toAdd = CertDuplicateCRLContext(pCrlContext);
966 break;
967 case CERT_STORE_ADD_NEWER:
968 if (existing)
970 LONG newer = CompareFileTime(&existing->pCrlInfo->ThisUpdate,
971 &pCrlContext->pCrlInfo->ThisUpdate);
973 if (newer < 0)
974 toAdd = CertDuplicateCRLContext(pCrlContext);
975 else
977 TRACE("existing CRL is newer, not adding\n");
978 SetLastError(CRYPT_E_EXISTS);
979 ret = FALSE;
982 else
983 toAdd = CertDuplicateCRLContext(pCrlContext);
984 break;
985 case CERT_STORE_ADD_REPLACE_EXISTING:
986 toAdd = CertDuplicateCRLContext(pCrlContext);
987 break;
988 case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES:
989 toAdd = CertDuplicateCRLContext(pCrlContext);
990 if (existing)
991 CrlContext_CopyProperties(toAdd, existing);
992 break;
993 case CERT_STORE_ADD_USE_EXISTING:
994 if (existing)
995 CrlContext_CopyProperties(existing, pCrlContext);
996 break;
997 default:
998 FIXME("Unimplemented add disposition %d\n", dwAddDisposition);
999 ret = FALSE;
1002 if (toAdd)
1004 if (store)
1005 ret = store->crls.addContext(store, (void *)toAdd,
1006 (void *)existing, (const void **)ppStoreContext);
1007 else if (ppStoreContext)
1008 *ppStoreContext = CertDuplicateCRLContext(toAdd);
1009 CertFreeCRLContext(toAdd);
1011 CertFreeCRLContext(existing);
1013 TRACE("returning %d\n", ret);
1014 return ret;
1017 BOOL WINAPI CertDeleteCRLFromStore(PCCRL_CONTEXT pCrlContext)
1019 BOOL ret;
1021 TRACE("(%p)\n", pCrlContext);
1023 if (!pCrlContext)
1024 ret = TRUE;
1025 else if (!pCrlContext->hCertStore)
1027 ret = TRUE;
1028 CertFreeCRLContext(pCrlContext);
1030 else
1032 PWINECRYPT_CERTSTORE hcs =
1033 (PWINECRYPT_CERTSTORE)pCrlContext->hCertStore;
1035 if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
1036 ret = FALSE;
1037 else
1038 ret = hcs->crls.deleteContext(hcs, (void *)pCrlContext);
1039 CertFreeCRLContext(pCrlContext);
1041 return ret;
1044 PCCRL_CONTEXT WINAPI CertEnumCRLsInStore(HCERTSTORE hCertStore,
1045 PCCRL_CONTEXT pPrev)
1047 WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *)hCertStore;
1048 PCCRL_CONTEXT ret;
1050 TRACE("(%p, %p)\n", hCertStore, pPrev);
1051 if (!hCertStore)
1052 ret = NULL;
1053 else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
1054 ret = NULL;
1055 else
1056 ret = (PCCRL_CONTEXT)hcs->crls.enumContext(hcs, (void *)pPrev);
1057 return ret;
1060 PCCTL_CONTEXT WINAPI CertCreateCTLContext(DWORD dwCertEncodingType,
1061 const BYTE* pbCtlEncoded, DWORD cbCtlEncoded)
1063 FIXME("(%08x, %p, %08x): stub\n", dwCertEncodingType, pbCtlEncoded,
1064 cbCtlEncoded);
1065 return NULL;
1068 BOOL WINAPI CertAddEncodedCTLToStore(HCERTSTORE hCertStore,
1069 DWORD dwMsgAndCertEncodingType, const BYTE *pbCtlEncoded, DWORD cbCtlEncoded,
1070 DWORD dwAddDisposition, PCCTL_CONTEXT *ppCtlContext)
1072 FIXME("(%p, %08x, %p, %d, %08x, %p): stub\n", hCertStore,
1073 dwMsgAndCertEncodingType, pbCtlEncoded, cbCtlEncoded, dwAddDisposition,
1074 ppCtlContext);
1075 return FALSE;
1078 BOOL WINAPI CertAddCTLContextToStore(HCERTSTORE hCertStore,
1079 PCCTL_CONTEXT pCtlContext, DWORD dwAddDisposition,
1080 PCCTL_CONTEXT* ppStoreContext)
1082 FIXME("(%p, %p, %08x, %p): stub\n", hCertStore, pCtlContext,
1083 dwAddDisposition, ppStoreContext);
1084 return TRUE;
1087 PCCTL_CONTEXT WINAPI CertDuplicateCTLContext(PCCTL_CONTEXT pCtlContext)
1089 FIXME("(%p): stub\n", pCtlContext );
1090 return pCtlContext;
1093 BOOL WINAPI CertFreeCTLContext(PCCTL_CONTEXT pCtlContext)
1095 FIXME("(%p): stub\n", pCtlContext );
1096 return TRUE;
1099 BOOL WINAPI CertDeleteCTLFromStore(PCCTL_CONTEXT pCtlContext)
1101 FIXME("(%p): stub\n", pCtlContext);
1102 return TRUE;
1105 PCCTL_CONTEXT WINAPI CertEnumCTLsInStore(HCERTSTORE hCertStore,
1106 PCCTL_CONTEXT pPrev)
1108 FIXME("(%p, %p): stub\n", hCertStore, pPrev);
1109 return NULL;
1112 HCERTSTORE WINAPI CertDuplicateStore(HCERTSTORE hCertStore)
1114 WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *)hCertStore;
1116 TRACE("(%p)\n", hCertStore);
1118 if (hcs && hcs->dwMagic == WINE_CRYPTCERTSTORE_MAGIC)
1119 InterlockedIncrement(&hcs->ref);
1120 return hCertStore;
1123 BOOL WINAPI CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
1125 WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *) hCertStore;
1127 TRACE("(%p, %08x)\n", hCertStore, dwFlags);
1129 if( ! hCertStore )
1130 return TRUE;
1132 if ( hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC )
1133 return FALSE;
1135 if (InterlockedDecrement(&hcs->ref) == 0)
1137 TRACE("%p's ref count is 0, freeing\n", hcs);
1138 hcs->dwMagic = 0;
1139 hcs->closeStore(hcs, dwFlags);
1141 else
1142 TRACE("%p's ref count is %d\n", hcs, hcs->ref);
1143 return TRUE;
1146 BOOL WINAPI CertControlStore(HCERTSTORE hCertStore, DWORD dwFlags,
1147 DWORD dwCtrlType, void const *pvCtrlPara)
1149 WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *)hCertStore;
1150 BOOL ret;
1152 TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType,
1153 pvCtrlPara);
1155 if (!hcs)
1156 ret = FALSE;
1157 else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
1158 ret = FALSE;
1159 else
1161 if (hcs->control)
1162 ret = hcs->control(hCertStore, dwFlags, dwCtrlType, pvCtrlPara);
1163 else
1164 ret = TRUE;
1166 return ret;
1169 BOOL WINAPI CertGetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId,
1170 void *pvData, DWORD *pcbData)
1172 PWINECRYPT_CERTSTORE store = (PWINECRYPT_CERTSTORE)hCertStore;
1173 BOOL ret = FALSE;
1175 TRACE("(%p, %d, %p, %p)\n", hCertStore, dwPropId, pvData, pcbData);
1177 switch (dwPropId)
1179 case CERT_ACCESS_STATE_PROP_ID:
1180 if (!pvData)
1182 *pcbData = sizeof(DWORD);
1183 ret = TRUE;
1185 else if (*pcbData < sizeof(DWORD))
1187 SetLastError(ERROR_MORE_DATA);
1188 *pcbData = sizeof(DWORD);
1190 else
1192 DWORD state = 0;
1194 if (store->type != StoreTypeMem &&
1195 !(store->dwOpenFlags & CERT_STORE_READONLY_FLAG))
1196 state |= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG;
1197 *(DWORD *)pvData = state;
1198 ret = TRUE;
1200 break;
1201 default:
1202 if (store->properties)
1204 CRYPT_DATA_BLOB blob;
1206 ret = ContextPropertyList_FindProperty(store->properties, dwPropId,
1207 &blob);
1208 if (ret)
1210 if (!pvData)
1211 *pcbData = blob.cbData;
1212 else if (*pcbData < blob.cbData)
1214 SetLastError(ERROR_MORE_DATA);
1215 *pcbData = blob.cbData;
1216 ret = FALSE;
1218 else
1220 memcpy(pvData, blob.pbData, blob.cbData);
1221 *pcbData = blob.cbData;
1224 else
1225 SetLastError(CRYPT_E_NOT_FOUND);
1227 else
1228 SetLastError(CRYPT_E_NOT_FOUND);
1230 return ret;
1233 BOOL WINAPI CertSetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId,
1234 DWORD dwFlags, const void *pvData)
1236 PWINECRYPT_CERTSTORE store = (PWINECRYPT_CERTSTORE)hCertStore;
1237 BOOL ret = FALSE;
1239 TRACE("(%p, %d, %08x, %p)\n", hCertStore, dwPropId, dwFlags, pvData);
1241 if (!store->properties)
1242 store->properties = ContextPropertyList_Create();
1243 switch (dwPropId)
1245 case CERT_ACCESS_STATE_PROP_ID:
1246 SetLastError(E_INVALIDARG);
1247 break;
1248 default:
1249 if (pvData)
1251 const CRYPT_DATA_BLOB *blob = (const CRYPT_DATA_BLOB *)pvData;
1253 ret = ContextPropertyList_SetProperty(store->properties, dwPropId,
1254 blob->pbData, blob->cbData);
1256 else
1258 ContextPropertyList_RemoveProperty(store->properties, dwPropId);
1259 ret = TRUE;
1262 return ret;
1265 DWORD WINAPI CertEnumCTLContextProperties(PCCTL_CONTEXT pCTLContext,
1266 DWORD dwPropId)
1268 FIXME("(%p, %d): stub\n", pCTLContext, dwPropId);
1269 return 0;
1272 BOOL WINAPI CertGetCTLContextProperty(PCCTL_CONTEXT pCTLContext,
1273 DWORD dwPropId, void *pvData, DWORD *pcbData)
1275 FIXME("(%p, %d, %p, %p): stub\n", pCTLContext, dwPropId, pvData, pcbData);
1276 return FALSE;
1279 BOOL WINAPI CertSetCTLContextProperty(PCCTL_CONTEXT pCTLContext,
1280 DWORD dwPropId, DWORD dwFlags, const void *pvData)
1282 FIXME("(%p, %d, %08x, %p): stub\n", pCTLContext, dwPropId, dwFlags,
1283 pvData);
1284 return FALSE;
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, 0, &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;