ddraw: Y coords are inversed.
[wine] / dlls / crypt32 / tests / msg.c
1 /*
2  * Unit test suite for crypt32.dll's CryptMsg functions
3  *
4  * Copyright 2007 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
28 #include "wine/test.h"
29
30 static void test_msg_open_to_encode(void)
31 {
32     HCRYPTMSG msg;
33
34     /* Crash
35     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, NULL,
36      NULL, NULL);
37     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, NULL, NULL,
38      NULL);
39     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, NULL, NULL,
40      NULL);
41      */
42
43     /* Bad encodings */
44     SetLastError(0xdeadbeef);
45     msg = CryptMsgOpenToEncode(0, 0, 0, NULL, NULL, NULL);
46     ok(!msg && GetLastError() == E_INVALIDARG,
47      "Expected E_INVALIDARG, got %x\n", GetLastError());
48     SetLastError(0xdeadbeef);
49     msg = CryptMsgOpenToEncode(X509_ASN_ENCODING, 0, 0, NULL, NULL, NULL);
50     ok(!msg && GetLastError() == E_INVALIDARG,
51      "Expected E_INVALIDARG, got %x\n", GetLastError());
52
53     /* Bad message types */
54     SetLastError(0xdeadbeef);
55     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, 0, NULL, NULL, NULL);
56     ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
57      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
58     SetLastError(0xdeadbeef);
59     msg = CryptMsgOpenToEncode(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, 0,
60      NULL, NULL, NULL);
61     ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
62      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
63     SetLastError(0xdeadbeef);
64     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0,
65      CMSG_SIGNED_AND_ENVELOPED, NULL, NULL, NULL);
66     ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
67      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
68     SetLastError(0xdeadbeef);
69     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, NULL,
70      NULL, NULL);
71     ok(!msg && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
72      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
73 }
74
75 static void test_msg_open_to_decode(void)
76 {
77     HCRYPTMSG msg;
78     CMSG_STREAM_INFO streamInfo = { 0 };
79
80     SetLastError(0xdeadbeef);
81     msg = CryptMsgOpenToDecode(0, 0, 0, 0, NULL, NULL);
82     ok(!msg && GetLastError() == E_INVALIDARG,
83      "Expected E_INVALIDARG, got %x\n", GetLastError());
84
85     /* Bad encodings */
86     SetLastError(0xdeadbeef);
87     msg = CryptMsgOpenToDecode(X509_ASN_ENCODING, 0, 0, 0, NULL, NULL);
88     ok(!msg && GetLastError() == E_INVALIDARG,
89      "Expected E_INVALIDARG, got %x\n", GetLastError());
90     SetLastError(0xdeadbeef);
91     msg = CryptMsgOpenToDecode(X509_ASN_ENCODING, 0, CMSG_DATA, 0, NULL, NULL);
92     ok(!msg && GetLastError() == E_INVALIDARG,
93      "Expected E_INVALIDARG, got %x\n", GetLastError());
94
95     /* The message type can be explicit... */
96     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
97      NULL);
98     todo_wine {
99     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
100     CryptMsgClose(msg);
101     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
102      NULL);
103     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
104     CryptMsgClose(msg);
105     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
106      NULL);
107     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
108     CryptMsgClose(msg);
109     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
110      NULL);
111     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
112     CryptMsgClose(msg);
113     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0,
114      CMSG_SIGNED_AND_ENVELOPED, 0, NULL, NULL);
115     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
116     CryptMsgClose(msg);
117     /* or implicit.. */
118     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
119     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
120     CryptMsgClose(msg);
121     /* or even invalid. */
122     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, 0, NULL,
123      NULL);
124     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
125     CryptMsgClose(msg);
126     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 1000, 0, NULL, NULL);
127     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
128     }
129     CryptMsgClose(msg);
130
131     /* And even though the stream info parameter "must be set to NULL" for
132      * CMSG_HASHED, it's still accepted.
133      */
134     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
135      &streamInfo);
136     todo_wine
137     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
138     CryptMsgClose(msg);
139 }
140
141 static void test_msg_get_param(void)
142 {
143     BOOL ret;
144     HCRYPTMSG msg;
145     DWORD size, i, value;
146     CMSG_SIGNED_ENCODE_INFO signInfo = { sizeof(signInfo), 0 };
147     CMSG_SIGNER_ENCODE_INFO signer = { sizeof(signer), 0 };
148
149     /* Crash
150     ret = CryptMsgGetParam(NULL, 0, 0, NULL, NULL);
151     ret = CryptMsgGetParam(NULL, 0, 0, NULL, &size);
152     ret = CryptMsgGetParam(msg, 0, 0, NULL, NULL);
153      */
154
155     /* Decoded messages */
156     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
157     todo_wine
158     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
159     /* For decoded messages, the type is always available */
160     size = 0;
161     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
162     todo_wine {
163     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
164     size = sizeof(value);
165     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
166     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
167     /* For this (empty) message, the type isn't set */
168     ok(value == 0, "Expected type 0, got %d\n", value);
169     }
170     CryptMsgClose(msg);
171
172     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, 0, NULL,
173      NULL);
174     todo_wine
175     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
176     /* For explicitly typed messages, the type is known. */
177     size = sizeof(value);
178     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
179     todo_wine {
180     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
181     ok(value == CMSG_DATA, "Expected CMSG_DATA, got %d\n", value);
182     }
183     for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
184     {
185         size = 0;
186         ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
187         ok(!ret, "Parameter %d: expected failure\n", i);
188     }
189     CryptMsgClose(msg);
190
191     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENVELOPED, 0, NULL,
192      NULL);
193     todo_wine {
194     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
195     size = sizeof(value);
196     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
197     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
198     ok(value == CMSG_ENVELOPED, "Expected CMSG_ENVELOPED, got %d\n", value);
199     }
200     for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
201     {
202         size = 0;
203         ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
204         ok(!ret, "Parameter %d: expected failure\n", i);
205     }
206     CryptMsgClose(msg);
207
208     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_HASHED, 0, NULL,
209      NULL);
210     todo_wine {
211     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
212     size = sizeof(value);
213     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
214     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
215     ok(value == CMSG_HASHED, "Expected CMSG_HASHED, got %d\n", value);
216     }
217     for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
218     {
219         size = 0;
220         ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
221         ok(!ret, "Parameter %d: expected failure\n", i);
222     }
223     CryptMsgClose(msg);
224
225     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
226      NULL);
227     todo_wine {
228     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
229     size = sizeof(value);
230     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
231     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
232     ok(value == CMSG_SIGNED, "Expected CMSG_SIGNED, got %d\n", value);
233     }
234     for (i = CMSG_CONTENT_PARAM; i <= CMSG_CMS_SIGNER_INFO_PARAM; i++)
235     {
236         size = 0;
237         ret = CryptMsgGetParam(msg, i, 0, NULL, &size);
238         ok(!ret, "Parameter %d: expected failure\n", i);
239     }
240     CryptMsgClose(msg);
241
242     /* Explicitly typed messages get their types set, even if they're invalid */
243     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_ENCRYPTED, 0, NULL,
244      NULL);
245     todo_wine {
246     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
247     size = sizeof(value);
248     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
249     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
250     ok(value == CMSG_ENCRYPTED, "Expected CMSG_ENCRYPTED, got %d\n", value);
251     }
252     CryptMsgClose(msg);
253
254     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 1000, 0, NULL, NULL);
255     todo_wine {
256     ok(msg != NULL, "CryptMsgOpenToDecode failed: %x\n", GetLastError());
257     size = sizeof(value);
258     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, (LPBYTE)&value, &size);
259     ok(ret, "CryptMsgGetParam failed: %x\n", GetLastError());
260     ok(value == 1000, "Expected 1000, got %d\n", value);
261     }
262     CryptMsgClose(msg);
263 }
264
265 static void test_msg_close(void)
266 {
267     BOOL ret;
268     HCRYPTMSG msg;
269
270     /* NULL succeeds.. */
271     ret = CryptMsgClose(NULL);
272     ok(ret, "CryptMsgClose failed: %x\n", GetLastError());
273     /* but an arbitrary pointer crashes. */
274     if (0)
275         ret = CryptMsgClose((HCRYPTMSG)1);
276     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
277      NULL);
278     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
279     ret = CryptMsgClose(msg);
280     ok(ret, "CryptMsgClose failed: %x\n", GetLastError());
281 }
282
283 static void check_param(LPCSTR test, HCRYPTMSG msg, DWORD param,
284  const BYTE *expected, DWORD expectedSize)
285 {
286     DWORD size;
287     LPBYTE buf;
288     BOOL ret;
289
290     size = 0;
291     ret = CryptMsgGetParam(msg, param, 0, NULL, &size);
292     ok(ret, "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError());
293     buf = HeapAlloc(GetProcessHeap(), 0, size);
294     ret = CryptMsgGetParam(msg, param, 0, buf, &size);
295     ok(ret, "%s: CryptMsgGetParam failed: %08x\n", test, GetLastError());
296     ok(size == expectedSize, "%s: expected size %d, got %d\n", test,
297      expectedSize, size);
298     if (size)
299         ok(!memcmp(buf, expected, size), "%s: unexpected data\n", test);
300     HeapFree(GetProcessHeap(), 0, buf);
301 }
302
303 static void test_data_msg_open(void)
304 {
305     HCRYPTMSG msg;
306     CMSG_HASHED_ENCODE_INFO hashInfo = { 0 };
307
308     /* The data message type takes no additional info */
309     SetLastError(0xdeadbeef);
310     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, &hashInfo,
311      NULL, NULL);
312     ok(!msg && GetLastError() == E_INVALIDARG,
313      "Expected E_INVALIDARG, got %x\n", GetLastError());
314     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
315      NULL);
316     ok(msg != NULL, "CryptMsgOpenToEncode failed: %x\n", GetLastError());
317     CryptMsgClose(msg);
318 }
319
320 static const BYTE msgData[] = { 1, 2, 3, 4 };
321
322 static void test_data_msg_update(void)
323 {
324     HCRYPTMSG msg;
325     BOOL ret;
326
327     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
328      NULL);
329     /* Can't update a message that wasn't opened detached with final = FALSE */
330     SetLastError(0xdeadbeef);
331     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
332     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
333      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
334     /* Updating it with final = TRUE succeeds */
335     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
336     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
337     /* Any subsequent update will fail, as the last was final */
338     SetLastError(0xdeadbeef);
339     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
340     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
341      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
342     CryptMsgClose(msg);
343
344     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
345      NULL);
346     /* Can't update a message with no data */
347     SetLastError(0xdeadbeef);
348     ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
349     ok(!ret && GetLastError() == E_INVALIDARG,
350      "Expected E_INVALIDARG, got %x\n", GetLastError());
351     /* Curiously, a valid update will now fail as well, presumably because of
352      * the last (invalid, but final) update.
353      */
354     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
355     ok(!ret && GetLastError() == CRYPT_E_MSG_ERROR,
356      "Expected CRYPT_E_MSG_ERROR, got %x\n", GetLastError());
357     CryptMsgClose(msg);
358
359     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG,
360      CMSG_DATA, NULL, NULL, NULL);
361     /* Doesn't appear to be able to update CMSG-DATA with non-final updates */
362     SetLastError(0xdeadbeef);
363     ret = CryptMsgUpdate(msg, NULL, 0, FALSE);
364     ok(!ret && GetLastError() == E_INVALIDARG,
365      "Expected E_INVALIDARG, got %x\n", GetLastError());
366     SetLastError(0xdeadbeef);
367     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), FALSE);
368     ok(!ret && GetLastError() == E_INVALIDARG,
369      "Expected E_INVALIDARG, got %x\n", GetLastError());
370     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
371     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
372     CryptMsgClose(msg);
373 }
374
375 static void test_data_msg_get_param(void)
376 {
377     HCRYPTMSG msg;
378     DWORD size;
379     BOOL ret;
380
381     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
382      NULL);
383
384     /* Content and bare content are always gettable */
385     size = 0;
386     ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, NULL, &size);
387     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
388     size = 0;
389     ret = CryptMsgGetParam(msg, CMSG_BARE_CONTENT_PARAM, 0, NULL, &size);
390     ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
391     /* But for this type of message, the signer and hash aren't applicable,
392      * and the type isn't available.
393      */
394     size = 0;
395     SetLastError(0xdeadbeef);
396     ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
397     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
398      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
399     SetLastError(0xdeadbeef);
400     ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
401     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
402      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
403     ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, NULL, &size);
404     ok(!ret && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
405      "Expected CRYPT_E_INVALID_MSG_TYPE, got %x\n", GetLastError());
406
407     CryptMsgClose(msg);
408 }
409
410 static const BYTE dataEmptyBareContent[] = { 0x04,0x00 };
411 static const BYTE dataEmptyContent[] = {
412 0x30,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x02,
413 0x04,0x00 };
414 static const BYTE dataBareContent[] = { 0x04,0x04,0x01,0x02,0x03,0x04 };
415 static const BYTE dataContent[] = {
416 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,
417 0x04,0x04,0x01,0x02,0x03,0x04 };
418
419 static void test_data_msg_encoding(void)
420 {
421     HCRYPTMSG msg;
422     BOOL ret;
423
424     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, 0, CMSG_DATA, NULL, NULL,
425      NULL);
426     check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
427      dataEmptyBareContent, sizeof(dataEmptyBareContent));
428     check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
429      sizeof(dataEmptyContent));
430     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
431     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
432     check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
433      dataBareContent, sizeof(dataBareContent));
434     check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
435      sizeof(dataContent));
436     CryptMsgClose(msg);
437     /* Same test, but with CMSG_BARE_CONTENT_FLAG set */
438     msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING, CMSG_BARE_CONTENT_FLAG,
439      CMSG_DATA, NULL, NULL, NULL);
440     check_param("data empty bare content", msg, CMSG_BARE_CONTENT_PARAM,
441      dataEmptyBareContent, sizeof(dataEmptyBareContent));
442     check_param("data empty content", msg, CMSG_CONTENT_PARAM, dataEmptyContent,
443      sizeof(dataEmptyContent));
444     ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
445     ok(ret, "CryptMsgUpdate failed: %x\n", GetLastError());
446     check_param("data bare content", msg, CMSG_BARE_CONTENT_PARAM,
447      dataBareContent, sizeof(dataBareContent));
448     check_param("data content", msg, CMSG_CONTENT_PARAM, dataContent,
449      sizeof(dataContent));
450     CryptMsgClose(msg);
451 }
452
453 static void test_data_msg(void)
454 {
455     test_data_msg_open();
456     test_data_msg_update();
457     test_data_msg_get_param();
458     test_data_msg_encoding();
459 }
460
461 START_TEST(msg)
462 {
463     /* Basic parameter checking tests */
464     test_msg_open_to_encode();
465     test_msg_open_to_decode();
466     test_msg_get_param();
467     test_msg_close();
468
469     /* Message-type specific tests */
470     test_data_msg();
471 }