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 static PWINECRYPT_CERTSTORE
CRYPT_SysRegOpenStoreW(HCRYPTPROV hCryptProv
,
272 DWORD dwFlags
, const void *pvPara
)
274 static const WCHAR rootW
[] = { 'R','o','o','t',0 };
275 static const WCHAR fmt
[] = { '%','s','\\','%','s',0 };
276 LPCWSTR storeName
= (LPCWSTR
)pvPara
;
278 PWINECRYPT_CERTSTORE store
= NULL
;
283 TRACE("(%ld, %08x, %s)\n", hCryptProv
, dwFlags
,
284 debugstr_w((LPCWSTR
)pvPara
));
288 SetLastError(E_INVALIDARG
);
291 if (!lstrcmpiW(storeName
, rootW
))
292 return CRYPT_RootOpenStore(hCryptProv
, dwFlags
);
295 switch (dwFlags
& CERT_SYSTEM_STORE_LOCATION_MASK
)
297 case CERT_SYSTEM_STORE_LOCAL_MACHINE
:
298 root
= HKEY_LOCAL_MACHINE
;
299 base
= CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH
;
301 case CERT_SYSTEM_STORE_CURRENT_USER
:
302 root
= HKEY_CURRENT_USER
;
303 base
= CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH
;
305 case CERT_SYSTEM_STORE_CURRENT_SERVICE
:
306 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
309 FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE, %s: stub\n",
310 debugstr_w(storeName
));
312 case CERT_SYSTEM_STORE_SERVICES
:
313 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
316 FIXME("CERT_SYSTEM_STORE_SERVICES, %s: stub\n",
317 debugstr_w(storeName
));
319 case CERT_SYSTEM_STORE_USERS
:
320 /* hku\user sid\Software\Microsoft\SystemCertificates */
321 FIXME("CERT_SYSTEM_STORE_USERS, %s: stub\n",
322 debugstr_w(storeName
));
324 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY
:
325 root
= HKEY_CURRENT_USER
;
326 base
= CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH
;
328 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY
:
329 root
= HKEY_LOCAL_MACHINE
;
330 base
= CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH
;
332 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE
:
333 /* hklm\Software\Microsoft\EnterpriseCertificates */
334 FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, %s: stub\n",
335 debugstr_w(storeName
));
338 SetLastError(E_INVALIDARG
);
342 storePath
= CryptMemAlloc((lstrlenW(base
) + lstrlenW(storeName
) + 2) *
348 REGSAM sam
= dwFlags
& CERT_STORE_READONLY_FLAG
? KEY_READ
:
351 wsprintfW(storePath
, fmt
, base
, storeName
);
352 if (dwFlags
& CERT_STORE_OPEN_EXISTING_FLAG
)
353 rc
= RegOpenKeyExW(root
, storePath
, 0, sam
, &key
);
358 rc
= RegCreateKeyExW(root
, storePath
, 0, NULL
, 0, sam
, NULL
,
360 if (!rc
&& dwFlags
& CERT_STORE_CREATE_NEW_FLAG
&&
361 disp
== REG_OPENED_EXISTING_KEY
)
364 rc
= ERROR_FILE_EXISTS
;
369 store
= CRYPT_RegOpenStore(hCryptProv
, dwFlags
, key
);
374 CryptMemFree(storePath
);
379 static PWINECRYPT_CERTSTORE
CRYPT_SysRegOpenStoreA(HCRYPTPROV hCryptProv
,
380 DWORD dwFlags
, const void *pvPara
)
383 PWINECRYPT_CERTSTORE ret
= NULL
;
385 TRACE("(%ld, %08x, %s)\n", hCryptProv
, dwFlags
,
386 debugstr_a((LPCSTR
)pvPara
));
390 SetLastError(ERROR_FILE_NOT_FOUND
);
393 len
= MultiByteToWideChar(CP_ACP
, 0, (LPCSTR
)pvPara
, -1, NULL
, 0);
396 LPWSTR storeName
= CryptMemAlloc(len
* sizeof(WCHAR
));
400 MultiByteToWideChar(CP_ACP
, 0, (LPCSTR
)pvPara
, -1, storeName
, len
);
401 ret
= CRYPT_SysRegOpenStoreW(hCryptProv
, dwFlags
, storeName
);
402 CryptMemFree(storeName
);
408 static PWINECRYPT_CERTSTORE
CRYPT_SysOpenStoreW(HCRYPTPROV hCryptProv
,
409 DWORD dwFlags
, const void *pvPara
)
411 HCERTSTORE store
= 0;
414 TRACE("(%ld, %08x, %s)\n", hCryptProv
, dwFlags
,
415 debugstr_w((LPCWSTR
)pvPara
));
419 SetLastError(ERROR_FILE_NOT_FOUND
);
422 /* This returns a different error than system registry stores if the
423 * location is invalid.
425 switch (dwFlags
& CERT_SYSTEM_STORE_LOCATION_MASK
)
427 case CERT_SYSTEM_STORE_LOCAL_MACHINE
:
428 case CERT_SYSTEM_STORE_CURRENT_USER
:
429 case CERT_SYSTEM_STORE_CURRENT_SERVICE
:
430 case CERT_SYSTEM_STORE_SERVICES
:
431 case CERT_SYSTEM_STORE_USERS
:
432 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY
:
433 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY
:
434 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE
:
438 SetLastError(ERROR_FILE_NOT_FOUND
);
443 HCERTSTORE regStore
= CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W
,
444 0, 0, dwFlags
, pvPara
);
448 store
= CertOpenStore(CERT_STORE_PROV_COLLECTION
, 0, 0,
449 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
450 CertAddStoreToCollection(store
, regStore
,
451 dwFlags
& CERT_STORE_READONLY_FLAG
? 0 :
452 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG
, 0);
453 CertCloseStore(regStore
, 0);
454 /* CERT_SYSTEM_STORE_CURRENT_USER returns both the HKCU and HKLM
457 if ((dwFlags
& CERT_SYSTEM_STORE_LOCATION_MASK
) ==
458 CERT_SYSTEM_STORE_CURRENT_USER
)
460 dwFlags
&= ~CERT_SYSTEM_STORE_CURRENT_USER
;
461 dwFlags
|= CERT_SYSTEM_STORE_LOCAL_MACHINE
;
462 regStore
= CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W
, 0,
466 CertAddStoreToCollection(store
, regStore
,
467 dwFlags
& CERT_STORE_READONLY_FLAG
? 0 :
468 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG
, 0);
469 CertCloseStore(regStore
, 0);
472 /* System store doesn't need crypto provider, so close it */
473 if (hCryptProv
&& !(dwFlags
& CERT_STORE_NO_CRYPT_RELEASE_FLAG
))
474 CryptReleaseContext(hCryptProv
, 0);
477 return (PWINECRYPT_CERTSTORE
)store
;
480 static PWINECRYPT_CERTSTORE
CRYPT_SysOpenStoreA(HCRYPTPROV hCryptProv
,
481 DWORD dwFlags
, const void *pvPara
)
484 PWINECRYPT_CERTSTORE ret
= NULL
;
486 TRACE("(%ld, %08x, %s)\n", hCryptProv
, dwFlags
,
487 debugstr_a((LPCSTR
)pvPara
));
491 SetLastError(ERROR_FILE_NOT_FOUND
);
494 len
= MultiByteToWideChar(CP_ACP
, 0, (LPCSTR
)pvPara
, -1, NULL
, 0);
497 LPWSTR storeName
= CryptMemAlloc(len
* sizeof(WCHAR
));
501 MultiByteToWideChar(CP_ACP
, 0, (LPCSTR
)pvPara
, -1, storeName
, len
);
502 ret
= CRYPT_SysOpenStoreW(hCryptProv
, dwFlags
, storeName
);
503 CryptMemFree(storeName
);
509 static void WINAPI
CRYPT_MsgCloseStore(HCERTSTORE hCertStore
, DWORD dwFlags
)
511 PWINE_MSGSTOREINFO store
= (PWINE_MSGSTOREINFO
)hCertStore
;
513 TRACE("(%p, %08x)\n", store
, dwFlags
);
514 CertCloseStore(store
->memStore
, dwFlags
);
515 CryptMsgClose(store
->msg
);
519 static void *msgProvFuncs
[] = {
521 NULL
, /* CERT_STORE_PROV_READ_CERT_FUNC */
522 NULL
, /* CERT_STORE_PROV_WRITE_CERT_FUNC */
523 NULL
, /* CERT_STORE_PROV_DELETE_CERT_FUNC */
524 NULL
, /* CERT_STORE_PROV_SET_CERT_PROPERTY_FUNC */
525 NULL
, /* CERT_STORE_PROV_READ_CRL_FUNC */
526 NULL
, /* CERT_STORE_PROV_WRITE_CRL_FUNC */
527 NULL
, /* CERT_STORE_PROV_DELETE_CRL_FUNC */
528 NULL
, /* CERT_STORE_PROV_SET_CRL_PROPERTY_FUNC */
529 NULL
, /* CERT_STORE_PROV_READ_CTL_FUNC */
530 NULL
, /* CERT_STORE_PROV_WRITE_CTL_FUNC */
531 NULL
, /* CERT_STORE_PROV_DELETE_CTL_FUNC */
532 NULL
, /* CERT_STORE_PROV_SET_CTL_PROPERTY_FUNC */
533 NULL
, /* CERT_STORE_PROV_CONTROL_FUNC */
536 static PWINECRYPT_CERTSTORE
CRYPT_MsgOpenStore(HCRYPTPROV hCryptProv
,
537 DWORD dwFlags
, const void *pvPara
)
539 PWINECRYPT_CERTSTORE store
= NULL
;
540 HCRYPTMSG msg
= (HCRYPTMSG
)pvPara
;
541 PWINECRYPT_CERTSTORE memStore
;
543 TRACE("(%ld, %08x, %p)\n", hCryptProv
, dwFlags
, pvPara
);
545 memStore
= CertOpenStore(CERT_STORE_PROV_MEMORY
, 0, 0,
546 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
550 DWORD size
, count
, i
;
552 size
= sizeof(count
);
553 ret
= CryptMsgGetParam(msg
, CMSG_CERT_COUNT_PARAM
, 0, &count
, &size
);
554 for (i
= 0; ret
&& i
< count
; i
++)
557 ret
= CryptMsgGetParam(msg
, CMSG_CERT_PARAM
, i
, NULL
, &size
);
560 LPBYTE buf
= CryptMemAlloc(size
);
564 ret
= CryptMsgGetParam(msg
, CMSG_CERT_PARAM
, i
, buf
, &size
);
566 ret
= CertAddEncodedCertificateToStore(memStore
,
567 X509_ASN_ENCODING
, buf
, size
, CERT_STORE_ADD_ALWAYS
,
573 size
= sizeof(count
);
574 ret
= CryptMsgGetParam(msg
, CMSG_CRL_COUNT_PARAM
, 0, &count
, &size
);
575 for (i
= 0; ret
&& i
< count
; i
++)
578 ret
= CryptMsgGetParam(msg
, CMSG_CRL_PARAM
, i
, NULL
, &size
);
581 LPBYTE buf
= CryptMemAlloc(size
);
585 ret
= CryptMsgGetParam(msg
, CMSG_CRL_PARAM
, i
, buf
, &size
);
587 ret
= CertAddEncodedCRLToStore(memStore
,
588 X509_ASN_ENCODING
, buf
, size
, CERT_STORE_ADD_ALWAYS
,
596 PWINE_MSGSTOREINFO info
= CryptMemAlloc(sizeof(WINE_MSGSTOREINFO
));
600 CERT_STORE_PROV_INFO provInfo
= { 0 };
602 info
->dwOpenFlags
= dwFlags
;
603 info
->memStore
= memStore
;
604 info
->msg
= CryptMsgDuplicate(msg
);
605 provInfo
.cbSize
= sizeof(provInfo
);
606 provInfo
.cStoreProvFunc
= sizeof(msgProvFuncs
) /
607 sizeof(msgProvFuncs
[0]);
608 provInfo
.rgpvStoreProvFunc
= msgProvFuncs
;
609 provInfo
.hStoreProv
= info
;
610 store
= CRYPT_ProvCreateStore(dwFlags
, memStore
,
612 /* Msg store doesn't need crypto provider, so close it */
613 if (hCryptProv
&& !(dwFlags
& CERT_STORE_NO_CRYPT_RELEASE_FLAG
))
614 CryptReleaseContext(hCryptProv
, 0);
617 CertCloseStore(memStore
, 0);
620 CertCloseStore(memStore
, 0);
622 TRACE("returning %p\n", store
);
626 static PWINECRYPT_CERTSTORE
CRYPT_PKCSOpenStore(HCRYPTPROV hCryptProv
,
627 DWORD dwFlags
, const void *pvPara
)
630 PWINECRYPT_CERTSTORE store
= NULL
;
631 const CRYPT_DATA_BLOB
*data
= (const CRYPT_DATA_BLOB
*)pvPara
;
633 DWORD msgOpenFlags
= dwFlags
& CERT_STORE_NO_CRYPT_RELEASE_FLAG
? 0 :
634 CMSG_CRYPT_RELEASE_CONTEXT_FLAG
;
636 TRACE("(%ld, %08x, %p)\n", hCryptProv
, dwFlags
, pvPara
);
638 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, msgOpenFlags
, CMSG_SIGNED
,
639 hCryptProv
, NULL
, NULL
);
640 ret
= CryptMsgUpdate(msg
, data
->pbData
, data
->cbData
, TRUE
);
644 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, msgOpenFlags
, 0,
645 hCryptProv
, NULL
, NULL
);
646 ret
= CryptMsgUpdate(msg
, data
->pbData
, data
->cbData
, TRUE
);
649 DWORD type
, size
= sizeof(type
);
651 /* Only signed messages are allowed, check type */
652 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, &type
, &size
);
653 if (ret
&& type
!= CMSG_SIGNED
)
655 SetLastError(CRYPT_E_INVALID_MSG_TYPE
);
661 store
= CRYPT_MsgOpenStore(0, dwFlags
, msg
);
663 TRACE("returning %p\n", store
);
667 static PWINECRYPT_CERTSTORE
CRYPT_PhysOpenStoreW(HCRYPTPROV hCryptProv
,
668 DWORD dwFlags
, const void *pvPara
)
670 if (dwFlags
& CERT_SYSTEM_STORE_RELOCATE_FLAG
)
671 FIXME("(%ld, %08x, %p): stub\n", hCryptProv
, dwFlags
, pvPara
);
673 FIXME("(%ld, %08x, %s): stub\n", hCryptProv
, dwFlags
,
674 debugstr_w((LPCWSTR
)pvPara
));
678 HCERTSTORE WINAPI
CertOpenStore(LPCSTR lpszStoreProvider
,
679 DWORD dwMsgAndCertEncodingType
, HCRYPTPROV_LEGACY hCryptProv
, DWORD dwFlags
,
682 WINECRYPT_CERTSTORE
*hcs
;
683 StoreOpenFunc openFunc
= NULL
;
685 TRACE("(%s, %08x, %08lx, %08x, %p)\n", debugstr_a(lpszStoreProvider
),
686 dwMsgAndCertEncodingType
, hCryptProv
, dwFlags
, pvPara
);
688 if (!HIWORD(lpszStoreProvider
))
690 switch (LOWORD(lpszStoreProvider
))
692 case (int)CERT_STORE_PROV_MSG
:
693 openFunc
= CRYPT_MsgOpenStore
;
695 case (int)CERT_STORE_PROV_MEMORY
:
696 openFunc
= CRYPT_MemOpenStore
;
698 case (int)CERT_STORE_PROV_FILE
:
699 openFunc
= CRYPT_FileOpenStore
;
701 case (int)CERT_STORE_PROV_PKCS7
:
702 openFunc
= CRYPT_PKCSOpenStore
;
704 case (int)CERT_STORE_PROV_REG
:
705 openFunc
= CRYPT_RegOpenStore
;
707 case (int)CERT_STORE_PROV_FILENAME_A
:
708 openFunc
= CRYPT_FileNameOpenStoreA
;
710 case (int)CERT_STORE_PROV_FILENAME_W
:
711 openFunc
= CRYPT_FileNameOpenStoreW
;
713 case (int)CERT_STORE_PROV_COLLECTION
:
714 openFunc
= CRYPT_CollectionOpenStore
;
716 case (int)CERT_STORE_PROV_SYSTEM_A
:
717 openFunc
= CRYPT_SysOpenStoreA
;
719 case (int)CERT_STORE_PROV_SYSTEM_W
:
720 openFunc
= CRYPT_SysOpenStoreW
;
722 case (int)CERT_STORE_PROV_SYSTEM_REGISTRY_A
:
723 openFunc
= CRYPT_SysRegOpenStoreA
;
725 case (int)CERT_STORE_PROV_SYSTEM_REGISTRY_W
:
726 openFunc
= CRYPT_SysRegOpenStoreW
;
728 case (int)CERT_STORE_PROV_PHYSICAL_W
:
729 openFunc
= CRYPT_PhysOpenStoreW
;
732 if (LOWORD(lpszStoreProvider
))
733 FIXME("unimplemented type %d\n", LOWORD(lpszStoreProvider
));
736 else if (!strcasecmp(lpszStoreProvider
, sz_CERT_STORE_PROV_MEMORY
))
737 openFunc
= CRYPT_MemOpenStore
;
738 else if (!strcasecmp(lpszStoreProvider
, sz_CERT_STORE_PROV_FILENAME_W
))
739 openFunc
= CRYPT_FileOpenStore
;
740 else if (!strcasecmp(lpszStoreProvider
, sz_CERT_STORE_PROV_SYSTEM
))
741 openFunc
= CRYPT_SysOpenStoreW
;
742 else if (!strcasecmp(lpszStoreProvider
, sz_CERT_STORE_PROV_COLLECTION
))
743 openFunc
= CRYPT_CollectionOpenStore
;
744 else if (!strcasecmp(lpszStoreProvider
, sz_CERT_STORE_PROV_SYSTEM_REGISTRY
))
745 openFunc
= CRYPT_SysRegOpenStoreW
;
748 FIXME("unimplemented type %s\n", lpszStoreProvider
);
753 hcs
= CRYPT_ProvOpenStore(lpszStoreProvider
, dwMsgAndCertEncodingType
,
754 hCryptProv
, dwFlags
, pvPara
);
756 hcs
= openFunc(hCryptProv
, dwFlags
, pvPara
);
757 return (HCERTSTORE
)hcs
;
760 HCERTSTORE WINAPI
CertOpenSystemStoreA(HCRYPTPROV_LEGACY hProv
,
761 LPCSTR szSubSystemProtocol
)
763 if (!szSubSystemProtocol
)
765 SetLastError(E_INVALIDARG
);
768 return CertOpenStore(CERT_STORE_PROV_SYSTEM_A
, 0, hProv
,
769 CERT_SYSTEM_STORE_CURRENT_USER
, szSubSystemProtocol
);
772 HCERTSTORE WINAPI
CertOpenSystemStoreW(HCRYPTPROV_LEGACY hProv
,
773 LPCWSTR szSubSystemProtocol
)
775 if (!szSubSystemProtocol
)
777 SetLastError(E_INVALIDARG
);
780 return CertOpenStore(CERT_STORE_PROV_SYSTEM_W
, 0, hProv
,
781 CERT_SYSTEM_STORE_CURRENT_USER
, szSubSystemProtocol
);
784 BOOL WINAPI
CertSaveStore(HCERTSTORE hCertStore
, DWORD dwMsgAndCertEncodingType
,
785 DWORD dwSaveAs
, DWORD dwSaveTo
, void* pvSaveToPara
, DWORD dwFlags
)
787 FIXME("(%p,%d,%d,%d,%p,%08x) stub!\n", hCertStore
,
788 dwMsgAndCertEncodingType
, dwSaveAs
, dwSaveTo
, pvSaveToPara
, dwFlags
);
792 #define CertContext_CopyProperties(to, from) \
793 Context_CopyProperties((to), (from), sizeof(CERT_CONTEXT))
795 BOOL WINAPI
CertAddCertificateContextToStore(HCERTSTORE hCertStore
,
796 PCCERT_CONTEXT pCertContext
, DWORD dwAddDisposition
,
797 PCCERT_CONTEXT
*ppStoreContext
)
799 PWINECRYPT_CERTSTORE store
= (PWINECRYPT_CERTSTORE
)hCertStore
;
801 PCCERT_CONTEXT toAdd
= NULL
, existing
= NULL
;
803 TRACE("(%p, %p, %08x, %p)\n", hCertStore
, pCertContext
,
804 dwAddDisposition
, ppStoreContext
);
806 /* Weird case to pass a test */
807 if (dwAddDisposition
== 0)
809 SetLastError(STATUS_ACCESS_VIOLATION
);
812 if (dwAddDisposition
!= CERT_STORE_ADD_ALWAYS
)
815 DWORD size
= sizeof(hashToAdd
);
817 ret
= CertGetCertificateContextProperty(pCertContext
, CERT_HASH_PROP_ID
,
821 CRYPT_HASH_BLOB blob
= { sizeof(hashToAdd
), hashToAdd
};
823 existing
= CertFindCertificateInStore(hCertStore
,
824 pCertContext
->dwCertEncodingType
, 0, CERT_FIND_SHA1_HASH
, &blob
,
829 switch (dwAddDisposition
)
831 case CERT_STORE_ADD_ALWAYS
:
832 toAdd
= CertDuplicateCertificateContext(pCertContext
);
834 case CERT_STORE_ADD_NEW
:
837 TRACE("found matching certificate, not adding\n");
838 SetLastError(CRYPT_E_EXISTS
);
842 toAdd
= CertDuplicateCertificateContext(pCertContext
);
844 case CERT_STORE_ADD_REPLACE_EXISTING
:
845 toAdd
= CertDuplicateCertificateContext(pCertContext
);
847 case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES
:
848 toAdd
= CertDuplicateCertificateContext(pCertContext
);
850 CertContext_CopyProperties(toAdd
, existing
);
852 case CERT_STORE_ADD_USE_EXISTING
:
855 CertContext_CopyProperties(existing
, pCertContext
);
856 *ppStoreContext
= CertDuplicateCertificateContext(existing
);
859 toAdd
= CertDuplicateCertificateContext(pCertContext
);
862 FIXME("Unimplemented add disposition %d\n", dwAddDisposition
);
869 ret
= store
->certs
.addContext(store
, (void *)toAdd
,
870 (void *)existing
, (const void **)ppStoreContext
);
871 else if (ppStoreContext
)
872 *ppStoreContext
= CertDuplicateCertificateContext(toAdd
);
873 CertFreeCertificateContext(toAdd
);
875 CertFreeCertificateContext(existing
);
877 TRACE("returning %d\n", ret
);
881 PCCERT_CONTEXT WINAPI
CertEnumCertificatesInStore(HCERTSTORE hCertStore
,
882 PCCERT_CONTEXT pPrev
)
884 WINECRYPT_CERTSTORE
*hcs
= (WINECRYPT_CERTSTORE
*)hCertStore
;
887 TRACE("(%p, %p)\n", hCertStore
, pPrev
);
890 else if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
893 ret
= (PCCERT_CONTEXT
)hcs
->certs
.enumContext(hcs
, (void *)pPrev
);
897 BOOL WINAPI
CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext
)
901 TRACE("(%p)\n", pCertContext
);
905 else if (!pCertContext
->hCertStore
)
908 CertFreeCertificateContext(pCertContext
);
912 PWINECRYPT_CERTSTORE hcs
=
913 (PWINECRYPT_CERTSTORE
)pCertContext
->hCertStore
;
915 if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
918 ret
= hcs
->certs
.deleteContext(hcs
, (void *)pCertContext
);
919 CertFreeCertificateContext(pCertContext
);
924 #define CrlContext_CopyProperties(to, from) \
925 Context_CopyProperties((to), (from), sizeof(CRL_CONTEXT))
927 BOOL WINAPI
CertAddCRLContextToStore(HCERTSTORE hCertStore
,
928 PCCRL_CONTEXT pCrlContext
, DWORD dwAddDisposition
,
929 PCCRL_CONTEXT
* ppStoreContext
)
931 PWINECRYPT_CERTSTORE store
= (PWINECRYPT_CERTSTORE
)hCertStore
;
933 PCCRL_CONTEXT toAdd
= NULL
, existing
= NULL
;
935 TRACE("(%p, %p, %08x, %p)\n", hCertStore
, pCrlContext
,
936 dwAddDisposition
, ppStoreContext
);
938 /* Weird case to pass a test */
939 if (dwAddDisposition
== 0)
941 SetLastError(STATUS_ACCESS_VIOLATION
);
944 if (dwAddDisposition
!= CERT_STORE_ADD_ALWAYS
)
946 existing
= CertFindCRLInStore(hCertStore
, 0, 0, CRL_FIND_EXISTING
,
950 switch (dwAddDisposition
)
952 case CERT_STORE_ADD_ALWAYS
:
953 toAdd
= CertDuplicateCRLContext(pCrlContext
);
955 case CERT_STORE_ADD_NEW
:
958 TRACE("found matching CRL, not adding\n");
959 SetLastError(CRYPT_E_EXISTS
);
963 toAdd
= CertDuplicateCRLContext(pCrlContext
);
965 case CERT_STORE_ADD_NEWER
:
968 LONG newer
= CompareFileTime(&existing
->pCrlInfo
->ThisUpdate
,
969 &pCrlContext
->pCrlInfo
->ThisUpdate
);
972 toAdd
= CertDuplicateCRLContext(pCrlContext
);
975 TRACE("existing CRL is newer, not adding\n");
976 SetLastError(CRYPT_E_EXISTS
);
981 toAdd
= CertDuplicateCRLContext(pCrlContext
);
983 case CERT_STORE_ADD_REPLACE_EXISTING
:
984 toAdd
= CertDuplicateCRLContext(pCrlContext
);
986 case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES
:
987 toAdd
= CertDuplicateCRLContext(pCrlContext
);
989 CrlContext_CopyProperties(toAdd
, existing
);
991 case CERT_STORE_ADD_USE_EXISTING
:
993 CrlContext_CopyProperties(existing
, pCrlContext
);
996 FIXME("Unimplemented add disposition %d\n", dwAddDisposition
);
1003 ret
= store
->crls
.addContext(store
, (void *)toAdd
,
1004 (void *)existing
, (const void **)ppStoreContext
);
1005 else if (ppStoreContext
)
1006 *ppStoreContext
= CertDuplicateCRLContext(toAdd
);
1007 CertFreeCRLContext(toAdd
);
1009 CertFreeCRLContext(existing
);
1011 TRACE("returning %d\n", ret
);
1015 BOOL WINAPI
CertDeleteCRLFromStore(PCCRL_CONTEXT pCrlContext
)
1019 TRACE("(%p)\n", pCrlContext
);
1023 else if (!pCrlContext
->hCertStore
)
1026 CertFreeCRLContext(pCrlContext
);
1030 PWINECRYPT_CERTSTORE hcs
=
1031 (PWINECRYPT_CERTSTORE
)pCrlContext
->hCertStore
;
1033 if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1036 ret
= hcs
->crls
.deleteContext(hcs
, (void *)pCrlContext
);
1037 CertFreeCRLContext(pCrlContext
);
1042 PCCRL_CONTEXT WINAPI
CertEnumCRLsInStore(HCERTSTORE hCertStore
,
1043 PCCRL_CONTEXT pPrev
)
1045 WINECRYPT_CERTSTORE
*hcs
= (WINECRYPT_CERTSTORE
*)hCertStore
;
1048 TRACE("(%p, %p)\n", hCertStore
, pPrev
);
1051 else if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1054 ret
= (PCCRL_CONTEXT
)hcs
->crls
.enumContext(hcs
, (void *)pPrev
);
1058 PCCTL_CONTEXT WINAPI
CertCreateCTLContext(DWORD dwCertEncodingType
,
1059 const BYTE
* pbCtlEncoded
, DWORD cbCtlEncoded
)
1061 FIXME("(%08x, %p, %08x): stub\n", dwCertEncodingType
, pbCtlEncoded
,
1066 BOOL WINAPI
CertAddEncodedCTLToStore(HCERTSTORE hCertStore
,
1067 DWORD dwMsgAndCertEncodingType
, const BYTE
*pbCtlEncoded
, DWORD cbCtlEncoded
,
1068 DWORD dwAddDisposition
, PCCTL_CONTEXT
*ppCtlContext
)
1070 FIXME("(%p, %08x, %p, %d, %08x, %p): stub\n", hCertStore
,
1071 dwMsgAndCertEncodingType
, pbCtlEncoded
, cbCtlEncoded
, dwAddDisposition
,
1076 BOOL WINAPI
CertAddCTLContextToStore(HCERTSTORE hCertStore
,
1077 PCCTL_CONTEXT pCtlContext
, DWORD dwAddDisposition
,
1078 PCCTL_CONTEXT
* ppStoreContext
)
1080 FIXME("(%p, %p, %08x, %p): stub\n", hCertStore
, pCtlContext
,
1081 dwAddDisposition
, ppStoreContext
);
1085 PCCTL_CONTEXT WINAPI
CertDuplicateCTLContext(PCCTL_CONTEXT pCtlContext
)
1087 FIXME("(%p): stub\n", pCtlContext
);
1091 BOOL WINAPI
CertFreeCTLContext(PCCTL_CONTEXT pCtlContext
)
1093 FIXME("(%p): stub\n", pCtlContext
);
1097 BOOL WINAPI
CertDeleteCTLFromStore(PCCTL_CONTEXT pCtlContext
)
1099 FIXME("(%p): stub\n", pCtlContext
);
1103 PCCTL_CONTEXT WINAPI
CertEnumCTLsInStore(HCERTSTORE hCertStore
,
1104 PCCTL_CONTEXT pPrev
)
1106 FIXME("(%p, %p): stub\n", hCertStore
, pPrev
);
1110 HCERTSTORE WINAPI
CertDuplicateStore(HCERTSTORE hCertStore
)
1112 WINECRYPT_CERTSTORE
*hcs
= (WINECRYPT_CERTSTORE
*)hCertStore
;
1114 TRACE("(%p)\n", hCertStore
);
1116 if (hcs
&& hcs
->dwMagic
== WINE_CRYPTCERTSTORE_MAGIC
)
1117 InterlockedIncrement(&hcs
->ref
);
1121 BOOL WINAPI
CertCloseStore(HCERTSTORE hCertStore
, DWORD dwFlags
)
1123 WINECRYPT_CERTSTORE
*hcs
= (WINECRYPT_CERTSTORE
*) hCertStore
;
1125 TRACE("(%p, %08x)\n", hCertStore
, dwFlags
);
1130 if ( hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1133 if (InterlockedDecrement(&hcs
->ref
) == 0)
1135 TRACE("%p's ref count is 0, freeing\n", hcs
);
1137 hcs
->closeStore(hcs
, dwFlags
);
1140 TRACE("%p's ref count is %d\n", hcs
, hcs
->ref
);
1144 BOOL WINAPI
CertControlStore(HCERTSTORE hCertStore
, DWORD dwFlags
,
1145 DWORD dwCtrlType
, void const *pvCtrlPara
)
1147 WINECRYPT_CERTSTORE
*hcs
= (WINECRYPT_CERTSTORE
*)hCertStore
;
1150 TRACE("(%p, %08x, %d, %p)\n", hCertStore
, dwFlags
, dwCtrlType
,
1155 else if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1160 ret
= hcs
->control(hCertStore
, dwFlags
, dwCtrlType
, pvCtrlPara
);
1167 BOOL WINAPI
CertGetStoreProperty(HCERTSTORE hCertStore
, DWORD dwPropId
,
1168 void *pvData
, DWORD
*pcbData
)
1170 PWINECRYPT_CERTSTORE store
= (PWINECRYPT_CERTSTORE
)hCertStore
;
1173 TRACE("(%p, %d, %p, %p)\n", hCertStore
, dwPropId
, pvData
, pcbData
);
1177 case CERT_ACCESS_STATE_PROP_ID
:
1180 *pcbData
= sizeof(DWORD
);
1183 else if (*pcbData
< sizeof(DWORD
))
1185 SetLastError(ERROR_MORE_DATA
);
1186 *pcbData
= sizeof(DWORD
);
1192 if (store
->type
!= StoreTypeMem
&&
1193 !(store
->dwOpenFlags
& CERT_STORE_READONLY_FLAG
))
1194 state
|= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG
;
1195 *(DWORD
*)pvData
= state
;
1200 if (store
->properties
)
1202 CRYPT_DATA_BLOB blob
;
1204 ret
= ContextPropertyList_FindProperty(store
->properties
, dwPropId
,
1209 *pcbData
= blob
.cbData
;
1210 else if (*pcbData
< blob
.cbData
)
1212 SetLastError(ERROR_MORE_DATA
);
1213 *pcbData
= blob
.cbData
;
1218 memcpy(pvData
, blob
.pbData
, blob
.cbData
);
1219 *pcbData
= blob
.cbData
;
1223 SetLastError(CRYPT_E_NOT_FOUND
);
1226 SetLastError(CRYPT_E_NOT_FOUND
);
1231 BOOL WINAPI
CertSetStoreProperty(HCERTSTORE hCertStore
, DWORD dwPropId
,
1232 DWORD dwFlags
, const void *pvData
)
1234 PWINECRYPT_CERTSTORE store
= (PWINECRYPT_CERTSTORE
)hCertStore
;
1237 TRACE("(%p, %d, %08x, %p)\n", hCertStore
, dwPropId
, dwFlags
, pvData
);
1239 if (!store
->properties
)
1240 store
->properties
= ContextPropertyList_Create();
1243 case CERT_ACCESS_STATE_PROP_ID
:
1244 SetLastError(E_INVALIDARG
);
1249 const CRYPT_DATA_BLOB
*blob
= (const CRYPT_DATA_BLOB
*)pvData
;
1251 ret
= ContextPropertyList_SetProperty(store
->properties
, dwPropId
,
1252 blob
->pbData
, blob
->cbData
);
1256 ContextPropertyList_RemoveProperty(store
->properties
, dwPropId
);
1263 DWORD WINAPI
CertEnumCTLContextProperties(PCCTL_CONTEXT pCTLContext
,
1266 FIXME("(%p, %d): stub\n", pCTLContext
, dwPropId
);
1270 BOOL WINAPI
CertGetCTLContextProperty(PCCTL_CONTEXT pCTLContext
,
1271 DWORD dwPropId
, void *pvData
, DWORD
*pcbData
)
1273 FIXME("(%p, %d, %p, %p): stub\n", pCTLContext
, dwPropId
, pvData
, pcbData
);
1277 BOOL WINAPI
CertSetCTLContextProperty(PCCTL_CONTEXT pCTLContext
,
1278 DWORD dwPropId
, DWORD dwFlags
, const void *pvData
)
1280 FIXME("(%p, %d, %08x, %p): stub\n", pCTLContext
, dwPropId
, dwFlags
,
1285 static LONG
CRYPT_OpenParentStore(DWORD dwFlags
,
1286 void *pvSystemStoreLocationPara
, HKEY
*key
)
1291 TRACE("(%08x, %p)\n", dwFlags
, pvSystemStoreLocationPara
);
1293 switch (dwFlags
& CERT_SYSTEM_STORE_LOCATION_MASK
)
1295 case CERT_SYSTEM_STORE_LOCAL_MACHINE
:
1296 root
= HKEY_LOCAL_MACHINE
;
1297 base
= CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH
;
1299 case CERT_SYSTEM_STORE_CURRENT_USER
:
1300 root
= HKEY_CURRENT_USER
;
1301 base
= CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH
;
1303 case CERT_SYSTEM_STORE_CURRENT_SERVICE
:
1304 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
1305 * SystemCertificates
1307 FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE\n");
1308 return ERROR_FILE_NOT_FOUND
;
1309 case CERT_SYSTEM_STORE_SERVICES
:
1310 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
1311 * SystemCertificates
1313 FIXME("CERT_SYSTEM_STORE_SERVICES\n");
1314 return ERROR_FILE_NOT_FOUND
;
1315 case CERT_SYSTEM_STORE_USERS
:
1316 /* hku\user sid\Software\Microsoft\SystemCertificates */
1317 FIXME("CERT_SYSTEM_STORE_USERS\n");
1318 return ERROR_FILE_NOT_FOUND
;
1319 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY
:
1320 root
= HKEY_CURRENT_USER
;
1321 base
= CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH
;
1323 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY
:
1324 root
= HKEY_LOCAL_MACHINE
;
1325 base
= CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH
;
1327 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE
:
1328 /* hklm\Software\Microsoft\EnterpriseCertificates */
1329 FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE\n");
1330 return ERROR_FILE_NOT_FOUND
;
1332 return ERROR_FILE_NOT_FOUND
;
1335 return RegOpenKeyExW(root
, base
, 0, KEY_READ
, key
);
1338 BOOL WINAPI
CertEnumSystemStore(DWORD dwFlags
, void *pvSystemStoreLocationPara
,
1339 void *pvArg
, PFN_CERT_ENUM_SYSTEM_STORE pfnEnum
)
1345 TRACE("(%08x, %p, %p, %p)\n", dwFlags
, pvSystemStoreLocationPara
, pvArg
,
1348 rc
= CRYPT_OpenParentStore(dwFlags
, pvArg
, &key
);
1352 CERT_SYSTEM_STORE_INFO info
= { sizeof(info
) };
1356 WCHAR name
[MAX_PATH
];
1357 DWORD size
= sizeof(name
) / sizeof(name
[0]);
1359 rc
= RegEnumKeyExW(key
, index
++, name
, &size
, NULL
, NULL
, NULL
,
1362 ret
= pfnEnum(name
, 0, &info
, NULL
, pvArg
);
1363 } while (ret
&& !rc
);
1364 if (ret
&& rc
!= ERROR_NO_MORE_ITEMS
)