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 const WINE_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 const WINE_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 const WINE_CONTEXT_INTERFACE
*pCTLInterface
= &gCTLInterface
;
89 typedef struct _WINE_MEMSTORE
91 WINECRYPT_CERTSTORE hdr
;
92 struct ContextList
*certs
;
93 struct ContextList
*crls
;
94 struct ContextList
*ctls
;
97 void CRYPT_InitStore(WINECRYPT_CERTSTORE
*store
, DWORD dwFlags
, CertStoreType type
, const store_vtbl_t
*vtbl
)
100 store
->dwMagic
= WINE_CRYPTCERTSTORE_MAGIC
;
102 store
->dwOpenFlags
= dwFlags
;
104 store
->properties
= NULL
;
107 void CRYPT_FreeStore(WINECRYPT_CERTSTORE
*store
)
109 if (store
->properties
)
110 ContextPropertyList_Free(store
->properties
);
114 BOOL WINAPI
I_CertUpdateStore(HCERTSTORE store1
, HCERTSTORE store2
, DWORD unk0
,
117 static BOOL warned
= FALSE
;
118 const WINE_CONTEXT_INTERFACE
* const interfaces
[] = { pCertInterface
,
119 pCRLInterface
, pCTLInterface
};
122 TRACE("(%p, %p, %08x, %08x)\n", store1
, store2
, unk0
, unk1
);
125 FIXME("semi-stub\n");
129 /* Poor-man's resync: empty first store, then add everything from second
132 for (i
= 0; i
< sizeof(interfaces
) / sizeof(interfaces
[0]); i
++)
137 context
= interfaces
[i
]->enumContextsInStore(store1
, NULL
);
139 interfaces
[i
]->deleteFromStore(context
);
142 context
= interfaces
[i
]->enumContextsInStore(store2
, context
);
144 interfaces
[i
]->addContextToStore(store1
, context
,
145 CERT_STORE_ADD_ALWAYS
, NULL
);
151 static BOOL
CRYPT_MemAddCert(WINECRYPT_CERTSTORE
*store
, void *cert
,
152 void *toReplace
, const void **ppStoreContext
)
154 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
155 PCERT_CONTEXT context
;
157 TRACE("(%p, %p, %p, %p)\n", store
, cert
, toReplace
, ppStoreContext
);
159 context
= ContextList_Add(ms
->certs
, cert
, toReplace
);
162 context
->hCertStore
= store
;
163 if (ppStoreContext
) {
164 *ppStoreContext
= CertDuplicateCertificateContext(context
);
170 static void *CRYPT_MemEnumCert(WINECRYPT_CERTSTORE
*store
, void *pPrev
)
172 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
175 TRACE("(%p, %p)\n", store
, pPrev
);
177 ret
= ContextList_Enum(ms
->certs
, pPrev
);
179 SetLastError(CRYPT_E_NOT_FOUND
);
181 TRACE("returning %p\n", ret
);
185 static BOOL
CRYPT_MemDeleteCert(WINECRYPT_CERTSTORE
*store
, void *pCertContext
)
187 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
190 if (ContextList_Remove(ms
->certs
, pCertContext
))
191 ret
= CertFreeCertificateContext(pCertContext
);
197 static BOOL
CRYPT_MemAddCrl(WINECRYPT_CERTSTORE
*store
, void *crl
,
198 void *toReplace
, const void **ppStoreContext
)
200 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
201 PCRL_CONTEXT context
;
203 TRACE("(%p, %p, %p, %p)\n", store
, crl
, toReplace
, ppStoreContext
);
205 context
= ContextList_Add(ms
->crls
, crl
, toReplace
);
208 context
->hCertStore
= store
;
210 *ppStoreContext
= CertDuplicateCRLContext(context
);
215 static void *CRYPT_MemEnumCrl(WINECRYPT_CERTSTORE
*store
, void *pPrev
)
217 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
220 TRACE("(%p, %p)\n", store
, pPrev
);
222 ret
= ContextList_Enum(ms
->crls
, pPrev
);
224 SetLastError(CRYPT_E_NOT_FOUND
);
226 TRACE("returning %p\n", ret
);
230 static BOOL
CRYPT_MemDeleteCrl(WINECRYPT_CERTSTORE
*store
, void *pCrlContext
)
232 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
235 if (ContextList_Remove(ms
->crls
, pCrlContext
))
236 ret
= CertFreeCRLContext(pCrlContext
);
242 static BOOL
CRYPT_MemAddCtl(WINECRYPT_CERTSTORE
*store
, void *ctl
,
243 void *toReplace
, const void **ppStoreContext
)
245 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
246 PCTL_CONTEXT context
;
248 TRACE("(%p, %p, %p, %p)\n", store
, ctl
, toReplace
, ppStoreContext
);
250 context
= ContextList_Add(ms
->ctls
, ctl
, toReplace
);
253 context
->hCertStore
= store
;
255 *ppStoreContext
= CertDuplicateCTLContext(context
);
260 static void *CRYPT_MemEnumCtl(WINECRYPT_CERTSTORE
*store
, void *pPrev
)
262 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
265 TRACE("(%p, %p)\n", store
, pPrev
);
267 ret
= ContextList_Enum(ms
->ctls
, pPrev
);
269 SetLastError(CRYPT_E_NOT_FOUND
);
271 TRACE("returning %p\n", ret
);
275 static BOOL
CRYPT_MemDeleteCtl(WINECRYPT_CERTSTORE
*store
, void *pCtlContext
)
277 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
280 if (ContextList_Remove(ms
->ctls
, pCtlContext
))
281 ret
= CertFreeCTLContext(pCtlContext
);
287 static void MemStore_closeStore(WINECRYPT_CERTSTORE
*cert_store
, DWORD dwFlags
)
289 WINE_MEMSTORE
*store
= (WINE_MEMSTORE
*)cert_store
;
291 TRACE("(%p, %08x)\n", store
, dwFlags
);
293 FIXME("Unimplemented flags: %08x\n", dwFlags
);
295 ContextList_Free(store
->certs
);
296 ContextList_Free(store
->crls
);
297 ContextList_Free(store
->ctls
);
298 CRYPT_FreeStore((WINECRYPT_CERTSTORE
*)store
);
301 static BOOL
MemStore_control(WINECRYPT_CERTSTORE
*store
, DWORD dwFlags
,
302 DWORD dwCtrlType
, void const *pvCtrlPara
)
304 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
308 static const store_vtbl_t MemStoreVtbl
= {
313 static WINECRYPT_CERTSTORE
*CRYPT_MemOpenStore(HCRYPTPROV hCryptProv
,
314 DWORD dwFlags
, const void *pvPara
)
316 WINE_MEMSTORE
*store
;
318 TRACE("(%ld, %08x, %p)\n", hCryptProv
, dwFlags
, pvPara
);
320 if (dwFlags
& CERT_STORE_DELETE_FLAG
)
322 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
327 store
= CryptMemAlloc(sizeof(WINE_MEMSTORE
));
330 memset(store
, 0, sizeof(WINE_MEMSTORE
));
331 CRYPT_InitStore(&store
->hdr
, dwFlags
, StoreTypeMem
, &MemStoreVtbl
);
332 store
->hdr
.certs
.addContext
= CRYPT_MemAddCert
;
333 store
->hdr
.certs
.enumContext
= CRYPT_MemEnumCert
;
334 store
->hdr
.certs
.deleteContext
= CRYPT_MemDeleteCert
;
335 store
->hdr
.crls
.addContext
= CRYPT_MemAddCrl
;
336 store
->hdr
.crls
.enumContext
= CRYPT_MemEnumCrl
;
337 store
->hdr
.crls
.deleteContext
= CRYPT_MemDeleteCrl
;
338 store
->hdr
.ctls
.addContext
= CRYPT_MemAddCtl
;
339 store
->hdr
.ctls
.enumContext
= CRYPT_MemEnumCtl
;
340 store
->hdr
.ctls
.deleteContext
= CRYPT_MemDeleteCtl
;
341 store
->certs
= ContextList_Create(pCertInterface
,
342 sizeof(CERT_CONTEXT
));
343 store
->crls
= ContextList_Create(pCRLInterface
,
344 sizeof(CRL_CONTEXT
));
345 store
->ctls
= ContextList_Create(pCTLInterface
,
346 sizeof(CTL_CONTEXT
));
347 /* Mem store doesn't need crypto provider, so close it */
348 if (hCryptProv
&& !(dwFlags
& CERT_STORE_NO_CRYPT_RELEASE_FLAG
))
349 CryptReleaseContext(hCryptProv
, 0);
352 return (WINECRYPT_CERTSTORE
*)store
;
355 static const WCHAR rootW
[] = { 'R','o','o','t',0 };
357 static WINECRYPT_CERTSTORE
*CRYPT_SysRegOpenStoreW(HCRYPTPROV hCryptProv
,
358 DWORD dwFlags
, const void *pvPara
)
360 static const WCHAR fmt
[] = { '%','s','\\','%','s',0 };
361 LPCWSTR storeName
= pvPara
;
363 WINECRYPT_CERTSTORE
*store
= NULL
;
367 TRACE("(%ld, %08x, %s)\n", hCryptProv
, dwFlags
,
372 SetLastError(E_INVALIDARG
);
375 /* FIXME: In Windows, the root store (even the current user location) is
376 * protected: adding to it or removing from it present a user interface,
377 * and the keys are owned by the system process, not the current user.
378 * Wine's registry doesn't implement access controls, so a similar
379 * mechanism isn't possible yet.
381 if ((dwFlags
& CERT_SYSTEM_STORE_LOCATION_MASK
) ==
382 CERT_SYSTEM_STORE_LOCAL_MACHINE
&& !lstrcmpiW(storeName
, rootW
))
383 return CRYPT_RootOpenStore(hCryptProv
, dwFlags
);
385 switch (dwFlags
& CERT_SYSTEM_STORE_LOCATION_MASK
)
387 case CERT_SYSTEM_STORE_LOCAL_MACHINE
:
388 root
= HKEY_LOCAL_MACHINE
;
389 base
= CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH
;
391 case CERT_SYSTEM_STORE_CURRENT_USER
:
392 root
= HKEY_CURRENT_USER
;
393 base
= CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH
;
395 case CERT_SYSTEM_STORE_CURRENT_SERVICE
:
396 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
399 FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE, %s: stub\n",
400 debugstr_w(storeName
));
402 case CERT_SYSTEM_STORE_SERVICES
:
403 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
406 FIXME("CERT_SYSTEM_STORE_SERVICES, %s: stub\n",
407 debugstr_w(storeName
));
409 case CERT_SYSTEM_STORE_USERS
:
410 /* hku\user sid\Software\Microsoft\SystemCertificates */
411 FIXME("CERT_SYSTEM_STORE_USERS, %s: stub\n",
412 debugstr_w(storeName
));
414 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY
:
415 root
= HKEY_CURRENT_USER
;
416 base
= CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH
;
418 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY
:
419 root
= HKEY_LOCAL_MACHINE
;
420 base
= CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH
;
422 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE
:
423 /* hklm\Software\Microsoft\EnterpriseCertificates */
424 FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, %s: stub\n",
425 debugstr_w(storeName
));
428 SetLastError(E_INVALIDARG
);
432 storePath
= CryptMemAlloc((lstrlenW(base
) + lstrlenW(storeName
) + 2) *
438 REGSAM sam
= dwFlags
& CERT_STORE_READONLY_FLAG
? KEY_READ
:
441 wsprintfW(storePath
, fmt
, base
, storeName
);
442 if (dwFlags
& CERT_STORE_OPEN_EXISTING_FLAG
)
443 rc
= RegOpenKeyExW(root
, storePath
, 0, sam
, &key
);
448 rc
= RegCreateKeyExW(root
, storePath
, 0, NULL
, 0, sam
, NULL
,
450 if (!rc
&& dwFlags
& CERT_STORE_CREATE_NEW_FLAG
&&
451 disp
== REG_OPENED_EXISTING_KEY
)
454 rc
= ERROR_FILE_EXISTS
;
459 store
= CRYPT_RegOpenStore(hCryptProv
, dwFlags
, key
);
464 CryptMemFree(storePath
);
469 static WINECRYPT_CERTSTORE
*CRYPT_SysRegOpenStoreA(HCRYPTPROV hCryptProv
,
470 DWORD dwFlags
, const void *pvPara
)
473 WINECRYPT_CERTSTORE
*ret
= NULL
;
475 TRACE("(%ld, %08x, %s)\n", hCryptProv
, dwFlags
,
480 SetLastError(ERROR_FILE_NOT_FOUND
);
483 len
= MultiByteToWideChar(CP_ACP
, 0, pvPara
, -1, NULL
, 0);
486 LPWSTR storeName
= CryptMemAlloc(len
* sizeof(WCHAR
));
490 MultiByteToWideChar(CP_ACP
, 0, pvPara
, -1, storeName
, len
);
491 ret
= CRYPT_SysRegOpenStoreW(hCryptProv
, dwFlags
, storeName
);
492 CryptMemFree(storeName
);
498 static WINECRYPT_CERTSTORE
*CRYPT_SysOpenStoreW(HCRYPTPROV hCryptProv
,
499 DWORD dwFlags
, const void *pvPara
)
501 HCERTSTORE store
= 0;
504 TRACE("(%ld, %08x, %s)\n", hCryptProv
, dwFlags
,
509 SetLastError(ERROR_FILE_NOT_FOUND
);
512 /* This returns a different error than system registry stores if the
513 * location is invalid.
515 switch (dwFlags
& CERT_SYSTEM_STORE_LOCATION_MASK
)
517 case CERT_SYSTEM_STORE_LOCAL_MACHINE
:
518 case CERT_SYSTEM_STORE_CURRENT_USER
:
519 case CERT_SYSTEM_STORE_CURRENT_SERVICE
:
520 case CERT_SYSTEM_STORE_SERVICES
:
521 case CERT_SYSTEM_STORE_USERS
:
522 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY
:
523 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY
:
524 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE
:
528 SetLastError(ERROR_FILE_NOT_FOUND
);
533 HCERTSTORE regStore
= CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W
,
534 0, 0, dwFlags
, pvPara
);
538 store
= CertOpenStore(CERT_STORE_PROV_COLLECTION
, 0, 0,
539 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
540 CertAddStoreToCollection(store
, regStore
,
541 dwFlags
& CERT_STORE_READONLY_FLAG
? 0 :
542 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG
, 0);
543 CertCloseStore(regStore
, 0);
544 /* CERT_SYSTEM_STORE_CURRENT_USER returns both the HKCU and HKLM
547 if ((dwFlags
& CERT_SYSTEM_STORE_LOCATION_MASK
) ==
548 CERT_SYSTEM_STORE_CURRENT_USER
)
550 dwFlags
&= ~CERT_SYSTEM_STORE_CURRENT_USER
;
551 dwFlags
|= CERT_SYSTEM_STORE_LOCAL_MACHINE
;
552 regStore
= CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W
, 0,
556 CertAddStoreToCollection(store
, regStore
,
557 dwFlags
& CERT_STORE_READONLY_FLAG
? 0 :
558 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG
, 0);
559 CertCloseStore(regStore
, 0);
562 /* System store doesn't need crypto provider, so close it */
563 if (hCryptProv
&& !(dwFlags
& CERT_STORE_NO_CRYPT_RELEASE_FLAG
))
564 CryptReleaseContext(hCryptProv
, 0);
570 static WINECRYPT_CERTSTORE
*CRYPT_SysOpenStoreA(HCRYPTPROV hCryptProv
,
571 DWORD dwFlags
, const void *pvPara
)
574 WINECRYPT_CERTSTORE
*ret
= NULL
;
576 TRACE("(%ld, %08x, %s)\n", hCryptProv
, dwFlags
,
581 SetLastError(ERROR_FILE_NOT_FOUND
);
584 len
= MultiByteToWideChar(CP_ACP
, 0, pvPara
, -1, NULL
, 0);
587 LPWSTR storeName
= CryptMemAlloc(len
* sizeof(WCHAR
));
591 MultiByteToWideChar(CP_ACP
, 0, pvPara
, -1, storeName
, len
);
592 ret
= CRYPT_SysOpenStoreW(hCryptProv
, dwFlags
, storeName
);
593 CryptMemFree(storeName
);
599 static void WINAPI
CRYPT_MsgCloseStore(HCERTSTORE hCertStore
, DWORD dwFlags
)
601 HCRYPTMSG msg
= hCertStore
;
603 TRACE("(%p, %08x)\n", msg
, dwFlags
);
607 static void *msgProvFuncs
[] = {
611 static WINECRYPT_CERTSTORE
*CRYPT_MsgOpenStore(HCRYPTPROV hCryptProv
,
612 DWORD dwFlags
, const void *pvPara
)
614 WINECRYPT_CERTSTORE
*store
= NULL
;
615 HCRYPTMSG msg
= (HCRYPTMSG
)pvPara
;
616 WINECRYPT_CERTSTORE
*memStore
;
618 TRACE("(%ld, %08x, %p)\n", hCryptProv
, dwFlags
, pvPara
);
620 memStore
= CertOpenStore(CERT_STORE_PROV_MEMORY
, 0, 0,
621 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
625 DWORD size
, count
, i
;
627 size
= sizeof(count
);
628 ret
= CryptMsgGetParam(msg
, CMSG_CERT_COUNT_PARAM
, 0, &count
, &size
);
629 for (i
= 0; ret
&& i
< count
; i
++)
632 ret
= CryptMsgGetParam(msg
, CMSG_CERT_PARAM
, i
, NULL
, &size
);
635 LPBYTE buf
= CryptMemAlloc(size
);
639 ret
= CryptMsgGetParam(msg
, CMSG_CERT_PARAM
, i
, buf
, &size
);
641 ret
= CertAddEncodedCertificateToStore(memStore
,
642 X509_ASN_ENCODING
, buf
, size
, CERT_STORE_ADD_ALWAYS
,
648 size
= sizeof(count
);
649 ret
= CryptMsgGetParam(msg
, CMSG_CRL_COUNT_PARAM
, 0, &count
, &size
);
650 for (i
= 0; ret
&& i
< count
; i
++)
653 ret
= CryptMsgGetParam(msg
, CMSG_CRL_PARAM
, i
, NULL
, &size
);
656 LPBYTE buf
= CryptMemAlloc(size
);
660 ret
= CryptMsgGetParam(msg
, CMSG_CRL_PARAM
, i
, buf
, &size
);
662 ret
= CertAddEncodedCRLToStore(memStore
,
663 X509_ASN_ENCODING
, buf
, size
, CERT_STORE_ADD_ALWAYS
,
671 CERT_STORE_PROV_INFO provInfo
= { 0 };
673 provInfo
.cbSize
= sizeof(provInfo
);
674 provInfo
.cStoreProvFunc
= sizeof(msgProvFuncs
) /
675 sizeof(msgProvFuncs
[0]);
676 provInfo
.rgpvStoreProvFunc
= msgProvFuncs
;
677 provInfo
.hStoreProv
= CryptMsgDuplicate(msg
);
678 store
= CRYPT_ProvCreateStore(dwFlags
, memStore
, &provInfo
);
679 /* Msg store doesn't need crypto provider, so close it */
680 if (hCryptProv
&& !(dwFlags
& CERT_STORE_NO_CRYPT_RELEASE_FLAG
))
681 CryptReleaseContext(hCryptProv
, 0);
684 CertCloseStore(memStore
, 0);
686 TRACE("returning %p\n", store
);
690 static WINECRYPT_CERTSTORE
*CRYPT_PKCSOpenStore(HCRYPTPROV hCryptProv
,
691 DWORD dwFlags
, const void *pvPara
)
694 WINECRYPT_CERTSTORE
*store
= NULL
;
695 const CRYPT_DATA_BLOB
*data
= pvPara
;
697 DWORD msgOpenFlags
= dwFlags
& CERT_STORE_NO_CRYPT_RELEASE_FLAG
? 0 :
698 CMSG_CRYPT_RELEASE_CONTEXT_FLAG
;
700 TRACE("(%ld, %08x, %p)\n", hCryptProv
, dwFlags
, pvPara
);
702 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, msgOpenFlags
, CMSG_SIGNED
,
703 hCryptProv
, NULL
, NULL
);
704 ret
= CryptMsgUpdate(msg
, data
->pbData
, data
->cbData
, TRUE
);
708 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, msgOpenFlags
, 0,
709 hCryptProv
, NULL
, NULL
);
710 ret
= CryptMsgUpdate(msg
, data
->pbData
, data
->cbData
, TRUE
);
713 DWORD type
, size
= sizeof(type
);
715 /* Only signed messages are allowed, check type */
716 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, &type
, &size
);
717 if (ret
&& type
!= CMSG_SIGNED
)
719 SetLastError(CRYPT_E_INVALID_MSG_TYPE
);
725 store
= CRYPT_MsgOpenStore(0, dwFlags
, msg
);
727 TRACE("returning %p\n", store
);
731 static WINECRYPT_CERTSTORE
*CRYPT_SerializedOpenStore(HCRYPTPROV hCryptProv
,
732 DWORD dwFlags
, const void *pvPara
)
735 const CRYPT_DATA_BLOB
*data
= pvPara
;
737 TRACE("(%ld, %08x, %p)\n", hCryptProv
, dwFlags
, pvPara
);
739 if (dwFlags
& CERT_STORE_DELETE_FLAG
)
741 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
745 store
= CertOpenStore(CERT_STORE_PROV_MEMORY
, 0, 0,
746 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
749 if (!CRYPT_ReadSerializedStoreFromBlob(data
, store
))
751 CertCloseStore(store
, 0);
755 TRACE("returning %p\n", store
);
756 return (WINECRYPT_CERTSTORE
*)store
;
759 static WINECRYPT_CERTSTORE
*CRYPT_PhysOpenStoreW(HCRYPTPROV hCryptProv
,
760 DWORD dwFlags
, const void *pvPara
)
762 if (dwFlags
& CERT_SYSTEM_STORE_RELOCATE_FLAG
)
763 FIXME("(%ld, %08x, %p): stub\n", hCryptProv
, dwFlags
, pvPara
);
765 FIXME("(%ld, %08x, %s): stub\n", hCryptProv
, dwFlags
,
770 HCERTSTORE WINAPI
CertOpenStore(LPCSTR lpszStoreProvider
,
771 DWORD dwMsgAndCertEncodingType
, HCRYPTPROV_LEGACY hCryptProv
, DWORD dwFlags
,
774 WINECRYPT_CERTSTORE
*hcs
;
775 StoreOpenFunc openFunc
= NULL
;
777 TRACE("(%s, %08x, %08lx, %08x, %p)\n", debugstr_a(lpszStoreProvider
),
778 dwMsgAndCertEncodingType
, hCryptProv
, dwFlags
, pvPara
);
780 if (IS_INTOID(lpszStoreProvider
))
782 switch (LOWORD(lpszStoreProvider
))
784 case LOWORD(CERT_STORE_PROV_MSG
):
785 openFunc
= CRYPT_MsgOpenStore
;
787 case LOWORD(CERT_STORE_PROV_MEMORY
):
788 openFunc
= CRYPT_MemOpenStore
;
790 case LOWORD(CERT_STORE_PROV_FILE
):
791 openFunc
= CRYPT_FileOpenStore
;
793 case LOWORD(CERT_STORE_PROV_PKCS7
):
794 openFunc
= CRYPT_PKCSOpenStore
;
796 case LOWORD(CERT_STORE_PROV_SERIALIZED
):
797 openFunc
= CRYPT_SerializedOpenStore
;
799 case LOWORD(CERT_STORE_PROV_REG
):
800 openFunc
= CRYPT_RegOpenStore
;
802 case LOWORD(CERT_STORE_PROV_FILENAME_A
):
803 openFunc
= CRYPT_FileNameOpenStoreA
;
805 case LOWORD(CERT_STORE_PROV_FILENAME_W
):
806 openFunc
= CRYPT_FileNameOpenStoreW
;
808 case LOWORD(CERT_STORE_PROV_COLLECTION
):
809 openFunc
= CRYPT_CollectionOpenStore
;
811 case LOWORD(CERT_STORE_PROV_SYSTEM_A
):
812 openFunc
= CRYPT_SysOpenStoreA
;
814 case LOWORD(CERT_STORE_PROV_SYSTEM_W
):
815 openFunc
= CRYPT_SysOpenStoreW
;
817 case LOWORD(CERT_STORE_PROV_SYSTEM_REGISTRY_A
):
818 openFunc
= CRYPT_SysRegOpenStoreA
;
820 case LOWORD(CERT_STORE_PROV_SYSTEM_REGISTRY_W
):
821 openFunc
= CRYPT_SysRegOpenStoreW
;
823 case LOWORD(CERT_STORE_PROV_PHYSICAL_W
):
824 openFunc
= CRYPT_PhysOpenStoreW
;
827 if (LOWORD(lpszStoreProvider
))
828 FIXME("unimplemented type %d\n", LOWORD(lpszStoreProvider
));
831 else if (!strcasecmp(lpszStoreProvider
, sz_CERT_STORE_PROV_MEMORY
))
832 openFunc
= CRYPT_MemOpenStore
;
833 else if (!strcasecmp(lpszStoreProvider
, sz_CERT_STORE_PROV_FILENAME_W
))
834 openFunc
= CRYPT_FileOpenStore
;
835 else if (!strcasecmp(lpszStoreProvider
, sz_CERT_STORE_PROV_SYSTEM
))
836 openFunc
= CRYPT_SysOpenStoreW
;
837 else if (!strcasecmp(lpszStoreProvider
, sz_CERT_STORE_PROV_PKCS7
))
838 openFunc
= CRYPT_PKCSOpenStore
;
839 else if (!strcasecmp(lpszStoreProvider
, sz_CERT_STORE_PROV_SERIALIZED
))
840 openFunc
= CRYPT_SerializedOpenStore
;
841 else if (!strcasecmp(lpszStoreProvider
, sz_CERT_STORE_PROV_COLLECTION
))
842 openFunc
= CRYPT_CollectionOpenStore
;
843 else if (!strcasecmp(lpszStoreProvider
, sz_CERT_STORE_PROV_SYSTEM_REGISTRY
))
844 openFunc
= CRYPT_SysRegOpenStoreW
;
847 FIXME("unimplemented type %s\n", lpszStoreProvider
);
852 hcs
= CRYPT_ProvOpenStore(lpszStoreProvider
, dwMsgAndCertEncodingType
,
853 hCryptProv
, dwFlags
, pvPara
);
855 hcs
= openFunc(hCryptProv
, dwFlags
, pvPara
);
859 HCERTSTORE WINAPI
CertOpenSystemStoreA(HCRYPTPROV_LEGACY hProv
,
860 LPCSTR szSubSystemProtocol
)
862 if (!szSubSystemProtocol
)
864 SetLastError(E_INVALIDARG
);
867 return CertOpenStore(CERT_STORE_PROV_SYSTEM_A
, 0, hProv
,
868 CERT_SYSTEM_STORE_CURRENT_USER
, szSubSystemProtocol
);
871 HCERTSTORE WINAPI
CertOpenSystemStoreW(HCRYPTPROV_LEGACY hProv
,
872 LPCWSTR szSubSystemProtocol
)
874 if (!szSubSystemProtocol
)
876 SetLastError(E_INVALIDARG
);
879 return CertOpenStore(CERT_STORE_PROV_SYSTEM_W
, 0, hProv
,
880 CERT_SYSTEM_STORE_CURRENT_USER
, szSubSystemProtocol
);
883 BOOL WINAPI
CertAddCertificateContextToStore(HCERTSTORE hCertStore
,
884 PCCERT_CONTEXT pCertContext
, DWORD dwAddDisposition
,
885 PCCERT_CONTEXT
*ppStoreContext
)
887 WINECRYPT_CERTSTORE
*store
= hCertStore
;
889 PCCERT_CONTEXT toAdd
= NULL
, existing
= NULL
;
891 TRACE("(%p, %p, %08x, %p)\n", hCertStore
, pCertContext
,
892 dwAddDisposition
, ppStoreContext
);
894 switch (dwAddDisposition
)
896 case CERT_STORE_ADD_ALWAYS
:
898 case CERT_STORE_ADD_NEW
:
899 case CERT_STORE_ADD_REPLACE_EXISTING
:
900 case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES
:
901 case CERT_STORE_ADD_USE_EXISTING
:
902 case CERT_STORE_ADD_NEWER
:
903 case CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES
:
906 DWORD size
= sizeof(hashToAdd
);
908 ret
= CertGetCertificateContextProperty(pCertContext
, CERT_HASH_PROP_ID
,
912 CRYPT_HASH_BLOB blob
= { sizeof(hashToAdd
), hashToAdd
};
914 existing
= CertFindCertificateInStore(hCertStore
,
915 pCertContext
->dwCertEncodingType
, 0, CERT_FIND_SHA1_HASH
, &blob
,
921 FIXME("Unimplemented add disposition %d\n", dwAddDisposition
);
922 SetLastError(E_INVALIDARG
);
926 switch (dwAddDisposition
)
928 case CERT_STORE_ADD_ALWAYS
:
929 toAdd
= CertDuplicateCertificateContext(pCertContext
);
931 case CERT_STORE_ADD_NEW
:
934 TRACE("found matching certificate, not adding\n");
935 SetLastError(CRYPT_E_EXISTS
);
939 toAdd
= CertDuplicateCertificateContext(pCertContext
);
941 case CERT_STORE_ADD_REPLACE_EXISTING
:
942 toAdd
= CertDuplicateCertificateContext(pCertContext
);
944 case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES
:
945 toAdd
= CertDuplicateCertificateContext(pCertContext
);
947 Context_CopyProperties(toAdd
, existing
);
949 case CERT_STORE_ADD_USE_EXISTING
:
952 Context_CopyProperties(existing
, pCertContext
);
954 *ppStoreContext
= CertDuplicateCertificateContext(existing
);
957 toAdd
= CertDuplicateCertificateContext(pCertContext
);
959 case CERT_STORE_ADD_NEWER
:
962 if (CompareFileTime(&existing
->pCertInfo
->NotBefore
,
963 &pCertContext
->pCertInfo
->NotBefore
) >= 0)
965 TRACE("existing certificate is newer, not adding\n");
966 SetLastError(CRYPT_E_EXISTS
);
970 toAdd
= CertDuplicateCertificateContext(pCertContext
);
973 toAdd
= CertDuplicateCertificateContext(pCertContext
);
975 case CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES
:
978 if (CompareFileTime(&existing
->pCertInfo
->NotBefore
,
979 &pCertContext
->pCertInfo
->NotBefore
) >= 0)
981 TRACE("existing certificate is newer, not adding\n");
982 SetLastError(CRYPT_E_EXISTS
);
987 toAdd
= CertDuplicateCertificateContext(pCertContext
);
988 Context_CopyProperties(toAdd
, existing
);
992 toAdd
= CertDuplicateCertificateContext(pCertContext
);
999 ret
= store
->certs
.addContext(store
, (void *)toAdd
,
1000 (void *)existing
, (const void **)ppStoreContext
);
1001 else if (ppStoreContext
)
1002 *ppStoreContext
= CertDuplicateCertificateContext(toAdd
);
1003 CertFreeCertificateContext(toAdd
);
1005 CertFreeCertificateContext(existing
);
1007 TRACE("returning %d\n", ret
);
1011 PCCERT_CONTEXT WINAPI
CertEnumCertificatesInStore(HCERTSTORE hCertStore
,
1012 PCCERT_CONTEXT pPrev
)
1014 WINECRYPT_CERTSTORE
*hcs
= hCertStore
;
1017 TRACE("(%p, %p)\n", hCertStore
, pPrev
);
1020 else if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1023 ret
= (PCCERT_CONTEXT
)hcs
->certs
.enumContext(hcs
, (void *)pPrev
);
1027 BOOL WINAPI
CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext
)
1031 TRACE("(%p)\n", pCertContext
);
1035 else if (!pCertContext
->hCertStore
)
1036 ret
= CertFreeCertificateContext(pCertContext
);
1039 WINECRYPT_CERTSTORE
*hcs
= pCertContext
->hCertStore
;
1041 if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1044 ret
= hcs
->certs
.deleteContext(hcs
, (void *)pCertContext
);
1046 ret
= CertFreeCertificateContext(pCertContext
);
1051 #define CrlContext_CopyProperties(to, from) \
1052 Context_CopyProperties((to), (from), sizeof(CRL_CONTEXT))
1054 BOOL WINAPI
CertAddCRLContextToStore(HCERTSTORE hCertStore
,
1055 PCCRL_CONTEXT pCrlContext
, DWORD dwAddDisposition
,
1056 PCCRL_CONTEXT
* ppStoreContext
)
1058 WINECRYPT_CERTSTORE
*store
= hCertStore
;
1060 PCCRL_CONTEXT toAdd
= NULL
, existing
= NULL
;
1062 TRACE("(%p, %p, %08x, %p)\n", hCertStore
, pCrlContext
,
1063 dwAddDisposition
, ppStoreContext
);
1065 /* Weird case to pass a test */
1066 if (dwAddDisposition
== 0)
1068 SetLastError(STATUS_ACCESS_VIOLATION
);
1071 if (dwAddDisposition
!= CERT_STORE_ADD_ALWAYS
)
1073 existing
= CertFindCRLInStore(hCertStore
, 0, 0, CRL_FIND_EXISTING
,
1077 switch (dwAddDisposition
)
1079 case CERT_STORE_ADD_ALWAYS
:
1080 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1082 case CERT_STORE_ADD_NEW
:
1085 TRACE("found matching CRL, not adding\n");
1086 SetLastError(CRYPT_E_EXISTS
);
1090 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1092 case CERT_STORE_ADD_NEWER
:
1095 LONG newer
= CompareFileTime(&existing
->pCrlInfo
->ThisUpdate
,
1096 &pCrlContext
->pCrlInfo
->ThisUpdate
);
1099 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1102 TRACE("existing CRL is newer, not adding\n");
1103 SetLastError(CRYPT_E_EXISTS
);
1108 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1110 case CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES
:
1113 LONG newer
= CompareFileTime(&existing
->pCrlInfo
->ThisUpdate
,
1114 &pCrlContext
->pCrlInfo
->ThisUpdate
);
1118 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1119 Context_CopyProperties(toAdd
, existing
);
1123 TRACE("existing CRL is newer, not adding\n");
1124 SetLastError(CRYPT_E_EXISTS
);
1129 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1131 case CERT_STORE_ADD_REPLACE_EXISTING
:
1132 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1134 case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES
:
1135 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1137 Context_CopyProperties(toAdd
, existing
);
1139 case CERT_STORE_ADD_USE_EXISTING
:
1142 Context_CopyProperties(existing
, pCrlContext
);
1144 *ppStoreContext
= CertDuplicateCRLContext(existing
);
1147 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1150 FIXME("Unimplemented add disposition %d\n", dwAddDisposition
);
1157 ret
= store
->crls
.addContext(store
, (void *)toAdd
,
1158 (void *)existing
, (const void **)ppStoreContext
);
1159 else if (ppStoreContext
)
1160 *ppStoreContext
= CertDuplicateCRLContext(toAdd
);
1161 CertFreeCRLContext(toAdd
);
1163 CertFreeCRLContext(existing
);
1165 TRACE("returning %d\n", ret
);
1169 BOOL WINAPI
CertDeleteCRLFromStore(PCCRL_CONTEXT pCrlContext
)
1173 TRACE("(%p)\n", pCrlContext
);
1177 else if (!pCrlContext
->hCertStore
)
1178 ret
= CertFreeCRLContext(pCrlContext
);
1181 WINECRYPT_CERTSTORE
*hcs
= pCrlContext
->hCertStore
;
1183 if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1186 ret
= hcs
->crls
.deleteContext(hcs
, (void *)pCrlContext
);
1188 ret
= CertFreeCRLContext(pCrlContext
);
1193 PCCRL_CONTEXT WINAPI
CertEnumCRLsInStore(HCERTSTORE hCertStore
,
1194 PCCRL_CONTEXT pPrev
)
1196 WINECRYPT_CERTSTORE
*hcs
= hCertStore
;
1199 TRACE("(%p, %p)\n", hCertStore
, pPrev
);
1202 else if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1205 ret
= (PCCRL_CONTEXT
)hcs
->crls
.enumContext(hcs
, (void *)pPrev
);
1209 HCERTSTORE WINAPI
CertDuplicateStore(HCERTSTORE hCertStore
)
1211 WINECRYPT_CERTSTORE
*hcs
= hCertStore
;
1213 TRACE("(%p)\n", hCertStore
);
1215 if (hcs
&& hcs
->dwMagic
== WINE_CRYPTCERTSTORE_MAGIC
)
1216 InterlockedIncrement(&hcs
->ref
);
1220 BOOL WINAPI
CertCloseStore(HCERTSTORE hCertStore
, DWORD dwFlags
)
1222 WINECRYPT_CERTSTORE
*hcs
= hCertStore
;
1224 TRACE("(%p, %08x)\n", hCertStore
, dwFlags
);
1229 if ( hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1233 ERR("%p's ref count is %d\n", hcs
, hcs
->ref
);
1234 if (InterlockedDecrement(&hcs
->ref
) == 0)
1236 TRACE("%p's ref count is 0, freeing\n", hcs
);
1238 hcs
->vtbl
->closeStore(hcs
, dwFlags
);
1241 TRACE("%p's ref count is %d\n", hcs
, hcs
->ref
);
1245 BOOL WINAPI
CertControlStore(HCERTSTORE hCertStore
, DWORD dwFlags
,
1246 DWORD dwCtrlType
, void const *pvCtrlPara
)
1248 WINECRYPT_CERTSTORE
*hcs
= hCertStore
;
1251 TRACE("(%p, %08x, %d, %p)\n", hCertStore
, dwFlags
, dwCtrlType
,
1256 else if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1260 if (hcs
->vtbl
->control
)
1261 ret
= hcs
->vtbl
->control(hcs
, dwFlags
, dwCtrlType
, pvCtrlPara
);
1268 BOOL WINAPI
CertGetStoreProperty(HCERTSTORE hCertStore
, DWORD dwPropId
,
1269 void *pvData
, DWORD
*pcbData
)
1271 WINECRYPT_CERTSTORE
*store
= hCertStore
;
1274 TRACE("(%p, %d, %p, %p)\n", hCertStore
, dwPropId
, pvData
, pcbData
);
1278 case CERT_ACCESS_STATE_PROP_ID
:
1281 *pcbData
= sizeof(DWORD
);
1284 else if (*pcbData
< sizeof(DWORD
))
1286 SetLastError(ERROR_MORE_DATA
);
1287 *pcbData
= sizeof(DWORD
);
1293 if (store
->type
!= StoreTypeMem
&&
1294 !(store
->dwOpenFlags
& CERT_STORE_READONLY_FLAG
))
1295 state
|= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG
;
1296 *(DWORD
*)pvData
= state
;
1301 if (store
->properties
)
1303 CRYPT_DATA_BLOB blob
;
1305 ret
= ContextPropertyList_FindProperty(store
->properties
, dwPropId
,
1310 *pcbData
= blob
.cbData
;
1311 else if (*pcbData
< blob
.cbData
)
1313 SetLastError(ERROR_MORE_DATA
);
1314 *pcbData
= blob
.cbData
;
1319 memcpy(pvData
, blob
.pbData
, blob
.cbData
);
1320 *pcbData
= blob
.cbData
;
1324 SetLastError(CRYPT_E_NOT_FOUND
);
1327 SetLastError(CRYPT_E_NOT_FOUND
);
1332 BOOL WINAPI
CertSetStoreProperty(HCERTSTORE hCertStore
, DWORD dwPropId
,
1333 DWORD dwFlags
, const void *pvData
)
1335 WINECRYPT_CERTSTORE
*store
= hCertStore
;
1338 TRACE("(%p, %d, %08x, %p)\n", hCertStore
, dwPropId
, dwFlags
, pvData
);
1340 if (!store
->properties
)
1341 store
->properties
= ContextPropertyList_Create();
1344 case CERT_ACCESS_STATE_PROP_ID
:
1345 SetLastError(E_INVALIDARG
);
1350 const CRYPT_DATA_BLOB
*blob
= pvData
;
1352 ret
= ContextPropertyList_SetProperty(store
->properties
, dwPropId
,
1353 blob
->pbData
, blob
->cbData
);
1357 ContextPropertyList_RemoveProperty(store
->properties
, dwPropId
);
1364 static LONG
CRYPT_OpenParentStore(DWORD dwFlags
,
1365 void *pvSystemStoreLocationPara
, HKEY
*key
)
1370 TRACE("(%08x, %p)\n", dwFlags
, pvSystemStoreLocationPara
);
1372 switch (dwFlags
& CERT_SYSTEM_STORE_LOCATION_MASK
)
1374 case CERT_SYSTEM_STORE_LOCAL_MACHINE
:
1375 root
= HKEY_LOCAL_MACHINE
;
1376 base
= CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH
;
1378 case CERT_SYSTEM_STORE_CURRENT_USER
:
1379 root
= HKEY_CURRENT_USER
;
1380 base
= CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH
;
1382 case CERT_SYSTEM_STORE_CURRENT_SERVICE
:
1383 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
1384 * SystemCertificates
1386 FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE\n");
1387 return ERROR_FILE_NOT_FOUND
;
1388 case CERT_SYSTEM_STORE_SERVICES
:
1389 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
1390 * SystemCertificates
1392 FIXME("CERT_SYSTEM_STORE_SERVICES\n");
1393 return ERROR_FILE_NOT_FOUND
;
1394 case CERT_SYSTEM_STORE_USERS
:
1395 /* hku\user sid\Software\Microsoft\SystemCertificates */
1396 FIXME("CERT_SYSTEM_STORE_USERS\n");
1397 return ERROR_FILE_NOT_FOUND
;
1398 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY
:
1399 root
= HKEY_CURRENT_USER
;
1400 base
= CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH
;
1402 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY
:
1403 root
= HKEY_LOCAL_MACHINE
;
1404 base
= CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH
;
1406 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE
:
1407 /* hklm\Software\Microsoft\EnterpriseCertificates */
1408 FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE\n");
1409 return ERROR_FILE_NOT_FOUND
;
1411 return ERROR_FILE_NOT_FOUND
;
1414 return RegOpenKeyExW(root
, base
, 0, KEY_READ
, key
);
1417 BOOL WINAPI
CertEnumSystemStore(DWORD dwFlags
, void *pvSystemStoreLocationPara
,
1418 void *pvArg
, PFN_CERT_ENUM_SYSTEM_STORE pfnEnum
)
1423 CERT_SYSTEM_STORE_INFO info
= { sizeof(info
) };
1425 TRACE("(%08x, %p, %p, %p)\n", dwFlags
, pvSystemStoreLocationPara
, pvArg
,
1428 rc
= CRYPT_OpenParentStore(dwFlags
, pvArg
, &key
);
1435 WCHAR name
[MAX_PATH
];
1436 DWORD size
= sizeof(name
) / sizeof(name
[0]);
1438 rc
= RegEnumKeyExW(key
, index
++, name
, &size
, NULL
, NULL
, NULL
,
1441 ret
= pfnEnum(name
, dwFlags
, &info
, NULL
, pvArg
);
1442 } while (ret
&& !rc
);
1443 if (ret
&& rc
!= ERROR_NO_MORE_ITEMS
)
1448 /* Include root store for the local machine location (it isn't in the
1451 if (ret
&& (dwFlags
& CERT_SYSTEM_STORE_LOCATION_MASK
) ==
1452 CERT_SYSTEM_STORE_LOCAL_MACHINE
)
1453 ret
= pfnEnum(rootW
, dwFlags
, &info
, NULL
, pvArg
);
1457 BOOL WINAPI
CertEnumPhysicalStore(const void *pvSystemStore
, DWORD dwFlags
,
1458 void *pvArg
, PFN_CERT_ENUM_PHYSICAL_STORE pfnEnum
)
1460 if (dwFlags
& CERT_SYSTEM_STORE_RELOCATE_FLAG
)
1461 FIXME("(%p, %08x, %p, %p): stub\n", pvSystemStore
, dwFlags
, pvArg
,
1464 FIXME("(%s, %08x, %p, %p): stub\n", debugstr_w(pvSystemStore
),
1470 BOOL WINAPI
CertRegisterPhysicalStore(const void *pvSystemStore
, DWORD dwFlags
,
1471 LPCWSTR pwszStoreName
, PCERT_PHYSICAL_STORE_INFO pStoreInfo
, void *pvReserved
)
1473 if (dwFlags
& CERT_SYSTEM_STORE_RELOCATE_FLAG
)
1474 FIXME("(%p, %08x, %s, %p, %p): stub\n", pvSystemStore
, dwFlags
,
1475 debugstr_w(pwszStoreName
), pStoreInfo
, pvReserved
);
1477 FIXME("(%s, %08x, %s, %p, %p): stub\n", debugstr_w(pvSystemStore
),
1478 dwFlags
, debugstr_w(pwszStoreName
), pStoreInfo
, pvReserved
);