mshtml: Added IHTMLCommentElement stub implementation.
[wine.git] / dlls / crypt32 / store.c
blob9534e5c2d3ac70242f661b416d51e63363a6e5aa
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 void CRYPT_InitStore(WINECRYPT_CERTSTORE *store, DWORD dwFlags,
97 CertStoreType type)
99 store->ref = 1;
100 store->dwMagic = WINE_CRYPTCERTSTORE_MAGIC;
101 store->type = type;
102 store->dwOpenFlags = dwFlags;
103 store->properties = NULL;
106 void CRYPT_FreeStore(PWINECRYPT_CERTSTORE store)
108 if (store->properties)
109 ContextPropertyList_Free(store->properties);
110 CryptMemFree(store);
113 BOOL WINAPI I_CertUpdateStore(HCERTSTORE store1, HCERTSTORE store2, DWORD unk0,
114 DWORD unk1)
116 static BOOL warned = FALSE;
117 const WINE_CONTEXT_INTERFACE * const interfaces[] = { pCertInterface,
118 pCRLInterface, pCTLInterface };
119 DWORD i;
121 TRACE("(%p, %p, %08x, %08x)\n", store1, store2, unk0, unk1);
122 if (!warned)
124 FIXME("semi-stub\n");
125 warned = TRUE;
128 /* Poor-man's resync: empty first store, then add everything from second
129 * store to it.
131 for (i = 0; i < sizeof(interfaces) / sizeof(interfaces[0]); i++)
133 const void *context;
135 do {
136 context = interfaces[i]->enumContextsInStore(store1, NULL);
137 if (context)
138 interfaces[i]->deleteFromStore(context);
139 } while (context);
140 do {
141 context = interfaces[i]->enumContextsInStore(store2, context);
142 if (context)
143 interfaces[i]->addContextToStore(store1, context,
144 CERT_STORE_ADD_ALWAYS, NULL);
145 } while (context);
147 return TRUE;
150 static BOOL CRYPT_MemAddCert(PWINECRYPT_CERTSTORE store, void *cert,
151 void *toReplace, const void **ppStoreContext)
153 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
154 PCERT_CONTEXT context;
156 TRACE("(%p, %p, %p, %p)\n", store, cert, toReplace, ppStoreContext);
158 context = (PCERT_CONTEXT)ContextList_Add(ms->certs, cert, toReplace);
159 if (context)
161 context->hCertStore = store;
162 if (ppStoreContext)
163 *ppStoreContext = CertDuplicateCertificateContext(context);
165 return context ? TRUE : FALSE;
168 static void *CRYPT_MemEnumCert(PWINECRYPT_CERTSTORE store, void *pPrev)
170 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
171 void *ret;
173 TRACE("(%p, %p)\n", store, pPrev);
175 ret = ContextList_Enum(ms->certs, pPrev);
176 if (!ret)
177 SetLastError(CRYPT_E_NOT_FOUND);
179 TRACE("returning %p\n", ret);
180 return ret;
183 static BOOL CRYPT_MemDeleteCert(PWINECRYPT_CERTSTORE store, void *pCertContext)
185 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
187 ContextList_Delete(ms->certs, pCertContext);
188 return TRUE;
191 static BOOL CRYPT_MemAddCrl(PWINECRYPT_CERTSTORE store, void *crl,
192 void *toReplace, const void **ppStoreContext)
194 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
195 PCRL_CONTEXT context;
197 TRACE("(%p, %p, %p, %p)\n", store, crl, toReplace, ppStoreContext);
199 context = (PCRL_CONTEXT)ContextList_Add(ms->crls, crl, toReplace);
200 if (context)
202 context->hCertStore = store;
203 if (ppStoreContext)
204 *ppStoreContext = CertDuplicateCRLContext(context);
206 return context ? TRUE : FALSE;
209 static void *CRYPT_MemEnumCrl(PWINECRYPT_CERTSTORE store, void *pPrev)
211 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
212 void *ret;
214 TRACE("(%p, %p)\n", store, pPrev);
216 ret = ContextList_Enum(ms->crls, pPrev);
217 if (!ret)
218 SetLastError(CRYPT_E_NOT_FOUND);
220 TRACE("returning %p\n", ret);
221 return ret;
224 static BOOL CRYPT_MemDeleteCrl(PWINECRYPT_CERTSTORE store, void *pCrlContext)
226 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
228 ContextList_Delete(ms->crls, pCrlContext);
229 return TRUE;
232 static void WINAPI CRYPT_MemCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
234 WINE_MEMSTORE *store = (WINE_MEMSTORE *)hCertStore;
236 TRACE("(%p, %08x)\n", store, dwFlags);
237 if (dwFlags)
238 FIXME("Unimplemented flags: %08x\n", dwFlags);
240 ContextList_Free(store->certs);
241 ContextList_Free(store->crls);
242 CRYPT_FreeStore((PWINECRYPT_CERTSTORE)store);
245 static WINECRYPT_CERTSTORE *CRYPT_MemOpenStore(HCRYPTPROV hCryptProv,
246 DWORD dwFlags, const void *pvPara)
248 PWINE_MEMSTORE store;
250 TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
252 if (dwFlags & CERT_STORE_DELETE_FLAG)
254 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
255 store = NULL;
257 else
259 store = CryptMemAlloc(sizeof(WINE_MEMSTORE));
260 if (store)
262 memset(store, 0, sizeof(WINE_MEMSTORE));
263 CRYPT_InitStore(&store->hdr, dwFlags, StoreTypeMem);
264 store->hdr.closeStore = CRYPT_MemCloseStore;
265 store->hdr.certs.addContext = CRYPT_MemAddCert;
266 store->hdr.certs.enumContext = CRYPT_MemEnumCert;
267 store->hdr.certs.deleteContext = CRYPT_MemDeleteCert;
268 store->hdr.crls.addContext = CRYPT_MemAddCrl;
269 store->hdr.crls.enumContext = CRYPT_MemEnumCrl;
270 store->hdr.crls.deleteContext = CRYPT_MemDeleteCrl;
271 store->hdr.control = NULL;
272 store->certs = ContextList_Create(pCertInterface,
273 sizeof(CERT_CONTEXT));
274 store->crls = ContextList_Create(pCRLInterface,
275 sizeof(CRL_CONTEXT));
276 /* Mem store doesn't need crypto provider, so close it */
277 if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
278 CryptReleaseContext(hCryptProv, 0);
281 return (PWINECRYPT_CERTSTORE)store;
284 static PWINECRYPT_CERTSTORE CRYPT_SysRegOpenStoreW(HCRYPTPROV hCryptProv,
285 DWORD dwFlags, const void *pvPara)
287 static const WCHAR rootW[] = { 'R','o','o','t',0 };
288 static const WCHAR fmt[] = { '%','s','\\','%','s',0 };
289 LPCWSTR storeName = (LPCWSTR)pvPara;
290 LPWSTR storePath;
291 PWINECRYPT_CERTSTORE store = NULL;
292 HKEY root;
293 LPCWSTR base;
295 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
296 debugstr_w((LPCWSTR)pvPara));
298 if (!pvPara)
300 SetLastError(E_INVALIDARG);
301 return NULL;
303 if (!lstrcmpiW(storeName, rootW))
304 return CRYPT_RootOpenStore(hCryptProv, dwFlags);
306 switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
308 case CERT_SYSTEM_STORE_LOCAL_MACHINE:
309 root = HKEY_LOCAL_MACHINE;
310 base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
311 break;
312 case CERT_SYSTEM_STORE_CURRENT_USER:
313 root = HKEY_CURRENT_USER;
314 base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
315 break;
316 case CERT_SYSTEM_STORE_CURRENT_SERVICE:
317 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
318 * SystemCertificates
320 FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE, %s: stub\n",
321 debugstr_w(storeName));
322 return NULL;
323 case CERT_SYSTEM_STORE_SERVICES:
324 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
325 * SystemCertificates
327 FIXME("CERT_SYSTEM_STORE_SERVICES, %s: stub\n",
328 debugstr_w(storeName));
329 return NULL;
330 case CERT_SYSTEM_STORE_USERS:
331 /* hku\user sid\Software\Microsoft\SystemCertificates */
332 FIXME("CERT_SYSTEM_STORE_USERS, %s: stub\n",
333 debugstr_w(storeName));
334 return NULL;
335 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY:
336 root = HKEY_CURRENT_USER;
337 base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
338 break;
339 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY:
340 root = HKEY_LOCAL_MACHINE;
341 base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
342 break;
343 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE:
344 /* hklm\Software\Microsoft\EnterpriseCertificates */
345 FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, %s: stub\n",
346 debugstr_w(storeName));
347 return NULL;
348 default:
349 SetLastError(E_INVALIDARG);
350 return NULL;
353 storePath = CryptMemAlloc((lstrlenW(base) + lstrlenW(storeName) + 2) *
354 sizeof(WCHAR));
355 if (storePath)
357 LONG rc;
358 HKEY key;
359 REGSAM sam = dwFlags & CERT_STORE_READONLY_FLAG ? KEY_READ :
360 KEY_ALL_ACCESS;
362 wsprintfW(storePath, fmt, base, storeName);
363 if (dwFlags & CERT_STORE_OPEN_EXISTING_FLAG)
364 rc = RegOpenKeyExW(root, storePath, 0, sam, &key);
365 else
367 DWORD disp;
369 rc = RegCreateKeyExW(root, storePath, 0, NULL, 0, sam, NULL,
370 &key, &disp);
371 if (!rc && dwFlags & CERT_STORE_CREATE_NEW_FLAG &&
372 disp == REG_OPENED_EXISTING_KEY)
374 RegCloseKey(key);
375 rc = ERROR_FILE_EXISTS;
378 if (!rc)
380 store = CRYPT_RegOpenStore(hCryptProv, dwFlags, key);
381 RegCloseKey(key);
383 else
384 SetLastError(rc);
385 CryptMemFree(storePath);
387 return store;
390 static PWINECRYPT_CERTSTORE CRYPT_SysRegOpenStoreA(HCRYPTPROV hCryptProv,
391 DWORD dwFlags, const void *pvPara)
393 int len;
394 PWINECRYPT_CERTSTORE ret = NULL;
396 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
397 debugstr_a((LPCSTR)pvPara));
399 if (!pvPara)
401 SetLastError(ERROR_FILE_NOT_FOUND);
402 return NULL;
404 len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, NULL, 0);
405 if (len)
407 LPWSTR storeName = CryptMemAlloc(len * sizeof(WCHAR));
409 if (storeName)
411 MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, storeName, len);
412 ret = CRYPT_SysRegOpenStoreW(hCryptProv, dwFlags, storeName);
413 CryptMemFree(storeName);
416 return ret;
419 static PWINECRYPT_CERTSTORE CRYPT_SysOpenStoreW(HCRYPTPROV hCryptProv,
420 DWORD dwFlags, const void *pvPara)
422 HCERTSTORE store = 0;
423 BOOL ret;
425 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
426 debugstr_w((LPCWSTR)pvPara));
428 if (!pvPara)
430 SetLastError(ERROR_FILE_NOT_FOUND);
431 return NULL;
433 /* This returns a different error than system registry stores if the
434 * location is invalid.
436 switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
438 case CERT_SYSTEM_STORE_LOCAL_MACHINE:
439 case CERT_SYSTEM_STORE_CURRENT_USER:
440 case CERT_SYSTEM_STORE_CURRENT_SERVICE:
441 case CERT_SYSTEM_STORE_SERVICES:
442 case CERT_SYSTEM_STORE_USERS:
443 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY:
444 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY:
445 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE:
446 ret = TRUE;
447 break;
448 default:
449 SetLastError(ERROR_FILE_NOT_FOUND);
450 ret = FALSE;
452 if (ret)
454 HCERTSTORE regStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,
455 0, 0, dwFlags, pvPara);
457 if (regStore)
459 store = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
460 CERT_STORE_CREATE_NEW_FLAG, NULL);
461 CertAddStoreToCollection(store, regStore,
462 dwFlags & CERT_STORE_READONLY_FLAG ? 0 :
463 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
464 CertCloseStore(regStore, 0);
465 /* CERT_SYSTEM_STORE_CURRENT_USER returns both the HKCU and HKLM
466 * stores.
468 if ((dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) ==
469 CERT_SYSTEM_STORE_CURRENT_USER)
471 dwFlags &= ~CERT_SYSTEM_STORE_CURRENT_USER;
472 dwFlags |= CERT_SYSTEM_STORE_LOCAL_MACHINE;
473 regStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0,
474 0, dwFlags, pvPara);
475 if (regStore)
477 CertAddStoreToCollection(store, regStore,
478 dwFlags & CERT_STORE_READONLY_FLAG ? 0 :
479 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
480 CertCloseStore(regStore, 0);
483 /* System store doesn't need crypto provider, so close it */
484 if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
485 CryptReleaseContext(hCryptProv, 0);
488 return (PWINECRYPT_CERTSTORE)store;
491 static PWINECRYPT_CERTSTORE CRYPT_SysOpenStoreA(HCRYPTPROV hCryptProv,
492 DWORD dwFlags, const void *pvPara)
494 int len;
495 PWINECRYPT_CERTSTORE ret = NULL;
497 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
498 debugstr_a((LPCSTR)pvPara));
500 if (!pvPara)
502 SetLastError(ERROR_FILE_NOT_FOUND);
503 return NULL;
505 len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, NULL, 0);
506 if (len)
508 LPWSTR storeName = CryptMemAlloc(len * sizeof(WCHAR));
510 if (storeName)
512 MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, storeName, len);
513 ret = CRYPT_SysOpenStoreW(hCryptProv, dwFlags, storeName);
514 CryptMemFree(storeName);
517 return ret;
520 static void WINAPI CRYPT_MsgCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
522 HCRYPTMSG msg = hCertStore;
524 TRACE("(%p, %08x)\n", msg, dwFlags);
525 CryptMsgClose(msg);
528 static void *msgProvFuncs[] = {
529 CRYPT_MsgCloseStore,
532 static PWINECRYPT_CERTSTORE CRYPT_MsgOpenStore(HCRYPTPROV hCryptProv,
533 DWORD dwFlags, const void *pvPara)
535 PWINECRYPT_CERTSTORE store = NULL;
536 HCRYPTMSG msg = (HCRYPTMSG)pvPara;
537 PWINECRYPT_CERTSTORE memStore;
539 TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
541 memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
542 CERT_STORE_CREATE_NEW_FLAG, NULL);
543 if (memStore)
545 BOOL ret;
546 DWORD size, count, i;
548 size = sizeof(count);
549 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &count, &size);
550 for (i = 0; ret && i < count; i++)
552 size = 0;
553 ret = CryptMsgGetParam(msg, CMSG_CERT_PARAM, i, NULL, &size);
554 if (ret)
556 LPBYTE buf = CryptMemAlloc(size);
558 if (buf)
560 ret = CryptMsgGetParam(msg, CMSG_CERT_PARAM, i, buf, &size);
561 if (ret)
562 ret = CertAddEncodedCertificateToStore(memStore,
563 X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_ALWAYS,
564 NULL);
565 CryptMemFree(buf);
569 size = sizeof(count);
570 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &count, &size);
571 for (i = 0; ret && i < count; i++)
573 size = 0;
574 ret = CryptMsgGetParam(msg, CMSG_CRL_PARAM, i, NULL, &size);
575 if (ret)
577 LPBYTE buf = CryptMemAlloc(size);
579 if (buf)
581 ret = CryptMsgGetParam(msg, CMSG_CRL_PARAM, i, buf, &size);
582 if (ret)
583 ret = CertAddEncodedCRLToStore(memStore,
584 X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_ALWAYS,
585 NULL);
586 CryptMemFree(buf);
590 if (ret)
592 CERT_STORE_PROV_INFO provInfo = { 0 };
594 provInfo.cbSize = sizeof(provInfo);
595 provInfo.cStoreProvFunc = sizeof(msgProvFuncs) /
596 sizeof(msgProvFuncs[0]);
597 provInfo.rgpvStoreProvFunc = msgProvFuncs;
598 provInfo.hStoreProv = CryptMsgDuplicate(msg);
599 store = CRYPT_ProvCreateStore(dwFlags, memStore, &provInfo);
600 /* Msg store doesn't need crypto provider, so close it */
601 if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
602 CryptReleaseContext(hCryptProv, 0);
604 else
605 CertCloseStore(memStore, 0);
607 TRACE("returning %p\n", store);
608 return store;
611 static PWINECRYPT_CERTSTORE CRYPT_PKCSOpenStore(HCRYPTPROV hCryptProv,
612 DWORD dwFlags, const void *pvPara)
614 HCRYPTMSG msg;
615 PWINECRYPT_CERTSTORE store = NULL;
616 const CRYPT_DATA_BLOB *data = (const CRYPT_DATA_BLOB *)pvPara;
617 BOOL ret;
618 DWORD msgOpenFlags = dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG ? 0 :
619 CMSG_CRYPT_RELEASE_CONTEXT_FLAG;
621 TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
623 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, msgOpenFlags, CMSG_SIGNED,
624 hCryptProv, NULL, NULL);
625 ret = CryptMsgUpdate(msg, data->pbData, data->cbData, TRUE);
626 if (!ret)
628 CryptMsgClose(msg);
629 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, msgOpenFlags, 0,
630 hCryptProv, NULL, NULL);
631 ret = CryptMsgUpdate(msg, data->pbData, data->cbData, TRUE);
632 if (ret)
634 DWORD type, size = sizeof(type);
636 /* Only signed messages are allowed, check type */
637 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &type, &size);
638 if (ret && type != CMSG_SIGNED)
640 SetLastError(CRYPT_E_INVALID_MSG_TYPE);
641 ret = FALSE;
645 if (ret)
646 store = CRYPT_MsgOpenStore(0, dwFlags, msg);
647 CryptMsgClose(msg);
648 TRACE("returning %p\n", store);
649 return store;
652 static PWINECRYPT_CERTSTORE CRYPT_PhysOpenStoreW(HCRYPTPROV hCryptProv,
653 DWORD dwFlags, const void *pvPara)
655 if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG)
656 FIXME("(%ld, %08x, %p): stub\n", hCryptProv, dwFlags, pvPara);
657 else
658 FIXME("(%ld, %08x, %s): stub\n", hCryptProv, dwFlags,
659 debugstr_w((LPCWSTR)pvPara));
660 return NULL;
663 HCERTSTORE WINAPI CertOpenStore(LPCSTR lpszStoreProvider,
664 DWORD dwMsgAndCertEncodingType, HCRYPTPROV_LEGACY hCryptProv, DWORD dwFlags,
665 const void* pvPara)
667 WINECRYPT_CERTSTORE *hcs;
668 StoreOpenFunc openFunc = NULL;
670 TRACE("(%s, %08x, %08lx, %08x, %p)\n", debugstr_a(lpszStoreProvider),
671 dwMsgAndCertEncodingType, hCryptProv, dwFlags, pvPara);
673 if (!HIWORD(lpszStoreProvider))
675 switch (LOWORD(lpszStoreProvider))
677 case LOWORD(CERT_STORE_PROV_MSG):
678 openFunc = CRYPT_MsgOpenStore;
679 break;
680 case LOWORD(CERT_STORE_PROV_MEMORY):
681 openFunc = CRYPT_MemOpenStore;
682 break;
683 case LOWORD(CERT_STORE_PROV_FILE):
684 openFunc = CRYPT_FileOpenStore;
685 break;
686 case LOWORD(CERT_STORE_PROV_PKCS7):
687 openFunc = CRYPT_PKCSOpenStore;
688 break;
689 case LOWORD(CERT_STORE_PROV_REG):
690 openFunc = CRYPT_RegOpenStore;
691 break;
692 case LOWORD(CERT_STORE_PROV_FILENAME_A):
693 openFunc = CRYPT_FileNameOpenStoreA;
694 break;
695 case LOWORD(CERT_STORE_PROV_FILENAME_W):
696 openFunc = CRYPT_FileNameOpenStoreW;
697 break;
698 case LOWORD(CERT_STORE_PROV_COLLECTION):
699 openFunc = CRYPT_CollectionOpenStore;
700 break;
701 case LOWORD(CERT_STORE_PROV_SYSTEM_A):
702 openFunc = CRYPT_SysOpenStoreA;
703 break;
704 case LOWORD(CERT_STORE_PROV_SYSTEM_W):
705 openFunc = CRYPT_SysOpenStoreW;
706 break;
707 case LOWORD(CERT_STORE_PROV_SYSTEM_REGISTRY_A):
708 openFunc = CRYPT_SysRegOpenStoreA;
709 break;
710 case LOWORD(CERT_STORE_PROV_SYSTEM_REGISTRY_W):
711 openFunc = CRYPT_SysRegOpenStoreW;
712 break;
713 case LOWORD(CERT_STORE_PROV_PHYSICAL_W):
714 openFunc = CRYPT_PhysOpenStoreW;
715 break;
716 default:
717 if (LOWORD(lpszStoreProvider))
718 FIXME("unimplemented type %d\n", LOWORD(lpszStoreProvider));
721 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_MEMORY))
722 openFunc = CRYPT_MemOpenStore;
723 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_FILENAME_W))
724 openFunc = CRYPT_FileOpenStore;
725 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_SYSTEM))
726 openFunc = CRYPT_SysOpenStoreW;
727 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_COLLECTION))
728 openFunc = CRYPT_CollectionOpenStore;
729 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_SYSTEM_REGISTRY))
730 openFunc = CRYPT_SysRegOpenStoreW;
731 else
733 FIXME("unimplemented type %s\n", lpszStoreProvider);
734 openFunc = NULL;
737 if (!openFunc)
738 hcs = CRYPT_ProvOpenStore(lpszStoreProvider, dwMsgAndCertEncodingType,
739 hCryptProv, dwFlags, pvPara);
740 else
741 hcs = openFunc(hCryptProv, dwFlags, pvPara);
742 return (HCERTSTORE)hcs;
745 HCERTSTORE WINAPI CertOpenSystemStoreA(HCRYPTPROV_LEGACY hProv,
746 LPCSTR szSubSystemProtocol)
748 if (!szSubSystemProtocol)
750 SetLastError(E_INVALIDARG);
751 return 0;
753 return CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, hProv,
754 CERT_SYSTEM_STORE_CURRENT_USER, szSubSystemProtocol);
757 HCERTSTORE WINAPI CertOpenSystemStoreW(HCRYPTPROV_LEGACY hProv,
758 LPCWSTR szSubSystemProtocol)
760 if (!szSubSystemProtocol)
762 SetLastError(E_INVALIDARG);
763 return 0;
765 return CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, hProv,
766 CERT_SYSTEM_STORE_CURRENT_USER, szSubSystemProtocol);
769 #define CertContext_CopyProperties(to, from) \
770 Context_CopyProperties((to), (from), sizeof(CERT_CONTEXT))
772 BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore,
773 PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition,
774 PCCERT_CONTEXT *ppStoreContext)
776 PWINECRYPT_CERTSTORE store = (PWINECRYPT_CERTSTORE)hCertStore;
777 BOOL ret = TRUE;
778 PCCERT_CONTEXT toAdd = NULL, existing = NULL;
780 TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCertContext,
781 dwAddDisposition, ppStoreContext);
783 if (dwAddDisposition != CERT_STORE_ADD_ALWAYS)
785 BYTE hashToAdd[20];
786 DWORD size = sizeof(hashToAdd);
788 ret = CertGetCertificateContextProperty(pCertContext, CERT_HASH_PROP_ID,
789 hashToAdd, &size);
790 if (ret)
792 CRYPT_HASH_BLOB blob = { sizeof(hashToAdd), hashToAdd };
794 existing = CertFindCertificateInStore(hCertStore,
795 pCertContext->dwCertEncodingType, 0, CERT_FIND_SHA1_HASH, &blob,
796 NULL);
800 switch (dwAddDisposition)
802 case CERT_STORE_ADD_ALWAYS:
803 toAdd = CertDuplicateCertificateContext(pCertContext);
804 break;
805 case CERT_STORE_ADD_NEW:
806 if (existing)
808 TRACE("found matching certificate, not adding\n");
809 SetLastError(CRYPT_E_EXISTS);
810 ret = FALSE;
812 else
813 toAdd = CertDuplicateCertificateContext(pCertContext);
814 break;
815 case CERT_STORE_ADD_REPLACE_EXISTING:
816 toAdd = CertDuplicateCertificateContext(pCertContext);
817 break;
818 case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES:
819 toAdd = CertDuplicateCertificateContext(pCertContext);
820 if (existing)
821 CertContext_CopyProperties(toAdd, existing);
822 break;
823 case CERT_STORE_ADD_USE_EXISTING:
824 if (existing)
826 CertContext_CopyProperties(existing, pCertContext);
827 *ppStoreContext = CertDuplicateCertificateContext(existing);
829 else
830 toAdd = CertDuplicateCertificateContext(pCertContext);
831 break;
832 case CERT_STORE_ADD_NEWER:
833 if (existing)
835 if (CompareFileTime(&existing->pCertInfo->NotBefore,
836 &pCertContext->pCertInfo->NotBefore) >= 0)
838 TRACE("existing certificate is newer, not adding\n");
839 SetLastError(CRYPT_E_EXISTS);
840 ret = FALSE;
842 else
843 toAdd = CertDuplicateCertificateContext(pCertContext);
845 else
846 toAdd = CertDuplicateCertificateContext(pCertContext);
847 break;
848 default:
849 FIXME("Unimplemented add disposition %d\n", dwAddDisposition);
850 SetLastError(E_INVALIDARG);
851 ret = FALSE;
854 if (toAdd)
856 if (store)
857 ret = store->certs.addContext(store, (void *)toAdd,
858 (void *)existing, (const void **)ppStoreContext);
859 else if (ppStoreContext)
860 *ppStoreContext = CertDuplicateCertificateContext(toAdd);
861 CertFreeCertificateContext(toAdd);
863 CertFreeCertificateContext(existing);
865 TRACE("returning %d\n", ret);
866 return ret;
869 PCCERT_CONTEXT WINAPI CertEnumCertificatesInStore(HCERTSTORE hCertStore,
870 PCCERT_CONTEXT pPrev)
872 WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *)hCertStore;
873 PCCERT_CONTEXT ret;
875 TRACE("(%p, %p)\n", hCertStore, pPrev);
876 if (!hCertStore)
877 ret = NULL;
878 else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
879 ret = NULL;
880 else
881 ret = (PCCERT_CONTEXT)hcs->certs.enumContext(hcs, (void *)pPrev);
882 return ret;
885 BOOL WINAPI CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext)
887 BOOL ret;
889 TRACE("(%p)\n", pCertContext);
891 if (!pCertContext)
892 ret = TRUE;
893 else if (!pCertContext->hCertStore)
895 ret = TRUE;
896 CertFreeCertificateContext(pCertContext);
898 else
900 PWINECRYPT_CERTSTORE hcs =
901 (PWINECRYPT_CERTSTORE)pCertContext->hCertStore;
903 if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
904 ret = FALSE;
905 else
906 ret = hcs->certs.deleteContext(hcs, (void *)pCertContext);
907 CertFreeCertificateContext(pCertContext);
909 return ret;
912 #define CrlContext_CopyProperties(to, from) \
913 Context_CopyProperties((to), (from), sizeof(CRL_CONTEXT))
915 BOOL WINAPI CertAddCRLContextToStore(HCERTSTORE hCertStore,
916 PCCRL_CONTEXT pCrlContext, DWORD dwAddDisposition,
917 PCCRL_CONTEXT* ppStoreContext)
919 PWINECRYPT_CERTSTORE store = (PWINECRYPT_CERTSTORE)hCertStore;
920 BOOL ret = TRUE;
921 PCCRL_CONTEXT toAdd = NULL, existing = NULL;
923 TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCrlContext,
924 dwAddDisposition, ppStoreContext);
926 /* Weird case to pass a test */
927 if (dwAddDisposition == 0)
929 SetLastError(STATUS_ACCESS_VIOLATION);
930 return FALSE;
932 if (dwAddDisposition != CERT_STORE_ADD_ALWAYS)
934 existing = CertFindCRLInStore(hCertStore, 0, 0, CRL_FIND_EXISTING,
935 pCrlContext, NULL);
938 switch (dwAddDisposition)
940 case CERT_STORE_ADD_ALWAYS:
941 toAdd = CertDuplicateCRLContext(pCrlContext);
942 break;
943 case CERT_STORE_ADD_NEW:
944 if (existing)
946 TRACE("found matching CRL, not adding\n");
947 SetLastError(CRYPT_E_EXISTS);
948 ret = FALSE;
950 else
951 toAdd = CertDuplicateCRLContext(pCrlContext);
952 break;
953 case CERT_STORE_ADD_NEWER:
954 if (existing)
956 LONG newer = CompareFileTime(&existing->pCrlInfo->ThisUpdate,
957 &pCrlContext->pCrlInfo->ThisUpdate);
959 if (newer < 0)
960 toAdd = CertDuplicateCRLContext(pCrlContext);
961 else
963 TRACE("existing CRL is newer, not adding\n");
964 SetLastError(CRYPT_E_EXISTS);
965 ret = FALSE;
968 else
969 toAdd = CertDuplicateCRLContext(pCrlContext);
970 break;
971 case CERT_STORE_ADD_REPLACE_EXISTING:
972 toAdd = CertDuplicateCRLContext(pCrlContext);
973 break;
974 case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES:
975 toAdd = CertDuplicateCRLContext(pCrlContext);
976 if (existing)
977 CrlContext_CopyProperties(toAdd, existing);
978 break;
979 case CERT_STORE_ADD_USE_EXISTING:
980 if (existing)
981 CrlContext_CopyProperties(existing, pCrlContext);
982 break;
983 default:
984 FIXME("Unimplemented add disposition %d\n", dwAddDisposition);
985 ret = FALSE;
988 if (toAdd)
990 if (store)
991 ret = store->crls.addContext(store, (void *)toAdd,
992 (void *)existing, (const void **)ppStoreContext);
993 else if (ppStoreContext)
994 *ppStoreContext = CertDuplicateCRLContext(toAdd);
995 CertFreeCRLContext(toAdd);
997 CertFreeCRLContext(existing);
999 TRACE("returning %d\n", ret);
1000 return ret;
1003 BOOL WINAPI CertDeleteCRLFromStore(PCCRL_CONTEXT pCrlContext)
1005 BOOL ret;
1007 TRACE("(%p)\n", pCrlContext);
1009 if (!pCrlContext)
1010 ret = TRUE;
1011 else if (!pCrlContext->hCertStore)
1013 ret = TRUE;
1014 CertFreeCRLContext(pCrlContext);
1016 else
1018 PWINECRYPT_CERTSTORE hcs =
1019 (PWINECRYPT_CERTSTORE)pCrlContext->hCertStore;
1021 if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
1022 ret = FALSE;
1023 else
1024 ret = hcs->crls.deleteContext(hcs, (void *)pCrlContext);
1025 CertFreeCRLContext(pCrlContext);
1027 return ret;
1030 PCCRL_CONTEXT WINAPI CertEnumCRLsInStore(HCERTSTORE hCertStore,
1031 PCCRL_CONTEXT pPrev)
1033 WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *)hCertStore;
1034 PCCRL_CONTEXT ret;
1036 TRACE("(%p, %p)\n", hCertStore, pPrev);
1037 if (!hCertStore)
1038 ret = NULL;
1039 else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
1040 ret = NULL;
1041 else
1042 ret = (PCCRL_CONTEXT)hcs->crls.enumContext(hcs, (void *)pPrev);
1043 return ret;
1046 PCCTL_CONTEXT WINAPI CertCreateCTLContext(DWORD dwCertEncodingType,
1047 const BYTE* pbCtlEncoded, DWORD cbCtlEncoded)
1049 FIXME("(%08x, %p, %08x): stub\n", dwCertEncodingType, pbCtlEncoded,
1050 cbCtlEncoded);
1051 return NULL;
1054 BOOL WINAPI CertAddEncodedCTLToStore(HCERTSTORE hCertStore,
1055 DWORD dwMsgAndCertEncodingType, const BYTE *pbCtlEncoded, DWORD cbCtlEncoded,
1056 DWORD dwAddDisposition, PCCTL_CONTEXT *ppCtlContext)
1058 FIXME("(%p, %08x, %p, %d, %08x, %p): stub\n", hCertStore,
1059 dwMsgAndCertEncodingType, pbCtlEncoded, cbCtlEncoded, dwAddDisposition,
1060 ppCtlContext);
1061 return FALSE;
1064 BOOL WINAPI CertAddCTLContextToStore(HCERTSTORE hCertStore,
1065 PCCTL_CONTEXT pCtlContext, DWORD dwAddDisposition,
1066 PCCTL_CONTEXT* ppStoreContext)
1068 FIXME("(%p, %p, %08x, %p): stub\n", hCertStore, pCtlContext,
1069 dwAddDisposition, ppStoreContext);
1070 return TRUE;
1073 PCCTL_CONTEXT WINAPI CertDuplicateCTLContext(PCCTL_CONTEXT pCtlContext)
1075 FIXME("(%p): stub\n", pCtlContext );
1076 return pCtlContext;
1079 BOOL WINAPI CertFreeCTLContext(PCCTL_CONTEXT pCtlContext)
1081 FIXME("(%p): stub\n", pCtlContext );
1082 return TRUE;
1085 BOOL WINAPI CertDeleteCTLFromStore(PCCTL_CONTEXT pCtlContext)
1087 FIXME("(%p): stub\n", pCtlContext);
1088 return TRUE;
1091 PCCTL_CONTEXT WINAPI CertEnumCTLsInStore(HCERTSTORE hCertStore,
1092 PCCTL_CONTEXT pPrev)
1094 FIXME("(%p, %p): stub\n", hCertStore, pPrev);
1095 return NULL;
1098 HCERTSTORE WINAPI CertDuplicateStore(HCERTSTORE hCertStore)
1100 WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *)hCertStore;
1102 TRACE("(%p)\n", hCertStore);
1104 if (hcs && hcs->dwMagic == WINE_CRYPTCERTSTORE_MAGIC)
1105 InterlockedIncrement(&hcs->ref);
1106 return hCertStore;
1109 BOOL WINAPI CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
1111 WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *) hCertStore;
1113 TRACE("(%p, %08x)\n", hCertStore, dwFlags);
1115 if( ! hCertStore )
1116 return TRUE;
1118 if ( hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC )
1119 return FALSE;
1121 if (InterlockedDecrement(&hcs->ref) == 0)
1123 TRACE("%p's ref count is 0, freeing\n", hcs);
1124 hcs->dwMagic = 0;
1125 hcs->closeStore(hcs, dwFlags);
1127 else
1128 TRACE("%p's ref count is %d\n", hcs, hcs->ref);
1129 return TRUE;
1132 BOOL WINAPI CertControlStore(HCERTSTORE hCertStore, DWORD dwFlags,
1133 DWORD dwCtrlType, void const *pvCtrlPara)
1135 WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *)hCertStore;
1136 BOOL ret;
1138 TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType,
1139 pvCtrlPara);
1141 if (!hcs)
1142 ret = FALSE;
1143 else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
1144 ret = FALSE;
1145 else
1147 if (hcs->control)
1148 ret = hcs->control(hCertStore, dwFlags, dwCtrlType, pvCtrlPara);
1149 else
1150 ret = TRUE;
1152 return ret;
1155 BOOL WINAPI CertGetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId,
1156 void *pvData, DWORD *pcbData)
1158 PWINECRYPT_CERTSTORE store = (PWINECRYPT_CERTSTORE)hCertStore;
1159 BOOL ret = FALSE;
1161 TRACE("(%p, %d, %p, %p)\n", hCertStore, dwPropId, pvData, pcbData);
1163 switch (dwPropId)
1165 case CERT_ACCESS_STATE_PROP_ID:
1166 if (!pvData)
1168 *pcbData = sizeof(DWORD);
1169 ret = TRUE;
1171 else if (*pcbData < sizeof(DWORD))
1173 SetLastError(ERROR_MORE_DATA);
1174 *pcbData = sizeof(DWORD);
1176 else
1178 DWORD state = 0;
1180 if (store->type != StoreTypeMem &&
1181 !(store->dwOpenFlags & CERT_STORE_READONLY_FLAG))
1182 state |= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG;
1183 *(DWORD *)pvData = state;
1184 ret = TRUE;
1186 break;
1187 default:
1188 if (store->properties)
1190 CRYPT_DATA_BLOB blob;
1192 ret = ContextPropertyList_FindProperty(store->properties, dwPropId,
1193 &blob);
1194 if (ret)
1196 if (!pvData)
1197 *pcbData = blob.cbData;
1198 else if (*pcbData < blob.cbData)
1200 SetLastError(ERROR_MORE_DATA);
1201 *pcbData = blob.cbData;
1202 ret = FALSE;
1204 else
1206 memcpy(pvData, blob.pbData, blob.cbData);
1207 *pcbData = blob.cbData;
1210 else
1211 SetLastError(CRYPT_E_NOT_FOUND);
1213 else
1214 SetLastError(CRYPT_E_NOT_FOUND);
1216 return ret;
1219 BOOL WINAPI CertSetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId,
1220 DWORD dwFlags, const void *pvData)
1222 PWINECRYPT_CERTSTORE store = (PWINECRYPT_CERTSTORE)hCertStore;
1223 BOOL ret = FALSE;
1225 TRACE("(%p, %d, %08x, %p)\n", hCertStore, dwPropId, dwFlags, pvData);
1227 if (!store->properties)
1228 store->properties = ContextPropertyList_Create();
1229 switch (dwPropId)
1231 case CERT_ACCESS_STATE_PROP_ID:
1232 SetLastError(E_INVALIDARG);
1233 break;
1234 default:
1235 if (pvData)
1237 const CRYPT_DATA_BLOB *blob = (const CRYPT_DATA_BLOB *)pvData;
1239 ret = ContextPropertyList_SetProperty(store->properties, dwPropId,
1240 blob->pbData, blob->cbData);
1242 else
1244 ContextPropertyList_RemoveProperty(store->properties, dwPropId);
1245 ret = TRUE;
1248 return ret;
1251 DWORD WINAPI CertEnumCTLContextProperties(PCCTL_CONTEXT pCTLContext,
1252 DWORD dwPropId)
1254 FIXME("(%p, %d): stub\n", pCTLContext, dwPropId);
1255 return 0;
1258 BOOL WINAPI CertGetCTLContextProperty(PCCTL_CONTEXT pCTLContext,
1259 DWORD dwPropId, void *pvData, DWORD *pcbData)
1261 FIXME("(%p, %d, %p, %p): stub\n", pCTLContext, dwPropId, pvData, pcbData);
1262 return FALSE;
1265 BOOL WINAPI CertSetCTLContextProperty(PCCTL_CONTEXT pCTLContext,
1266 DWORD dwPropId, DWORD dwFlags, const void *pvData)
1268 FIXME("(%p, %d, %08x, %p): stub\n", pCTLContext, dwPropId, dwFlags,
1269 pvData);
1270 return FALSE;
1273 static LONG CRYPT_OpenParentStore(DWORD dwFlags,
1274 void *pvSystemStoreLocationPara, HKEY *key)
1276 HKEY root;
1277 LPCWSTR base;
1279 TRACE("(%08x, %p)\n", dwFlags, pvSystemStoreLocationPara);
1281 switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
1283 case CERT_SYSTEM_STORE_LOCAL_MACHINE:
1284 root = HKEY_LOCAL_MACHINE;
1285 base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
1286 break;
1287 case CERT_SYSTEM_STORE_CURRENT_USER:
1288 root = HKEY_CURRENT_USER;
1289 base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
1290 break;
1291 case CERT_SYSTEM_STORE_CURRENT_SERVICE:
1292 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
1293 * SystemCertificates
1295 FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE\n");
1296 return ERROR_FILE_NOT_FOUND;
1297 case CERT_SYSTEM_STORE_SERVICES:
1298 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
1299 * SystemCertificates
1301 FIXME("CERT_SYSTEM_STORE_SERVICES\n");
1302 return ERROR_FILE_NOT_FOUND;
1303 case CERT_SYSTEM_STORE_USERS:
1304 /* hku\user sid\Software\Microsoft\SystemCertificates */
1305 FIXME("CERT_SYSTEM_STORE_USERS\n");
1306 return ERROR_FILE_NOT_FOUND;
1307 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY:
1308 root = HKEY_CURRENT_USER;
1309 base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
1310 break;
1311 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY:
1312 root = HKEY_LOCAL_MACHINE;
1313 base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
1314 break;
1315 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE:
1316 /* hklm\Software\Microsoft\EnterpriseCertificates */
1317 FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE\n");
1318 return ERROR_FILE_NOT_FOUND;
1319 default:
1320 return ERROR_FILE_NOT_FOUND;
1323 return RegOpenKeyExW(root, base, 0, KEY_READ, key);
1326 BOOL WINAPI CertEnumSystemStore(DWORD dwFlags, void *pvSystemStoreLocationPara,
1327 void *pvArg, PFN_CERT_ENUM_SYSTEM_STORE pfnEnum)
1329 BOOL ret = FALSE;
1330 LONG rc;
1331 HKEY key;
1333 TRACE("(%08x, %p, %p, %p)\n", dwFlags, pvSystemStoreLocationPara, pvArg,
1334 pfnEnum);
1336 rc = CRYPT_OpenParentStore(dwFlags, pvArg, &key);
1337 if (!rc)
1339 DWORD index = 0;
1340 CERT_SYSTEM_STORE_INFO info = { sizeof(info) };
1342 ret = TRUE;
1343 do {
1344 WCHAR name[MAX_PATH];
1345 DWORD size = sizeof(name) / sizeof(name[0]);
1347 rc = RegEnumKeyExW(key, index++, name, &size, NULL, NULL, NULL,
1348 NULL);
1349 if (!rc)
1350 ret = pfnEnum(name, 0, &info, NULL, pvArg);
1351 } while (ret && !rc);
1352 if (ret && rc != ERROR_NO_MORE_ITEMS)
1353 SetLastError(rc);
1355 else
1356 SetLastError(rc);
1357 return ret;