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 struct ContextList
*ctls
;
95 } WINE_MEMSTORE
, *PWINE_MEMSTORE
;
97 void CRYPT_InitStore(WINECRYPT_CERTSTORE
*store
, DWORD dwFlags
,
101 store
->dwMagic
= WINE_CRYPTCERTSTORE_MAGIC
;
103 store
->dwOpenFlags
= dwFlags
;
104 store
->properties
= NULL
;
107 void CRYPT_FreeStore(PWINECRYPT_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(PWINECRYPT_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
;
164 *ppStoreContext
= CertDuplicateCertificateContext(context
);
166 return context
? TRUE
: FALSE
;
169 static void *CRYPT_MemEnumCert(PWINECRYPT_CERTSTORE store
, void *pPrev
)
171 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
174 TRACE("(%p, %p)\n", store
, pPrev
);
176 ret
= ContextList_Enum(ms
->certs
, pPrev
);
178 SetLastError(CRYPT_E_NOT_FOUND
);
180 TRACE("returning %p\n", ret
);
184 static BOOL
CRYPT_MemDeleteCert(PWINECRYPT_CERTSTORE store
, void *pCertContext
)
186 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
189 if (ContextList_Remove(ms
->certs
, pCertContext
))
190 ret
= CertFreeCertificateContext(pCertContext
);
196 static BOOL
CRYPT_MemAddCrl(PWINECRYPT_CERTSTORE store
, void *crl
,
197 void *toReplace
, const void **ppStoreContext
)
199 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
200 PCRL_CONTEXT context
;
202 TRACE("(%p, %p, %p, %p)\n", store
, crl
, toReplace
, ppStoreContext
);
204 context
= ContextList_Add(ms
->crls
, crl
, toReplace
);
207 context
->hCertStore
= store
;
209 *ppStoreContext
= CertDuplicateCRLContext(context
);
211 return context
? TRUE
: FALSE
;
214 static void *CRYPT_MemEnumCrl(PWINECRYPT_CERTSTORE store
, void *pPrev
)
216 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
219 TRACE("(%p, %p)\n", store
, pPrev
);
221 ret
= ContextList_Enum(ms
->crls
, pPrev
);
223 SetLastError(CRYPT_E_NOT_FOUND
);
225 TRACE("returning %p\n", ret
);
229 static BOOL
CRYPT_MemDeleteCrl(PWINECRYPT_CERTSTORE store
, void *pCrlContext
)
231 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
234 if (ContextList_Remove(ms
->crls
, pCrlContext
))
235 ret
= CertFreeCRLContext(pCrlContext
);
241 static BOOL
CRYPT_MemAddCtl(PWINECRYPT_CERTSTORE store
, void *ctl
,
242 void *toReplace
, const void **ppStoreContext
)
244 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
245 PCTL_CONTEXT context
;
247 TRACE("(%p, %p, %p, %p)\n", store
, ctl
, toReplace
, ppStoreContext
);
249 context
= ContextList_Add(ms
->ctls
, ctl
, toReplace
);
252 context
->hCertStore
= store
;
254 *ppStoreContext
= CertDuplicateCTLContext(context
);
256 return context
? TRUE
: FALSE
;
259 static void *CRYPT_MemEnumCtl(PWINECRYPT_CERTSTORE store
, void *pPrev
)
261 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
264 TRACE("(%p, %p)\n", store
, pPrev
);
266 ret
= ContextList_Enum(ms
->ctls
, pPrev
);
268 SetLastError(CRYPT_E_NOT_FOUND
);
270 TRACE("returning %p\n", ret
);
274 static BOOL
CRYPT_MemDeleteCtl(PWINECRYPT_CERTSTORE store
, void *pCtlContext
)
276 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
279 if (ContextList_Remove(ms
->ctls
, pCtlContext
))
280 ret
= CertFreeCTLContext(pCtlContext
);
286 static BOOL WINAPI
CRYPT_MemControl(HCERTSTORE hCertStore
, DWORD dwFlags
,
287 DWORD dwCtrlType
, void const *pvCtrlPara
)
289 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
293 static void WINAPI
CRYPT_MemCloseStore(HCERTSTORE hCertStore
, DWORD dwFlags
)
295 WINE_MEMSTORE
*store
= hCertStore
;
297 TRACE("(%p, %08x)\n", store
, dwFlags
);
299 FIXME("Unimplemented flags: %08x\n", dwFlags
);
301 ContextList_Free(store
->certs
);
302 ContextList_Free(store
->crls
);
303 ContextList_Free(store
->ctls
);
304 CRYPT_FreeStore((PWINECRYPT_CERTSTORE
)store
);
307 static WINECRYPT_CERTSTORE
*CRYPT_MemOpenStore(HCRYPTPROV hCryptProv
,
308 DWORD dwFlags
, const void *pvPara
)
310 PWINE_MEMSTORE store
;
312 TRACE("(%ld, %08x, %p)\n", hCryptProv
, dwFlags
, pvPara
);
314 if (dwFlags
& CERT_STORE_DELETE_FLAG
)
316 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
321 store
= CryptMemAlloc(sizeof(WINE_MEMSTORE
));
324 memset(store
, 0, sizeof(WINE_MEMSTORE
));
325 CRYPT_InitStore(&store
->hdr
, dwFlags
, StoreTypeMem
);
326 store
->hdr
.closeStore
= CRYPT_MemCloseStore
;
327 store
->hdr
.certs
.addContext
= CRYPT_MemAddCert
;
328 store
->hdr
.certs
.enumContext
= CRYPT_MemEnumCert
;
329 store
->hdr
.certs
.deleteContext
= CRYPT_MemDeleteCert
;
330 store
->hdr
.crls
.addContext
= CRYPT_MemAddCrl
;
331 store
->hdr
.crls
.enumContext
= CRYPT_MemEnumCrl
;
332 store
->hdr
.crls
.deleteContext
= CRYPT_MemDeleteCrl
;
333 store
->hdr
.ctls
.addContext
= CRYPT_MemAddCtl
;
334 store
->hdr
.ctls
.enumContext
= CRYPT_MemEnumCtl
;
335 store
->hdr
.ctls
.deleteContext
= CRYPT_MemDeleteCtl
;
336 store
->hdr
.control
= CRYPT_MemControl
;
337 store
->certs
= ContextList_Create(pCertInterface
,
338 sizeof(CERT_CONTEXT
));
339 store
->crls
= ContextList_Create(pCRLInterface
,
340 sizeof(CRL_CONTEXT
));
341 store
->ctls
= ContextList_Create(pCTLInterface
,
342 sizeof(CTL_CONTEXT
));
343 /* Mem store doesn't need crypto provider, so close it */
344 if (hCryptProv
&& !(dwFlags
& CERT_STORE_NO_CRYPT_RELEASE_FLAG
))
345 CryptReleaseContext(hCryptProv
, 0);
348 return (PWINECRYPT_CERTSTORE
)store
;
351 static const WCHAR rootW
[] = { 'R','o','o','t',0 };
353 static PWINECRYPT_CERTSTORE
CRYPT_SysRegOpenStoreW(HCRYPTPROV hCryptProv
,
354 DWORD dwFlags
, const void *pvPara
)
356 static const WCHAR fmt
[] = { '%','s','\\','%','s',0 };
357 LPCWSTR storeName
= pvPara
;
359 PWINECRYPT_CERTSTORE store
= NULL
;
363 TRACE("(%ld, %08x, %s)\n", hCryptProv
, dwFlags
,
368 SetLastError(E_INVALIDARG
);
371 /* FIXME: In Windows, the root store (even the current user location) is
372 * protected: adding to it or removing from it present a user interface,
373 * and the keys are owned by the system process, not the current user.
374 * Wine's registry doesn't implement access controls, so a similar
375 * mechanism isn't possible yet.
377 if ((dwFlags
& CERT_SYSTEM_STORE_LOCATION_MASK
) ==
378 CERT_SYSTEM_STORE_LOCAL_MACHINE
&& !lstrcmpiW(storeName
, rootW
))
379 return CRYPT_RootOpenStore(hCryptProv
, dwFlags
);
381 switch (dwFlags
& CERT_SYSTEM_STORE_LOCATION_MASK
)
383 case CERT_SYSTEM_STORE_LOCAL_MACHINE
:
384 root
= HKEY_LOCAL_MACHINE
;
385 base
= CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH
;
387 case CERT_SYSTEM_STORE_CURRENT_USER
:
388 root
= HKEY_CURRENT_USER
;
389 base
= CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH
;
391 case CERT_SYSTEM_STORE_CURRENT_SERVICE
:
392 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
395 FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE, %s: stub\n",
396 debugstr_w(storeName
));
398 case CERT_SYSTEM_STORE_SERVICES
:
399 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
402 FIXME("CERT_SYSTEM_STORE_SERVICES, %s: stub\n",
403 debugstr_w(storeName
));
405 case CERT_SYSTEM_STORE_USERS
:
406 /* hku\user sid\Software\Microsoft\SystemCertificates */
407 FIXME("CERT_SYSTEM_STORE_USERS, %s: stub\n",
408 debugstr_w(storeName
));
410 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY
:
411 root
= HKEY_CURRENT_USER
;
412 base
= CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH
;
414 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY
:
415 root
= HKEY_LOCAL_MACHINE
;
416 base
= CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH
;
418 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE
:
419 /* hklm\Software\Microsoft\EnterpriseCertificates */
420 FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, %s: stub\n",
421 debugstr_w(storeName
));
424 SetLastError(E_INVALIDARG
);
428 storePath
= CryptMemAlloc((lstrlenW(base
) + lstrlenW(storeName
) + 2) *
434 REGSAM sam
= dwFlags
& CERT_STORE_READONLY_FLAG
? KEY_READ
:
437 wsprintfW(storePath
, fmt
, base
, storeName
);
438 if (dwFlags
& CERT_STORE_OPEN_EXISTING_FLAG
)
439 rc
= RegOpenKeyExW(root
, storePath
, 0, sam
, &key
);
444 rc
= RegCreateKeyExW(root
, storePath
, 0, NULL
, 0, sam
, NULL
,
446 if (!rc
&& dwFlags
& CERT_STORE_CREATE_NEW_FLAG
&&
447 disp
== REG_OPENED_EXISTING_KEY
)
450 rc
= ERROR_FILE_EXISTS
;
455 store
= CRYPT_RegOpenStore(hCryptProv
, dwFlags
, key
);
460 CryptMemFree(storePath
);
465 static PWINECRYPT_CERTSTORE
CRYPT_SysRegOpenStoreA(HCRYPTPROV hCryptProv
,
466 DWORD dwFlags
, const void *pvPara
)
469 PWINECRYPT_CERTSTORE ret
= NULL
;
471 TRACE("(%ld, %08x, %s)\n", hCryptProv
, dwFlags
,
476 SetLastError(ERROR_FILE_NOT_FOUND
);
479 len
= MultiByteToWideChar(CP_ACP
, 0, pvPara
, -1, NULL
, 0);
482 LPWSTR storeName
= CryptMemAlloc(len
* sizeof(WCHAR
));
486 MultiByteToWideChar(CP_ACP
, 0, pvPara
, -1, storeName
, len
);
487 ret
= CRYPT_SysRegOpenStoreW(hCryptProv
, dwFlags
, storeName
);
488 CryptMemFree(storeName
);
494 static PWINECRYPT_CERTSTORE
CRYPT_SysOpenStoreW(HCRYPTPROV hCryptProv
,
495 DWORD dwFlags
, const void *pvPara
)
497 HCERTSTORE store
= 0;
500 TRACE("(%ld, %08x, %s)\n", hCryptProv
, dwFlags
,
505 SetLastError(ERROR_FILE_NOT_FOUND
);
508 /* This returns a different error than system registry stores if the
509 * location is invalid.
511 switch (dwFlags
& CERT_SYSTEM_STORE_LOCATION_MASK
)
513 case CERT_SYSTEM_STORE_LOCAL_MACHINE
:
514 case CERT_SYSTEM_STORE_CURRENT_USER
:
515 case CERT_SYSTEM_STORE_CURRENT_SERVICE
:
516 case CERT_SYSTEM_STORE_SERVICES
:
517 case CERT_SYSTEM_STORE_USERS
:
518 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY
:
519 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY
:
520 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE
:
524 SetLastError(ERROR_FILE_NOT_FOUND
);
529 HCERTSTORE regStore
= CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W
,
530 0, 0, dwFlags
, pvPara
);
534 store
= CertOpenStore(CERT_STORE_PROV_COLLECTION
, 0, 0,
535 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
536 CertAddStoreToCollection(store
, regStore
,
537 dwFlags
& CERT_STORE_READONLY_FLAG
? 0 :
538 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG
, 0);
539 CertCloseStore(regStore
, 0);
540 /* CERT_SYSTEM_STORE_CURRENT_USER returns both the HKCU and HKLM
543 if ((dwFlags
& CERT_SYSTEM_STORE_LOCATION_MASK
) ==
544 CERT_SYSTEM_STORE_CURRENT_USER
)
546 dwFlags
&= ~CERT_SYSTEM_STORE_CURRENT_USER
;
547 dwFlags
|= CERT_SYSTEM_STORE_LOCAL_MACHINE
;
548 regStore
= CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W
, 0,
552 CertAddStoreToCollection(store
, regStore
,
553 dwFlags
& CERT_STORE_READONLY_FLAG
? 0 :
554 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG
, 0);
555 CertCloseStore(regStore
, 0);
558 /* System store doesn't need crypto provider, so close it */
559 if (hCryptProv
&& !(dwFlags
& CERT_STORE_NO_CRYPT_RELEASE_FLAG
))
560 CryptReleaseContext(hCryptProv
, 0);
566 static PWINECRYPT_CERTSTORE
CRYPT_SysOpenStoreA(HCRYPTPROV hCryptProv
,
567 DWORD dwFlags
, const void *pvPara
)
570 PWINECRYPT_CERTSTORE ret
= NULL
;
572 TRACE("(%ld, %08x, %s)\n", hCryptProv
, dwFlags
,
577 SetLastError(ERROR_FILE_NOT_FOUND
);
580 len
= MultiByteToWideChar(CP_ACP
, 0, pvPara
, -1, NULL
, 0);
583 LPWSTR storeName
= CryptMemAlloc(len
* sizeof(WCHAR
));
587 MultiByteToWideChar(CP_ACP
, 0, pvPara
, -1, storeName
, len
);
588 ret
= CRYPT_SysOpenStoreW(hCryptProv
, dwFlags
, storeName
);
589 CryptMemFree(storeName
);
595 static void WINAPI
CRYPT_MsgCloseStore(HCERTSTORE hCertStore
, DWORD dwFlags
)
597 HCRYPTMSG msg
= hCertStore
;
599 TRACE("(%p, %08x)\n", msg
, dwFlags
);
603 static void *msgProvFuncs
[] = {
607 static PWINECRYPT_CERTSTORE
CRYPT_MsgOpenStore(HCRYPTPROV hCryptProv
,
608 DWORD dwFlags
, const void *pvPara
)
610 PWINECRYPT_CERTSTORE store
= NULL
;
611 HCRYPTMSG msg
= (HCRYPTMSG
)pvPara
;
612 PWINECRYPT_CERTSTORE memStore
;
614 TRACE("(%ld, %08x, %p)\n", hCryptProv
, dwFlags
, pvPara
);
616 memStore
= CertOpenStore(CERT_STORE_PROV_MEMORY
, 0, 0,
617 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
621 DWORD size
, count
, i
;
623 size
= sizeof(count
);
624 ret
= CryptMsgGetParam(msg
, CMSG_CERT_COUNT_PARAM
, 0, &count
, &size
);
625 for (i
= 0; ret
&& i
< count
; i
++)
628 ret
= CryptMsgGetParam(msg
, CMSG_CERT_PARAM
, i
, NULL
, &size
);
631 LPBYTE buf
= CryptMemAlloc(size
);
635 ret
= CryptMsgGetParam(msg
, CMSG_CERT_PARAM
, i
, buf
, &size
);
637 ret
= CertAddEncodedCertificateToStore(memStore
,
638 X509_ASN_ENCODING
, buf
, size
, CERT_STORE_ADD_ALWAYS
,
644 size
= sizeof(count
);
645 ret
= CryptMsgGetParam(msg
, CMSG_CRL_COUNT_PARAM
, 0, &count
, &size
);
646 for (i
= 0; ret
&& i
< count
; i
++)
649 ret
= CryptMsgGetParam(msg
, CMSG_CRL_PARAM
, i
, NULL
, &size
);
652 LPBYTE buf
= CryptMemAlloc(size
);
656 ret
= CryptMsgGetParam(msg
, CMSG_CRL_PARAM
, i
, buf
, &size
);
658 ret
= CertAddEncodedCRLToStore(memStore
,
659 X509_ASN_ENCODING
, buf
, size
, CERT_STORE_ADD_ALWAYS
,
667 CERT_STORE_PROV_INFO provInfo
= { 0 };
669 provInfo
.cbSize
= sizeof(provInfo
);
670 provInfo
.cStoreProvFunc
= sizeof(msgProvFuncs
) /
671 sizeof(msgProvFuncs
[0]);
672 provInfo
.rgpvStoreProvFunc
= msgProvFuncs
;
673 provInfo
.hStoreProv
= CryptMsgDuplicate(msg
);
674 store
= CRYPT_ProvCreateStore(dwFlags
, memStore
, &provInfo
);
675 /* Msg store doesn't need crypto provider, so close it */
676 if (hCryptProv
&& !(dwFlags
& CERT_STORE_NO_CRYPT_RELEASE_FLAG
))
677 CryptReleaseContext(hCryptProv
, 0);
680 CertCloseStore(memStore
, 0);
682 TRACE("returning %p\n", store
);
686 static PWINECRYPT_CERTSTORE
CRYPT_PKCSOpenStore(HCRYPTPROV hCryptProv
,
687 DWORD dwFlags
, const void *pvPara
)
690 PWINECRYPT_CERTSTORE store
= NULL
;
691 const CRYPT_DATA_BLOB
*data
= pvPara
;
693 DWORD msgOpenFlags
= dwFlags
& CERT_STORE_NO_CRYPT_RELEASE_FLAG
? 0 :
694 CMSG_CRYPT_RELEASE_CONTEXT_FLAG
;
696 TRACE("(%ld, %08x, %p)\n", hCryptProv
, dwFlags
, pvPara
);
698 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, msgOpenFlags
, CMSG_SIGNED
,
699 hCryptProv
, NULL
, NULL
);
700 ret
= CryptMsgUpdate(msg
, data
->pbData
, data
->cbData
, TRUE
);
704 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, msgOpenFlags
, 0,
705 hCryptProv
, NULL
, NULL
);
706 ret
= CryptMsgUpdate(msg
, data
->pbData
, data
->cbData
, TRUE
);
709 DWORD type
, size
= sizeof(type
);
711 /* Only signed messages are allowed, check type */
712 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, &type
, &size
);
713 if (ret
&& type
!= CMSG_SIGNED
)
715 SetLastError(CRYPT_E_INVALID_MSG_TYPE
);
721 store
= CRYPT_MsgOpenStore(0, dwFlags
, msg
);
723 TRACE("returning %p\n", store
);
727 static PWINECRYPT_CERTSTORE
CRYPT_SerializedOpenStore(HCRYPTPROV hCryptProv
,
728 DWORD dwFlags
, const void *pvPara
)
731 const CRYPT_DATA_BLOB
*data
= pvPara
;
733 TRACE("(%ld, %08x, %p)\n", hCryptProv
, dwFlags
, pvPara
);
735 if (dwFlags
& CERT_STORE_DELETE_FLAG
)
737 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
741 store
= CertOpenStore(CERT_STORE_PROV_MEMORY
, 0, 0,
742 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
745 if (!CRYPT_ReadSerializedStoreFromBlob(data
, store
))
747 CertCloseStore(store
, 0);
751 TRACE("returning %p\n", store
);
752 return (PWINECRYPT_CERTSTORE
)store
;
755 static PWINECRYPT_CERTSTORE
CRYPT_PhysOpenStoreW(HCRYPTPROV hCryptProv
,
756 DWORD dwFlags
, const void *pvPara
)
758 if (dwFlags
& CERT_SYSTEM_STORE_RELOCATE_FLAG
)
759 FIXME("(%ld, %08x, %p): stub\n", hCryptProv
, dwFlags
, pvPara
);
761 FIXME("(%ld, %08x, %s): stub\n", hCryptProv
, dwFlags
,
766 HCERTSTORE WINAPI
CertOpenStore(LPCSTR lpszStoreProvider
,
767 DWORD dwMsgAndCertEncodingType
, HCRYPTPROV_LEGACY hCryptProv
, DWORD dwFlags
,
770 WINECRYPT_CERTSTORE
*hcs
;
771 StoreOpenFunc openFunc
= NULL
;
773 TRACE("(%s, %08x, %08lx, %08x, %p)\n", debugstr_a(lpszStoreProvider
),
774 dwMsgAndCertEncodingType
, hCryptProv
, dwFlags
, pvPara
);
776 if (IS_INTOID(lpszStoreProvider
))
778 switch (LOWORD(lpszStoreProvider
))
780 case LOWORD(CERT_STORE_PROV_MSG
):
781 openFunc
= CRYPT_MsgOpenStore
;
783 case LOWORD(CERT_STORE_PROV_MEMORY
):
784 openFunc
= CRYPT_MemOpenStore
;
786 case LOWORD(CERT_STORE_PROV_FILE
):
787 openFunc
= CRYPT_FileOpenStore
;
789 case LOWORD(CERT_STORE_PROV_PKCS7
):
790 openFunc
= CRYPT_PKCSOpenStore
;
792 case LOWORD(CERT_STORE_PROV_SERIALIZED
):
793 openFunc
= CRYPT_SerializedOpenStore
;
795 case LOWORD(CERT_STORE_PROV_REG
):
796 openFunc
= CRYPT_RegOpenStore
;
798 case LOWORD(CERT_STORE_PROV_FILENAME_A
):
799 openFunc
= CRYPT_FileNameOpenStoreA
;
801 case LOWORD(CERT_STORE_PROV_FILENAME_W
):
802 openFunc
= CRYPT_FileNameOpenStoreW
;
804 case LOWORD(CERT_STORE_PROV_COLLECTION
):
805 openFunc
= CRYPT_CollectionOpenStore
;
807 case LOWORD(CERT_STORE_PROV_SYSTEM_A
):
808 openFunc
= CRYPT_SysOpenStoreA
;
810 case LOWORD(CERT_STORE_PROV_SYSTEM_W
):
811 openFunc
= CRYPT_SysOpenStoreW
;
813 case LOWORD(CERT_STORE_PROV_SYSTEM_REGISTRY_A
):
814 openFunc
= CRYPT_SysRegOpenStoreA
;
816 case LOWORD(CERT_STORE_PROV_SYSTEM_REGISTRY_W
):
817 openFunc
= CRYPT_SysRegOpenStoreW
;
819 case LOWORD(CERT_STORE_PROV_PHYSICAL_W
):
820 openFunc
= CRYPT_PhysOpenStoreW
;
823 if (LOWORD(lpszStoreProvider
))
824 FIXME("unimplemented type %d\n", LOWORD(lpszStoreProvider
));
827 else if (!strcasecmp(lpszStoreProvider
, sz_CERT_STORE_PROV_MEMORY
))
828 openFunc
= CRYPT_MemOpenStore
;
829 else if (!strcasecmp(lpszStoreProvider
, sz_CERT_STORE_PROV_FILENAME_W
))
830 openFunc
= CRYPT_FileOpenStore
;
831 else if (!strcasecmp(lpszStoreProvider
, sz_CERT_STORE_PROV_SYSTEM
))
832 openFunc
= CRYPT_SysOpenStoreW
;
833 else if (!strcasecmp(lpszStoreProvider
, sz_CERT_STORE_PROV_PKCS7
))
834 openFunc
= CRYPT_PKCSOpenStore
;
835 else if (!strcasecmp(lpszStoreProvider
, sz_CERT_STORE_PROV_SERIALIZED
))
836 openFunc
= CRYPT_SerializedOpenStore
;
837 else if (!strcasecmp(lpszStoreProvider
, sz_CERT_STORE_PROV_COLLECTION
))
838 openFunc
= CRYPT_CollectionOpenStore
;
839 else if (!strcasecmp(lpszStoreProvider
, sz_CERT_STORE_PROV_SYSTEM_REGISTRY
))
840 openFunc
= CRYPT_SysRegOpenStoreW
;
843 FIXME("unimplemented type %s\n", lpszStoreProvider
);
848 hcs
= CRYPT_ProvOpenStore(lpszStoreProvider
, dwMsgAndCertEncodingType
,
849 hCryptProv
, dwFlags
, pvPara
);
851 hcs
= openFunc(hCryptProv
, dwFlags
, pvPara
);
855 HCERTSTORE WINAPI
CertOpenSystemStoreA(HCRYPTPROV_LEGACY hProv
,
856 LPCSTR szSubSystemProtocol
)
858 if (!szSubSystemProtocol
)
860 SetLastError(E_INVALIDARG
);
863 return CertOpenStore(CERT_STORE_PROV_SYSTEM_A
, 0, hProv
,
864 CERT_SYSTEM_STORE_CURRENT_USER
, szSubSystemProtocol
);
867 HCERTSTORE WINAPI
CertOpenSystemStoreW(HCRYPTPROV_LEGACY hProv
,
868 LPCWSTR szSubSystemProtocol
)
870 if (!szSubSystemProtocol
)
872 SetLastError(E_INVALIDARG
);
875 return CertOpenStore(CERT_STORE_PROV_SYSTEM_W
, 0, hProv
,
876 CERT_SYSTEM_STORE_CURRENT_USER
, szSubSystemProtocol
);
879 #define CertContext_CopyProperties(to, from) \
880 Context_CopyProperties((to), (from), sizeof(CERT_CONTEXT))
882 BOOL WINAPI
CertAddCertificateContextToStore(HCERTSTORE hCertStore
,
883 PCCERT_CONTEXT pCertContext
, DWORD dwAddDisposition
,
884 PCCERT_CONTEXT
*ppStoreContext
)
886 PWINECRYPT_CERTSTORE store
= hCertStore
;
888 PCCERT_CONTEXT toAdd
= NULL
, existing
= NULL
;
890 TRACE("(%p, %p, %08x, %p)\n", hCertStore
, pCertContext
,
891 dwAddDisposition
, ppStoreContext
);
893 switch (dwAddDisposition
)
895 case CERT_STORE_ADD_ALWAYS
:
897 case CERT_STORE_ADD_NEW
:
898 case CERT_STORE_ADD_REPLACE_EXISTING
:
899 case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES
:
900 case CERT_STORE_ADD_USE_EXISTING
:
901 case CERT_STORE_ADD_NEWER
:
902 case CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES
:
905 DWORD size
= sizeof(hashToAdd
);
907 ret
= CertGetCertificateContextProperty(pCertContext
, CERT_HASH_PROP_ID
,
911 CRYPT_HASH_BLOB blob
= { sizeof(hashToAdd
), hashToAdd
};
913 existing
= CertFindCertificateInStore(hCertStore
,
914 pCertContext
->dwCertEncodingType
, 0, CERT_FIND_SHA1_HASH
, &blob
,
920 FIXME("Unimplemented add disposition %d\n", dwAddDisposition
);
921 SetLastError(E_INVALIDARG
);
925 switch (dwAddDisposition
)
927 case CERT_STORE_ADD_ALWAYS
:
928 toAdd
= CertDuplicateCertificateContext(pCertContext
);
930 case CERT_STORE_ADD_NEW
:
933 TRACE("found matching certificate, not adding\n");
934 SetLastError(CRYPT_E_EXISTS
);
938 toAdd
= CertDuplicateCertificateContext(pCertContext
);
940 case CERT_STORE_ADD_REPLACE_EXISTING
:
941 toAdd
= CertDuplicateCertificateContext(pCertContext
);
943 case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES
:
944 toAdd
= CertDuplicateCertificateContext(pCertContext
);
946 CertContext_CopyProperties(toAdd
, existing
);
948 case CERT_STORE_ADD_USE_EXISTING
:
951 CertContext_CopyProperties(existing
, pCertContext
);
953 *ppStoreContext
= CertDuplicateCertificateContext(existing
);
956 toAdd
= CertDuplicateCertificateContext(pCertContext
);
958 case CERT_STORE_ADD_NEWER
:
961 if (CompareFileTime(&existing
->pCertInfo
->NotBefore
,
962 &pCertContext
->pCertInfo
->NotBefore
) >= 0)
964 TRACE("existing certificate is newer, not adding\n");
965 SetLastError(CRYPT_E_EXISTS
);
969 toAdd
= CertDuplicateCertificateContext(pCertContext
);
972 toAdd
= CertDuplicateCertificateContext(pCertContext
);
974 case CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES
:
977 if (CompareFileTime(&existing
->pCertInfo
->NotBefore
,
978 &pCertContext
->pCertInfo
->NotBefore
) >= 0)
980 TRACE("existing certificate is newer, not adding\n");
981 SetLastError(CRYPT_E_EXISTS
);
986 toAdd
= CertDuplicateCertificateContext(pCertContext
);
987 CertContext_CopyProperties(toAdd
, existing
);
991 toAdd
= CertDuplicateCertificateContext(pCertContext
);
998 ret
= store
->certs
.addContext(store
, (void *)toAdd
,
999 (void *)existing
, (const void **)ppStoreContext
);
1000 else if (ppStoreContext
)
1001 *ppStoreContext
= CertDuplicateCertificateContext(toAdd
);
1002 CertFreeCertificateContext(toAdd
);
1004 CertFreeCertificateContext(existing
);
1006 TRACE("returning %d\n", ret
);
1010 PCCERT_CONTEXT WINAPI
CertEnumCertificatesInStore(HCERTSTORE hCertStore
,
1011 PCCERT_CONTEXT pPrev
)
1013 WINECRYPT_CERTSTORE
*hcs
= hCertStore
;
1016 TRACE("(%p, %p)\n", hCertStore
, pPrev
);
1019 else if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1022 ret
= (PCCERT_CONTEXT
)hcs
->certs
.enumContext(hcs
, (void *)pPrev
);
1026 BOOL WINAPI
CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext
)
1030 TRACE("(%p)\n", pCertContext
);
1034 else if (!pCertContext
->hCertStore
)
1035 ret
= CertFreeCertificateContext(pCertContext
);
1038 PWINECRYPT_CERTSTORE hcs
= pCertContext
->hCertStore
;
1040 if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1043 ret
= hcs
->certs
.deleteContext(hcs
, (void *)pCertContext
);
1045 ret
= CertFreeCertificateContext(pCertContext
);
1050 #define CrlContext_CopyProperties(to, from) \
1051 Context_CopyProperties((to), (from), sizeof(CRL_CONTEXT))
1053 BOOL WINAPI
CertAddCRLContextToStore(HCERTSTORE hCertStore
,
1054 PCCRL_CONTEXT pCrlContext
, DWORD dwAddDisposition
,
1055 PCCRL_CONTEXT
* ppStoreContext
)
1057 PWINECRYPT_CERTSTORE store
= hCertStore
;
1059 PCCRL_CONTEXT toAdd
= NULL
, existing
= NULL
;
1061 TRACE("(%p, %p, %08x, %p)\n", hCertStore
, pCrlContext
,
1062 dwAddDisposition
, ppStoreContext
);
1064 /* Weird case to pass a test */
1065 if (dwAddDisposition
== 0)
1067 SetLastError(STATUS_ACCESS_VIOLATION
);
1070 if (dwAddDisposition
!= CERT_STORE_ADD_ALWAYS
)
1072 existing
= CertFindCRLInStore(hCertStore
, 0, 0, CRL_FIND_EXISTING
,
1076 switch (dwAddDisposition
)
1078 case CERT_STORE_ADD_ALWAYS
:
1079 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1081 case CERT_STORE_ADD_NEW
:
1084 TRACE("found matching CRL, not adding\n");
1085 SetLastError(CRYPT_E_EXISTS
);
1089 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1091 case CERT_STORE_ADD_NEWER
:
1094 LONG newer
= CompareFileTime(&existing
->pCrlInfo
->ThisUpdate
,
1095 &pCrlContext
->pCrlInfo
->ThisUpdate
);
1098 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1101 TRACE("existing CRL is newer, not adding\n");
1102 SetLastError(CRYPT_E_EXISTS
);
1107 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1109 case CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES
:
1112 LONG newer
= CompareFileTime(&existing
->pCrlInfo
->ThisUpdate
,
1113 &pCrlContext
->pCrlInfo
->ThisUpdate
);
1117 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1118 CrlContext_CopyProperties(toAdd
, existing
);
1122 TRACE("existing CRL is newer, not adding\n");
1123 SetLastError(CRYPT_E_EXISTS
);
1128 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1130 case CERT_STORE_ADD_REPLACE_EXISTING
:
1131 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1133 case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES
:
1134 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1136 CrlContext_CopyProperties(toAdd
, existing
);
1138 case CERT_STORE_ADD_USE_EXISTING
:
1141 CrlContext_CopyProperties(existing
, pCrlContext
);
1143 *ppStoreContext
= CertDuplicateCRLContext(existing
);
1146 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1149 FIXME("Unimplemented add disposition %d\n", dwAddDisposition
);
1156 ret
= store
->crls
.addContext(store
, (void *)toAdd
,
1157 (void *)existing
, (const void **)ppStoreContext
);
1158 else if (ppStoreContext
)
1159 *ppStoreContext
= CertDuplicateCRLContext(toAdd
);
1160 CertFreeCRLContext(toAdd
);
1162 CertFreeCRLContext(existing
);
1164 TRACE("returning %d\n", ret
);
1168 BOOL WINAPI
CertDeleteCRLFromStore(PCCRL_CONTEXT pCrlContext
)
1172 TRACE("(%p)\n", pCrlContext
);
1176 else if (!pCrlContext
->hCertStore
)
1177 ret
= CertFreeCRLContext(pCrlContext
);
1180 PWINECRYPT_CERTSTORE hcs
= pCrlContext
->hCertStore
;
1182 if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1185 ret
= hcs
->crls
.deleteContext(hcs
, (void *)pCrlContext
);
1187 ret
= CertFreeCRLContext(pCrlContext
);
1192 PCCRL_CONTEXT WINAPI
CertEnumCRLsInStore(HCERTSTORE hCertStore
,
1193 PCCRL_CONTEXT pPrev
)
1195 WINECRYPT_CERTSTORE
*hcs
= hCertStore
;
1198 TRACE("(%p, %p)\n", hCertStore
, pPrev
);
1201 else if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1204 ret
= (PCCRL_CONTEXT
)hcs
->crls
.enumContext(hcs
, (void *)pPrev
);
1208 HCERTSTORE WINAPI
CertDuplicateStore(HCERTSTORE hCertStore
)
1210 WINECRYPT_CERTSTORE
*hcs
= hCertStore
;
1212 TRACE("(%p)\n", hCertStore
);
1214 if (hcs
&& hcs
->dwMagic
== WINE_CRYPTCERTSTORE_MAGIC
)
1215 InterlockedIncrement(&hcs
->ref
);
1219 BOOL WINAPI
CertCloseStore(HCERTSTORE hCertStore
, DWORD dwFlags
)
1221 WINECRYPT_CERTSTORE
*hcs
= hCertStore
;
1223 TRACE("(%p, %08x)\n", hCertStore
, dwFlags
);
1228 if ( hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1232 ERR("%p's ref count is %d\n", hcs
, hcs
->ref
);
1233 if (InterlockedDecrement(&hcs
->ref
) == 0)
1235 TRACE("%p's ref count is 0, freeing\n", hcs
);
1237 hcs
->closeStore(hcs
, dwFlags
);
1240 TRACE("%p's ref count is %d\n", hcs
, hcs
->ref
);
1244 BOOL WINAPI
CertControlStore(HCERTSTORE hCertStore
, DWORD dwFlags
,
1245 DWORD dwCtrlType
, void const *pvCtrlPara
)
1247 WINECRYPT_CERTSTORE
*hcs
= hCertStore
;
1250 TRACE("(%p, %08x, %d, %p)\n", hCertStore
, dwFlags
, dwCtrlType
,
1255 else if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1260 ret
= hcs
->control(hCertStore
, dwFlags
, dwCtrlType
, pvCtrlPara
);
1267 BOOL WINAPI
CertGetStoreProperty(HCERTSTORE hCertStore
, DWORD dwPropId
,
1268 void *pvData
, DWORD
*pcbData
)
1270 PWINECRYPT_CERTSTORE store
= hCertStore
;
1273 TRACE("(%p, %d, %p, %p)\n", hCertStore
, dwPropId
, pvData
, pcbData
);
1277 case CERT_ACCESS_STATE_PROP_ID
:
1280 *pcbData
= sizeof(DWORD
);
1283 else if (*pcbData
< sizeof(DWORD
))
1285 SetLastError(ERROR_MORE_DATA
);
1286 *pcbData
= sizeof(DWORD
);
1292 if (store
->type
!= StoreTypeMem
&&
1293 !(store
->dwOpenFlags
& CERT_STORE_READONLY_FLAG
))
1294 state
|= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG
;
1295 *(DWORD
*)pvData
= state
;
1300 if (store
->properties
)
1302 CRYPT_DATA_BLOB blob
;
1304 ret
= ContextPropertyList_FindProperty(store
->properties
, dwPropId
,
1309 *pcbData
= blob
.cbData
;
1310 else if (*pcbData
< blob
.cbData
)
1312 SetLastError(ERROR_MORE_DATA
);
1313 *pcbData
= blob
.cbData
;
1318 memcpy(pvData
, blob
.pbData
, blob
.cbData
);
1319 *pcbData
= blob
.cbData
;
1323 SetLastError(CRYPT_E_NOT_FOUND
);
1326 SetLastError(CRYPT_E_NOT_FOUND
);
1331 BOOL WINAPI
CertSetStoreProperty(HCERTSTORE hCertStore
, DWORD dwPropId
,
1332 DWORD dwFlags
, const void *pvData
)
1334 PWINECRYPT_CERTSTORE store
= hCertStore
;
1337 TRACE("(%p, %d, %08x, %p)\n", hCertStore
, dwPropId
, dwFlags
, pvData
);
1339 if (!store
->properties
)
1340 store
->properties
= ContextPropertyList_Create();
1343 case CERT_ACCESS_STATE_PROP_ID
:
1344 SetLastError(E_INVALIDARG
);
1349 const CRYPT_DATA_BLOB
*blob
= pvData
;
1351 ret
= ContextPropertyList_SetProperty(store
->properties
, dwPropId
,
1352 blob
->pbData
, blob
->cbData
);
1356 ContextPropertyList_RemoveProperty(store
->properties
, dwPropId
);
1363 static LONG
CRYPT_OpenParentStore(DWORD dwFlags
,
1364 void *pvSystemStoreLocationPara
, HKEY
*key
)
1369 TRACE("(%08x, %p)\n", dwFlags
, pvSystemStoreLocationPara
);
1371 switch (dwFlags
& CERT_SYSTEM_STORE_LOCATION_MASK
)
1373 case CERT_SYSTEM_STORE_LOCAL_MACHINE
:
1374 root
= HKEY_LOCAL_MACHINE
;
1375 base
= CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH
;
1377 case CERT_SYSTEM_STORE_CURRENT_USER
:
1378 root
= HKEY_CURRENT_USER
;
1379 base
= CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH
;
1381 case CERT_SYSTEM_STORE_CURRENT_SERVICE
:
1382 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
1383 * SystemCertificates
1385 FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE\n");
1386 return ERROR_FILE_NOT_FOUND
;
1387 case CERT_SYSTEM_STORE_SERVICES
:
1388 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
1389 * SystemCertificates
1391 FIXME("CERT_SYSTEM_STORE_SERVICES\n");
1392 return ERROR_FILE_NOT_FOUND
;
1393 case CERT_SYSTEM_STORE_USERS
:
1394 /* hku\user sid\Software\Microsoft\SystemCertificates */
1395 FIXME("CERT_SYSTEM_STORE_USERS\n");
1396 return ERROR_FILE_NOT_FOUND
;
1397 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY
:
1398 root
= HKEY_CURRENT_USER
;
1399 base
= CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH
;
1401 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY
:
1402 root
= HKEY_LOCAL_MACHINE
;
1403 base
= CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH
;
1405 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE
:
1406 /* hklm\Software\Microsoft\EnterpriseCertificates */
1407 FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE\n");
1408 return ERROR_FILE_NOT_FOUND
;
1410 return ERROR_FILE_NOT_FOUND
;
1413 return RegOpenKeyExW(root
, base
, 0, KEY_READ
, key
);
1416 BOOL WINAPI
CertEnumSystemStore(DWORD dwFlags
, void *pvSystemStoreLocationPara
,
1417 void *pvArg
, PFN_CERT_ENUM_SYSTEM_STORE pfnEnum
)
1422 CERT_SYSTEM_STORE_INFO info
= { sizeof(info
) };
1424 TRACE("(%08x, %p, %p, %p)\n", dwFlags
, pvSystemStoreLocationPara
, pvArg
,
1427 rc
= CRYPT_OpenParentStore(dwFlags
, pvArg
, &key
);
1434 WCHAR name
[MAX_PATH
];
1435 DWORD size
= sizeof(name
) / sizeof(name
[0]);
1437 rc
= RegEnumKeyExW(key
, index
++, name
, &size
, NULL
, NULL
, NULL
,
1440 ret
= pfnEnum(name
, dwFlags
, &info
, NULL
, pvArg
);
1441 } while (ret
&& !rc
);
1442 if (ret
&& rc
!= ERROR_NO_MORE_ITEMS
)
1447 /* Include root store for the local machine location (it isn't in the
1450 if (ret
&& (dwFlags
& CERT_SYSTEM_STORE_LOCATION_MASK
) ==
1451 CERT_SYSTEM_STORE_LOCAL_MACHINE
)
1452 ret
= pfnEnum(rootW
, dwFlags
, &info
, NULL
, pvArg
);
1456 BOOL WINAPI
CertEnumPhysicalStore(const void *pvSystemStore
, DWORD dwFlags
,
1457 void *pvArg
, PFN_CERT_ENUM_PHYSICAL_STORE pfnEnum
)
1459 if (dwFlags
& CERT_SYSTEM_STORE_RELOCATE_FLAG
)
1460 FIXME("(%p, %08x, %p, %p): stub\n", pvSystemStore
, dwFlags
, pvArg
,
1463 FIXME("(%s, %08x, %p, %p): stub\n", debugstr_w(pvSystemStore
),