xref: /reactos/dll/win32/crypt32/provstore.c (revision a6e10342)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  * Copyright 2004-2007 Juan Lang
3c2c66affSColin Finck  *
4c2c66affSColin Finck  * This library is free software; you can redistribute it and/or
5c2c66affSColin Finck  * modify it under the terms of the GNU Lesser General Public
6c2c66affSColin Finck  * License as published by the Free Software Foundation; either
7c2c66affSColin Finck  * version 2.1 of the License, or (at your option) any later version.
8c2c66affSColin Finck  *
9c2c66affSColin Finck  * This library is distributed in the hope that it will be useful,
10c2c66affSColin Finck  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11c2c66affSColin Finck  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12c2c66affSColin Finck  * Lesser General Public License for more details.
13c2c66affSColin Finck  *
14c2c66affSColin Finck  * You should have received a copy of the GNU Lesser General Public
15c2c66affSColin Finck  * License along with this library; if not, write to the Free Software
16c2c66affSColin Finck  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17c2c66affSColin Finck  */
18c2c66affSColin Finck 
19*a6e10342SAmine Khaldi #include <stdarg.h>
20*a6e10342SAmine Khaldi #include <assert.h>
21*a6e10342SAmine Khaldi 
22*a6e10342SAmine Khaldi #include "windef.h"
23*a6e10342SAmine Khaldi #include "winbase.h"
24*a6e10342SAmine Khaldi #include "wincrypt.h"
25*a6e10342SAmine Khaldi #include "wine/debug.h"
26c2c66affSColin Finck #include "crypt32_private.h"
27c2c66affSColin Finck 
28c2c66affSColin Finck WINE_DEFAULT_DEBUG_CHANNEL(crypt);
29c2c66affSColin Finck 
30c2c66affSColin Finck typedef struct _WINE_PROVIDERSTORE
31c2c66affSColin Finck {
32c2c66affSColin Finck     WINECRYPT_CERTSTORE             hdr;
33c2c66affSColin Finck     DWORD                           dwStoreProvFlags;
34c2c66affSColin Finck     WINECRYPT_CERTSTORE            *memStore;
35c2c66affSColin Finck     HCERTSTOREPROV                  hStoreProv;
36c2c66affSColin Finck     PFN_CERT_STORE_PROV_CLOSE       provCloseStore;
37c2c66affSColin Finck     PFN_CERT_STORE_PROV_WRITE_CERT  provWriteCert;
38c2c66affSColin Finck     PFN_CERT_STORE_PROV_DELETE_CERT provDeleteCert;
39c2c66affSColin Finck     PFN_CERT_STORE_PROV_WRITE_CRL   provWriteCrl;
40c2c66affSColin Finck     PFN_CERT_STORE_PROV_DELETE_CRL  provDeleteCrl;
41c2c66affSColin Finck     PFN_CERT_STORE_PROV_WRITE_CTL   provWriteCtl;
42c2c66affSColin Finck     PFN_CERT_STORE_PROV_DELETE_CTL  provDeleteCtl;
43c2c66affSColin Finck     PFN_CERT_STORE_PROV_CONTROL     provControl;
44c2c66affSColin Finck } WINE_PROVIDERSTORE;
45c2c66affSColin Finck 
ProvStore_addref(WINECRYPT_CERTSTORE * store)46c2c66affSColin Finck static void ProvStore_addref(WINECRYPT_CERTSTORE *store)
47c2c66affSColin Finck {
48c2c66affSColin Finck     LONG ref = InterlockedIncrement(&store->ref);
49c2c66affSColin Finck     TRACE("ref = %d\n", ref);
50c2c66affSColin Finck }
51c2c66affSColin Finck 
ProvStore_release(WINECRYPT_CERTSTORE * cert_store,DWORD flags)52c2c66affSColin Finck static DWORD ProvStore_release(WINECRYPT_CERTSTORE *cert_store, DWORD flags)
53c2c66affSColin Finck {
54c2c66affSColin Finck     WINE_PROVIDERSTORE *store = (WINE_PROVIDERSTORE*)cert_store;
55c2c66affSColin Finck     LONG ref;
56c2c66affSColin Finck 
57c2c66affSColin Finck     if(flags)
58c2c66affSColin Finck         FIXME("Unimplemented flags %x\n", flags);
59c2c66affSColin Finck 
60c2c66affSColin Finck     ref = InterlockedDecrement(&store->hdr.ref);
61c2c66affSColin Finck     TRACE("(%p) ref=%d\n", store, ref);
62c2c66affSColin Finck 
63c2c66affSColin Finck     if(ref)
64c2c66affSColin Finck         return ERROR_SUCCESS;
65c2c66affSColin Finck 
66c2c66affSColin Finck     if (store->provCloseStore)
67c2c66affSColin Finck         store->provCloseStore(store->hStoreProv, flags);
68c2c66affSColin Finck     if (!(store->dwStoreProvFlags & CERT_STORE_PROV_EXTERNAL_FLAG))
69c2c66affSColin Finck         store->memStore->vtbl->release(store->memStore, flags);
70c2c66affSColin Finck     CRYPT_FreeStore(&store->hdr);
71c2c66affSColin Finck     return ERROR_SUCCESS;
72c2c66affSColin Finck }
73c2c66affSColin Finck 
ProvStore_releaseContext(WINECRYPT_CERTSTORE * store,context_t * context)74c2c66affSColin Finck static void ProvStore_releaseContext(WINECRYPT_CERTSTORE *store, context_t *context)
75c2c66affSColin Finck {
76c2c66affSColin Finck     /* As long as we don't have contexts properly stored (and hack around hCertStore
77c2c66affSColin Finck        in add* and enum* functions), this function should never be called. */
78c2c66affSColin Finck     assert(0);
79c2c66affSColin Finck }
80c2c66affSColin Finck 
ProvStore_addCert(WINECRYPT_CERTSTORE * store,context_t * cert,context_t * toReplace,context_t ** ppStoreContext,BOOL use_link)81c2c66affSColin Finck static BOOL ProvStore_addCert(WINECRYPT_CERTSTORE *store, context_t *cert,
82c2c66affSColin Finck  context_t *toReplace, context_t **ppStoreContext, BOOL use_link)
83c2c66affSColin Finck {
84c2c66affSColin Finck     WINE_PROVIDERSTORE *ps = (WINE_PROVIDERSTORE*)store;
85c2c66affSColin Finck     BOOL ret;
86c2c66affSColin Finck 
87c2c66affSColin Finck     TRACE("(%p, %p, %p, %p)\n", store, cert, toReplace, ppStoreContext);
88c2c66affSColin Finck 
89c2c66affSColin Finck     if (toReplace)
90c2c66affSColin Finck         ret = ps->memStore->vtbl->certs.addContext(ps->memStore, cert, toReplace,
91c2c66affSColin Finck          ppStoreContext, TRUE);
92c2c66affSColin Finck     else
93c2c66affSColin Finck     {
94c2c66affSColin Finck         ret = TRUE;
95c2c66affSColin Finck         if (ps->provWriteCert)
96c2c66affSColin Finck             ret = ps->provWriteCert(ps->hStoreProv, context_ptr(cert), CERT_STORE_PROV_WRITE_ADD_FLAG);
97c2c66affSColin Finck         if (ret)
98c2c66affSColin Finck             ret = ps->memStore->vtbl->certs.addContext(ps->memStore, cert, NULL,
99c2c66affSColin Finck              ppStoreContext, TRUE);
100c2c66affSColin Finck     }
101c2c66affSColin Finck     /* dirty trick: replace the returned context's hCertStore with
102c2c66affSColin Finck      * store.
103c2c66affSColin Finck      */
104c2c66affSColin Finck     if (ret && ppStoreContext)
105c2c66affSColin Finck         (*(cert_t**)ppStoreContext)->ctx.hCertStore = store;
106c2c66affSColin Finck     return ret;
107c2c66affSColin Finck }
108c2c66affSColin Finck 
ProvStore_enumCert(WINECRYPT_CERTSTORE * store,context_t * prev)109c2c66affSColin Finck static context_t *ProvStore_enumCert(WINECRYPT_CERTSTORE *store, context_t *prev)
110c2c66affSColin Finck {
111c2c66affSColin Finck     WINE_PROVIDERSTORE *ps = (WINE_PROVIDERSTORE*)store;
112c2c66affSColin Finck     cert_t *ret;
113c2c66affSColin Finck 
114c2c66affSColin Finck     ret = (cert_t*)ps->memStore->vtbl->certs.enumContext(ps->memStore, prev);
115c2c66affSColin Finck     if (!ret)
116c2c66affSColin Finck         return NULL;
117c2c66affSColin Finck 
118c2c66affSColin Finck     /* same dirty trick: replace the returned context's hCertStore with
119c2c66affSColin Finck      * store.
120c2c66affSColin Finck      */
121c2c66affSColin Finck     ret->ctx.hCertStore = store;
122c2c66affSColin Finck     return &ret->base;
123c2c66affSColin Finck }
124c2c66affSColin Finck 
ProvStore_deleteCert(WINECRYPT_CERTSTORE * store,context_t * context)125c2c66affSColin Finck static BOOL ProvStore_deleteCert(WINECRYPT_CERTSTORE *store, context_t *context)
126c2c66affSColin Finck {
127c2c66affSColin Finck     WINE_PROVIDERSTORE *ps = (WINE_PROVIDERSTORE*)store;
128c2c66affSColin Finck     BOOL ret = TRUE;
129c2c66affSColin Finck 
130c2c66affSColin Finck     TRACE("(%p, %p)\n", store, context);
131c2c66affSColin Finck 
132c2c66affSColin Finck     if (ps->provDeleteCert)
133c2c66affSColin Finck         ret = ps->provDeleteCert(ps->hStoreProv, context_ptr(context), 0);
134c2c66affSColin Finck     if (ret)
135c2c66affSColin Finck         ret = ps->memStore->vtbl->certs.delete(ps->memStore, context);
136c2c66affSColin Finck     return ret;
137c2c66affSColin Finck }
138c2c66affSColin Finck 
ProvStore_addCRL(WINECRYPT_CERTSTORE * store,context_t * crl,context_t * toReplace,context_t ** ppStoreContext,BOOL use_link)139c2c66affSColin Finck static BOOL ProvStore_addCRL(WINECRYPT_CERTSTORE *store, context_t *crl,
140c2c66affSColin Finck  context_t *toReplace, context_t **ppStoreContext, BOOL use_link)
141c2c66affSColin Finck {
142c2c66affSColin Finck     WINE_PROVIDERSTORE *ps = (WINE_PROVIDERSTORE*)store;
143c2c66affSColin Finck     BOOL ret;
144c2c66affSColin Finck 
145c2c66affSColin Finck     TRACE("(%p, %p, %p, %p)\n", store, crl, toReplace, ppStoreContext);
146c2c66affSColin Finck 
147c2c66affSColin Finck     if (toReplace)
148c2c66affSColin Finck         ret = ps->memStore->vtbl->crls.addContext(ps->memStore, crl, toReplace,
149c2c66affSColin Finck          ppStoreContext, TRUE);
150c2c66affSColin Finck     else
151c2c66affSColin Finck     {
152c2c66affSColin Finck         if (ps->hdr.dwOpenFlags & CERT_STORE_READONLY_FLAG)
153c2c66affSColin Finck         {
154c2c66affSColin Finck             SetLastError(ERROR_ACCESS_DENIED);
155c2c66affSColin Finck             ret = FALSE;
156c2c66affSColin Finck         }
157c2c66affSColin Finck         else
158c2c66affSColin Finck         {
159c2c66affSColin Finck             ret = TRUE;
160c2c66affSColin Finck             if (ps->provWriteCrl)
161c2c66affSColin Finck                 ret = ps->provWriteCrl(ps->hStoreProv, context_ptr(crl),
162c2c66affSColin Finck                  CERT_STORE_PROV_WRITE_ADD_FLAG);
163c2c66affSColin Finck             if (ret)
164c2c66affSColin Finck                 ret = ps->memStore->vtbl->crls.addContext(ps->memStore, crl, NULL,
165c2c66affSColin Finck                  ppStoreContext, TRUE);
166c2c66affSColin Finck         }
167c2c66affSColin Finck     }
168c2c66affSColin Finck     /* dirty trick: replace the returned context's hCertStore with
169c2c66affSColin Finck      * store.
170c2c66affSColin Finck      */
171c2c66affSColin Finck     if (ret && ppStoreContext)
172c2c66affSColin Finck         (*(crl_t**)ppStoreContext)->ctx.hCertStore = store;
173c2c66affSColin Finck     return ret;
174c2c66affSColin Finck }
175c2c66affSColin Finck 
ProvStore_enumCRL(WINECRYPT_CERTSTORE * store,context_t * prev)176c2c66affSColin Finck static context_t *ProvStore_enumCRL(WINECRYPT_CERTSTORE *store, context_t *prev)
177c2c66affSColin Finck {
178c2c66affSColin Finck     WINE_PROVIDERSTORE *ps = (WINE_PROVIDERSTORE*)store;
179c2c66affSColin Finck     crl_t *ret;
180c2c66affSColin Finck 
181c2c66affSColin Finck     ret = (crl_t*)ps->memStore->vtbl->crls.enumContext(ps->memStore, prev);
182c2c66affSColin Finck     if (!ret)
183c2c66affSColin Finck         return NULL;
184c2c66affSColin Finck 
185c2c66affSColin Finck     /* same dirty trick: replace the returned context's hCertStore with
186c2c66affSColin Finck      * store.
187c2c66affSColin Finck      */
188c2c66affSColin Finck     ret->ctx.hCertStore = store;
189c2c66affSColin Finck     return &ret->base;
190c2c66affSColin Finck }
191c2c66affSColin Finck 
ProvStore_deleteCRL(WINECRYPT_CERTSTORE * store,context_t * crl)192c2c66affSColin Finck static BOOL ProvStore_deleteCRL(WINECRYPT_CERTSTORE *store, context_t *crl)
193c2c66affSColin Finck {
194c2c66affSColin Finck     WINE_PROVIDERSTORE *ps = (WINE_PROVIDERSTORE*)store;
195c2c66affSColin Finck     BOOL ret = TRUE;
196c2c66affSColin Finck 
197c2c66affSColin Finck     TRACE("(%p, %p)\n", store, crl);
198c2c66affSColin Finck 
199c2c66affSColin Finck     if (ps->provDeleteCrl)
200c2c66affSColin Finck         ret = ps->provDeleteCrl(ps->hStoreProv, context_ptr(crl), 0);
201c2c66affSColin Finck     if (ret)
202c2c66affSColin Finck         ret = ps->memStore->vtbl->crls.delete(ps->memStore, crl);
203c2c66affSColin Finck     return ret;
204c2c66affSColin Finck }
205c2c66affSColin Finck 
ProvStore_addCTL(WINECRYPT_CERTSTORE * store,context_t * ctl,context_t * toReplace,context_t ** ppStoreContext,BOOL use_link)206c2c66affSColin Finck static BOOL ProvStore_addCTL(WINECRYPT_CERTSTORE *store, context_t *ctl,
207c2c66affSColin Finck  context_t *toReplace, context_t **ppStoreContext, BOOL use_link)
208c2c66affSColin Finck {
209c2c66affSColin Finck     WINE_PROVIDERSTORE *ps = (WINE_PROVIDERSTORE*)store;
210c2c66affSColin Finck     BOOL ret;
211c2c66affSColin Finck 
212c2c66affSColin Finck     TRACE("(%p, %p, %p, %p)\n", store, ctl, toReplace, ppStoreContext);
213c2c66affSColin Finck 
214c2c66affSColin Finck     if (toReplace)
215c2c66affSColin Finck         ret = ps->memStore->vtbl->ctls.addContext(ps->memStore, ctl, toReplace,
216c2c66affSColin Finck          ppStoreContext, TRUE);
217c2c66affSColin Finck     else
218c2c66affSColin Finck     {
219c2c66affSColin Finck         if (ps->hdr.dwOpenFlags & CERT_STORE_READONLY_FLAG)
220c2c66affSColin Finck         {
221c2c66affSColin Finck             SetLastError(ERROR_ACCESS_DENIED);
222c2c66affSColin Finck             ret = FALSE;
223c2c66affSColin Finck         }
224c2c66affSColin Finck         else
225c2c66affSColin Finck         {
226c2c66affSColin Finck             ret = TRUE;
227c2c66affSColin Finck             if (ps->provWriteCtl)
228c2c66affSColin Finck                 ret = ps->provWriteCtl(ps->hStoreProv, context_ptr(ctl),
229c2c66affSColin Finck                  CERT_STORE_PROV_WRITE_ADD_FLAG);
230c2c66affSColin Finck             if (ret)
231c2c66affSColin Finck                 ret = ps->memStore->vtbl->ctls.addContext(ps->memStore, ctl, NULL,
232c2c66affSColin Finck                  ppStoreContext, TRUE);
233c2c66affSColin Finck         }
234c2c66affSColin Finck     }
235c2c66affSColin Finck     /* dirty trick: replace the returned context's hCertStore with
236c2c66affSColin Finck      * store.
237c2c66affSColin Finck      */
238c2c66affSColin Finck     if (ret && ppStoreContext)
239c2c66affSColin Finck         (*(ctl_t**)ppStoreContext)->ctx.hCertStore = store;
240c2c66affSColin Finck     return ret;
241c2c66affSColin Finck }
242c2c66affSColin Finck 
ProvStore_enumCTL(WINECRYPT_CERTSTORE * store,context_t * prev)243c2c66affSColin Finck static context_t *ProvStore_enumCTL(WINECRYPT_CERTSTORE *store, context_t *prev)
244c2c66affSColin Finck {
245c2c66affSColin Finck     WINE_PROVIDERSTORE *ps = (WINE_PROVIDERSTORE*)store;
246c2c66affSColin Finck     ctl_t *ret;
247c2c66affSColin Finck 
248c2c66affSColin Finck     ret = (ctl_t*)ps->memStore->vtbl->ctls.enumContext(ps->memStore, prev);
249c2c66affSColin Finck     if (!ret)
250c2c66affSColin Finck         return NULL;
251c2c66affSColin Finck 
252c2c66affSColin Finck     /* same dirty trick: replace the returned context's hCertStore with
253c2c66affSColin Finck      * store.
254c2c66affSColin Finck      */
255c2c66affSColin Finck     ret->ctx.hCertStore = store;
256c2c66affSColin Finck     return &ret->base;
257c2c66affSColin Finck }
258c2c66affSColin Finck 
ProvStore_deleteCTL(WINECRYPT_CERTSTORE * store,context_t * ctl)259c2c66affSColin Finck static BOOL ProvStore_deleteCTL(WINECRYPT_CERTSTORE *store, context_t *ctl)
260c2c66affSColin Finck {
261c2c66affSColin Finck     WINE_PROVIDERSTORE *ps = (WINE_PROVIDERSTORE*)store;
262c2c66affSColin Finck     BOOL ret = TRUE;
263c2c66affSColin Finck 
264c2c66affSColin Finck     TRACE("(%p, %p)\n", store, ctl);
265c2c66affSColin Finck 
266c2c66affSColin Finck     if (ps->provDeleteCtl)
267c2c66affSColin Finck         ret = ps->provDeleteCtl(ps->hStoreProv, context_ptr(ctl), 0);
268c2c66affSColin Finck     if (ret)
269c2c66affSColin Finck         ret = ps->memStore->vtbl->ctls.delete(ps->memStore, ctl);
270c2c66affSColin Finck     return ret;
271c2c66affSColin Finck }
272c2c66affSColin Finck 
ProvStore_control(WINECRYPT_CERTSTORE * cert_store,DWORD dwFlags,DWORD dwCtrlType,void const * pvCtrlPara)273c2c66affSColin Finck static BOOL ProvStore_control(WINECRYPT_CERTSTORE *cert_store, DWORD dwFlags, DWORD dwCtrlType, void const *pvCtrlPara)
274c2c66affSColin Finck {
275c2c66affSColin Finck     WINE_PROVIDERSTORE *store = (WINE_PROVIDERSTORE*)cert_store;
276c2c66affSColin Finck     BOOL ret = TRUE;
277c2c66affSColin Finck 
278c2c66affSColin Finck     TRACE("(%p, %08x, %d, %p)\n", store, dwFlags, dwCtrlType,
279c2c66affSColin Finck      pvCtrlPara);
280c2c66affSColin Finck 
281c2c66affSColin Finck     if (store->provControl)
282c2c66affSColin Finck         ret = store->provControl(store->hStoreProv, dwFlags, dwCtrlType,
283c2c66affSColin Finck          pvCtrlPara);
284c2c66affSColin Finck     return ret;
285c2c66affSColin Finck }
286c2c66affSColin Finck 
287c2c66affSColin Finck static const store_vtbl_t ProvStoreVtbl = {
288c2c66affSColin Finck     ProvStore_addref,
289c2c66affSColin Finck     ProvStore_release,
290c2c66affSColin Finck     ProvStore_releaseContext,
291c2c66affSColin Finck     ProvStore_control,
292c2c66affSColin Finck     {
293c2c66affSColin Finck         ProvStore_addCert,
294c2c66affSColin Finck         ProvStore_enumCert,
295c2c66affSColin Finck         ProvStore_deleteCert
296c2c66affSColin Finck     }, {
297c2c66affSColin Finck         ProvStore_addCRL,
298c2c66affSColin Finck         ProvStore_enumCRL,
299c2c66affSColin Finck         ProvStore_deleteCRL
300c2c66affSColin Finck     }, {
301c2c66affSColin Finck         ProvStore_addCTL,
302c2c66affSColin Finck         ProvStore_enumCTL,
303c2c66affSColin Finck         ProvStore_deleteCTL
304c2c66affSColin Finck     }
305c2c66affSColin Finck };
306c2c66affSColin Finck 
CRYPT_ProvCreateStore(DWORD dwFlags,WINECRYPT_CERTSTORE * memStore,const CERT_STORE_PROV_INFO * pProvInfo)307c2c66affSColin Finck WINECRYPT_CERTSTORE *CRYPT_ProvCreateStore(DWORD dwFlags,
308c2c66affSColin Finck  WINECRYPT_CERTSTORE *memStore, const CERT_STORE_PROV_INFO *pProvInfo)
309c2c66affSColin Finck {
310c2c66affSColin Finck     WINE_PROVIDERSTORE *ret = CryptMemAlloc(sizeof(WINE_PROVIDERSTORE));
311c2c66affSColin Finck 
312c2c66affSColin Finck     if (ret)
313c2c66affSColin Finck     {
314c2c66affSColin Finck         CRYPT_InitStore(&ret->hdr, dwFlags, StoreTypeProvider, &ProvStoreVtbl);
315c2c66affSColin Finck         ret->dwStoreProvFlags = pProvInfo->dwStoreProvFlags;
316c2c66affSColin Finck         if (ret->dwStoreProvFlags & CERT_STORE_PROV_EXTERNAL_FLAG)
317c2c66affSColin Finck         {
318c2c66affSColin Finck             CertCloseStore(memStore, 0);
319c2c66affSColin Finck             ret->memStore = NULL;
320c2c66affSColin Finck         }
321c2c66affSColin Finck         else
322c2c66affSColin Finck             ret->memStore = memStore;
323c2c66affSColin Finck         ret->hStoreProv = pProvInfo->hStoreProv;
324c2c66affSColin Finck         if (pProvInfo->cStoreProvFunc > CERT_STORE_PROV_CLOSE_FUNC)
325c2c66affSColin Finck             ret->provCloseStore =
326c2c66affSColin Finck              pProvInfo->rgpvStoreProvFunc[CERT_STORE_PROV_CLOSE_FUNC];
327c2c66affSColin Finck         else
328c2c66affSColin Finck             ret->provCloseStore = NULL;
329c2c66affSColin Finck         if (pProvInfo->cStoreProvFunc >
330c2c66affSColin Finck          CERT_STORE_PROV_WRITE_CERT_FUNC)
331c2c66affSColin Finck             ret->provWriteCert = pProvInfo->rgpvStoreProvFunc[
332c2c66affSColin Finck              CERT_STORE_PROV_WRITE_CERT_FUNC];
333c2c66affSColin Finck         else
334c2c66affSColin Finck             ret->provWriteCert = NULL;
335c2c66affSColin Finck         if (pProvInfo->cStoreProvFunc >
336c2c66affSColin Finck          CERT_STORE_PROV_DELETE_CERT_FUNC)
337c2c66affSColin Finck             ret->provDeleteCert = pProvInfo->rgpvStoreProvFunc[
338c2c66affSColin Finck              CERT_STORE_PROV_DELETE_CERT_FUNC];
339c2c66affSColin Finck         else
340c2c66affSColin Finck             ret->provDeleteCert = NULL;
341c2c66affSColin Finck         if (pProvInfo->cStoreProvFunc >
342c2c66affSColin Finck          CERT_STORE_PROV_WRITE_CRL_FUNC)
343c2c66affSColin Finck             ret->provWriteCrl = pProvInfo->rgpvStoreProvFunc[
344c2c66affSColin Finck              CERT_STORE_PROV_WRITE_CRL_FUNC];
345c2c66affSColin Finck         else
346c2c66affSColin Finck             ret->provWriteCrl = NULL;
347c2c66affSColin Finck         if (pProvInfo->cStoreProvFunc >
348c2c66affSColin Finck          CERT_STORE_PROV_DELETE_CRL_FUNC)
349c2c66affSColin Finck             ret->provDeleteCrl = pProvInfo->rgpvStoreProvFunc[
350c2c66affSColin Finck              CERT_STORE_PROV_DELETE_CRL_FUNC];
351c2c66affSColin Finck         else
352c2c66affSColin Finck             ret->provDeleteCrl = NULL;
353c2c66affSColin Finck         if (pProvInfo->cStoreProvFunc >
354c2c66affSColin Finck          CERT_STORE_PROV_WRITE_CTL_FUNC)
355c2c66affSColin Finck             ret->provWriteCtl = pProvInfo->rgpvStoreProvFunc[
356c2c66affSColin Finck              CERT_STORE_PROV_WRITE_CTL_FUNC];
357c2c66affSColin Finck         else
358c2c66affSColin Finck             ret->provWriteCtl = NULL;
359c2c66affSColin Finck         if (pProvInfo->cStoreProvFunc >
360c2c66affSColin Finck          CERT_STORE_PROV_DELETE_CTL_FUNC)
361c2c66affSColin Finck             ret->provDeleteCtl = pProvInfo->rgpvStoreProvFunc[
362c2c66affSColin Finck              CERT_STORE_PROV_DELETE_CTL_FUNC];
363c2c66affSColin Finck         else
364c2c66affSColin Finck             ret->provDeleteCtl = NULL;
365c2c66affSColin Finck         if (pProvInfo->cStoreProvFunc >
366c2c66affSColin Finck          CERT_STORE_PROV_CONTROL_FUNC)
367c2c66affSColin Finck             ret->provControl = pProvInfo->rgpvStoreProvFunc[
368c2c66affSColin Finck              CERT_STORE_PROV_CONTROL_FUNC];
369c2c66affSColin Finck         else
370c2c66affSColin Finck             ret->provControl = NULL;
371c2c66affSColin Finck     }
372c2c66affSColin Finck     return (WINECRYPT_CERTSTORE*)ret;
373c2c66affSColin Finck }
374c2c66affSColin Finck 
CRYPT_ProvOpenStore(LPCSTR lpszStoreProvider,DWORD dwEncodingType,HCRYPTPROV hCryptProv,DWORD dwFlags,const void * pvPara)375c2c66affSColin Finck WINECRYPT_CERTSTORE *CRYPT_ProvOpenStore(LPCSTR lpszStoreProvider,
376c2c66affSColin Finck  DWORD dwEncodingType, HCRYPTPROV hCryptProv, DWORD dwFlags, const void *pvPara)
377c2c66affSColin Finck {
378c2c66affSColin Finck     static HCRYPTOIDFUNCSET set = NULL;
379c2c66affSColin Finck     PFN_CERT_DLL_OPEN_STORE_PROV_FUNC provOpenFunc;
380c2c66affSColin Finck     HCRYPTOIDFUNCADDR hFunc;
381c2c66affSColin Finck     WINECRYPT_CERTSTORE *ret = NULL;
382c2c66affSColin Finck 
383c2c66affSColin Finck     if (!set)
384c2c66affSColin Finck         set = CryptInitOIDFunctionSet(CRYPT_OID_OPEN_STORE_PROV_FUNC, 0);
385c2c66affSColin Finck     CryptGetOIDFunctionAddress(set, dwEncodingType, lpszStoreProvider, 0,
386c2c66affSColin Finck      (void **)&provOpenFunc, &hFunc);
387c2c66affSColin Finck     if (provOpenFunc)
388c2c66affSColin Finck     {
389c2c66affSColin Finck         CERT_STORE_PROV_INFO provInfo = { 0 };
390c2c66affSColin Finck 
391c2c66affSColin Finck         provInfo.cbSize = sizeof(provInfo);
392c2c66affSColin Finck         if (dwFlags & CERT_STORE_DELETE_FLAG)
393c2c66affSColin Finck             provOpenFunc(lpszStoreProvider, dwEncodingType, hCryptProv,
394c2c66affSColin Finck              dwFlags, pvPara, NULL, &provInfo);
395c2c66affSColin Finck         else
396c2c66affSColin Finck         {
397c2c66affSColin Finck             HCERTSTORE memStore;
398c2c66affSColin Finck 
399c2c66affSColin Finck             memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
400c2c66affSColin Finck              CERT_STORE_CREATE_NEW_FLAG, NULL);
401c2c66affSColin Finck             if (memStore)
402c2c66affSColin Finck             {
403c2c66affSColin Finck                 if (provOpenFunc(lpszStoreProvider, dwEncodingType, hCryptProv,
404c2c66affSColin Finck                  dwFlags, pvPara, memStore, &provInfo))
405c2c66affSColin Finck                     ret = CRYPT_ProvCreateStore(dwFlags, memStore, &provInfo);
406c2c66affSColin Finck                 else
407c2c66affSColin Finck                     CertCloseStore(memStore, 0);
408c2c66affSColin Finck             }
409c2c66affSColin Finck         }
410c2c66affSColin Finck         CryptFreeOIDFunctionAddress(hFunc, 0);
411c2c66affSColin Finck     }
412c2c66affSColin Finck     else
413c2c66affSColin Finck         SetLastError(ERROR_FILE_NOT_FOUND);
414c2c66affSColin Finck     return ret;
415c2c66affSColin Finck }
416