wined3d: Don't report filtering for WINED3DFMT_R32F.
[wine/multimedia.git] / dlls / crypt32 / filestore.c
blob8294e827ccda843bb691624693bd1775b8fa6f39
1 /*
2 * Copyright 2004-2007 Juan Lang
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 #include <stdarg.h>
19 #include "windef.h"
20 #include "winbase.h"
21 #include "wincrypt.h"
22 #include "winnls.h"
23 #include "wine/debug.h"
24 #include "wine/unicode.h"
25 #include "crypt32_private.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(crypt);
29 typedef struct _WINE_FILESTOREINFO
31 DWORD dwOpenFlags;
32 HCERTSTORE memStore;
33 HANDLE file;
34 DWORD type;
35 BOOL dirty;
36 } WINE_FILESTOREINFO, *PWINE_FILESTOREINFO;
38 static void WINAPI CRYPT_FileCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
40 PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
42 TRACE("(%p, %08x)\n", store, dwFlags);
43 if (store->dirty)
44 CertSaveStore(store->memStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
45 store->type, CERT_STORE_SAVE_TO_FILE, store->file, 0);
46 CertCloseStore(store->memStore, dwFlags);
47 CloseHandle(store->file);
48 CryptMemFree(store);
51 static BOOL WINAPI CRYPT_FileWriteCert(HCERTSTORE hCertStore,
52 PCCERT_CONTEXT cert, DWORD dwFlags)
54 PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
56 TRACE("(%p, %p, %d)\n", hCertStore, cert, dwFlags);
57 store->dirty = TRUE;
58 return TRUE;
61 static BOOL WINAPI CRYPT_FileDeleteCert(HCERTSTORE hCertStore,
62 PCCERT_CONTEXT pCertContext, DWORD dwFlags)
64 PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
66 TRACE("(%p, %p, %08x)\n", hCertStore, pCertContext, dwFlags);
67 store->dirty = TRUE;
68 return TRUE;
71 static BOOL WINAPI CRYPT_FileWriteCRL(HCERTSTORE hCertStore,
72 PCCRL_CONTEXT crl, DWORD dwFlags)
74 PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
76 TRACE("(%p, %p, %d)\n", hCertStore, crl, dwFlags);
77 store->dirty = TRUE;
78 return TRUE;
81 static BOOL WINAPI CRYPT_FileDeleteCRL(HCERTSTORE hCertStore,
82 PCCRL_CONTEXT pCrlContext, DWORD dwFlags)
84 PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
86 TRACE("(%p, %p, %08x)\n", hCertStore, pCrlContext, dwFlags);
87 store->dirty = TRUE;
88 return TRUE;
91 static BOOL CRYPT_ReadBlobFromFile(HANDLE file, PCERT_BLOB blob)
93 BOOL ret = TRUE;
95 blob->cbData = GetFileSize(file, NULL);
96 if (blob->cbData)
98 blob->pbData = CryptMemAlloc(blob->cbData);
99 if (blob->pbData)
101 DWORD read;
103 ret = ReadFile(file, blob->pbData, blob->cbData, &read, NULL);
106 return ret;
109 static BOOL WINAPI CRYPT_FileControl(HCERTSTORE hCertStore, DWORD dwFlags,
110 DWORD dwCtrlType, void const *pvCtrlPara)
112 PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
113 BOOL ret;
115 TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType,
116 pvCtrlPara);
118 switch (dwCtrlType)
120 case CERT_STORE_CTRL_RESYNC:
121 CRYPT_EmptyStore(store->memStore);
122 store->dirty = FALSE;
123 if (store->type == CERT_STORE_SAVE_AS_STORE)
124 ret = CRYPT_ReadSerializedStoreFromFile(store->file,
125 store->memStore);
126 else if (store->type == CERT_STORE_SAVE_AS_PKCS7)
128 CERT_BLOB blob = { 0, NULL };
130 ret = CRYPT_ReadBlobFromFile(store->file, &blob);
131 if (ret)
133 HCERTSTORE messageStore;
135 ret = CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob,
136 CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED,
137 CERT_QUERY_FORMAT_FLAG_BINARY, 0, NULL, NULL, NULL,
138 &messageStore, NULL, NULL);
139 if (ret)
141 PCCERT_CONTEXT cert = NULL;
142 PCCRL_CONTEXT crl = NULL;
144 do {
145 cert = CertEnumCertificatesInStore(messageStore, cert);
146 if (cert)
147 CertAddCertificateContextToStore(store->memStore,
148 cert, CERT_STORE_ADD_ALWAYS, NULL);
149 } while (cert);
150 do {
151 crl = CertEnumCRLsInStore(messageStore, crl);
152 if (crl)
153 CertAddCRLContextToStore(store->memStore, crl,
154 CERT_STORE_ADD_ALWAYS, NULL);
155 } while (crl);
157 CryptMemFree(blob.pbData);
160 else
162 WARN("unknown type %d\n", store->type);
163 ret = FALSE;
165 break;
166 case CERT_STORE_CTRL_COMMIT:
167 if (!(store->dwOpenFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG))
169 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
170 ret = FALSE;
172 else if (store->dirty)
173 ret = CertSaveStore(store->memStore,
174 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
175 store->type, CERT_STORE_SAVE_TO_FILE, store->file, 0);
176 else
177 ret = TRUE;
178 break;
179 default:
180 FIXME("%d: stub\n", dwCtrlType);
181 ret = FALSE;
183 return ret;
186 static void *fileProvFuncs[] = {
187 CRYPT_FileCloseStore,
188 NULL, /* CERT_STORE_PROV_READ_CERT_FUNC */
189 CRYPT_FileWriteCert,
190 CRYPT_FileDeleteCert,
191 NULL, /* CERT_STORE_PROV_SET_CERT_PROPERTY_FUNC */
192 NULL, /* CERT_STORE_PROV_READ_CRL_FUNC */
193 CRYPT_FileWriteCRL,
194 CRYPT_FileDeleteCRL,
195 NULL, /* CERT_STORE_PROV_SET_CRL_PROPERTY_FUNC */
196 NULL, /* CERT_STORE_PROV_READ_CTL_FUNC */
197 NULL, /* CERT_STORE_PROV_WRITE_CTL_FUNC */
198 NULL, /* CERT_STORE_PROV_DELETE_CTL_FUNC */
199 NULL, /* CERT_STORE_PROV_SET_CTL_PROPERTY_FUNC */
200 CRYPT_FileControl,
203 static PWINECRYPT_CERTSTORE CRYPT_CreateFileStore(DWORD dwFlags,
204 HCERTSTORE memStore, HANDLE file, DWORD type)
206 PWINECRYPT_CERTSTORE store = NULL;
207 PWINE_FILESTOREINFO info = CryptMemAlloc(sizeof(WINE_FILESTOREINFO));
209 if (info)
211 CERT_STORE_PROV_INFO provInfo = { 0 };
213 info->dwOpenFlags = dwFlags;
214 info->memStore = memStore;
215 info->file = file;
216 info->type = type;
217 info->dirty = FALSE;
218 provInfo.cbSize = sizeof(provInfo);
219 provInfo.cStoreProvFunc = sizeof(fileProvFuncs) /
220 sizeof(fileProvFuncs[0]);
221 provInfo.rgpvStoreProvFunc = fileProvFuncs;
222 provInfo.hStoreProv = info;
223 store = CRYPT_ProvCreateStore(dwFlags, memStore, &provInfo);
225 return store;
228 PWINECRYPT_CERTSTORE CRYPT_FileOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags,
229 const void *pvPara)
231 PWINECRYPT_CERTSTORE store = NULL;
232 HANDLE file = (HANDLE)pvPara;
234 TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
236 if (!pvPara)
238 SetLastError(ERROR_INVALID_HANDLE);
239 return NULL;
241 if (dwFlags & CERT_STORE_DELETE_FLAG)
243 SetLastError(E_INVALIDARG);
244 return NULL;
246 if ((dwFlags & CERT_STORE_READONLY_FLAG) &&
247 (dwFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG))
249 SetLastError(E_INVALIDARG);
250 return NULL;
253 if (DuplicateHandle(GetCurrentProcess(), (HANDLE)pvPara,
254 GetCurrentProcess(), &file, dwFlags & CERT_STORE_READONLY_FLAG ?
255 GENERIC_READ : GENERIC_READ | GENERIC_WRITE, TRUE, 0))
257 HCERTSTORE memStore;
259 memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
260 CERT_STORE_CREATE_NEW_FLAG, NULL);
261 if (memStore)
263 if (CRYPT_ReadSerializedStoreFromFile(file, memStore))
265 store = CRYPT_CreateFileStore(dwFlags, memStore, file,
266 CERT_STORE_SAVE_AS_STORE);
267 /* File store doesn't need crypto provider, so close it */
268 if (hCryptProv &&
269 !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
270 CryptReleaseContext(hCryptProv, 0);
274 TRACE("returning %p\n", store);
275 return store;
278 PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreW(HCRYPTPROV hCryptProv,
279 DWORD dwFlags, const void *pvPara)
281 HCERTSTORE store = 0;
282 LPCWSTR fileName = (LPCWSTR)pvPara;
283 DWORD access, create;
284 HANDLE file;
286 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags, debugstr_w(fileName));
288 if (!fileName)
290 SetLastError(ERROR_PATH_NOT_FOUND);
291 return NULL;
293 if ((dwFlags & CERT_STORE_READONLY_FLAG) &&
294 (dwFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG))
296 SetLastError(E_INVALIDARG);
297 return NULL;
300 access = GENERIC_READ;
301 if (dwFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG)
302 access |= GENERIC_WRITE;
303 if (dwFlags & CERT_STORE_CREATE_NEW_FLAG)
304 create = CREATE_NEW;
305 else if (dwFlags & CERT_STORE_OPEN_EXISTING_FLAG)
306 create = OPEN_EXISTING;
307 else
308 create = OPEN_ALWAYS;
309 file = CreateFileW(fileName, access, FILE_SHARE_READ, NULL, create,
310 FILE_ATTRIBUTE_NORMAL, NULL);
311 if (file != INVALID_HANDLE_VALUE)
313 HCERTSTORE memStore = NULL;
314 DWORD size = GetFileSize(file, NULL), type = 0;
316 /* If the file isn't empty, try to get the type from the file itself */
317 if (size)
319 DWORD contentType;
320 BOOL ret;
322 /* Close the file so CryptQueryObject can succeed.. */
323 CloseHandle(file);
324 ret = CryptQueryObject(CERT_QUERY_OBJECT_FILE, fileName,
325 CERT_QUERY_CONTENT_FLAG_CERT |
326 CERT_QUERY_CONTENT_FLAG_SERIALIZED_STORE |
327 CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED,
328 CERT_QUERY_FORMAT_FLAG_BINARY, 0, NULL, &contentType, NULL,
329 &memStore, NULL, NULL);
330 if (ret)
332 if (contentType == CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED)
333 type = CERT_STORE_SAVE_AS_PKCS7;
334 else
335 type = CERT_STORE_SAVE_AS_STORE;
336 /* and reopen the file. */
337 file = CreateFileW(fileName, access, FILE_SHARE_READ, NULL,
338 create, FILE_ATTRIBUTE_NORMAL, NULL);
341 else
343 static const WCHAR spc[] = { 's','p','c',0 };
344 static const WCHAR p7c[] = { 'p','7','c',0 };
345 LPCWSTR ext = strrchrW(fileName, '.');
347 if (ext)
349 ext++;
350 if (!lstrcmpiW(ext, spc) || !lstrcmpiW(ext, p7c))
351 type = CERT_STORE_SAVE_AS_PKCS7;
353 if (!type)
354 type = CERT_STORE_SAVE_AS_STORE;
355 memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
356 CERT_STORE_CREATE_NEW_FLAG, NULL);
358 if (memStore)
360 store = CRYPT_CreateFileStore(dwFlags, memStore, file, type);
361 /* File store doesn't need crypto provider, so close it */
362 if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
363 CryptReleaseContext(hCryptProv, 0);
366 return (PWINECRYPT_CERTSTORE)store;
369 PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreA(HCRYPTPROV hCryptProv,
370 DWORD dwFlags, const void *pvPara)
372 int len;
373 PWINECRYPT_CERTSTORE ret = NULL;
375 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
376 debugstr_a((LPCSTR)pvPara));
378 if (!pvPara)
380 SetLastError(ERROR_FILE_NOT_FOUND);
381 return NULL;
383 len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, NULL, 0);
384 if (len)
386 LPWSTR storeName = CryptMemAlloc(len * sizeof(WCHAR));
388 if (storeName)
390 MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, storeName, len);
391 ret = CRYPT_FileNameOpenStoreW(hCryptProv, dwFlags, storeName);
392 CryptMemFree(storeName);
395 return ret;