crypt32/tests: Some tests for CryptSIPLoad.
[wine] / dlls / crypt32 / tests / main.c
1 /*
2  * Miscellaneous crypt32 tests
3  *
4  * Copyright 2005 Juan Lang
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include <stdio.h>
22 #include <stdarg.h>
23 #include <windef.h>
24 #include <winbase.h>
25 #include <winerror.h>
26 #include <wincrypt.h>
27 #include <winreg.h>
28 #include <mssip.h>
29
30 #include "wine/test.h"
31
32 HMODULE hCrypt;
33
34 static void test_findAttribute(void)
35 {
36     PCRYPT_ATTRIBUTE ret;
37     BYTE blobbin[] = {0x02,0x01,0x01};
38     static CHAR oid[] = "1.2.3";
39     CRYPT_ATTR_BLOB blobs[] = { { sizeof blobbin, blobbin }, };
40     CRYPT_ATTRIBUTE attr = { oid, sizeof(blobs) / sizeof(blobs[0]), blobs };
41
42     /* returns NULL, last error not set */
43     SetLastError(0xdeadbeef);
44     ret = CertFindAttribute(NULL, 0, NULL);
45     ok(ret == NULL, "Expected failure\n");
46     ok(GetLastError() == 0xdeadbeef, "Last error was set to %08lx\n",
47      GetLastError());
48     /* crashes
49     SetLastError(0xdeadbeef);
50     ret = CertFindAttribute(NULL, 1, NULL);
51      */
52     /* returns NULL, last error is ERROR_INVALID_PARAMETER */
53     SetLastError(0xdeadbeef);
54     ret = CertFindAttribute(NULL, 1, &attr);
55     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
56      "Expected ERROR_INVALID_PARAMETER, got %ld (%08lx)\n", GetLastError(),
57      GetLastError());
58     /* returns NULL, last error not set */
59     SetLastError(0xdeadbeef);
60     ret = CertFindAttribute("bogus", 1, &attr);
61     ok(ret == NULL, "Expected failure\n");
62     ok(GetLastError() == 0xdeadbeef, "Last error was set to %08lx\n",
63      GetLastError());
64     /* returns NULL, last error not set */
65     SetLastError(0xdeadbeef);
66     ret = CertFindAttribute("1.2.4", 1, &attr);
67     ok(ret == NULL, "Expected failure\n");
68     ok(GetLastError() == 0xdeadbeef, "Last error was set to %08lx\n",
69      GetLastError());
70     /* succeeds, last error not set */
71     SetLastError(0xdeadbeef);
72     ret = CertFindAttribute("1.2.3", 1, &attr);
73     ok(ret != NULL, "CertFindAttribute failed: %08lx\n", GetLastError());
74 }
75
76 static void test_findExtension(void)
77 {
78     PCERT_EXTENSION ret;
79     static CHAR oid[] = "1.2.3";
80     BYTE blobbin[] = {0x02,0x01,0x01};
81     CERT_EXTENSION ext = { oid, TRUE, { sizeof blobbin, blobbin } };
82
83     /* returns NULL, last error not set */
84     SetLastError(0xdeadbeef);
85     ret = CertFindExtension(NULL, 0, NULL);
86     ok(ret == NULL, "Expected failure\n");
87     ok(GetLastError() == 0xdeadbeef, "Last error was set to %08lx\n",
88      GetLastError());
89     /* crashes
90     SetLastError(0xdeadbeef);
91     ret = CertFindExtension(NULL, 1, NULL);
92      */
93     /* returns NULL, last error is ERROR_INVALID_PARAMETER */
94     SetLastError(0xdeadbeef);
95     ret = CertFindExtension(NULL, 1, &ext);
96     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
97      "Expected ERROR_INVALID_PARAMETER, got %ld (%08lx)\n", GetLastError(),
98      GetLastError());
99     /* returns NULL, last error not set */
100     SetLastError(0xdeadbeef);
101     ret = CertFindExtension("bogus", 1, &ext);
102     ok(ret == NULL, "Expected failure\n");
103     ok(GetLastError() == 0xdeadbeef, "Last error was set to %08lx\n",
104      GetLastError());
105     /* returns NULL, last error not set */
106     SetLastError(0xdeadbeef);
107     ret = CertFindExtension("1.2.4", 1, &ext);
108     ok(ret == NULL, "Expected failure\n");
109     ok(GetLastError() == 0xdeadbeef, "Last error was set to %08lx\n",
110      GetLastError());
111     /* succeeds, last error not set */
112     SetLastError(0xdeadbeef);
113     ret = CertFindExtension("1.2.3", 1, &ext);
114     ok(ret != NULL, "CertFindExtension failed: %08lx\n", GetLastError());
115 }
116
117 static void test_findRDNAttr(void)
118 {
119     PCERT_RDN_ATTR ret;
120     static CHAR oid[] = "1.2.3";
121     BYTE bin[] = { 0x16,0x09,'J','u','a','n',' ','L','a','n','g' };
122     CERT_RDN_ATTR attrs[] = {
123      { oid, CERT_RDN_IA5_STRING, { sizeof bin, bin } },
124     };
125     CERT_RDN rdns[] = {
126      { sizeof(attrs) / sizeof(attrs[0]), attrs },
127     };
128     CERT_NAME_INFO nameInfo = { sizeof(rdns) / sizeof(rdns[0]), rdns };
129
130     /* crashes
131     SetLastError(0xdeadbeef);
132     ret = CertFindRDNAttr(NULL, NULL);
133      */
134     /* returns NULL, last error is ERROR_INVALID_PARAMETER */
135     SetLastError(0xdeadbeef);
136     ret = CertFindRDNAttr(NULL, &nameInfo);
137     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
138      "Expected ERROR_INVALID_PARAMETER, got %ld (%08lx)\n", GetLastError(),
139      GetLastError());
140     /* returns NULL, last error not set */
141     SetLastError(0xdeadbeef);
142     ret = CertFindRDNAttr("bogus", &nameInfo);
143     ok(ret == NULL, "Expected failure\n");
144     ok(GetLastError() == 0xdeadbeef, "Last error was set to %08lx\n",
145      GetLastError());
146     /* returns NULL, last error not set */
147     SetLastError(0xdeadbeef);
148     ret = CertFindRDNAttr("1.2.4", &nameInfo);
149     ok(ret == NULL, "Expected failure\n");
150     ok(GetLastError() == 0xdeadbeef, "Last error was set to %08lx\n",
151      GetLastError());
152     /* succeeds, last error not set */
153     SetLastError(0xdeadbeef);
154     ret = CertFindRDNAttr("1.2.3", &nameInfo);
155     ok(ret != NULL, "CertFindRDNAttr failed: %08lx\n", GetLastError());
156 }
157
158 static void test_verifyTimeValidity(void)
159 {
160     SYSTEMTIME sysTime;
161     FILETIME fileTime;
162     CERT_INFO info = { 0 };
163     LONG ret;
164
165     GetSystemTime(&sysTime);
166     SystemTimeToFileTime(&sysTime, &fileTime);
167     /* crashes
168     ret = CertVerifyTimeValidity(NULL, NULL);
169     ret = CertVerifyTimeValidity(&fileTime, NULL);
170      */
171     /* Check with 0 NotBefore and NotAfter */
172     ret = CertVerifyTimeValidity(&fileTime, &info);
173     ok(ret == 1, "Expected 1, got %ld\n", ret);
174     memcpy(&info.NotAfter, &fileTime, sizeof(info.NotAfter));
175     /* Check with NotAfter equal to comparison time */
176     ret = CertVerifyTimeValidity(&fileTime, &info);
177     ok(ret == 0, "Expected 0, got %ld\n", ret);
178     /* Check with NotBefore after comparison time */
179     memcpy(&info.NotBefore, &fileTime, sizeof(info.NotBefore));
180     info.NotBefore.dwLowDateTime += 5000;
181     ret = CertVerifyTimeValidity(&fileTime, &info);
182     ok(ret == -1, "Expected -1, got %ld\n", ret);
183 }
184
185 static void test_cryptAllocate(void)
186 {
187     LPVOID buf;
188
189     buf = CryptMemAlloc(0);
190     ok(buf != NULL, "CryptMemAlloc failed: %08lx\n", GetLastError());
191     CryptMemFree(buf);
192     buf = CryptMemRealloc(NULL, 0);
193     ok(!buf, "Expected NULL\n");
194     buf = CryptMemAlloc(0);
195     buf = CryptMemRealloc(buf, 1);
196     ok(buf != NULL, "CryptMemRealloc failed: %08lx\n", GetLastError());
197     CryptMemFree(buf);
198 }
199
200 typedef DWORD  (WINAPI *I_CryptAllocTlsFunc)(void);
201 typedef LPVOID (WINAPI *I_CryptDetachTlsFunc)(DWORD dwTlsIndex);
202 typedef LPVOID (WINAPI *I_CryptGetTlsFunc)(DWORD dwTlsIndex);
203 typedef BOOL   (WINAPI *I_CryptSetTlsFunc)(DWORD dwTlsIndex, LPVOID lpTlsValue);
204 typedef BOOL   (WINAPI *I_CryptFreeTlsFunc)(DWORD dwTlsIndex, DWORD unknown);
205
206 static I_CryptAllocTlsFunc pI_CryptAllocTls;
207 static I_CryptDetachTlsFunc pI_CryptDetachTls;
208 static I_CryptGetTlsFunc pI_CryptGetTls;
209 static I_CryptSetTlsFunc pI_CryptSetTls;
210 static I_CryptFreeTlsFunc pI_CryptFreeTls;
211
212 static void test_cryptTls(void)
213 {
214     DWORD index;
215     BOOL ret;
216
217     if (!hCrypt) return;
218
219     pI_CryptAllocTls = (I_CryptAllocTlsFunc)GetProcAddress(hCrypt,
220      "I_CryptAllocTls");
221     pI_CryptDetachTls = (I_CryptDetachTlsFunc)GetProcAddress(hCrypt,
222      "I_CryptDetachTls");
223     pI_CryptGetTls = (I_CryptGetTlsFunc)GetProcAddress(hCrypt,
224      "I_CryptGetTls");
225     pI_CryptSetTls = (I_CryptSetTlsFunc)GetProcAddress(hCrypt,
226      "I_CryptSetTls");
227     pI_CryptFreeTls = (I_CryptFreeTlsFunc)GetProcAddress(hCrypt,
228      "I_CryptFreeTls");
229
230     /* One normal pass */
231     index = pI_CryptAllocTls();
232     ok(index, "I_CryptAllocTls failed: %08lx\n", GetLastError());
233     if (index)
234     {
235         LPVOID ptr;
236
237         ptr = pI_CryptGetTls(index);
238         ok(!ptr, "Expected NULL\n");
239         ret = pI_CryptSetTls(index, (LPVOID)0xdeadbeef);
240         ok(ret, "I_CryptSetTls failed: %08lx\n", GetLastError());
241         ptr = pI_CryptGetTls(index);
242         ok(ptr == (LPVOID)0xdeadbeef, "Expected 0xdeadbeef, got %p\n", ptr);
243         /* This crashes
244         ret = pI_CryptFreeTls(index, 1);
245          */
246         ret = pI_CryptFreeTls(index, 0);
247         ok(ret, "I_CryptFreeTls failed: %08lx\n", GetLastError());
248         ret = pI_CryptFreeTls(index, 0);
249         /* Not sure if this fails because TlsFree should fail, so leave as
250          * todo for now.
251          */
252         todo_wine ok(!ret && GetLastError() == E_INVALIDARG,
253          "Expected E_INVALIDARG, got %08lx\n", GetLastError());
254     }
255     /* Similar pass, check I_CryptDetachTls */
256     index = pI_CryptAllocTls();
257     ok(index, "I_CryptAllocTls failed: %08lx\n", GetLastError());
258     if (index)
259     {
260         LPVOID ptr;
261
262         ptr = pI_CryptGetTls(index);
263         ok(!ptr, "Expected NULL\n");
264         ret = pI_CryptSetTls(index, (LPVOID)0xdeadbeef);
265         ok(ret, "I_CryptSetTls failed: %08lx\n", GetLastError());
266         ptr = pI_CryptGetTls(index);
267         ok(ptr == (LPVOID)0xdeadbeef, "Expected 0xdeadbeef, got %p\n", ptr);
268         ptr = pI_CryptDetachTls(index);
269         ok(ptr == (LPVOID)0xdeadbeef, "Expected 0xdeadbeef, got %p\n", ptr);
270         ptr = pI_CryptGetTls(index);
271         ok(!ptr, "Expected NULL\n");
272     }
273 }
274
275 typedef BOOL (WINAPI *I_CryptReadTrustedPublisherDWORDValueFromRegistryFunc)
276  (LPCWSTR, DWORD *);
277
278 static void test_readTrustedPublisherDWORD(void)
279 {
280     I_CryptReadTrustedPublisherDWORDValueFromRegistryFunc pReadDWORD;
281
282     if (!hCrypt) return;
283
284     pReadDWORD = 
285      (I_CryptReadTrustedPublisherDWORDValueFromRegistryFunc)GetProcAddress(
286      hCrypt, "I_CryptReadTrustedPublisherDWORDValueFromRegistry");
287     if (pReadDWORD)
288     {
289         static const WCHAR safer[] = { 
290          'S','o','f','t','w','a','r','e','\\',
291          'P','o','l','i','c','i','e','s','\\',
292          'M','i','c','r','o','s','o','f','t','\\','S','y','s','t','e','m',
293          'C','e','r','t','i','f','i','c','a','t','e','s','\\',
294          'T','r','u','s','t','e','d','P','u','b','l','i','s','h','e','r',
295          '\\','S','a','f','e','r',0 };
296         static const WCHAR authenticodeFlags[] = { 'A','u','t','h','e','n',
297          't','i','c','o','d','e','F','l','a','g','s',0 };
298         BOOL ret, exists = FALSE;
299         DWORD size, readFlags = 0, returnedFlags;
300         HKEY key;
301         LONG rc;
302
303         rc = RegOpenKeyW(HKEY_LOCAL_MACHINE, safer, &key);
304         if (rc == ERROR_SUCCESS)
305         {
306             size = sizeof(readFlags);
307             rc = RegQueryValueExW(key, authenticodeFlags, NULL, NULL,
308              (LPBYTE)&readFlags, &size);
309             if (rc == ERROR_SUCCESS)
310                 exists = TRUE;
311         }
312         returnedFlags = 0xdeadbeef;
313         ret = pReadDWORD(authenticodeFlags, &returnedFlags);
314         ok(ret == exists, "Unexpected return value\n");
315         ok(readFlags == returnedFlags,
316          "Expected flags %08lx, got %08lx\n", readFlags, returnedFlags);
317     }
318 }
319
320 typedef HCRYPTPROV (WINAPI *I_CryptGetDefaultCryptProvFunc)(DWORD w);
321
322 static void test_getDefaultCryptProv(void)
323 {
324     I_CryptGetDefaultCryptProvFunc pI_CryptGetDefaultCryptProv;
325     HCRYPTPROV prov;
326
327     if (!hCrypt) return;
328
329     pI_CryptGetDefaultCryptProv = (I_CryptGetDefaultCryptProvFunc)
330      GetProcAddress(hCrypt, "I_CryptGetDefaultCryptProv");
331     if (!pI_CryptGetDefaultCryptProv) return;
332
333     prov = pI_CryptGetDefaultCryptProv(0xdeadbeef);
334     ok(prov == 0 && GetLastError() == E_INVALIDARG,
335      "Expected E_INVALIDARG, got %08lx\n", GetLastError());
336     prov = pI_CryptGetDefaultCryptProv(PROV_RSA_FULL);
337     ok(prov == 0 && GetLastError() == E_INVALIDARG,
338      "Expected E_INVALIDARG, got %08lx\n", GetLastError());
339     prov = pI_CryptGetDefaultCryptProv(1);
340     ok(prov == 0 && GetLastError() == E_INVALIDARG,
341      "Expected E_INVALIDARG, got %08lx\n", GetLastError());
342     prov = pI_CryptGetDefaultCryptProv(0);
343     ok(prov != 0, "I_CryptGetDefaultCryptProv failed: %08lx\n", GetLastError());
344     CryptReleaseContext(prov, 0);
345 }
346
347 static void test_AddRemoveProvider(void)
348 {
349     BOOL ret;
350     SIP_ADD_NEWPROVIDER newprov;
351     GUID actionid = { 0xdeadbe, 0xefde, 0xadbe, { 0xef,0xde,0xad,0xbe,0xef,0xde,0xad,0xbe }};
352     static WCHAR dummydll[]      = {'d','e','a','d','b','e','e','f','.','d','l','l',0 };
353     static WCHAR dummyfunction[] = {'d','u','m','m','y','f','u','n','c','t','i','o','n',0 };
354
355     /* NULL check */
356     SetLastError(0xdeadbeef);
357     ret = CryptSIPRemoveProvider(NULL);
358     ok (!ret, "Expected CryptSIPRemoveProvider to fail.\n");
359     ok (GetLastError() == ERROR_INVALID_PARAMETER,
360         "Expected ERROR_INVALID_PARAMETER, got %ld.\n", GetLastError());
361
362     /* nonexistent provider should result in a registry error */
363     SetLastError(0xdeadbeef);
364     ret = CryptSIPRemoveProvider(&actionid);
365     ok (!ret, "Expected CryptSIPRemoveProvider to fail.\n");
366     ok (GetLastError() == ERROR_FILE_NOT_FOUND,
367         "Expected ERROR_FILE_NOT_FOUND, got %ld.\n", GetLastError());
368
369     /* Everything OK, pwszIsFunctionName and pwszIsFunctionNameFmt2 are left NULL
370      * as allowed */
371
372     memset(&newprov, 0, sizeof(SIP_ADD_NEWPROVIDER));
373     newprov.cbStruct = sizeof(SIP_ADD_NEWPROVIDER);
374     newprov.pgSubject = &actionid;
375     newprov.pwszDLLFileName = dummydll;
376     newprov.pwszGetFuncName = dummyfunction;
377     newprov.pwszPutFuncName = dummyfunction;
378     newprov.pwszCreateFuncName = dummyfunction;
379     newprov.pwszVerifyFuncName = dummyfunction;
380     newprov.pwszRemoveFuncName = dummyfunction;
381     SetLastError(0xdeadbeef);
382     ret = CryptSIPAddProvider(&newprov);
383     ok ( ret, "CryptSIPAddProvider should have succeeded\n");
384     ok ( GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n",
385      GetLastError());
386
387     /* Dummy provider will be deleted, but the function still fails because
388      * pwszIsFunctionName and pwszIsFunctionNameFmt2 are not present in the
389      * registry.
390      */
391     SetLastError(0xdeadbeef);
392     ret = CryptSIPRemoveProvider(&actionid);
393     ok (!ret, "Expected CryptSIPRemoveProvider to fail.\n");
394     ok (GetLastError() == ERROR_FILE_NOT_FOUND,
395         "Expected ERROR_FILE_NOT_FOUND, got %ld.\n", GetLastError());
396
397     /* Everything OK */
398     memset(&newprov, 0, sizeof(SIP_ADD_NEWPROVIDER));
399     newprov.cbStruct = sizeof(SIP_ADD_NEWPROVIDER);
400     newprov.pgSubject = &actionid;
401     newprov.pwszDLLFileName = dummydll;
402     newprov.pwszGetFuncName = dummyfunction;
403     newprov.pwszPutFuncName = dummyfunction;
404     newprov.pwszCreateFuncName = dummyfunction;
405     newprov.pwszVerifyFuncName = dummyfunction;
406     newprov.pwszRemoveFuncName = dummyfunction;
407     newprov.pwszIsFunctionNameFmt2 = dummyfunction;
408     newprov.pwszIsFunctionName = dummyfunction;
409     SetLastError(0xdeadbeef);
410     ret = CryptSIPAddProvider(&newprov);
411     ok ( ret, "CryptSIPAddProvider should have succeeded\n");
412     ok ( GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n",
413      GetLastError());
414
415     /* Dummy provider should be deleted */
416     SetLastError(0xdeadbeef);
417     ret = CryptSIPRemoveProvider(&actionid);
418     ok ( ret, "CryptSIPRemoveProvider should have succeeded\n");
419     ok ( GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n",
420      GetLastError());
421 }
422
423 static void test_SIPLoad(void)
424 {
425     BOOL ret;
426     GUID subject;
427     static GUID dummySubject = { 0xdeadbeef, 0xdead, 0xbeef, { 0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef }};
428     static GUID unknown      = { 0xC689AABA, 0x8E78, 0x11D0, { 0x8C,0x47,0x00,0xC0,0x4F,0xC2,0x95,0xEE }};
429     SIP_DISPATCH_INFO sdi;
430
431     /* All NULL */
432     SetLastError(0xdeadbeef);
433     ret = CryptSIPLoad(NULL, 0, NULL);
434     ok ( !ret, "Expected CryptSIPLoad to fail\n");
435     todo_wine
436         ok ( GetLastError() == ERROR_INVALID_PARAMETER,
437             "Expected ERROR_INVALID_PARAMETER, got 0x%08lx\n", GetLastError());
438
439     /* Only pSipDispatch NULL */
440     SetLastError(0xdeadbeef);
441     ret = CryptSIPLoad(&subject, 0, NULL);
442     ok ( !ret, "Expected CryptSIPLoad to fail\n");
443     todo_wine
444         ok ( GetLastError() == ERROR_INVALID_PARAMETER,
445             "Expected ERROR_INVALID_PARAMETER, got 0x%08lx\n", GetLastError());
446
447     /* No NULLs, but nonexistent pgSubject */
448     SetLastError(0xdeadbeef);
449     memset(&sdi, 0, sizeof(SIP_DISPATCH_INFO));
450     sdi.cbSize = sizeof(SIP_DISPATCH_INFO);
451     ret = CryptSIPLoad(&dummySubject, 0, &sdi);
452     ok ( !ret, "Expected CryptSIPLoad to fail\n");
453     todo_wine
454         ok ( GetLastError() == TRUST_E_SUBJECT_FORM_UNKNOWN,
455             "Expected TRUST_E_SUBJECT_FORM_UNKNOWN, got 0x%08lx\n", GetLastError());
456
457     /* cbSize not initialized */
458     SetLastError(0xdeadbeef);
459     memset(&sdi, 0, sizeof(SIP_DISPATCH_INFO));
460     ret = CryptSIPLoad(&dummySubject, 0, &sdi);
461     ok ( !ret, "Expected CryptSIPLoad to fail\n");
462     todo_wine
463         ok ( GetLastError() == TRUST_E_SUBJECT_FORM_UNKNOWN,
464             "Expected TRUST_E_SUBJECT_FORM_UNKNOWN, got 0x%08lx\n", GetLastError());
465
466     /* cbSize not initialized, but valid subject (named unknown but registered by wintrust) */
467     SetLastError(0xdeadbeef);
468     memset(&sdi, 0, sizeof(SIP_DISPATCH_INFO));
469     ret = CryptSIPLoad(&unknown, 0, &sdi);
470     todo_wine
471     {
472         ok ( ret, "Expected CryptSIPLoad to succeed\n");
473         ok ( GetLastError() == ERROR_PROC_NOT_FOUND,
474             "Expected ERROR_PROC_NOT_FOUND, got 0x%08lx\n", GetLastError());
475     }
476
477     /* All OK */
478     SetLastError(0xdeadbeef);
479     memset(&sdi, 0, sizeof(SIP_DISPATCH_INFO));
480     sdi.cbSize = sizeof(SIP_DISPATCH_INFO);
481     ret = CryptSIPLoad(&unknown, 0, &sdi);
482     todo_wine
483         ok ( ret, "Expected CryptSIPLoad to succeed\n");
484     ok ( GetLastError() == 0xdeadbeef,
485         "Expected 0xdeadbeef, got 0x%08lx\n", GetLastError());
486
487     /* Reserved parameter not 0 */
488     SetLastError(0xdeadbeef);
489     memset(&sdi, 0, sizeof(SIP_DISPATCH_INFO));
490     sdi.cbSize = sizeof(SIP_DISPATCH_INFO);
491     ret = CryptSIPLoad(&unknown, 1, &sdi);
492     ok ( !ret, "Expected CryptSIPLoad to fail\n");
493     todo_wine
494         ok ( GetLastError() == ERROR_INVALID_PARAMETER,
495             "Expected ERROR_INVALID_PARAMETER, got 0x%08lx\n", GetLastError());
496 }
497
498 START_TEST(main)
499 {
500     hCrypt = LoadLibraryA("crypt32.dll");
501     test_findAttribute();
502     test_findExtension();
503     test_findRDNAttr();
504     test_verifyTimeValidity();
505     test_cryptAllocate();
506     test_cryptTls();
507     test_readTrustedPublisherDWORD();
508     test_getDefaultCryptProv();
509     test_AddRemoveProvider();
510     test_SIPLoad();
511 }