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"
38 #include "wine/debug.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 (EnumContextsInStoreFunc
)CertEnumCertificatesInStore
,
49 (EnumPropertiesFunc
)CertEnumCertificateContextProperties
,
50 (GetContextPropertyFunc
)CertGetCertificateContextProperty
,
51 (SetContextPropertyFunc
)CertSetCertificateContextProperty
,
52 (SerializeElementFunc
)CertSerializeCertificateStoreElement
,
53 (DeleteContextFunc
)CertDeleteCertificateFromStore
,
55 const WINE_CONTEXT_INTERFACE
*pCertInterface
= &gCertInterface
;
57 static const WINE_CONTEXT_INTERFACE gCRLInterface
= {
58 (CreateContextFunc
)CertCreateCRLContext
,
59 (AddContextToStoreFunc
)CertAddCRLContextToStore
,
60 (AddEncodedContextToStoreFunc
)CertAddEncodedCRLToStore
,
61 (EnumContextsInStoreFunc
)CertEnumCRLsInStore
,
62 (EnumPropertiesFunc
)CertEnumCRLContextProperties
,
63 (GetContextPropertyFunc
)CertGetCRLContextProperty
,
64 (SetContextPropertyFunc
)CertSetCRLContextProperty
,
65 (SerializeElementFunc
)CertSerializeCRLStoreElement
,
66 (DeleteContextFunc
)CertDeleteCRLFromStore
,
68 const WINE_CONTEXT_INTERFACE
*pCRLInterface
= &gCRLInterface
;
70 static const WINE_CONTEXT_INTERFACE gCTLInterface
= {
71 (CreateContextFunc
)CertCreateCTLContext
,
72 (AddContextToStoreFunc
)CertAddCTLContextToStore
,
73 (AddEncodedContextToStoreFunc
)CertAddEncodedCTLToStore
,
74 (EnumContextsInStoreFunc
)CertEnumCTLsInStore
,
75 (EnumPropertiesFunc
)CertEnumCTLContextProperties
,
76 (GetContextPropertyFunc
)CertGetCTLContextProperty
,
77 (SetContextPropertyFunc
)CertSetCTLContextProperty
,
78 (SerializeElementFunc
)CertSerializeCTLStoreElement
,
79 (DeleteContextFunc
)CertDeleteCTLFromStore
,
81 const WINE_CONTEXT_INTERFACE
*pCTLInterface
= &gCTLInterface
;
83 typedef struct _WINE_MEMSTORE
85 WINECRYPT_CERTSTORE hdr
;
92 void CRYPT_InitStore(WINECRYPT_CERTSTORE
*store
, DWORD dwFlags
, CertStoreType type
, const store_vtbl_t
*vtbl
)
95 store
->dwMagic
= WINE_CRYPTCERTSTORE_MAGIC
;
97 store
->dwOpenFlags
= dwFlags
;
99 store
->properties
= NULL
;
102 void CRYPT_FreeStore(WINECRYPT_CERTSTORE
*store
)
104 if (store
->properties
)
105 ContextPropertyList_Free(store
->properties
);
110 BOOL WINAPI
I_CertUpdateStore(HCERTSTORE store1
, HCERTSTORE store2
, DWORD unk0
,
113 static BOOL warned
= FALSE
;
114 const WINE_CONTEXT_INTERFACE
* const interfaces
[] = { pCertInterface
,
115 pCRLInterface
, pCTLInterface
};
118 TRACE("(%p, %p, %08x, %08x)\n", store1
, store2
, unk0
, unk1
);
121 FIXME("semi-stub\n");
125 /* Poor-man's resync: empty first store, then add everything from second
128 for (i
= 0; i
< ARRAY_SIZE(interfaces
); i
++)
133 context
= interfaces
[i
]->enumContextsInStore(store1
, NULL
);
135 interfaces
[i
]->deleteFromStore(context
);
138 context
= interfaces
[i
]->enumContextsInStore(store2
, context
);
140 interfaces
[i
]->addContextToStore(store1
, context
,
141 CERT_STORE_ADD_ALWAYS
, NULL
);
147 static BOOL
MemStore_addContext(WINE_MEMSTORE
*store
, struct list
*list
, context_t
*orig_context
,
148 context_t
*existing
, context_t
**ret_context
, BOOL use_link
)
152 context
= orig_context
->vtbl
->clone(orig_context
, &store
->hdr
, use_link
);
156 TRACE("adding %p\n", context
);
157 EnterCriticalSection(&store
->cs
);
159 context
->u
.entry
.prev
= existing
->u
.entry
.prev
;
160 context
->u
.entry
.next
= existing
->u
.entry
.next
;
161 context
->u
.entry
.prev
->next
= &context
->u
.entry
;
162 context
->u
.entry
.next
->prev
= &context
->u
.entry
;
163 list_init(&existing
->u
.entry
);
165 Context_Release(existing
);
167 list_add_head(list
, &context
->u
.entry
);
169 LeaveCriticalSection(&store
->cs
);
172 *ret_context
= context
;
174 Context_Release(context
);
178 static context_t
*MemStore_enumContext(WINE_MEMSTORE
*store
, struct list
*list
, context_t
*prev
)
183 EnterCriticalSection(&store
->cs
);
185 next
= list_next(list
, &prev
->u
.entry
);
186 Context_Release(prev
);
188 next
= list_next(list
, list
);
190 LeaveCriticalSection(&store
->cs
);
193 SetLastError(CRYPT_E_NOT_FOUND
);
197 ret
= LIST_ENTRY(next
, context_t
, u
.entry
);
202 static BOOL
MemStore_deleteContext(WINE_MEMSTORE
*store
, context_t
*context
)
204 BOOL in_list
= FALSE
;
206 EnterCriticalSection(&store
->cs
);
207 if (!list_empty(&context
->u
.entry
)) {
208 list_remove(&context
->u
.entry
);
209 list_init(&context
->u
.entry
);
212 LeaveCriticalSection(&store
->cs
);
214 if(in_list
&& !context
->ref
)
215 Context_Free(context
);
219 static void free_contexts(struct list
*list
)
221 context_t
*context
, *next
;
223 LIST_FOR_EACH_ENTRY_SAFE(context
, next
, list
, context_t
, u
.entry
)
225 TRACE("freeing %p\n", context
);
226 list_remove(&context
->u
.entry
);
227 Context_Free(context
);
231 static void MemStore_releaseContext(WINECRYPT_CERTSTORE
*store
, context_t
*context
)
233 /* Free the context only if it's not in a list. Otherwise it may be reused later. */
234 if(list_empty(&context
->u
.entry
))
235 Context_Free(context
);
238 static BOOL
MemStore_addCert(WINECRYPT_CERTSTORE
*store
, context_t
*cert
,
239 context_t
*toReplace
, context_t
**ppStoreContext
, BOOL use_link
)
241 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
243 TRACE("(%p, %p, %p, %p)\n", store
, cert
, toReplace
, ppStoreContext
);
244 return MemStore_addContext(ms
, &ms
->certs
, cert
, toReplace
, ppStoreContext
, use_link
);
247 static context_t
*MemStore_enumCert(WINECRYPT_CERTSTORE
*store
, context_t
*prev
)
249 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
251 TRACE("(%p, %p)\n", store
, prev
);
253 return MemStore_enumContext(ms
, &ms
->certs
, prev
);
256 static BOOL
MemStore_deleteCert(WINECRYPT_CERTSTORE
*store
, context_t
*context
)
258 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
260 TRACE("(%p, %p)\n", store
, context
);
262 return MemStore_deleteContext(ms
, context
);
265 static BOOL
MemStore_addCRL(WINECRYPT_CERTSTORE
*store
, context_t
*crl
,
266 context_t
*toReplace
, context_t
**ppStoreContext
, BOOL use_link
)
268 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
270 TRACE("(%p, %p, %p, %p)\n", store
, crl
, toReplace
, ppStoreContext
);
272 return MemStore_addContext(ms
, &ms
->crls
, crl
, toReplace
, ppStoreContext
, use_link
);
275 static context_t
*MemStore_enumCRL(WINECRYPT_CERTSTORE
*store
, context_t
*prev
)
277 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
279 TRACE("(%p, %p)\n", store
, prev
);
281 return MemStore_enumContext(ms
, &ms
->crls
, prev
);
284 static BOOL
MemStore_deleteCRL(WINECRYPT_CERTSTORE
*store
, context_t
*context
)
286 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
288 TRACE("(%p, %p)\n", store
, context
);
290 return MemStore_deleteContext(ms
, context
);
293 static BOOL
MemStore_addCTL(WINECRYPT_CERTSTORE
*store
, context_t
*ctl
,
294 context_t
*toReplace
, context_t
**ppStoreContext
, BOOL use_link
)
296 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
298 TRACE("(%p, %p, %p, %p)\n", store
, ctl
, toReplace
, ppStoreContext
);
300 return MemStore_addContext(ms
, &ms
->ctls
, ctl
, toReplace
, ppStoreContext
, use_link
);
303 static context_t
*MemStore_enumCTL(WINECRYPT_CERTSTORE
*store
, context_t
*prev
)
305 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
307 TRACE("(%p, %p)\n", store
, prev
);
309 return MemStore_enumContext(ms
, &ms
->ctls
, prev
);
312 static BOOL
MemStore_deleteCTL(WINECRYPT_CERTSTORE
*store
, context_t
*context
)
314 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
316 TRACE("(%p, %p)\n", store
, context
);
318 return MemStore_deleteContext(ms
, context
);
321 static void MemStore_addref(WINECRYPT_CERTSTORE
*store
)
323 LONG ref
= InterlockedIncrement(&store
->ref
);
324 TRACE("ref = %d\n", ref
);
327 static DWORD
MemStore_release(WINECRYPT_CERTSTORE
*cert_store
, DWORD flags
)
329 WINE_MEMSTORE
*store
= (WINE_MEMSTORE
*)cert_store
;
332 if(flags
& ~CERT_CLOSE_STORE_CHECK_FLAG
)
333 FIXME("Unimplemented flags %x\n", flags
);
335 ref
= InterlockedDecrement(&store
->hdr
.ref
);
336 TRACE("(%p) ref=%d\n", store
, ref
);
338 return (flags
& CERT_CLOSE_STORE_CHECK_FLAG
) ? CRYPT_E_PENDING_CLOSE
: ERROR_SUCCESS
;
340 free_contexts(&store
->certs
);
341 free_contexts(&store
->crls
);
342 free_contexts(&store
->ctls
);
343 store
->cs
.DebugInfo
->Spare
[0] = 0;
344 DeleteCriticalSection(&store
->cs
);
345 CRYPT_FreeStore(&store
->hdr
);
346 return ERROR_SUCCESS
;
349 static BOOL
MemStore_control(WINECRYPT_CERTSTORE
*store
, DWORD dwFlags
,
350 DWORD dwCtrlType
, void const *pvCtrlPara
)
352 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
356 static const store_vtbl_t MemStoreVtbl
= {
359 MemStore_releaseContext
,
376 static WINECRYPT_CERTSTORE
*CRYPT_MemOpenStore(HCRYPTPROV hCryptProv
,
377 DWORD dwFlags
, const void *pvPara
)
379 WINE_MEMSTORE
*store
;
381 TRACE("(%ld, %08x, %p)\n", hCryptProv
, dwFlags
, pvPara
);
383 if (dwFlags
& CERT_STORE_DELETE_FLAG
)
385 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
390 store
= CryptMemAlloc(sizeof(WINE_MEMSTORE
));
393 memset(store
, 0, sizeof(WINE_MEMSTORE
));
394 CRYPT_InitStore(&store
->hdr
, dwFlags
, StoreTypeMem
, &MemStoreVtbl
);
395 InitializeCriticalSection(&store
->cs
);
396 store
->cs
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": ContextList.cs");
397 list_init(&store
->certs
);
398 list_init(&store
->crls
);
399 list_init(&store
->ctls
);
400 /* Mem store doesn't need crypto provider, so close it */
401 if (hCryptProv
&& !(dwFlags
& CERT_STORE_NO_CRYPT_RELEASE_FLAG
))
402 CryptReleaseContext(hCryptProv
, 0);
405 return (WINECRYPT_CERTSTORE
*)store
;
408 static const WCHAR rootW
[] = { 'R','o','o','t',0 };
410 static WINECRYPT_CERTSTORE
*CRYPT_SysRegOpenStoreW(HCRYPTPROV hCryptProv
,
411 DWORD dwFlags
, const void *pvPara
)
413 static const WCHAR fmt
[] = { '%','s','\\','%','s',0 };
414 LPCWSTR storeName
= pvPara
;
416 WINECRYPT_CERTSTORE
*store
= NULL
;
420 TRACE("(%ld, %08x, %s)\n", hCryptProv
, dwFlags
,
425 SetLastError(E_INVALIDARG
);
429 switch (dwFlags
& CERT_SYSTEM_STORE_LOCATION_MASK
)
431 case CERT_SYSTEM_STORE_LOCAL_MACHINE
:
432 root
= HKEY_LOCAL_MACHINE
;
433 base
= CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH
;
434 /* If the HKLM\Root certs are requested, expressing system certs into the registry */
435 if (!lstrcmpiW(storeName
, rootW
))
436 CRYPT_ImportSystemRootCertsToReg();
438 case CERT_SYSTEM_STORE_CURRENT_USER
:
439 root
= HKEY_CURRENT_USER
;
440 base
= CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH
;
442 case CERT_SYSTEM_STORE_CURRENT_SERVICE
:
443 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
446 FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE, %s: stub\n",
447 debugstr_w(storeName
));
449 case CERT_SYSTEM_STORE_SERVICES
:
450 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
453 FIXME("CERT_SYSTEM_STORE_SERVICES, %s: stub\n",
454 debugstr_w(storeName
));
456 case CERT_SYSTEM_STORE_USERS
:
457 /* hku\user sid\Software\Microsoft\SystemCertificates */
458 FIXME("CERT_SYSTEM_STORE_USERS, %s: stub\n",
459 debugstr_w(storeName
));
461 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY
:
462 root
= HKEY_CURRENT_USER
;
463 base
= CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH
;
465 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY
:
466 root
= HKEY_LOCAL_MACHINE
;
467 base
= CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH
;
469 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE
:
470 /* hklm\Software\Microsoft\EnterpriseCertificates */
471 FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, %s: stub\n",
472 debugstr_w(storeName
));
475 SetLastError(E_INVALIDARG
);
479 storePath
= CryptMemAlloc((lstrlenW(base
) + lstrlenW(storeName
) + 2) *
485 REGSAM sam
= dwFlags
& CERT_STORE_READONLY_FLAG
? KEY_READ
:
488 wsprintfW(storePath
, fmt
, base
, storeName
);
489 if (dwFlags
& CERT_STORE_OPEN_EXISTING_FLAG
)
490 rc
= RegOpenKeyExW(root
, storePath
, 0, sam
, &key
);
495 rc
= RegCreateKeyExW(root
, storePath
, 0, NULL
, 0, sam
, NULL
,
497 if (!rc
&& dwFlags
& CERT_STORE_CREATE_NEW_FLAG
&&
498 disp
== REG_OPENED_EXISTING_KEY
)
501 rc
= ERROR_FILE_EXISTS
;
506 store
= CRYPT_RegOpenStore(hCryptProv
, dwFlags
, key
);
511 CryptMemFree(storePath
);
516 static WINECRYPT_CERTSTORE
*CRYPT_SysRegOpenStoreA(HCRYPTPROV hCryptProv
,
517 DWORD dwFlags
, const void *pvPara
)
520 WINECRYPT_CERTSTORE
*ret
= NULL
;
522 TRACE("(%ld, %08x, %s)\n", hCryptProv
, dwFlags
,
527 SetLastError(ERROR_FILE_NOT_FOUND
);
530 len
= MultiByteToWideChar(CP_ACP
, 0, pvPara
, -1, NULL
, 0);
533 LPWSTR storeName
= CryptMemAlloc(len
* sizeof(WCHAR
));
537 MultiByteToWideChar(CP_ACP
, 0, pvPara
, -1, storeName
, len
);
538 ret
= CRYPT_SysRegOpenStoreW(hCryptProv
, dwFlags
, storeName
);
539 CryptMemFree(storeName
);
545 static WINECRYPT_CERTSTORE
*CRYPT_SysOpenStoreW(HCRYPTPROV hCryptProv
,
546 DWORD dwFlags
, const void *pvPara
)
548 HCERTSTORE store
= 0;
551 TRACE("(%ld, %08x, %s)\n", hCryptProv
, dwFlags
,
556 SetLastError(ERROR_FILE_NOT_FOUND
);
559 /* This returns a different error than system registry stores if the
560 * location is invalid.
562 switch (dwFlags
& CERT_SYSTEM_STORE_LOCATION_MASK
)
564 case CERT_SYSTEM_STORE_LOCAL_MACHINE
:
565 case CERT_SYSTEM_STORE_CURRENT_USER
:
566 case CERT_SYSTEM_STORE_CURRENT_SERVICE
:
567 case CERT_SYSTEM_STORE_SERVICES
:
568 case CERT_SYSTEM_STORE_USERS
:
569 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY
:
570 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY
:
571 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE
:
575 SetLastError(ERROR_FILE_NOT_FOUND
);
580 HCERTSTORE regStore
= CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W
,
581 0, 0, dwFlags
, pvPara
);
585 store
= CertOpenStore(CERT_STORE_PROV_COLLECTION
, 0, 0,
586 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
587 CertAddStoreToCollection(store
, regStore
,
588 dwFlags
& CERT_STORE_READONLY_FLAG
? 0 :
589 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG
, 0);
590 CertCloseStore(regStore
, 0);
591 /* CERT_SYSTEM_STORE_CURRENT_USER returns both the HKCU and HKLM
594 if ((dwFlags
& CERT_SYSTEM_STORE_LOCATION_MASK
) ==
595 CERT_SYSTEM_STORE_CURRENT_USER
)
597 dwFlags
&= ~CERT_SYSTEM_STORE_CURRENT_USER
;
598 dwFlags
|= CERT_SYSTEM_STORE_LOCAL_MACHINE
;
599 regStore
= CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W
, 0,
603 CertAddStoreToCollection(store
, regStore
,
604 dwFlags
& CERT_STORE_READONLY_FLAG
? 0 :
605 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG
, 0);
606 CertCloseStore(regStore
, 0);
609 /* System store doesn't need crypto provider, so close it */
610 if (hCryptProv
&& !(dwFlags
& CERT_STORE_NO_CRYPT_RELEASE_FLAG
))
611 CryptReleaseContext(hCryptProv
, 0);
617 static WINECRYPT_CERTSTORE
*CRYPT_SysOpenStoreA(HCRYPTPROV hCryptProv
,
618 DWORD dwFlags
, const void *pvPara
)
621 WINECRYPT_CERTSTORE
*ret
= NULL
;
623 TRACE("(%ld, %08x, %s)\n", hCryptProv
, dwFlags
,
628 SetLastError(ERROR_FILE_NOT_FOUND
);
631 len
= MultiByteToWideChar(CP_ACP
, 0, pvPara
, -1, NULL
, 0);
634 LPWSTR storeName
= CryptMemAlloc(len
* sizeof(WCHAR
));
638 MultiByteToWideChar(CP_ACP
, 0, pvPara
, -1, storeName
, len
);
639 ret
= CRYPT_SysOpenStoreW(hCryptProv
, dwFlags
, storeName
);
640 CryptMemFree(storeName
);
646 static void WINAPI
CRYPT_MsgCloseStore(HCERTSTORE hCertStore
, DWORD dwFlags
)
648 HCRYPTMSG msg
= hCertStore
;
650 TRACE("(%p, %08x)\n", msg
, dwFlags
);
654 static void *msgProvFuncs
[] = {
658 static WINECRYPT_CERTSTORE
*CRYPT_MsgOpenStore(HCRYPTPROV hCryptProv
,
659 DWORD dwFlags
, const void *pvPara
)
661 WINECRYPT_CERTSTORE
*store
= NULL
;
662 HCRYPTMSG msg
= (HCRYPTMSG
)pvPara
;
663 WINECRYPT_CERTSTORE
*memStore
;
665 TRACE("(%ld, %08x, %p)\n", hCryptProv
, dwFlags
, pvPara
);
667 memStore
= CertOpenStore(CERT_STORE_PROV_MEMORY
, 0, 0,
668 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
672 DWORD size
, count
, i
;
674 size
= sizeof(count
);
675 ret
= CryptMsgGetParam(msg
, CMSG_CERT_COUNT_PARAM
, 0, &count
, &size
);
676 for (i
= 0; ret
&& i
< count
; i
++)
679 ret
= CryptMsgGetParam(msg
, CMSG_CERT_PARAM
, i
, NULL
, &size
);
682 LPBYTE buf
= CryptMemAlloc(size
);
686 ret
= CryptMsgGetParam(msg
, CMSG_CERT_PARAM
, i
, buf
, &size
);
688 ret
= CertAddEncodedCertificateToStore(memStore
,
689 X509_ASN_ENCODING
, buf
, size
, CERT_STORE_ADD_ALWAYS
,
695 size
= sizeof(count
);
696 ret
= CryptMsgGetParam(msg
, CMSG_CRL_COUNT_PARAM
, 0, &count
, &size
);
697 for (i
= 0; ret
&& i
< count
; i
++)
700 ret
= CryptMsgGetParam(msg
, CMSG_CRL_PARAM
, i
, NULL
, &size
);
703 LPBYTE buf
= CryptMemAlloc(size
);
707 ret
= CryptMsgGetParam(msg
, CMSG_CRL_PARAM
, i
, buf
, &size
);
709 ret
= CertAddEncodedCRLToStore(memStore
,
710 X509_ASN_ENCODING
, buf
, size
, CERT_STORE_ADD_ALWAYS
,
718 CERT_STORE_PROV_INFO provInfo
= { 0 };
720 provInfo
.cbSize
= sizeof(provInfo
);
721 provInfo
.cStoreProvFunc
= ARRAY_SIZE(msgProvFuncs
);
722 provInfo
.rgpvStoreProvFunc
= msgProvFuncs
;
723 provInfo
.hStoreProv
= CryptMsgDuplicate(msg
);
724 store
= CRYPT_ProvCreateStore(dwFlags
, memStore
, &provInfo
);
725 /* Msg store doesn't need crypto provider, so close it */
726 if (hCryptProv
&& !(dwFlags
& CERT_STORE_NO_CRYPT_RELEASE_FLAG
))
727 CryptReleaseContext(hCryptProv
, 0);
730 CertCloseStore(memStore
, 0);
732 TRACE("returning %p\n", store
);
736 static WINECRYPT_CERTSTORE
*CRYPT_PKCSOpenStore(HCRYPTPROV hCryptProv
,
737 DWORD dwFlags
, const void *pvPara
)
740 WINECRYPT_CERTSTORE
*store
= NULL
;
741 const CRYPT_DATA_BLOB
*data
= pvPara
;
743 DWORD msgOpenFlags
= dwFlags
& CERT_STORE_NO_CRYPT_RELEASE_FLAG
? 0 :
744 CMSG_CRYPT_RELEASE_CONTEXT_FLAG
;
746 TRACE("(%ld, %08x, %p)\n", hCryptProv
, dwFlags
, pvPara
);
748 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, msgOpenFlags
, CMSG_SIGNED
,
749 hCryptProv
, NULL
, NULL
);
750 ret
= CryptMsgUpdate(msg
, data
->pbData
, data
->cbData
, TRUE
);
754 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, msgOpenFlags
, 0,
755 hCryptProv
, NULL
, NULL
);
756 ret
= CryptMsgUpdate(msg
, data
->pbData
, data
->cbData
, TRUE
);
759 DWORD type
, size
= sizeof(type
);
761 /* Only signed messages are allowed, check type */
762 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, &type
, &size
);
763 if (ret
&& type
!= CMSG_SIGNED
)
765 SetLastError(CRYPT_E_INVALID_MSG_TYPE
);
771 store
= CRYPT_MsgOpenStore(0, dwFlags
, msg
);
773 TRACE("returning %p\n", store
);
777 static WINECRYPT_CERTSTORE
*CRYPT_SerializedOpenStore(HCRYPTPROV hCryptProv
,
778 DWORD dwFlags
, const void *pvPara
)
781 const CRYPT_DATA_BLOB
*data
= pvPara
;
783 TRACE("(%ld, %08x, %p)\n", hCryptProv
, dwFlags
, pvPara
);
785 if (dwFlags
& CERT_STORE_DELETE_FLAG
)
787 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
791 store
= CertOpenStore(CERT_STORE_PROV_MEMORY
, 0, 0,
792 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
795 if (!CRYPT_ReadSerializedStoreFromBlob(data
, store
))
797 CertCloseStore(store
, 0);
801 TRACE("returning %p\n", store
);
802 return (WINECRYPT_CERTSTORE
*)store
;
805 static WINECRYPT_CERTSTORE
*CRYPT_PhysOpenStoreW(HCRYPTPROV hCryptProv
,
806 DWORD dwFlags
, const void *pvPara
)
808 if (dwFlags
& CERT_SYSTEM_STORE_RELOCATE_FLAG
)
809 FIXME("(%ld, %08x, %p): stub\n", hCryptProv
, dwFlags
, pvPara
);
811 FIXME("(%ld, %08x, %s): stub\n", hCryptProv
, dwFlags
,
816 HCERTSTORE WINAPI
CertOpenStore(LPCSTR lpszStoreProvider
,
817 DWORD dwMsgAndCertEncodingType
, HCRYPTPROV_LEGACY hCryptProv
, DWORD dwFlags
,
820 WINECRYPT_CERTSTORE
*hcs
;
821 StoreOpenFunc openFunc
= NULL
;
823 TRACE("(%s, %08x, %08lx, %08x, %p)\n", debugstr_a(lpszStoreProvider
),
824 dwMsgAndCertEncodingType
, hCryptProv
, dwFlags
, pvPara
);
826 if (IS_INTOID(lpszStoreProvider
))
828 switch (LOWORD(lpszStoreProvider
))
830 case LOWORD(CERT_STORE_PROV_MSG
):
831 openFunc
= CRYPT_MsgOpenStore
;
833 case LOWORD(CERT_STORE_PROV_MEMORY
):
834 openFunc
= CRYPT_MemOpenStore
;
836 case LOWORD(CERT_STORE_PROV_FILE
):
837 openFunc
= CRYPT_FileOpenStore
;
839 case LOWORD(CERT_STORE_PROV_PKCS7
):
840 openFunc
= CRYPT_PKCSOpenStore
;
842 case LOWORD(CERT_STORE_PROV_SERIALIZED
):
843 openFunc
= CRYPT_SerializedOpenStore
;
845 case LOWORD(CERT_STORE_PROV_REG
):
846 openFunc
= CRYPT_RegOpenStore
;
848 case LOWORD(CERT_STORE_PROV_FILENAME_A
):
849 openFunc
= CRYPT_FileNameOpenStoreA
;
851 case LOWORD(CERT_STORE_PROV_FILENAME_W
):
852 openFunc
= CRYPT_FileNameOpenStoreW
;
854 case LOWORD(CERT_STORE_PROV_COLLECTION
):
855 openFunc
= CRYPT_CollectionOpenStore
;
857 case LOWORD(CERT_STORE_PROV_SYSTEM_A
):
858 openFunc
= CRYPT_SysOpenStoreA
;
860 case LOWORD(CERT_STORE_PROV_SYSTEM_W
):
861 openFunc
= CRYPT_SysOpenStoreW
;
863 case LOWORD(CERT_STORE_PROV_SYSTEM_REGISTRY_A
):
864 openFunc
= CRYPT_SysRegOpenStoreA
;
866 case LOWORD(CERT_STORE_PROV_SYSTEM_REGISTRY_W
):
867 openFunc
= CRYPT_SysRegOpenStoreW
;
869 case LOWORD(CERT_STORE_PROV_PHYSICAL_W
):
870 openFunc
= CRYPT_PhysOpenStoreW
;
873 if (LOWORD(lpszStoreProvider
))
874 FIXME("unimplemented type %d\n", LOWORD(lpszStoreProvider
));
877 else if (!_strnicmp(lpszStoreProvider
, sz_CERT_STORE_PROV_MEMORY
, -1))
878 openFunc
= CRYPT_MemOpenStore
;
879 else if (!_strnicmp(lpszStoreProvider
, sz_CERT_STORE_PROV_FILENAME_W
, -1))
880 openFunc
= CRYPT_FileOpenStore
;
881 else if (!_strnicmp(lpszStoreProvider
, sz_CERT_STORE_PROV_SYSTEM
, -1))
882 openFunc
= CRYPT_SysOpenStoreW
;
883 else if (!_strnicmp(lpszStoreProvider
, sz_CERT_STORE_PROV_PKCS7
, -1))
884 openFunc
= CRYPT_PKCSOpenStore
;
885 else if (!_strnicmp(lpszStoreProvider
, sz_CERT_STORE_PROV_SERIALIZED
, -1))
886 openFunc
= CRYPT_SerializedOpenStore
;
887 else if (!_strnicmp(lpszStoreProvider
, sz_CERT_STORE_PROV_COLLECTION
, -1))
888 openFunc
= CRYPT_CollectionOpenStore
;
889 else if (!_strnicmp(lpszStoreProvider
, sz_CERT_STORE_PROV_SYSTEM_REGISTRY
, -1))
890 openFunc
= CRYPT_SysRegOpenStoreW
;
893 FIXME("unimplemented type %s\n", lpszStoreProvider
);
898 hcs
= CRYPT_ProvOpenStore(lpszStoreProvider
, dwMsgAndCertEncodingType
,
899 hCryptProv
, dwFlags
, pvPara
);
901 hcs
= openFunc(hCryptProv
, dwFlags
, pvPara
);
905 HCERTSTORE WINAPI
CertOpenSystemStoreA(HCRYPTPROV_LEGACY hProv
,
906 LPCSTR szSubSystemProtocol
)
908 if (!szSubSystemProtocol
)
910 SetLastError(E_INVALIDARG
);
913 return CertOpenStore(CERT_STORE_PROV_SYSTEM_A
, 0, hProv
,
914 CERT_SYSTEM_STORE_CURRENT_USER
, szSubSystemProtocol
);
917 HCERTSTORE WINAPI
CertOpenSystemStoreW(HCRYPTPROV_LEGACY hProv
,
918 LPCWSTR szSubSystemProtocol
)
920 if (!szSubSystemProtocol
)
922 SetLastError(E_INVALIDARG
);
925 return CertOpenStore(CERT_STORE_PROV_SYSTEM_W
, 0, hProv
,
926 CERT_SYSTEM_STORE_CURRENT_USER
, szSubSystemProtocol
);
929 PCCERT_CONTEXT WINAPI
CertEnumCertificatesInStore(HCERTSTORE hCertStore
, PCCERT_CONTEXT pPrev
)
931 cert_t
*prev
= pPrev
? cert_from_ptr(pPrev
) : NULL
, *ret
;
932 WINECRYPT_CERTSTORE
*hcs
= hCertStore
;
934 TRACE("(%p, %p)\n", hCertStore
, pPrev
);
937 else if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
940 ret
= (cert_t
*)hcs
->vtbl
->certs
.enumContext(hcs
, prev
? &prev
->base
: NULL
);
941 return ret
? &ret
->ctx
: NULL
;
944 BOOL WINAPI
CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext
)
946 WINECRYPT_CERTSTORE
*hcs
;
948 TRACE("(%p)\n", pCertContext
);
953 hcs
= pCertContext
->hCertStore
;
955 if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
958 return hcs
->vtbl
->certs
.delete(hcs
, &cert_from_ptr(pCertContext
)->base
);
961 BOOL WINAPI
CertAddCRLContextToStore(HCERTSTORE hCertStore
,
962 PCCRL_CONTEXT pCrlContext
, DWORD dwAddDisposition
,
963 PCCRL_CONTEXT
* ppStoreContext
)
965 WINECRYPT_CERTSTORE
*store
= hCertStore
;
967 PCCRL_CONTEXT toAdd
= NULL
, existing
= NULL
;
969 TRACE("(%p, %p, %08x, %p)\n", hCertStore
, pCrlContext
,
970 dwAddDisposition
, ppStoreContext
);
972 /* Weird case to pass a test */
973 if (dwAddDisposition
== 0)
975 SetLastError(STATUS_ACCESS_VIOLATION
);
978 if (dwAddDisposition
!= CERT_STORE_ADD_ALWAYS
)
980 existing
= CertFindCRLInStore(hCertStore
, 0, 0, CRL_FIND_EXISTING
,
984 switch (dwAddDisposition
)
986 case CERT_STORE_ADD_ALWAYS
:
987 toAdd
= CertDuplicateCRLContext(pCrlContext
);
989 case CERT_STORE_ADD_NEW
:
992 TRACE("found matching CRL, not adding\n");
993 SetLastError(CRYPT_E_EXISTS
);
997 toAdd
= CertDuplicateCRLContext(pCrlContext
);
999 case CERT_STORE_ADD_NEWER
:
1002 LONG newer
= CompareFileTime(&existing
->pCrlInfo
->ThisUpdate
,
1003 &pCrlContext
->pCrlInfo
->ThisUpdate
);
1006 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1009 TRACE("existing CRL is newer, not adding\n");
1010 SetLastError(CRYPT_E_EXISTS
);
1015 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1017 case CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES
:
1020 LONG newer
= CompareFileTime(&existing
->pCrlInfo
->ThisUpdate
,
1021 &pCrlContext
->pCrlInfo
->ThisUpdate
);
1025 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1026 Context_CopyProperties(toAdd
, existing
);
1030 TRACE("existing CRL is newer, not adding\n");
1031 SetLastError(CRYPT_E_EXISTS
);
1036 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1038 case CERT_STORE_ADD_REPLACE_EXISTING
:
1039 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1041 case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES
:
1042 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1044 Context_CopyProperties(toAdd
, existing
);
1046 case CERT_STORE_ADD_USE_EXISTING
:
1049 Context_CopyProperties(existing
, pCrlContext
);
1051 *ppStoreContext
= CertDuplicateCRLContext(existing
);
1054 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1057 FIXME("Unimplemented add disposition %d\n", dwAddDisposition
);
1064 context_t
*ret_context
;
1065 ret
= store
->vtbl
->crls
.addContext(store
, context_from_ptr(toAdd
),
1066 existing
? context_from_ptr(existing
) : NULL
, ppStoreContext
? &ret_context
: NULL
, FALSE
);
1067 if (ret
&& ppStoreContext
)
1068 *ppStoreContext
= context_ptr(ret_context
);
1069 }else if (ppStoreContext
) {
1070 *ppStoreContext
= CertDuplicateCRLContext(toAdd
);
1072 CertFreeCRLContext(toAdd
);
1075 CertFreeCRLContext(existing
);
1077 TRACE("returning %d\n", ret
);
1081 BOOL WINAPI
CertDeleteCRLFromStore(PCCRL_CONTEXT pCrlContext
)
1083 WINECRYPT_CERTSTORE
*hcs
;
1086 TRACE("(%p)\n", pCrlContext
);
1091 hcs
= pCrlContext
->hCertStore
;
1093 if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1096 ret
= hcs
->vtbl
->crls
.delete(hcs
, &crl_from_ptr(pCrlContext
)->base
);
1098 ret
= CertFreeCRLContext(pCrlContext
);
1102 PCCRL_CONTEXT WINAPI
CertEnumCRLsInStore(HCERTSTORE hCertStore
, PCCRL_CONTEXT pPrev
)
1104 crl_t
*ret
, *prev
= pPrev
? crl_from_ptr(pPrev
) : NULL
;
1105 WINECRYPT_CERTSTORE
*hcs
= hCertStore
;
1107 TRACE("(%p, %p)\n", hCertStore
, pPrev
);
1110 else if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1113 ret
= (crl_t
*)hcs
->vtbl
->crls
.enumContext(hcs
, prev
? &prev
->base
: NULL
);
1114 return ret
? &ret
->ctx
: NULL
;
1117 HCERTSTORE WINAPI
CertDuplicateStore(HCERTSTORE hCertStore
)
1119 WINECRYPT_CERTSTORE
*hcs
= hCertStore
;
1121 TRACE("(%p)\n", hCertStore
);
1123 if (hcs
&& hcs
->dwMagic
== WINE_CRYPTCERTSTORE_MAGIC
)
1124 hcs
->vtbl
->addref(hcs
);
1128 BOOL WINAPI
CertCloseStore(HCERTSTORE hCertStore
, DWORD dwFlags
)
1130 WINECRYPT_CERTSTORE
*hcs
= hCertStore
;
1133 TRACE("(%p, %08x)\n", hCertStore
, dwFlags
);
1138 if ( hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1141 res
= hcs
->vtbl
->release(hcs
, dwFlags
);
1142 if (res
!= ERROR_SUCCESS
) {
1150 BOOL WINAPI
CertControlStore(HCERTSTORE hCertStore
, DWORD dwFlags
,
1151 DWORD dwCtrlType
, void const *pvCtrlPara
)
1153 WINECRYPT_CERTSTORE
*hcs
= hCertStore
;
1156 TRACE("(%p, %08x, %d, %p)\n", hCertStore
, dwFlags
, dwCtrlType
,
1161 else if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1165 if (hcs
->vtbl
->control
)
1166 ret
= hcs
->vtbl
->control(hcs
, dwFlags
, dwCtrlType
, pvCtrlPara
);
1173 BOOL WINAPI
CertGetStoreProperty(HCERTSTORE hCertStore
, DWORD dwPropId
,
1174 void *pvData
, DWORD
*pcbData
)
1176 WINECRYPT_CERTSTORE
*store
= hCertStore
;
1179 TRACE("(%p, %d, %p, %p)\n", hCertStore
, dwPropId
, pvData
, pcbData
);
1183 case CERT_ACCESS_STATE_PROP_ID
:
1186 *pcbData
= sizeof(DWORD
);
1189 else if (*pcbData
< sizeof(DWORD
))
1191 SetLastError(ERROR_MORE_DATA
);
1192 *pcbData
= sizeof(DWORD
);
1198 if (store
->type
!= StoreTypeMem
&&
1199 !(store
->dwOpenFlags
& CERT_STORE_READONLY_FLAG
))
1200 state
|= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG
;
1201 *(DWORD
*)pvData
= state
;
1206 if (store
->properties
)
1208 CRYPT_DATA_BLOB blob
;
1210 ret
= ContextPropertyList_FindProperty(store
->properties
, dwPropId
,
1215 *pcbData
= blob
.cbData
;
1216 else if (*pcbData
< blob
.cbData
)
1218 SetLastError(ERROR_MORE_DATA
);
1219 *pcbData
= blob
.cbData
;
1224 memcpy(pvData
, blob
.pbData
, blob
.cbData
);
1225 *pcbData
= blob
.cbData
;
1229 SetLastError(CRYPT_E_NOT_FOUND
);
1232 SetLastError(CRYPT_E_NOT_FOUND
);
1237 BOOL WINAPI
CertSetStoreProperty(HCERTSTORE hCertStore
, DWORD dwPropId
,
1238 DWORD dwFlags
, const void *pvData
)
1240 WINECRYPT_CERTSTORE
*store
= hCertStore
;
1243 TRACE("(%p, %d, %08x, %p)\n", hCertStore
, dwPropId
, dwFlags
, pvData
);
1245 if (!store
->properties
)
1246 store
->properties
= ContextPropertyList_Create();
1249 case CERT_ACCESS_STATE_PROP_ID
:
1250 SetLastError(E_INVALIDARG
);
1255 const CRYPT_DATA_BLOB
*blob
= pvData
;
1257 ret
= ContextPropertyList_SetProperty(store
->properties
, dwPropId
,
1258 blob
->pbData
, blob
->cbData
);
1262 ContextPropertyList_RemoveProperty(store
->properties
, dwPropId
);
1269 static LONG
CRYPT_OpenParentStore(DWORD dwFlags
,
1270 void *pvSystemStoreLocationPara
, HKEY
*key
)
1275 TRACE("(%08x, %p)\n", dwFlags
, pvSystemStoreLocationPara
);
1277 switch (dwFlags
& CERT_SYSTEM_STORE_LOCATION_MASK
)
1279 case CERT_SYSTEM_STORE_LOCAL_MACHINE
:
1280 root
= HKEY_LOCAL_MACHINE
;
1281 base
= CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH
;
1283 case CERT_SYSTEM_STORE_CURRENT_USER
:
1284 root
= HKEY_CURRENT_USER
;
1285 base
= CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH
;
1287 case CERT_SYSTEM_STORE_CURRENT_SERVICE
:
1288 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
1289 * SystemCertificates
1291 FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE\n");
1292 return ERROR_FILE_NOT_FOUND
;
1293 case CERT_SYSTEM_STORE_SERVICES
:
1294 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
1295 * SystemCertificates
1297 FIXME("CERT_SYSTEM_STORE_SERVICES\n");
1298 return ERROR_FILE_NOT_FOUND
;
1299 case CERT_SYSTEM_STORE_USERS
:
1300 /* hku\user sid\Software\Microsoft\SystemCertificates */
1301 FIXME("CERT_SYSTEM_STORE_USERS\n");
1302 return ERROR_FILE_NOT_FOUND
;
1303 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY
:
1304 root
= HKEY_CURRENT_USER
;
1305 base
= CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH
;
1307 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY
:
1308 root
= HKEY_LOCAL_MACHINE
;
1309 base
= CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH
;
1311 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE
:
1312 /* hklm\Software\Microsoft\EnterpriseCertificates */
1313 FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE\n");
1314 return ERROR_FILE_NOT_FOUND
;
1316 return ERROR_FILE_NOT_FOUND
;
1319 return RegOpenKeyExW(root
, base
, 0, KEY_READ
, key
);
1322 BOOL WINAPI
CertEnumSystemStore(DWORD dwFlags
, void *pvSystemStoreLocationPara
,
1323 void *pvArg
, PFN_CERT_ENUM_SYSTEM_STORE pfnEnum
)
1328 CERT_SYSTEM_STORE_INFO info
= { sizeof(info
) };
1330 TRACE("(%08x, %p, %p, %p)\n", dwFlags
, pvSystemStoreLocationPara
, pvArg
,
1333 rc
= CRYPT_OpenParentStore(dwFlags
, pvArg
, &key
);
1340 WCHAR name
[MAX_PATH
];
1341 DWORD size
= ARRAY_SIZE(name
);
1343 rc
= RegEnumKeyExW(key
, index
++, name
, &size
, NULL
, NULL
, NULL
,
1346 ret
= pfnEnum(name
, dwFlags
, &info
, NULL
, pvArg
);
1347 } while (ret
&& !rc
);
1348 if (ret
&& rc
!= ERROR_NO_MORE_ITEMS
)
1353 /* Include root store for the local machine location (it isn't in the
1356 if (ret
&& (dwFlags
& CERT_SYSTEM_STORE_LOCATION_MASK
) ==
1357 CERT_SYSTEM_STORE_LOCAL_MACHINE
)
1358 ret
= pfnEnum(rootW
, dwFlags
, &info
, NULL
, pvArg
);
1362 BOOL WINAPI
CertEnumPhysicalStore(const void *pvSystemStore
, DWORD dwFlags
,
1363 void *pvArg
, PFN_CERT_ENUM_PHYSICAL_STORE pfnEnum
)
1365 if (dwFlags
& CERT_SYSTEM_STORE_RELOCATE_FLAG
)
1366 FIXME("(%p, %08x, %p, %p): stub\n", pvSystemStore
, dwFlags
, pvArg
,
1369 FIXME("(%s, %08x, %p, %p): stub\n", debugstr_w(pvSystemStore
),
1375 BOOL WINAPI
CertRegisterPhysicalStore(const void *pvSystemStore
, DWORD dwFlags
,
1376 LPCWSTR pwszStoreName
, PCERT_PHYSICAL_STORE_INFO pStoreInfo
, void *pvReserved
)
1378 if (dwFlags
& CERT_SYSTEM_STORE_RELOCATE_FLAG
)
1379 FIXME("(%p, %08x, %s, %p, %p): stub\n", pvSystemStore
, dwFlags
,
1380 debugstr_w(pwszStoreName
), pStoreInfo
, pvReserved
);
1382 FIXME("(%s, %08x, %s, %p, %p): stub\n", debugstr_w(pvSystemStore
),
1383 dwFlags
, debugstr_w(pwszStoreName
), pStoreInfo
, pvReserved
);
1387 BOOL WINAPI
CertUnregisterPhysicalStore(const void *pvSystemStore
, DWORD dwFlags
,
1388 LPCWSTR pwszStoreName
)
1390 FIXME("(%p, %08x, %s): stub\n", pvSystemStore
, dwFlags
, debugstr_w(pwszStoreName
));
1394 BOOL WINAPI
CertRegisterSystemStore(const void *pvSystemStore
, DWORD dwFlags
,
1395 PCERT_SYSTEM_STORE_INFO pStoreInfo
, void *pvReserved
)
1399 if (dwFlags
& CERT_SYSTEM_STORE_RELOCATE_FLAG
)
1401 FIXME("(%p, %08x, %p, %p): flag not supported\n", pvSystemStore
, dwFlags
, pStoreInfo
, pvReserved
);
1405 TRACE("(%s, %08x, %p, %p)\n", debugstr_w(pvSystemStore
), dwFlags
, pStoreInfo
, pvReserved
);
1407 hstore
= CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W
, 0, 0, dwFlags
, pvSystemStore
);
1410 CertCloseStore(hstore
, 0);
1417 BOOL WINAPI
CertUnregisterSystemStore(const void *pvSystemStore
, DWORD dwFlags
)
1421 if (dwFlags
& CERT_SYSTEM_STORE_RELOCATE_FLAG
)
1423 FIXME("(%p, %08x): flag not supported\n", pvSystemStore
, dwFlags
);
1426 TRACE("(%s, %08x)\n", debugstr_w(pvSystemStore
), dwFlags
);
1428 hstore
= CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W
, 0, 0, dwFlags
| CERT_STORE_OPEN_EXISTING_FLAG
, pvSystemStore
);
1432 hstore
= CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W
, 0, 0, dwFlags
| CERT_STORE_DELETE_FLAG
, pvSystemStore
);
1433 if (hstore
== NULL
&& GetLastError() == 0)
1439 static void EmptyStore_addref(WINECRYPT_CERTSTORE
*store
)
1441 TRACE("(%p)\n", store
);
1444 static DWORD
EmptyStore_release(WINECRYPT_CERTSTORE
*store
, DWORD flags
)
1446 TRACE("(%p)\n", store
);
1447 return E_UNEXPECTED
;
1450 static void EmptyStore_releaseContext(WINECRYPT_CERTSTORE
*store
, context_t
*context
)
1452 Context_Free(context
);
1455 static BOOL
EmptyStore_add(WINECRYPT_CERTSTORE
*store
, context_t
*context
,
1456 context_t
*replace
, context_t
**ret_context
, BOOL use_link
)
1458 TRACE("(%p, %p, %p, %p)\n", store
, context
, replace
, ret_context
);
1460 /* FIXME: We should clone the context */
1462 Context_AddRef(context
);
1463 *ret_context
= context
;
1469 static context_t
*EmptyStore_enum(WINECRYPT_CERTSTORE
*store
, context_t
*prev
)
1471 TRACE("(%p, %p)\n", store
, prev
);
1473 SetLastError(CRYPT_E_NOT_FOUND
);
1477 static BOOL
EmptyStore_delete(WINECRYPT_CERTSTORE
*store
, context_t
*context
)
1482 static BOOL
EmptyStore_control(WINECRYPT_CERTSTORE
*store
, DWORD flags
, DWORD ctrl_type
, void const *ctrl_para
)
1486 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1490 static const store_vtbl_t EmptyStoreVtbl
= {
1493 EmptyStore_releaseContext
,
1510 WINECRYPT_CERTSTORE empty_store
;
1512 void init_empty_store(void)
1514 CRYPT_InitStore(&empty_store
, CERT_STORE_READONLY_FLAG
, StoreTypeEmpty
, &EmptyStoreVtbl
);