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 void CRYPT_InitStore(WINECRYPT_CERTSTORE
*store
, DWORD dwFlags
,
100 store
->dwMagic
= WINE_CRYPTCERTSTORE_MAGIC
;
102 store
->dwOpenFlags
= dwFlags
;
103 store
->properties
= NULL
;
106 void CRYPT_FreeStore(PWINECRYPT_CERTSTORE store
)
108 if (store
->properties
)
109 ContextPropertyList_Free(store
->properties
);
113 BOOL WINAPI
I_CertUpdateStore(HCERTSTORE store1
, HCERTSTORE store2
, DWORD unk0
,
116 static BOOL warned
= FALSE
;
117 const WINE_CONTEXT_INTERFACE
* const interfaces
[] = { pCertInterface
,
118 pCRLInterface
, pCTLInterface
};
121 TRACE("(%p, %p, %08x, %08x)\n", store1
, store2
, unk0
, unk1
);
124 FIXME("semi-stub\n");
128 /* Poor-man's resync: empty first store, then add everything from second
131 for (i
= 0; i
< sizeof(interfaces
) / sizeof(interfaces
[0]); i
++)
136 context
= interfaces
[i
]->enumContextsInStore(store1
, NULL
);
138 interfaces
[i
]->deleteFromStore(context
);
141 context
= interfaces
[i
]->enumContextsInStore(store2
, context
);
143 interfaces
[i
]->addContextToStore(store1
, context
,
144 CERT_STORE_ADD_ALWAYS
, NULL
);
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
);
161 context
->hCertStore
= store
;
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
;
173 TRACE("(%p, %p)\n", store
, pPrev
);
175 ret
= ContextList_Enum(ms
->certs
, pPrev
);
177 SetLastError(CRYPT_E_NOT_FOUND
);
179 TRACE("returning %p\n", ret
);
183 static BOOL
CRYPT_MemDeleteCert(PWINECRYPT_CERTSTORE store
, void *pCertContext
)
185 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
187 ContextList_Delete(ms
->certs
, pCertContext
);
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
);
202 context
->hCertStore
= store
;
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
;
214 TRACE("(%p, %p)\n", store
, pPrev
);
216 ret
= ContextList_Enum(ms
->crls
, pPrev
);
218 SetLastError(CRYPT_E_NOT_FOUND
);
220 TRACE("returning %p\n", ret
);
224 static BOOL
CRYPT_MemDeleteCrl(PWINECRYPT_CERTSTORE store
, void *pCrlContext
)
226 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
228 ContextList_Delete(ms
->crls
, pCrlContext
);
232 static void WINAPI
CRYPT_MemCloseStore(HCERTSTORE hCertStore
, DWORD dwFlags
)
234 WINE_MEMSTORE
*store
= (WINE_MEMSTORE
*)hCertStore
;
236 TRACE("(%p, %08x)\n", store
, 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
);
259 store
= CryptMemAlloc(sizeof(WINE_MEMSTORE
));
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
;
291 PWINECRYPT_CERTSTORE store
= NULL
;
296 TRACE("(%ld, %08x, %s)\n", hCryptProv
, dwFlags
,
297 debugstr_w((LPCWSTR
)pvPara
));
301 SetLastError(E_INVALIDARG
);
304 if (!lstrcmpiW(storeName
, rootW
))
305 return CRYPT_RootOpenStore(hCryptProv
, dwFlags
);
308 switch (dwFlags
& CERT_SYSTEM_STORE_LOCATION_MASK
)
310 case CERT_SYSTEM_STORE_LOCAL_MACHINE
:
311 root
= HKEY_LOCAL_MACHINE
;
312 base
= CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH
;
314 case CERT_SYSTEM_STORE_CURRENT_USER
:
315 root
= HKEY_CURRENT_USER
;
316 base
= CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH
;
318 case CERT_SYSTEM_STORE_CURRENT_SERVICE
:
319 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
322 FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE, %s: stub\n",
323 debugstr_w(storeName
));
325 case CERT_SYSTEM_STORE_SERVICES
:
326 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
329 FIXME("CERT_SYSTEM_STORE_SERVICES, %s: stub\n",
330 debugstr_w(storeName
));
332 case CERT_SYSTEM_STORE_USERS
:
333 /* hku\user sid\Software\Microsoft\SystemCertificates */
334 FIXME("CERT_SYSTEM_STORE_USERS, %s: stub\n",
335 debugstr_w(storeName
));
337 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY
:
338 root
= HKEY_CURRENT_USER
;
339 base
= CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH
;
341 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY
:
342 root
= HKEY_LOCAL_MACHINE
;
343 base
= CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH
;
345 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE
:
346 /* hklm\Software\Microsoft\EnterpriseCertificates */
347 FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, %s: stub\n",
348 debugstr_w(storeName
));
351 SetLastError(E_INVALIDARG
);
355 storePath
= CryptMemAlloc((lstrlenW(base
) + lstrlenW(storeName
) + 2) *
361 REGSAM sam
= dwFlags
& CERT_STORE_READONLY_FLAG
? KEY_READ
:
364 wsprintfW(storePath
, fmt
, base
, storeName
);
365 if (dwFlags
& CERT_STORE_OPEN_EXISTING_FLAG
)
366 rc
= RegOpenKeyExW(root
, storePath
, 0, sam
, &key
);
371 rc
= RegCreateKeyExW(root
, storePath
, 0, NULL
, 0, sam
, NULL
,
373 if (!rc
&& dwFlags
& CERT_STORE_CREATE_NEW_FLAG
&&
374 disp
== REG_OPENED_EXISTING_KEY
)
377 rc
= ERROR_FILE_EXISTS
;
382 store
= CRYPT_RegOpenStore(hCryptProv
, dwFlags
, key
);
387 CryptMemFree(storePath
);
392 static PWINECRYPT_CERTSTORE
CRYPT_SysRegOpenStoreA(HCRYPTPROV hCryptProv
,
393 DWORD dwFlags
, const void *pvPara
)
396 PWINECRYPT_CERTSTORE ret
= NULL
;
398 TRACE("(%ld, %08x, %s)\n", hCryptProv
, dwFlags
,
399 debugstr_a((LPCSTR
)pvPara
));
403 SetLastError(ERROR_FILE_NOT_FOUND
);
406 len
= MultiByteToWideChar(CP_ACP
, 0, (LPCSTR
)pvPara
, -1, NULL
, 0);
409 LPWSTR storeName
= CryptMemAlloc(len
* sizeof(WCHAR
));
413 MultiByteToWideChar(CP_ACP
, 0, (LPCSTR
)pvPara
, -1, storeName
, len
);
414 ret
= CRYPT_SysRegOpenStoreW(hCryptProv
, dwFlags
, storeName
);
415 CryptMemFree(storeName
);
421 static PWINECRYPT_CERTSTORE
CRYPT_SysOpenStoreW(HCRYPTPROV hCryptProv
,
422 DWORD dwFlags
, const void *pvPara
)
424 HCERTSTORE store
= 0;
427 TRACE("(%ld, %08x, %s)\n", hCryptProv
, dwFlags
,
428 debugstr_w((LPCWSTR
)pvPara
));
432 SetLastError(ERROR_FILE_NOT_FOUND
);
435 /* This returns a different error than system registry stores if the
436 * location is invalid.
438 switch (dwFlags
& CERT_SYSTEM_STORE_LOCATION_MASK
)
440 case CERT_SYSTEM_STORE_LOCAL_MACHINE
:
441 case CERT_SYSTEM_STORE_CURRENT_USER
:
442 case CERT_SYSTEM_STORE_CURRENT_SERVICE
:
443 case CERT_SYSTEM_STORE_SERVICES
:
444 case CERT_SYSTEM_STORE_USERS
:
445 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY
:
446 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY
:
447 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE
:
451 SetLastError(ERROR_FILE_NOT_FOUND
);
456 HCERTSTORE regStore
= CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W
,
457 0, 0, dwFlags
, pvPara
);
461 store
= CertOpenStore(CERT_STORE_PROV_COLLECTION
, 0, 0,
462 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
463 CertAddStoreToCollection(store
, regStore
,
464 dwFlags
& CERT_STORE_READONLY_FLAG
? 0 :
465 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG
, 0);
466 CertCloseStore(regStore
, 0);
467 /* CERT_SYSTEM_STORE_CURRENT_USER returns both the HKCU and HKLM
470 if ((dwFlags
& CERT_SYSTEM_STORE_LOCATION_MASK
) ==
471 CERT_SYSTEM_STORE_CURRENT_USER
)
473 dwFlags
&= ~CERT_SYSTEM_STORE_CURRENT_USER
;
474 dwFlags
|= CERT_SYSTEM_STORE_LOCAL_MACHINE
;
475 regStore
= CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W
, 0,
479 CertAddStoreToCollection(store
, regStore
,
480 dwFlags
& CERT_STORE_READONLY_FLAG
? 0 :
481 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG
, 0);
482 CertCloseStore(regStore
, 0);
485 /* System store doesn't need crypto provider, so close it */
486 if (hCryptProv
&& !(dwFlags
& CERT_STORE_NO_CRYPT_RELEASE_FLAG
))
487 CryptReleaseContext(hCryptProv
, 0);
490 return (PWINECRYPT_CERTSTORE
)store
;
493 static PWINECRYPT_CERTSTORE
CRYPT_SysOpenStoreA(HCRYPTPROV hCryptProv
,
494 DWORD dwFlags
, const void *pvPara
)
497 PWINECRYPT_CERTSTORE ret
= NULL
;
499 TRACE("(%ld, %08x, %s)\n", hCryptProv
, dwFlags
,
500 debugstr_a((LPCSTR
)pvPara
));
504 SetLastError(ERROR_FILE_NOT_FOUND
);
507 len
= MultiByteToWideChar(CP_ACP
, 0, (LPCSTR
)pvPara
, -1, NULL
, 0);
510 LPWSTR storeName
= CryptMemAlloc(len
* sizeof(WCHAR
));
514 MultiByteToWideChar(CP_ACP
, 0, (LPCSTR
)pvPara
, -1, storeName
, len
);
515 ret
= CRYPT_SysOpenStoreW(hCryptProv
, dwFlags
, storeName
);
516 CryptMemFree(storeName
);
522 static void WINAPI
CRYPT_MsgCloseStore(HCERTSTORE hCertStore
, DWORD dwFlags
)
524 HCRYPTMSG msg
= hCertStore
;
526 TRACE("(%p, %08x)\n", msg
, dwFlags
);
530 static void *msgProvFuncs
[] = {
534 static PWINECRYPT_CERTSTORE
CRYPT_MsgOpenStore(HCRYPTPROV hCryptProv
,
535 DWORD dwFlags
, const void *pvPara
)
537 PWINECRYPT_CERTSTORE store
= NULL
;
538 HCRYPTMSG msg
= (HCRYPTMSG
)pvPara
;
539 PWINECRYPT_CERTSTORE memStore
;
541 TRACE("(%ld, %08x, %p)\n", hCryptProv
, dwFlags
, pvPara
);
543 memStore
= CertOpenStore(CERT_STORE_PROV_MEMORY
, 0, 0,
544 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
548 DWORD size
, count
, i
;
550 size
= sizeof(count
);
551 ret
= CryptMsgGetParam(msg
, CMSG_CERT_COUNT_PARAM
, 0, &count
, &size
);
552 for (i
= 0; ret
&& i
< count
; i
++)
555 ret
= CryptMsgGetParam(msg
, CMSG_CERT_PARAM
, i
, NULL
, &size
);
558 LPBYTE buf
= CryptMemAlloc(size
);
562 ret
= CryptMsgGetParam(msg
, CMSG_CERT_PARAM
, i
, buf
, &size
);
564 ret
= CertAddEncodedCertificateToStore(memStore
,
565 X509_ASN_ENCODING
, buf
, size
, CERT_STORE_ADD_ALWAYS
,
571 size
= sizeof(count
);
572 ret
= CryptMsgGetParam(msg
, CMSG_CRL_COUNT_PARAM
, 0, &count
, &size
);
573 for (i
= 0; ret
&& i
< count
; i
++)
576 ret
= CryptMsgGetParam(msg
, CMSG_CRL_PARAM
, i
, NULL
, &size
);
579 LPBYTE buf
= CryptMemAlloc(size
);
583 ret
= CryptMsgGetParam(msg
, CMSG_CRL_PARAM
, i
, buf
, &size
);
585 ret
= CertAddEncodedCRLToStore(memStore
,
586 X509_ASN_ENCODING
, buf
, size
, CERT_STORE_ADD_ALWAYS
,
594 CERT_STORE_PROV_INFO provInfo
= { 0 };
596 provInfo
.cbSize
= sizeof(provInfo
);
597 provInfo
.cStoreProvFunc
= sizeof(msgProvFuncs
) /
598 sizeof(msgProvFuncs
[0]);
599 provInfo
.rgpvStoreProvFunc
= msgProvFuncs
;
600 provInfo
.hStoreProv
= CryptMsgDuplicate(msg
);
601 store
= CRYPT_ProvCreateStore(dwFlags
, memStore
, &provInfo
);
602 /* Msg store doesn't need crypto provider, so close it */
603 if (hCryptProv
&& !(dwFlags
& CERT_STORE_NO_CRYPT_RELEASE_FLAG
))
604 CryptReleaseContext(hCryptProv
, 0);
607 CertCloseStore(memStore
, 0);
609 TRACE("returning %p\n", store
);
613 static PWINECRYPT_CERTSTORE
CRYPT_PKCSOpenStore(HCRYPTPROV hCryptProv
,
614 DWORD dwFlags
, const void *pvPara
)
617 PWINECRYPT_CERTSTORE store
= NULL
;
618 const CRYPT_DATA_BLOB
*data
= (const CRYPT_DATA_BLOB
*)pvPara
;
620 DWORD msgOpenFlags
= dwFlags
& CERT_STORE_NO_CRYPT_RELEASE_FLAG
? 0 :
621 CMSG_CRYPT_RELEASE_CONTEXT_FLAG
;
623 TRACE("(%ld, %08x, %p)\n", hCryptProv
, dwFlags
, pvPara
);
625 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, msgOpenFlags
, CMSG_SIGNED
,
626 hCryptProv
, NULL
, NULL
);
627 ret
= CryptMsgUpdate(msg
, data
->pbData
, data
->cbData
, TRUE
);
631 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, msgOpenFlags
, 0,
632 hCryptProv
, NULL
, NULL
);
633 ret
= CryptMsgUpdate(msg
, data
->pbData
, data
->cbData
, TRUE
);
636 DWORD type
, size
= sizeof(type
);
638 /* Only signed messages are allowed, check type */
639 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, &type
, &size
);
640 if (ret
&& type
!= CMSG_SIGNED
)
642 SetLastError(CRYPT_E_INVALID_MSG_TYPE
);
648 store
= CRYPT_MsgOpenStore(0, dwFlags
, msg
);
650 TRACE("returning %p\n", store
);
654 static PWINECRYPT_CERTSTORE
CRYPT_PhysOpenStoreW(HCRYPTPROV hCryptProv
,
655 DWORD dwFlags
, const void *pvPara
)
657 if (dwFlags
& CERT_SYSTEM_STORE_RELOCATE_FLAG
)
658 FIXME("(%ld, %08x, %p): stub\n", hCryptProv
, dwFlags
, pvPara
);
660 FIXME("(%ld, %08x, %s): stub\n", hCryptProv
, dwFlags
,
661 debugstr_w((LPCWSTR
)pvPara
));
665 HCERTSTORE WINAPI
CertOpenStore(LPCSTR lpszStoreProvider
,
666 DWORD dwMsgAndCertEncodingType
, HCRYPTPROV_LEGACY hCryptProv
, DWORD dwFlags
,
669 WINECRYPT_CERTSTORE
*hcs
;
670 StoreOpenFunc openFunc
= NULL
;
672 TRACE("(%s, %08x, %08lx, %08x, %p)\n", debugstr_a(lpszStoreProvider
),
673 dwMsgAndCertEncodingType
, hCryptProv
, dwFlags
, pvPara
);
675 if (!HIWORD(lpszStoreProvider
))
677 switch (LOWORD(lpszStoreProvider
))
679 case (int)CERT_STORE_PROV_MSG
:
680 openFunc
= CRYPT_MsgOpenStore
;
682 case (int)CERT_STORE_PROV_MEMORY
:
683 openFunc
= CRYPT_MemOpenStore
;
685 case (int)CERT_STORE_PROV_FILE
:
686 openFunc
= CRYPT_FileOpenStore
;
688 case (int)CERT_STORE_PROV_PKCS7
:
689 openFunc
= CRYPT_PKCSOpenStore
;
691 case (int)CERT_STORE_PROV_REG
:
692 openFunc
= CRYPT_RegOpenStore
;
694 case (int)CERT_STORE_PROV_FILENAME_A
:
695 openFunc
= CRYPT_FileNameOpenStoreA
;
697 case (int)CERT_STORE_PROV_FILENAME_W
:
698 openFunc
= CRYPT_FileNameOpenStoreW
;
700 case (int)CERT_STORE_PROV_COLLECTION
:
701 openFunc
= CRYPT_CollectionOpenStore
;
703 case (int)CERT_STORE_PROV_SYSTEM_A
:
704 openFunc
= CRYPT_SysOpenStoreA
;
706 case (int)CERT_STORE_PROV_SYSTEM_W
:
707 openFunc
= CRYPT_SysOpenStoreW
;
709 case (int)CERT_STORE_PROV_SYSTEM_REGISTRY_A
:
710 openFunc
= CRYPT_SysRegOpenStoreA
;
712 case (int)CERT_STORE_PROV_SYSTEM_REGISTRY_W
:
713 openFunc
= CRYPT_SysRegOpenStoreW
;
715 case (int)CERT_STORE_PROV_PHYSICAL_W
:
716 openFunc
= CRYPT_PhysOpenStoreW
;
719 if (LOWORD(lpszStoreProvider
))
720 FIXME("unimplemented type %d\n", LOWORD(lpszStoreProvider
));
723 else if (!strcasecmp(lpszStoreProvider
, sz_CERT_STORE_PROV_MEMORY
))
724 openFunc
= CRYPT_MemOpenStore
;
725 else if (!strcasecmp(lpszStoreProvider
, sz_CERT_STORE_PROV_FILENAME_W
))
726 openFunc
= CRYPT_FileOpenStore
;
727 else if (!strcasecmp(lpszStoreProvider
, sz_CERT_STORE_PROV_SYSTEM
))
728 openFunc
= CRYPT_SysOpenStoreW
;
729 else if (!strcasecmp(lpszStoreProvider
, sz_CERT_STORE_PROV_COLLECTION
))
730 openFunc
= CRYPT_CollectionOpenStore
;
731 else if (!strcasecmp(lpszStoreProvider
, sz_CERT_STORE_PROV_SYSTEM_REGISTRY
))
732 openFunc
= CRYPT_SysRegOpenStoreW
;
735 FIXME("unimplemented type %s\n", lpszStoreProvider
);
740 hcs
= CRYPT_ProvOpenStore(lpszStoreProvider
, dwMsgAndCertEncodingType
,
741 hCryptProv
, dwFlags
, pvPara
);
743 hcs
= openFunc(hCryptProv
, dwFlags
, pvPara
);
744 return (HCERTSTORE
)hcs
;
747 HCERTSTORE WINAPI
CertOpenSystemStoreA(HCRYPTPROV_LEGACY hProv
,
748 LPCSTR szSubSystemProtocol
)
750 if (!szSubSystemProtocol
)
752 SetLastError(E_INVALIDARG
);
755 return CertOpenStore(CERT_STORE_PROV_SYSTEM_A
, 0, hProv
,
756 CERT_SYSTEM_STORE_CURRENT_USER
, szSubSystemProtocol
);
759 HCERTSTORE WINAPI
CertOpenSystemStoreW(HCRYPTPROV_LEGACY hProv
,
760 LPCWSTR szSubSystemProtocol
)
762 if (!szSubSystemProtocol
)
764 SetLastError(E_INVALIDARG
);
767 return CertOpenStore(CERT_STORE_PROV_SYSTEM_W
, 0, hProv
,
768 CERT_SYSTEM_STORE_CURRENT_USER
, szSubSystemProtocol
);
771 #define CertContext_CopyProperties(to, from) \
772 Context_CopyProperties((to), (from), sizeof(CERT_CONTEXT))
774 BOOL WINAPI
CertAddCertificateContextToStore(HCERTSTORE hCertStore
,
775 PCCERT_CONTEXT pCertContext
, DWORD dwAddDisposition
,
776 PCCERT_CONTEXT
*ppStoreContext
)
778 PWINECRYPT_CERTSTORE store
= (PWINECRYPT_CERTSTORE
)hCertStore
;
780 PCCERT_CONTEXT toAdd
= NULL
, existing
= NULL
;
782 TRACE("(%p, %p, %08x, %p)\n", hCertStore
, pCertContext
,
783 dwAddDisposition
, ppStoreContext
);
785 /* Weird case to pass a test */
786 if (dwAddDisposition
== 0)
788 SetLastError(STATUS_ACCESS_VIOLATION
);
791 if (dwAddDisposition
!= CERT_STORE_ADD_ALWAYS
)
794 DWORD size
= sizeof(hashToAdd
);
796 ret
= CertGetCertificateContextProperty(pCertContext
, CERT_HASH_PROP_ID
,
800 CRYPT_HASH_BLOB blob
= { sizeof(hashToAdd
), hashToAdd
};
802 existing
= CertFindCertificateInStore(hCertStore
,
803 pCertContext
->dwCertEncodingType
, 0, CERT_FIND_SHA1_HASH
, &blob
,
808 switch (dwAddDisposition
)
810 case CERT_STORE_ADD_ALWAYS
:
811 toAdd
= CertDuplicateCertificateContext(pCertContext
);
813 case CERT_STORE_ADD_NEW
:
816 TRACE("found matching certificate, not adding\n");
817 SetLastError(CRYPT_E_EXISTS
);
821 toAdd
= CertDuplicateCertificateContext(pCertContext
);
823 case CERT_STORE_ADD_REPLACE_EXISTING
:
824 toAdd
= CertDuplicateCertificateContext(pCertContext
);
826 case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES
:
827 toAdd
= CertDuplicateCertificateContext(pCertContext
);
829 CertContext_CopyProperties(toAdd
, existing
);
831 case CERT_STORE_ADD_USE_EXISTING
:
834 CertContext_CopyProperties(existing
, pCertContext
);
835 *ppStoreContext
= CertDuplicateCertificateContext(existing
);
838 toAdd
= CertDuplicateCertificateContext(pCertContext
);
840 case CERT_STORE_ADD_NEWER
:
843 if (CompareFileTime(&existing
->pCertInfo
->NotBefore
,
844 &pCertContext
->pCertInfo
->NotBefore
) >= 0)
846 TRACE("existing certificate is newer, not adding\n");
847 SetLastError(CRYPT_E_EXISTS
);
851 toAdd
= CertDuplicateCertificateContext(pCertContext
);
854 toAdd
= CertDuplicateCertificateContext(pCertContext
);
857 FIXME("Unimplemented add disposition %d\n", dwAddDisposition
);
864 ret
= store
->certs
.addContext(store
, (void *)toAdd
,
865 (void *)existing
, (const void **)ppStoreContext
);
866 else if (ppStoreContext
)
867 *ppStoreContext
= CertDuplicateCertificateContext(toAdd
);
868 CertFreeCertificateContext(toAdd
);
870 CertFreeCertificateContext(existing
);
872 TRACE("returning %d\n", ret
);
876 PCCERT_CONTEXT WINAPI
CertEnumCertificatesInStore(HCERTSTORE hCertStore
,
877 PCCERT_CONTEXT pPrev
)
879 WINECRYPT_CERTSTORE
*hcs
= (WINECRYPT_CERTSTORE
*)hCertStore
;
882 TRACE("(%p, %p)\n", hCertStore
, pPrev
);
885 else if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
888 ret
= (PCCERT_CONTEXT
)hcs
->certs
.enumContext(hcs
, (void *)pPrev
);
892 BOOL WINAPI
CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext
)
896 TRACE("(%p)\n", pCertContext
);
900 else if (!pCertContext
->hCertStore
)
903 CertFreeCertificateContext(pCertContext
);
907 PWINECRYPT_CERTSTORE hcs
=
908 (PWINECRYPT_CERTSTORE
)pCertContext
->hCertStore
;
910 if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
913 ret
= hcs
->certs
.deleteContext(hcs
, (void *)pCertContext
);
914 CertFreeCertificateContext(pCertContext
);
919 #define CrlContext_CopyProperties(to, from) \
920 Context_CopyProperties((to), (from), sizeof(CRL_CONTEXT))
922 BOOL WINAPI
CertAddCRLContextToStore(HCERTSTORE hCertStore
,
923 PCCRL_CONTEXT pCrlContext
, DWORD dwAddDisposition
,
924 PCCRL_CONTEXT
* ppStoreContext
)
926 PWINECRYPT_CERTSTORE store
= (PWINECRYPT_CERTSTORE
)hCertStore
;
928 PCCRL_CONTEXT toAdd
= NULL
, existing
= NULL
;
930 TRACE("(%p, %p, %08x, %p)\n", hCertStore
, pCrlContext
,
931 dwAddDisposition
, ppStoreContext
);
933 /* Weird case to pass a test */
934 if (dwAddDisposition
== 0)
936 SetLastError(STATUS_ACCESS_VIOLATION
);
939 if (dwAddDisposition
!= CERT_STORE_ADD_ALWAYS
)
941 existing
= CertFindCRLInStore(hCertStore
, 0, 0, CRL_FIND_EXISTING
,
945 switch (dwAddDisposition
)
947 case CERT_STORE_ADD_ALWAYS
:
948 toAdd
= CertDuplicateCRLContext(pCrlContext
);
950 case CERT_STORE_ADD_NEW
:
953 TRACE("found matching CRL, not adding\n");
954 SetLastError(CRYPT_E_EXISTS
);
958 toAdd
= CertDuplicateCRLContext(pCrlContext
);
960 case CERT_STORE_ADD_NEWER
:
963 LONG newer
= CompareFileTime(&existing
->pCrlInfo
->ThisUpdate
,
964 &pCrlContext
->pCrlInfo
->ThisUpdate
);
967 toAdd
= CertDuplicateCRLContext(pCrlContext
);
970 TRACE("existing CRL is newer, not adding\n");
971 SetLastError(CRYPT_E_EXISTS
);
976 toAdd
= CertDuplicateCRLContext(pCrlContext
);
978 case CERT_STORE_ADD_REPLACE_EXISTING
:
979 toAdd
= CertDuplicateCRLContext(pCrlContext
);
981 case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES
:
982 toAdd
= CertDuplicateCRLContext(pCrlContext
);
984 CrlContext_CopyProperties(toAdd
, existing
);
986 case CERT_STORE_ADD_USE_EXISTING
:
988 CrlContext_CopyProperties(existing
, pCrlContext
);
991 FIXME("Unimplemented add disposition %d\n", dwAddDisposition
);
998 ret
= store
->crls
.addContext(store
, (void *)toAdd
,
999 (void *)existing
, (const void **)ppStoreContext
);
1000 else if (ppStoreContext
)
1001 *ppStoreContext
= CertDuplicateCRLContext(toAdd
);
1002 CertFreeCRLContext(toAdd
);
1004 CertFreeCRLContext(existing
);
1006 TRACE("returning %d\n", ret
);
1010 BOOL WINAPI
CertDeleteCRLFromStore(PCCRL_CONTEXT pCrlContext
)
1014 TRACE("(%p)\n", pCrlContext
);
1018 else if (!pCrlContext
->hCertStore
)
1021 CertFreeCRLContext(pCrlContext
);
1025 PWINECRYPT_CERTSTORE hcs
=
1026 (PWINECRYPT_CERTSTORE
)pCrlContext
->hCertStore
;
1028 if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1031 ret
= hcs
->crls
.deleteContext(hcs
, (void *)pCrlContext
);
1032 CertFreeCRLContext(pCrlContext
);
1037 PCCRL_CONTEXT WINAPI
CertEnumCRLsInStore(HCERTSTORE hCertStore
,
1038 PCCRL_CONTEXT pPrev
)
1040 WINECRYPT_CERTSTORE
*hcs
= (WINECRYPT_CERTSTORE
*)hCertStore
;
1043 TRACE("(%p, %p)\n", hCertStore
, pPrev
);
1046 else if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1049 ret
= (PCCRL_CONTEXT
)hcs
->crls
.enumContext(hcs
, (void *)pPrev
);
1053 PCCTL_CONTEXT WINAPI
CertCreateCTLContext(DWORD dwCertEncodingType
,
1054 const BYTE
* pbCtlEncoded
, DWORD cbCtlEncoded
)
1056 FIXME("(%08x, %p, %08x): stub\n", dwCertEncodingType
, pbCtlEncoded
,
1061 BOOL WINAPI
CertAddEncodedCTLToStore(HCERTSTORE hCertStore
,
1062 DWORD dwMsgAndCertEncodingType
, const BYTE
*pbCtlEncoded
, DWORD cbCtlEncoded
,
1063 DWORD dwAddDisposition
, PCCTL_CONTEXT
*ppCtlContext
)
1065 FIXME("(%p, %08x, %p, %d, %08x, %p): stub\n", hCertStore
,
1066 dwMsgAndCertEncodingType
, pbCtlEncoded
, cbCtlEncoded
, dwAddDisposition
,
1071 BOOL WINAPI
CertAddCTLContextToStore(HCERTSTORE hCertStore
,
1072 PCCTL_CONTEXT pCtlContext
, DWORD dwAddDisposition
,
1073 PCCTL_CONTEXT
* ppStoreContext
)
1075 FIXME("(%p, %p, %08x, %p): stub\n", hCertStore
, pCtlContext
,
1076 dwAddDisposition
, ppStoreContext
);
1080 PCCTL_CONTEXT WINAPI
CertDuplicateCTLContext(PCCTL_CONTEXT pCtlContext
)
1082 FIXME("(%p): stub\n", pCtlContext
);
1086 BOOL WINAPI
CertFreeCTLContext(PCCTL_CONTEXT pCtlContext
)
1088 FIXME("(%p): stub\n", pCtlContext
);
1092 BOOL WINAPI
CertDeleteCTLFromStore(PCCTL_CONTEXT pCtlContext
)
1094 FIXME("(%p): stub\n", pCtlContext
);
1098 PCCTL_CONTEXT WINAPI
CertEnumCTLsInStore(HCERTSTORE hCertStore
,
1099 PCCTL_CONTEXT pPrev
)
1101 FIXME("(%p, %p): stub\n", hCertStore
, pPrev
);
1105 HCERTSTORE WINAPI
CertDuplicateStore(HCERTSTORE hCertStore
)
1107 WINECRYPT_CERTSTORE
*hcs
= (WINECRYPT_CERTSTORE
*)hCertStore
;
1109 TRACE("(%p)\n", hCertStore
);
1111 if (hcs
&& hcs
->dwMagic
== WINE_CRYPTCERTSTORE_MAGIC
)
1112 InterlockedIncrement(&hcs
->ref
);
1116 BOOL WINAPI
CertCloseStore(HCERTSTORE hCertStore
, DWORD dwFlags
)
1118 WINECRYPT_CERTSTORE
*hcs
= (WINECRYPT_CERTSTORE
*) hCertStore
;
1120 TRACE("(%p, %08x)\n", hCertStore
, dwFlags
);
1125 if ( hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1128 if (InterlockedDecrement(&hcs
->ref
) == 0)
1130 TRACE("%p's ref count is 0, freeing\n", hcs
);
1132 hcs
->closeStore(hcs
, dwFlags
);
1135 TRACE("%p's ref count is %d\n", hcs
, hcs
->ref
);
1139 BOOL WINAPI
CertControlStore(HCERTSTORE hCertStore
, DWORD dwFlags
,
1140 DWORD dwCtrlType
, void const *pvCtrlPara
)
1142 WINECRYPT_CERTSTORE
*hcs
= (WINECRYPT_CERTSTORE
*)hCertStore
;
1145 TRACE("(%p, %08x, %d, %p)\n", hCertStore
, dwFlags
, dwCtrlType
,
1150 else if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1155 ret
= hcs
->control(hCertStore
, dwFlags
, dwCtrlType
, pvCtrlPara
);
1162 BOOL WINAPI
CertGetStoreProperty(HCERTSTORE hCertStore
, DWORD dwPropId
,
1163 void *pvData
, DWORD
*pcbData
)
1165 PWINECRYPT_CERTSTORE store
= (PWINECRYPT_CERTSTORE
)hCertStore
;
1168 TRACE("(%p, %d, %p, %p)\n", hCertStore
, dwPropId
, pvData
, pcbData
);
1172 case CERT_ACCESS_STATE_PROP_ID
:
1175 *pcbData
= sizeof(DWORD
);
1178 else if (*pcbData
< sizeof(DWORD
))
1180 SetLastError(ERROR_MORE_DATA
);
1181 *pcbData
= sizeof(DWORD
);
1187 if (store
->type
!= StoreTypeMem
&&
1188 !(store
->dwOpenFlags
& CERT_STORE_READONLY_FLAG
))
1189 state
|= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG
;
1190 *(DWORD
*)pvData
= state
;
1195 if (store
->properties
)
1197 CRYPT_DATA_BLOB blob
;
1199 ret
= ContextPropertyList_FindProperty(store
->properties
, dwPropId
,
1204 *pcbData
= blob
.cbData
;
1205 else if (*pcbData
< blob
.cbData
)
1207 SetLastError(ERROR_MORE_DATA
);
1208 *pcbData
= blob
.cbData
;
1213 memcpy(pvData
, blob
.pbData
, blob
.cbData
);
1214 *pcbData
= blob
.cbData
;
1218 SetLastError(CRYPT_E_NOT_FOUND
);
1221 SetLastError(CRYPT_E_NOT_FOUND
);
1226 BOOL WINAPI
CertSetStoreProperty(HCERTSTORE hCertStore
, DWORD dwPropId
,
1227 DWORD dwFlags
, const void *pvData
)
1229 PWINECRYPT_CERTSTORE store
= (PWINECRYPT_CERTSTORE
)hCertStore
;
1232 TRACE("(%p, %d, %08x, %p)\n", hCertStore
, dwPropId
, dwFlags
, pvData
);
1234 if (!store
->properties
)
1235 store
->properties
= ContextPropertyList_Create();
1238 case CERT_ACCESS_STATE_PROP_ID
:
1239 SetLastError(E_INVALIDARG
);
1244 const CRYPT_DATA_BLOB
*blob
= (const CRYPT_DATA_BLOB
*)pvData
;
1246 ret
= ContextPropertyList_SetProperty(store
->properties
, dwPropId
,
1247 blob
->pbData
, blob
->cbData
);
1251 ContextPropertyList_RemoveProperty(store
->properties
, dwPropId
);
1258 DWORD WINAPI
CertEnumCTLContextProperties(PCCTL_CONTEXT pCTLContext
,
1261 FIXME("(%p, %d): stub\n", pCTLContext
, dwPropId
);
1265 BOOL WINAPI
CertGetCTLContextProperty(PCCTL_CONTEXT pCTLContext
,
1266 DWORD dwPropId
, void *pvData
, DWORD
*pcbData
)
1268 FIXME("(%p, %d, %p, %p): stub\n", pCTLContext
, dwPropId
, pvData
, pcbData
);
1272 BOOL WINAPI
CertSetCTLContextProperty(PCCTL_CONTEXT pCTLContext
,
1273 DWORD dwPropId
, DWORD dwFlags
, const void *pvData
)
1275 FIXME("(%p, %d, %08x, %p): stub\n", pCTLContext
, dwPropId
, dwFlags
,
1280 static LONG
CRYPT_OpenParentStore(DWORD dwFlags
,
1281 void *pvSystemStoreLocationPara
, HKEY
*key
)
1286 TRACE("(%08x, %p)\n", dwFlags
, pvSystemStoreLocationPara
);
1288 switch (dwFlags
& CERT_SYSTEM_STORE_LOCATION_MASK
)
1290 case CERT_SYSTEM_STORE_LOCAL_MACHINE
:
1291 root
= HKEY_LOCAL_MACHINE
;
1292 base
= CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH
;
1294 case CERT_SYSTEM_STORE_CURRENT_USER
:
1295 root
= HKEY_CURRENT_USER
;
1296 base
= CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH
;
1298 case CERT_SYSTEM_STORE_CURRENT_SERVICE
:
1299 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
1300 * SystemCertificates
1302 FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE\n");
1303 return ERROR_FILE_NOT_FOUND
;
1304 case CERT_SYSTEM_STORE_SERVICES
:
1305 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
1306 * SystemCertificates
1308 FIXME("CERT_SYSTEM_STORE_SERVICES\n");
1309 return ERROR_FILE_NOT_FOUND
;
1310 case CERT_SYSTEM_STORE_USERS
:
1311 /* hku\user sid\Software\Microsoft\SystemCertificates */
1312 FIXME("CERT_SYSTEM_STORE_USERS\n");
1313 return ERROR_FILE_NOT_FOUND
;
1314 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY
:
1315 root
= HKEY_CURRENT_USER
;
1316 base
= CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH
;
1318 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY
:
1319 root
= HKEY_LOCAL_MACHINE
;
1320 base
= CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH
;
1322 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE
:
1323 /* hklm\Software\Microsoft\EnterpriseCertificates */
1324 FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE\n");
1325 return ERROR_FILE_NOT_FOUND
;
1327 return ERROR_FILE_NOT_FOUND
;
1330 return RegOpenKeyExW(root
, base
, 0, KEY_READ
, key
);
1333 BOOL WINAPI
CertEnumSystemStore(DWORD dwFlags
, void *pvSystemStoreLocationPara
,
1334 void *pvArg
, PFN_CERT_ENUM_SYSTEM_STORE pfnEnum
)
1340 TRACE("(%08x, %p, %p, %p)\n", dwFlags
, pvSystemStoreLocationPara
, pvArg
,
1343 rc
= CRYPT_OpenParentStore(dwFlags
, pvArg
, &key
);
1347 CERT_SYSTEM_STORE_INFO info
= { sizeof(info
) };
1351 WCHAR name
[MAX_PATH
];
1352 DWORD size
= sizeof(name
) / sizeof(name
[0]);
1354 rc
= RegEnumKeyExW(key
, index
++, name
, &size
, NULL
, NULL
, NULL
,
1357 ret
= pfnEnum(name
, 0, &info
, NULL
, pvArg
);
1358 } while (ret
&& !rc
);
1359 if (ret
&& rc
!= ERROR_NO_MORE_ITEMS
)