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
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.
27 #include "wine/port.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
101 } WINE_MSGSTOREINFO
, *PWINE_MSGSTOREINFO
;
103 void CRYPT_InitStore(WINECRYPT_CERTSTORE
*store
, DWORD dwFlags
,
107 store
->dwMagic
= WINE_CRYPTCERTSTORE_MAGIC
;
109 store
->dwOpenFlags
= dwFlags
;
110 store
->properties
= NULL
;
113 void CRYPT_FreeStore(PWINECRYPT_CERTSTORE store
)
115 if (store
->properties
)
116 ContextPropertyList_Free(store
->properties
);
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
);
131 context
->hCertStore
= store
;
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
;
143 TRACE("(%p, %p)\n", store
, pPrev
);
145 ret
= ContextList_Enum(ms
->certs
, pPrev
);
147 SetLastError(CRYPT_E_NOT_FOUND
);
149 TRACE("returning %p\n", ret
);
153 static BOOL
CRYPT_MemDeleteCert(PWINECRYPT_CERTSTORE store
, void *pCertContext
)
155 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
157 ContextList_Delete(ms
->certs
, pCertContext
);
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
);
172 context
->hCertStore
= store
;
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
;
184 TRACE("(%p, %p)\n", store
, pPrev
);
186 ret
= ContextList_Enum(ms
->crls
, pPrev
);
188 SetLastError(CRYPT_E_NOT_FOUND
);
190 TRACE("returning %p\n", ret
);
194 static BOOL
CRYPT_MemDeleteCrl(PWINECRYPT_CERTSTORE store
, void *pCrlContext
)
196 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
198 ContextList_Delete(ms
->crls
, pCrlContext
);
202 void CRYPT_EmptyStore(HCERTSTORE store
)
208 cert
= CertEnumCertificatesInStore(store
, NULL
);
210 CertDeleteCertificateFromStore(cert
);
213 crl
= CertEnumCRLsInStore(store
, NULL
);
215 CertDeleteCRLFromStore(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
);
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
);
246 store
= CryptMemAlloc(sizeof(WINE_MEMSTORE
));
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
;
282 PWINECRYPT_CERTSTORE store
= NULL
;
287 TRACE("(%ld, %08x, %s)\n", hCryptProv
, dwFlags
,
288 debugstr_w((LPCWSTR
)pvPara
));
292 SetLastError(E_INVALIDARG
);
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
;
303 case CERT_SYSTEM_STORE_CURRENT_USER
:
304 root
= HKEY_CURRENT_USER
;
305 base
= CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH
;
307 case CERT_SYSTEM_STORE_CURRENT_SERVICE
:
308 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
311 FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE, %s: stub\n",
312 debugstr_w(storeName
));
314 case CERT_SYSTEM_STORE_SERVICES
:
315 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
318 FIXME("CERT_SYSTEM_STORE_SERVICES, %s: stub\n",
319 debugstr_w(storeName
));
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
));
326 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY
:
327 root
= HKEY_CURRENT_USER
;
328 base
= CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH
;
330 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY
:
331 root
= HKEY_LOCAL_MACHINE
;
332 base
= CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH
;
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
));
340 SetLastError(E_INVALIDARG
);
344 storePath
= CryptMemAlloc((lstrlenW(base
) + lstrlenW(storeName
) + 2) *
350 REGSAM sam
= dwFlags
& CERT_STORE_READONLY_FLAG
? KEY_READ
:
353 wsprintfW(storePath
, fmt
, base
, storeName
);
354 if (dwFlags
& CERT_STORE_OPEN_EXISTING_FLAG
)
355 rc
= RegOpenKeyExW(root
, storePath
, 0, sam
, &key
);
360 rc
= RegCreateKeyExW(root
, storePath
, 0, NULL
, 0, sam
, NULL
,
362 if (!rc
&& dwFlags
& CERT_STORE_CREATE_NEW_FLAG
&&
363 disp
== REG_OPENED_EXISTING_KEY
)
366 rc
= ERROR_FILE_EXISTS
;
371 store
= CRYPT_RegOpenStore(hCryptProv
, dwFlags
, key
);
376 CryptMemFree(storePath
);
381 static PWINECRYPT_CERTSTORE
CRYPT_SysRegOpenStoreA(HCRYPTPROV hCryptProv
,
382 DWORD dwFlags
, const void *pvPara
)
385 PWINECRYPT_CERTSTORE ret
= NULL
;
387 TRACE("(%ld, %08x, %s)\n", hCryptProv
, dwFlags
,
388 debugstr_a((LPCSTR
)pvPara
));
392 SetLastError(ERROR_FILE_NOT_FOUND
);
395 len
= MultiByteToWideChar(CP_ACP
, 0, (LPCSTR
)pvPara
, -1, NULL
, 0);
398 LPWSTR storeName
= CryptMemAlloc(len
* sizeof(WCHAR
));
402 MultiByteToWideChar(CP_ACP
, 0, (LPCSTR
)pvPara
, -1, storeName
, len
);
403 ret
= CRYPT_SysRegOpenStoreW(hCryptProv
, dwFlags
, storeName
);
404 CryptMemFree(storeName
);
410 static PWINECRYPT_CERTSTORE
CRYPT_SysOpenStoreW(HCRYPTPROV hCryptProv
,
411 DWORD dwFlags
, const void *pvPara
)
413 HCERTSTORE store
= 0;
416 TRACE("(%ld, %08x, %s)\n", hCryptProv
, dwFlags
,
417 debugstr_w((LPCWSTR
)pvPara
));
421 SetLastError(ERROR_FILE_NOT_FOUND
);
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
:
440 SetLastError(ERROR_FILE_NOT_FOUND
);
445 HCERTSTORE regStore
= CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W
,
446 0, 0, dwFlags
, pvPara
);
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
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,
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
)
486 PWINECRYPT_CERTSTORE ret
= NULL
;
488 TRACE("(%ld, %08x, %s)\n", hCryptProv
, dwFlags
,
489 debugstr_a((LPCSTR
)pvPara
));
493 SetLastError(ERROR_FILE_NOT_FOUND
);
496 len
= MultiByteToWideChar(CP_ACP
, 0, (LPCSTR
)pvPara
, -1, NULL
, 0);
499 LPWSTR storeName
= CryptMemAlloc(len
* sizeof(WCHAR
));
503 MultiByteToWideChar(CP_ACP
, 0, (LPCSTR
)pvPara
, -1, storeName
, len
);
504 ret
= CRYPT_SysOpenStoreW(hCryptProv
, dwFlags
, storeName
);
505 CryptMemFree(storeName
);
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
);
521 static void *msgProvFuncs
[] = {
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
);
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
++)
559 ret
= CryptMsgGetParam(msg
, CMSG_CERT_PARAM
, i
, NULL
, &size
);
562 LPBYTE buf
= CryptMemAlloc(size
);
566 ret
= CryptMsgGetParam(msg
, CMSG_CERT_PARAM
, i
, buf
, &size
);
568 ret
= CertAddEncodedCertificateToStore(memStore
,
569 X509_ASN_ENCODING
, buf
, size
, CERT_STORE_ADD_ALWAYS
,
575 size
= sizeof(count
);
576 ret
= CryptMsgGetParam(msg
, CMSG_CRL_COUNT_PARAM
, 0, &count
, &size
);
577 for (i
= 0; ret
&& i
< count
; i
++)
580 ret
= CryptMsgGetParam(msg
, CMSG_CRL_PARAM
, i
, NULL
, &size
);
583 LPBYTE buf
= CryptMemAlloc(size
);
587 ret
= CryptMsgGetParam(msg
, CMSG_CRL_PARAM
, i
, buf
, &size
);
589 ret
= CertAddEncodedCRLToStore(memStore
,
590 X509_ASN_ENCODING
, buf
, size
, CERT_STORE_ADD_ALWAYS
,
598 PWINE_MSGSTOREINFO info
= CryptMemAlloc(sizeof(WINE_MSGSTOREINFO
));
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
,
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);
619 CertCloseStore(memStore
, 0);
622 CertCloseStore(memStore
, 0);
624 TRACE("returning %p\n", store
);
628 static PWINECRYPT_CERTSTORE
CRYPT_PKCSOpenStore(HCRYPTPROV hCryptProv
,
629 DWORD dwFlags
, const void *pvPara
)
632 PWINECRYPT_CERTSTORE store
= NULL
;
633 const CRYPT_DATA_BLOB
*data
= (const CRYPT_DATA_BLOB
*)pvPara
;
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
);
646 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, msgOpenFlags
, 0,
647 hCryptProv
, NULL
, NULL
);
648 ret
= CryptMsgUpdate(msg
, data
->pbData
, data
->cbData
, TRUE
);
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
);
663 store
= CRYPT_MsgOpenStore(0, dwFlags
, msg
);
665 TRACE("returning %p\n", 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
);
675 FIXME("(%ld, %08x, %s): stub\n", hCryptProv
, dwFlags
,
676 debugstr_w((LPCWSTR
)pvPara
));
680 HCERTSTORE WINAPI
CertOpenStore(LPCSTR lpszStoreProvider
,
681 DWORD dwMsgAndCertEncodingType
, HCRYPTPROV_LEGACY hCryptProv
, DWORD dwFlags
,
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
;
697 case (int)CERT_STORE_PROV_MEMORY
:
698 openFunc
= CRYPT_MemOpenStore
;
700 case (int)CERT_STORE_PROV_FILE
:
701 openFunc
= CRYPT_FileOpenStore
;
703 case (int)CERT_STORE_PROV_PKCS7
:
704 openFunc
= CRYPT_PKCSOpenStore
;
706 case (int)CERT_STORE_PROV_REG
:
707 openFunc
= CRYPT_RegOpenStore
;
709 case (int)CERT_STORE_PROV_FILENAME_A
:
710 openFunc
= CRYPT_FileNameOpenStoreA
;
712 case (int)CERT_STORE_PROV_FILENAME_W
:
713 openFunc
= CRYPT_FileNameOpenStoreW
;
715 case (int)CERT_STORE_PROV_COLLECTION
:
716 openFunc
= CRYPT_CollectionOpenStore
;
718 case (int)CERT_STORE_PROV_SYSTEM_A
:
719 openFunc
= CRYPT_SysOpenStoreA
;
721 case (int)CERT_STORE_PROV_SYSTEM_W
:
722 openFunc
= CRYPT_SysOpenStoreW
;
724 case (int)CERT_STORE_PROV_SYSTEM_REGISTRY_A
:
725 openFunc
= CRYPT_SysRegOpenStoreA
;
727 case (int)CERT_STORE_PROV_SYSTEM_REGISTRY_W
:
728 openFunc
= CRYPT_SysRegOpenStoreW
;
730 case (int)CERT_STORE_PROV_PHYSICAL_W
:
731 openFunc
= CRYPT_PhysOpenStoreW
;
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
;
750 FIXME("unimplemented type %s\n", lpszStoreProvider
);
755 hcs
= CRYPT_ProvOpenStore(lpszStoreProvider
, dwMsgAndCertEncodingType
,
756 hCryptProv
, dwFlags
, pvPara
);
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
);
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
);
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
);
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
;
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
);
814 if (dwAddDisposition
!= CERT_STORE_ADD_ALWAYS
)
817 DWORD size
= sizeof(hashToAdd
);
819 ret
= CertGetCertificateContextProperty(pCertContext
, CERT_HASH_PROP_ID
,
823 CRYPT_HASH_BLOB blob
= { sizeof(hashToAdd
), hashToAdd
};
825 existing
= CertFindCertificateInStore(hCertStore
,
826 pCertContext
->dwCertEncodingType
, 0, CERT_FIND_SHA1_HASH
, &blob
,
831 switch (dwAddDisposition
)
833 case CERT_STORE_ADD_ALWAYS
:
834 toAdd
= CertDuplicateCertificateContext(pCertContext
);
836 case CERT_STORE_ADD_NEW
:
839 TRACE("found matching certificate, not adding\n");
840 SetLastError(CRYPT_E_EXISTS
);
844 toAdd
= CertDuplicateCertificateContext(pCertContext
);
846 case CERT_STORE_ADD_REPLACE_EXISTING
:
847 toAdd
= CertDuplicateCertificateContext(pCertContext
);
849 case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES
:
850 toAdd
= CertDuplicateCertificateContext(pCertContext
);
852 CertContext_CopyProperties(toAdd
, existing
);
854 case CERT_STORE_ADD_USE_EXISTING
:
857 CertContext_CopyProperties(existing
, pCertContext
);
858 *ppStoreContext
= CertDuplicateCertificateContext(existing
);
861 toAdd
= CertDuplicateCertificateContext(pCertContext
);
864 FIXME("Unimplemented add disposition %d\n", dwAddDisposition
);
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
);
883 PCCERT_CONTEXT WINAPI
CertEnumCertificatesInStore(HCERTSTORE hCertStore
,
884 PCCERT_CONTEXT pPrev
)
886 WINECRYPT_CERTSTORE
*hcs
= (WINECRYPT_CERTSTORE
*)hCertStore
;
889 TRACE("(%p, %p)\n", hCertStore
, pPrev
);
892 else if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
895 ret
= (PCCERT_CONTEXT
)hcs
->certs
.enumContext(hcs
, (void *)pPrev
);
899 BOOL WINAPI
CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext
)
903 TRACE("(%p)\n", pCertContext
);
907 else if (!pCertContext
->hCertStore
)
910 CertFreeCertificateContext(pCertContext
);
914 PWINECRYPT_CERTSTORE hcs
=
915 (PWINECRYPT_CERTSTORE
)pCertContext
->hCertStore
;
917 if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
920 ret
= hcs
->certs
.deleteContext(hcs
, (void *)pCertContext
);
921 CertFreeCertificateContext(pCertContext
);
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
;
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
);
946 if (dwAddDisposition
!= CERT_STORE_ADD_ALWAYS
)
948 existing
= CertFindCRLInStore(hCertStore
, 0, 0, CRL_FIND_EXISTING
,
952 switch (dwAddDisposition
)
954 case CERT_STORE_ADD_ALWAYS
:
955 toAdd
= CertDuplicateCRLContext(pCrlContext
);
957 case CERT_STORE_ADD_NEW
:
960 TRACE("found matching CRL, not adding\n");
961 SetLastError(CRYPT_E_EXISTS
);
965 toAdd
= CertDuplicateCRLContext(pCrlContext
);
967 case CERT_STORE_ADD_NEWER
:
970 LONG newer
= CompareFileTime(&existing
->pCrlInfo
->ThisUpdate
,
971 &pCrlContext
->pCrlInfo
->ThisUpdate
);
974 toAdd
= CertDuplicateCRLContext(pCrlContext
);
977 TRACE("existing CRL is newer, not adding\n");
978 SetLastError(CRYPT_E_EXISTS
);
983 toAdd
= CertDuplicateCRLContext(pCrlContext
);
985 case CERT_STORE_ADD_REPLACE_EXISTING
:
986 toAdd
= CertDuplicateCRLContext(pCrlContext
);
988 case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES
:
989 toAdd
= CertDuplicateCRLContext(pCrlContext
);
991 CrlContext_CopyProperties(toAdd
, existing
);
993 case CERT_STORE_ADD_USE_EXISTING
:
995 CrlContext_CopyProperties(existing
, pCrlContext
);
998 FIXME("Unimplemented add disposition %d\n", dwAddDisposition
);
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
);
1017 BOOL WINAPI
CertDeleteCRLFromStore(PCCRL_CONTEXT pCrlContext
)
1021 TRACE("(%p)\n", pCrlContext
);
1025 else if (!pCrlContext
->hCertStore
)
1028 CertFreeCRLContext(pCrlContext
);
1032 PWINECRYPT_CERTSTORE hcs
=
1033 (PWINECRYPT_CERTSTORE
)pCrlContext
->hCertStore
;
1035 if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1038 ret
= hcs
->crls
.deleteContext(hcs
, (void *)pCrlContext
);
1039 CertFreeCRLContext(pCrlContext
);
1044 PCCRL_CONTEXT WINAPI
CertEnumCRLsInStore(HCERTSTORE hCertStore
,
1045 PCCRL_CONTEXT pPrev
)
1047 WINECRYPT_CERTSTORE
*hcs
= (WINECRYPT_CERTSTORE
*)hCertStore
;
1050 TRACE("(%p, %p)\n", hCertStore
, pPrev
);
1053 else if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1056 ret
= (PCCRL_CONTEXT
)hcs
->crls
.enumContext(hcs
, (void *)pPrev
);
1060 PCCTL_CONTEXT WINAPI
CertCreateCTLContext(DWORD dwCertEncodingType
,
1061 const BYTE
* pbCtlEncoded
, DWORD cbCtlEncoded
)
1063 FIXME("(%08x, %p, %08x): stub\n", dwCertEncodingType
, pbCtlEncoded
,
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
,
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
);
1087 PCCTL_CONTEXT WINAPI
CertDuplicateCTLContext(PCCTL_CONTEXT pCtlContext
)
1089 FIXME("(%p): stub\n", pCtlContext
);
1093 BOOL WINAPI
CertFreeCTLContext(PCCTL_CONTEXT pCtlContext
)
1095 FIXME("(%p): stub\n", pCtlContext
);
1099 BOOL WINAPI
CertDeleteCTLFromStore(PCCTL_CONTEXT pCtlContext
)
1101 FIXME("(%p): stub\n", pCtlContext
);
1105 PCCTL_CONTEXT WINAPI
CertEnumCTLsInStore(HCERTSTORE hCertStore
,
1106 PCCTL_CONTEXT pPrev
)
1108 FIXME("(%p, %p): stub\n", hCertStore
, pPrev
);
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
);
1123 BOOL WINAPI
CertCloseStore(HCERTSTORE hCertStore
, DWORD dwFlags
)
1125 WINECRYPT_CERTSTORE
*hcs
= (WINECRYPT_CERTSTORE
*) hCertStore
;
1127 TRACE("(%p, %08x)\n", hCertStore
, dwFlags
);
1132 if ( hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1135 if (InterlockedDecrement(&hcs
->ref
) == 0)
1137 TRACE("%p's ref count is 0, freeing\n", hcs
);
1139 hcs
->closeStore(hcs
, dwFlags
);
1142 TRACE("%p's ref count is %d\n", hcs
, hcs
->ref
);
1146 BOOL WINAPI
CertControlStore(HCERTSTORE hCertStore
, DWORD dwFlags
,
1147 DWORD dwCtrlType
, void const *pvCtrlPara
)
1149 WINECRYPT_CERTSTORE
*hcs
= (WINECRYPT_CERTSTORE
*)hCertStore
;
1152 TRACE("(%p, %08x, %d, %p)\n", hCertStore
, dwFlags
, dwCtrlType
,
1157 else if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1162 ret
= hcs
->control(hCertStore
, dwFlags
, dwCtrlType
, pvCtrlPara
);
1169 BOOL WINAPI
CertGetStoreProperty(HCERTSTORE hCertStore
, DWORD dwPropId
,
1170 void *pvData
, DWORD
*pcbData
)
1172 PWINECRYPT_CERTSTORE store
= (PWINECRYPT_CERTSTORE
)hCertStore
;
1175 TRACE("(%p, %d, %p, %p)\n", hCertStore
, dwPropId
, pvData
, pcbData
);
1179 case CERT_ACCESS_STATE_PROP_ID
:
1182 *pcbData
= sizeof(DWORD
);
1185 else if (*pcbData
< sizeof(DWORD
))
1187 SetLastError(ERROR_MORE_DATA
);
1188 *pcbData
= sizeof(DWORD
);
1194 if (store
->type
!= StoreTypeMem
&&
1195 !(store
->dwOpenFlags
& CERT_STORE_READONLY_FLAG
))
1196 state
|= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG
;
1197 *(DWORD
*)pvData
= state
;
1202 if (store
->properties
)
1204 CRYPT_DATA_BLOB blob
;
1206 ret
= ContextPropertyList_FindProperty(store
->properties
, dwPropId
,
1211 *pcbData
= blob
.cbData
;
1212 else if (*pcbData
< blob
.cbData
)
1214 SetLastError(ERROR_MORE_DATA
);
1215 *pcbData
= blob
.cbData
;
1220 memcpy(pvData
, blob
.pbData
, blob
.cbData
);
1221 *pcbData
= blob
.cbData
;
1225 SetLastError(CRYPT_E_NOT_FOUND
);
1228 SetLastError(CRYPT_E_NOT_FOUND
);
1233 BOOL WINAPI
CertSetStoreProperty(HCERTSTORE hCertStore
, DWORD dwPropId
,
1234 DWORD dwFlags
, const void *pvData
)
1236 PWINECRYPT_CERTSTORE store
= (PWINECRYPT_CERTSTORE
)hCertStore
;
1239 TRACE("(%p, %d, %08x, %p)\n", hCertStore
, dwPropId
, dwFlags
, pvData
);
1241 if (!store
->properties
)
1242 store
->properties
= ContextPropertyList_Create();
1245 case CERT_ACCESS_STATE_PROP_ID
:
1246 SetLastError(E_INVALIDARG
);
1251 const CRYPT_DATA_BLOB
*blob
= (const CRYPT_DATA_BLOB
*)pvData
;
1253 ret
= ContextPropertyList_SetProperty(store
->properties
, dwPropId
,
1254 blob
->pbData
, blob
->cbData
);
1258 ContextPropertyList_RemoveProperty(store
->properties
, dwPropId
);
1265 DWORD WINAPI
CertEnumCTLContextProperties(PCCTL_CONTEXT pCTLContext
,
1268 FIXME("(%p, %d): stub\n", pCTLContext
, dwPropId
);
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
);
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
,
1287 static LONG
CRYPT_OpenParentStore(DWORD dwFlags
,
1288 void *pvSystemStoreLocationPara
, HKEY
*key
)
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
;
1301 case CERT_SYSTEM_STORE_CURRENT_USER
:
1302 root
= HKEY_CURRENT_USER
;
1303 base
= CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH
;
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
;
1325 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY
:
1326 root
= HKEY_LOCAL_MACHINE
;
1327 base
= CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH
;
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
;
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
)
1347 TRACE("(%08x, %p, %p, %p)\n", dwFlags
, pvSystemStoreLocationPara
, pvArg
,
1350 rc
= CRYPT_OpenParentStore(dwFlags
, pvArg
, &key
);
1354 CERT_SYSTEM_STORE_INFO info
= { sizeof(info
) };
1358 WCHAR name
[MAX_PATH
];
1359 DWORD size
= sizeof(name
) / sizeof(name
[0]);
1361 rc
= RegEnumKeyExW(key
, index
++, name
, &size
, NULL
, NULL
, NULL
,
1364 ret
= pfnEnum(name
, 0, &info
, NULL
, pvArg
);
1365 } while (ret
&& !rc
);
1366 if (ret
&& rc
!= ERROR_NO_MORE_ITEMS
)