kernel32/tests: Fix a test for real hardware.
[wine] / dlls / kernel32 / tests / format_msg.c
1 /* Unit test suite for FormatMessageA/W
2  *
3  * Copyright 2002 Mike McCormack for CodeWeavers
4  *
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.
9  *
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.
14  *
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
18  */
19
20 #include <stdarg.h>
21
22 #include "wine/test.h"
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winnls.h"
26
27 static DWORD __cdecl doit(DWORD flags, LPCVOID src, DWORD msg_id, DWORD lang_id,
28                           LPSTR out, DWORD outsize, ... )
29 {
30     __ms_va_list list;
31     DWORD r;
32
33     __ms_va_start(list, outsize);
34     r = FormatMessageA(flags, src, msg_id,
35         lang_id, out, outsize, &list);
36     __ms_va_end(list);
37     return r;
38 }
39
40 static DWORD __cdecl doitW(DWORD flags, LPCVOID src, DWORD msg_id, DWORD lang_id,
41                            LPWSTR out, DWORD outsize, ... )
42 {
43     __ms_va_list list;
44     DWORD r;
45
46     __ms_va_start(list, outsize);
47     r = FormatMessageW(flags, src, msg_id,
48         lang_id, out, outsize, &list);
49     __ms_va_end(list);
50     return r;
51 }
52
53 static void test_message_from_string_wide(void)
54 {
55     static const WCHAR test[]        = {'t','e','s','t',0};
56     static const WCHAR empty[]       = {0};
57     static const WCHAR te[]          = {'t','e',0};
58     static const WCHAR st[]          = {'s','t',0};
59     static const WCHAR t[]           = {'t',0};
60     static const WCHAR e[]           = {'e',0};
61     static const WCHAR s[]           = {'s',0};
62     static const WCHAR fmt_null[]    = {'%',0};
63     static const WCHAR fmt_tnull[]   = {'t','e','s','t','%',0};
64     static const WCHAR fmt_1[]       = {'%','1',0};
65     static const WCHAR fmt_12[]      = {'%','1','%','2',0};
66     static const WCHAR fmt_123[]     = {'%','1','%','3','%','2','%','1',0};
67     static const WCHAR fmt_123c[]    = {'%','1','!','c','!','%','2','!','c','!','%','3','!','c','!','%','1','!','c','!',0};
68     static const WCHAR fmt_123lc[]   = {'%','1','!','l','c','!','%','2','!','l','c','!','%','3','!','l','c','!','%','1','!','l','c','!',0};
69     static const WCHAR fmt_123wc[]   = {'%','1','!','w','c','!','%','2','!','w','c','!','%','3','!','w','c','!','%','1','!','w','c','!',0};
70     static const WCHAR fmt_123C[]    = {'%','1','!','C','!','%','2','!','C','!','%','3','!','C','!','%','1','!','C','!',0};
71     static const WCHAR fmt_123d[]    = {'%','1','!','d','!','%','2','!','d','!','%','3','!','d','!',0};
72     static const WCHAR fmt_1s[]      = {'%','1','!','s','!',0};
73     static const WCHAR fmt_s[]       = {'%','!','s','!',0};
74     static const WCHAR fmt_ls[]      = {'%','!','l','s','!',0};
75     static const WCHAR fmt_ws[]      = {'%','!','w','s','!',0};
76     static const WCHAR fmt_S[]       = {'%','!','S','!',0};
77     static const WCHAR fmt_14d[]     = {'%','1','!','4','d','!',0};
78     static const WCHAR fmt_14x[]     = {'%','1','!','4','x','!',0};
79     static const WCHAR fmt_14X[]     = {'%','1','!','4','X','!',0};
80     static const WCHAR fmt_1_4X[]    = {'%','1','!','-','4','X','!',0};
81     static const WCHAR fmt_1_4d[]    = {'%','1','!','-','4','d','!',0};
82     static const WCHAR fmt_2pct[]    = {' ','%','%','%','%',' ',0};
83     static const WCHAR fmt_2dot1d[]  = {' ', '%','.','%','.',' ',' ','%','1','!','d','!',0};
84     static const WCHAR fmt_t0t[]     = {'t','e','s','t','%','0','t','e','s','t',0};
85     static const WCHAR fmt_yah[]     = {'y','a','h','%','!','%','0',' ',' ',' ',0};
86     static const WCHAR fmt_space[]   = {'%',' ','%',' ',' ',' ',0};
87     static const WCHAR fmt_nrt[]     = {'%','n','%','r','%','t',0};
88     static const WCHAR fmt_hi_lf[]   = {'h','i','\n',0};
89     static const WCHAR fmt_hi_crlf[] = {'h','i','\r','\n',0};
90     static const WCHAR fmt_cr[]      = {'\r',0};
91     static const WCHAR fmt_crcrlf[]  = {'\r','\r','\n',0};
92     static const WCHAR fmt_13s[]     = {'%','1','!','3','s','!',0};
93     static const WCHAR fmt_1os[]     = {'%','1','!','*','s','!',0};
94     static const WCHAR fmt_142u[]    = {'%','1','!','4','.','2','u','!',0};
95     static const WCHAR fmt_1oou[]    = {'%','1','!','*','.','*','u','!',0};
96     static const WCHAR fmt_1oou1oou[] = {'%','1','!','*','.','*','u','!',',','%','1','!','*','.','*','u','!',0};
97     static const WCHAR fmt_1oou3oou[] = {'%','1','!','*','.','*','u','!',',','%','3','!','*','.','*','u','!',0};
98     static const WCHAR fmt_1oou4oou[] = {'%','1','!','*','.','*','u','!',',','%','4','!','*','.','*','u','!',0};
99
100     static const WCHAR s_123d[]      = {'1','2','3',0};
101     static const WCHAR s_14d[]       = {' ',' ',' ','1',0};
102     static const WCHAR s_14x[]       = {' ',' ',' ','b',0};
103     static const WCHAR s_14X[]       = {' ',' ',' ','B',0};
104     static const WCHAR s_1_4X[]      = {'B',' ',' ',' ',0};
105     static const WCHAR s_14d2[]      = {' ',' ','1','1',0};
106     static const WCHAR s_1_4d[]      = {'1',' ',' ',' ',0};
107     static const WCHAR s_1AB[]       = {' ','1','A','B',0};
108     static const WCHAR s_2pct[]      = {' ','%','%',' ',0};
109     static const WCHAR s_2dot147[]   = {' ','.','.',' ',' ','4','2','7',0};
110     static const WCHAR s_yah[]       = {'y','a','h','!',0};
111     static const WCHAR s_space[]     = {' ',' ',' ',' ',0};
112     static const WCHAR s_nrt[]       = {'\r','\n','\r','\t',0};
113     static const WCHAR s_hi_crlf[]   = {'h','i','\r','\n',0};
114     static const WCHAR s_crlf[]      = {'\r','\n',0};
115     static const WCHAR s_crlfcrlf[]  = {'\r','\n','\r','\n',0};
116     static const WCHAR s_hi_sp[]     = {'h','i',' ',0};
117     static const WCHAR s_sp[]        = {' ',0};
118     static const WCHAR s_2sp[]       = {' ',' ',0};
119     static const WCHAR s_spt[]       = {' ',' ','t',0};
120     static const WCHAR s_sp3t[]      = {' ',' ',' ','t',0};
121     static const WCHAR s_sp03[]      = {' ',' ','0','3',0};
122     static const WCHAR s_sp001[]     = {' ',' ','0','0','1',0};
123     static const WCHAR s_sp001002[]  = {' ',' ','0','0','1',',',' ','0','0','0','2',0};
124     static const WCHAR s_sp001sp002[] = {' ',' ','0','0','1',',',' ',' ','0','0','0','2',0};
125     static const WCHAR s_sp002sp001[] = {' ',' ','0','0','0','2',',',' ',' ','0','0','1',0};
126     static const WCHAR s_sp002sp003[] = {' ',' ','0','0','0','2',',',' ','0','0','0','0','3',0};
127     static const WCHAR s_sp001004[]   = {' ',' ','0','0','1',',','0','0','0','0','0','4',0};
128
129     static const WCHAR init_buf[] = {'x', 'x', 'x', 'x', 'x', 'x'};
130     static const WCHAR broken_buf[] = {'t','e','s','t','x','x'};
131
132     WCHAR out[0x100] = {0};
133     DWORD r, error;
134
135     /* the basics */
136     r = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, test, 0,
137         0, out, sizeof(out)/sizeof(WCHAR), NULL);
138     ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out));
139     ok(r==4, "failed: r=%d\n", r);
140
141     /* null string, crashes on Windows */
142     if (0)
143     {
144         SetLastError(0xdeadbeef);
145         memcpy(out, init_buf, sizeof(init_buf));
146         FormatMessageW(FORMAT_MESSAGE_FROM_STRING, NULL, 0,
147             0, out, sizeof(out)/sizeof(WCHAR), NULL);
148     }
149
150     /* empty string */
151     SetLastError(0xdeadbeef);
152     memcpy(out, init_buf, sizeof(init_buf));
153     r = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, empty, 0,
154         0, out, sizeof(out)/sizeof(WCHAR), NULL);
155     error = GetLastError();
156     ok(!lstrcmpW(empty, out), "failed out=%s\n", wine_dbgstr_w(out));
157     ok(r==0, "succeeded: r=%d\n", r);
158     ok(error==0xdeadbeef, "last error %u\n", error);
159
160     /* format placeholder with no specifier */
161     SetLastError(0xdeadbeef);
162     memcpy(out, init_buf, sizeof(init_buf));
163     r = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, fmt_null, 0,
164         0, out, sizeof(out)/sizeof(WCHAR), NULL);
165     error = GetLastError();
166     ok(!memcmp(out, init_buf, sizeof(init_buf)),
167        "Expected the buffer to be unchanged\n");
168     ok(r==0, "succeeded: r=%d\n", r);
169     ok(error==ERROR_INVALID_PARAMETER, "last error %u\n", error);
170
171     /* test string with format placeholder with no specifier */
172     SetLastError(0xdeadbeef);
173     memcpy(out, init_buf, sizeof(init_buf));
174     r = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, fmt_tnull, 0,
175         0, out, sizeof(out)/sizeof(WCHAR), NULL);
176     error = GetLastError();
177     ok(!memcmp(out, init_buf, sizeof(init_buf)) ||
178        broken(!memcmp(out, broken_buf, sizeof(broken_buf))), /* W2K3+ */
179        "Expected the buffer to be unchanged\n");
180     ok(r==0, "succeeded: r=%d\n", r);
181     ok(error==ERROR_INVALID_PARAMETER, "last error %u\n", error);
182
183     /* insertion with no variadic arguments */
184     SetLastError(0xdeadbeef);
185     memcpy(out, init_buf, sizeof(init_buf));
186     r = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, fmt_1, 0,
187         0, out, sizeof(out)/sizeof(WCHAR), NULL);
188     error = GetLastError();
189     ok(!memcmp(out, init_buf, sizeof(init_buf)),
190        "Expected the buffer to be unchanged\n");
191     ok(r==0, "succeeded: r=%d\n", r);
192     ok(error==ERROR_INVALID_PARAMETER, "last error %u\n", error);
193
194     SetLastError(0xdeadbeef);
195     memcpy(out, init_buf, sizeof(init_buf));
196     r = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, fmt_1, 0,
197         0, out, sizeof(out)/sizeof(WCHAR), NULL);
198     error = GetLastError();
199     ok(!memcmp(out, init_buf, sizeof(init_buf)),
200        "Expected the buffer to be unchanged\n");
201     ok(r==0, "succeeded: r=%d\n", r);
202     ok(error==ERROR_INVALID_PARAMETER, "last error %u\n", error);
203
204     /* using the format feature */
205     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1s, 0,
206         0, out, sizeof(out)/sizeof(WCHAR), test);
207     ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out));
208     ok(r==4,"failed: r=%d\n", r);
209
210     /* no format */
211     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1, 0,
212         0, out, sizeof(out)/sizeof(WCHAR), test);
213     ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out));
214     ok(r==4,"failed: r=%d\n", r);
215
216     /* two pieces */
217     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_12, 0,
218         0, out, sizeof(out)/sizeof(WCHAR), te, st);
219     ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out));
220     ok(r==4,"failed: r=%d\n", r);
221
222     /* three pieces */
223     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_123, 0,
224         0, out, sizeof(out)/sizeof(WCHAR), t, s, e);
225     ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out));
226     ok(r==4,"failed: r=%d\n", r);
227
228     /* s doesn't seem to work in format strings */
229     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_s, 0,
230         0, out, sizeof(out)/sizeof(WCHAR), test);
231     ok(!lstrcmpW(&fmt_s[1], out), "failed out=%s\n", wine_dbgstr_w(out));
232     ok(r==3, "failed: r=%d\n", r);
233
234     /* nor ls */
235     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_ls, 0,
236         0, out, sizeof(out)/sizeof(WCHAR), test);
237     ok(!lstrcmpW(&fmt_ls[1], out), "failed out=%s\n", wine_dbgstr_w(out));
238     ok(r==4, "failed: r=%d\n", r);
239
240     /* nor S */
241     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_S, 0,
242         0, out, sizeof(out)/sizeof(WCHAR), test);
243     ok(!lstrcmpW(&fmt_S[1], out), "failed out=%s\n", wine_dbgstr_w(out));
244     ok(r==3, "failed: r=%d\n", r);
245
246     /* nor ws */
247     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_ws, 0,
248         0, out, sizeof(out)/sizeof(WCHAR), test);
249     ok(!lstrcmpW(&fmt_ws[1], out), "failed out=%s\n", wine_dbgstr_w(out));
250     ok(r==4, "failed: r=%d\n", r);
251
252     /* as characters */
253     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_123c, 0,
254         0, out, sizeof(out)/sizeof(WCHAR), 't', 'e', 's');
255     ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out));
256     ok(r==4,"failed: r=%d\n", r);
257
258     /* lc is unicode */
259     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_123lc, 0,
260         0, out, sizeof(out)/sizeof(WCHAR), 't', 'e', 's');
261     ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out));
262     ok(r==4,"failed: r=%d\n", r);
263
264     /* wc is unicode */
265     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_123wc, 0,
266         0, out, sizeof(out)/sizeof(WCHAR), 't', 'e', 's');
267     ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out));
268     ok(r==4,"failed: r=%d\n", r);
269
270     /* C is unicode */
271     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_123C, 0,
272         0, out, sizeof(out)/sizeof(WCHAR), 't', 'e', 's');
273     ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out));
274     ok(r==4,"failed: r=%d\n", r);
275
276     /* some numbers */
277     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_123d, 0,
278         0, out, sizeof(out)/sizeof(WCHAR), 1, 2, 3);
279     ok(!lstrcmpW(s_123d, out), "failed out=%s\n", wine_dbgstr_w(out));
280     ok(r==3,"failed: r=%d\n", r);
281
282     /* a single digit with some spacing */
283     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_14d, 0,
284         0, out, sizeof(out)/sizeof(WCHAR), 1);
285     ok(!lstrcmpW(s_14d, out), "failed out=%s\n", wine_dbgstr_w(out));
286     ok(r==4,"failed: r=%d\n", r);
287
288     /* a single digit, left justified */
289     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1_4d, 0,
290         0, out, sizeof(out)/sizeof(CHAR), 1);
291     ok(!lstrcmpW(s_1_4d, out), "failed out=%s\n", wine_dbgstr_w(out));
292     ok(r==4,"failed: r=%d\n", r);
293
294     /* two digit decimal number */
295     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_14d, 0,
296         0, out, sizeof(out)/sizeof(WCHAR), 11);
297     ok(!lstrcmpW(s_14d2, out), "failed out=%s\n", wine_dbgstr_w(out));
298     ok(r==4,"failed: r=%d\n", r);
299
300     /* a hex number */
301     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_14x, 0,
302         0, out, sizeof(out)/sizeof(WCHAR), 11);
303     ok(!lstrcmpW(s_14x, out), "failed out=%s\n", wine_dbgstr_w(out));
304     ok(r==4,"failed: r=%d\n", r);
305
306     /* a hex number, upper case */
307     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_14X, 0,
308         0, out, sizeof(out)/sizeof(WCHAR), 11);
309     ok(!lstrcmpW(s_14X, out), "failed out=%s\n", wine_dbgstr_w(out));
310     ok(r==4,"failed: r=%d\n", r);
311
312     /* a hex number, upper case, left justified */
313     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1_4X, 0,
314         0, out, sizeof(out)/sizeof(WCHAR), 11);
315     ok(!lstrcmpW(s_1_4X, out), "failed out=%s\n", wine_dbgstr_w(out));
316     ok(r==4,"failed: r=%d\n", r);
317
318     /* a long hex number, upper case */
319     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_14X, 0,
320         0, out, sizeof(out)/sizeof(WCHAR), 0x1ab);
321     ok(!lstrcmpW(s_1AB, out), "failed out=%s\n", wine_dbgstr_w(out));
322     ok(r==4,"failed: r=%d\n", r);
323
324     /* two percent... */
325     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_2pct, 0,
326         0, out, sizeof(out)/sizeof(WCHAR));
327     ok(!lstrcmpW(s_2pct, out), "failed out=%s\n", wine_dbgstr_w(out));
328     ok(r==4,"failed: r=%d\n", r);
329
330     /* periods are special cases */
331     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_2dot1d, 0,
332         0, out, sizeof(out)/sizeof(WCHAR), 0x1ab);
333     ok(!lstrcmpW(s_2dot147, out), "failed out=%s\n", wine_dbgstr_w(out));
334     ok(r==8,"failed: r=%d\n", r);
335
336     /* %0 ends the line */
337     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_t0t, 0,
338         0, out, sizeof(out)/sizeof(WCHAR));
339     ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out));
340     ok(r==4,"failed: r=%d\n", r);
341
342     /* %! prints an exclamation */
343     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_yah, 0,
344         0, out, sizeof(out)/sizeof(WCHAR));
345     ok(!lstrcmpW(s_yah, out), "failed out=%s\n", wine_dbgstr_w(out));
346     ok(r==4,"failed: r=%d\n", r);
347
348     /* %space */
349     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_space, 0,
350         0, out, sizeof(out)/sizeof(WCHAR));
351     ok(!lstrcmpW(s_space, out), "failed out=%s\n", wine_dbgstr_w(out));
352     ok(r==4,"failed: r=%d\n", r);
353
354     /* %n yields \r\n, %r yields \r, %t yields \t */
355     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_nrt, 0,
356         0, out, sizeof(out)/sizeof(WCHAR));
357     ok(!lstrcmpW(s_nrt, out), "failed out=%s\n", wine_dbgstr_w(out));
358     ok(r==4,"failed: r=%d\n", r);
359
360     /* line feed */
361     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_hi_lf, 0,
362         0, out, sizeof(out)/sizeof(WCHAR));
363     ok(!lstrcmpW(s_hi_crlf, out), "failed out=%s\n", wine_dbgstr_w(out));
364     ok(r==4,"failed: r=%d\n", r);
365
366     /* carriage return line feed */
367     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_hi_crlf, 0,
368         0, out, sizeof(out)/sizeof(WCHAR));
369     ok(!lstrcmpW(s_hi_crlf, out), "failed out=%s\n", wine_dbgstr_w(out));
370     ok(r==4,"failed: r=%d\n", r);
371
372     /* carriage return */
373     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_cr, 0,
374         0, out, sizeof(out)/sizeof(WCHAR));
375     ok(!lstrcmpW(s_crlf, out), "failed out=%s\n", wine_dbgstr_w(out));
376     ok(r==2,"failed: r=%d\n", r);
377
378     /* double carriage return line feed */
379     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_crcrlf, 0,
380         0, out, sizeof(out)/sizeof(WCHAR));
381     ok(!lstrcmpW(s_crlfcrlf, out), "failed out=%s\n", wine_dbgstr_w(out));
382     ok(r==4,"failed: r=%d\n", r);
383
384     /* precision and width */
385
386     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_13s,
387               0, 0, out, sizeof(out)/sizeof(WCHAR), t );
388     ok(!lstrcmpW(s_spt, out),"failed out=[%s]\n", wine_dbgstr_w(out));
389     ok(r==3, "failed: r=%d\n",r);
390     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1os,
391               0, 0, out, sizeof(out)/sizeof(WCHAR), 4, t );
392     ok(!lstrcmpW( s_sp3t, out),"failed out=[%s]\n", wine_dbgstr_w(out));
393     ok(r==4,"failed: r=%d\n",r);
394     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_142u,
395               0, 0, out, sizeof(out)/sizeof(WCHAR), 3 );
396     ok(!lstrcmpW( s_sp03, out),"failed out=[%s]\n", wine_dbgstr_w(out));
397     ok(r==4,"failed: r=%d\n",r);
398     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1oou,
399               0, 0, out, sizeof(out)/sizeof(WCHAR), 5, 3, 1 );
400     ok(!lstrcmpW( s_sp001, out),"failed out=[%s]\n", wine_dbgstr_w(out));
401     ok(r==5,"failed: r=%d\n",r);
402     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1oou1oou,
403               0, 0, out, sizeof(out)/sizeof(WCHAR), 5, 3, 1, 4, 2 );
404     ok(!lstrcmpW( s_sp001002, out),"failed out=[%s]\n", wine_dbgstr_w(out));
405     ok(r==11,"failed: r=%d\n",r);
406     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1oou3oou,
407               0, 0, out, sizeof(out)/sizeof(WCHAR), 5, 3, 1, 6, 4, 2 );
408     ok(!lstrcmpW( s_sp001sp002, out) ||
409        broken(!lstrcmpW(s_sp001004, out)), /* NT4/Win2k */
410        "failed out=[%s]\n", wine_dbgstr_w(out));
411     ok(r==12,"failed: r=%d\n",r);
412     /* args are not counted the same way with an argument array */
413     {
414         ULONG_PTR args[] = { 6, 4, 2, 5, 3, 1 };
415         r = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, fmt_1oou1oou,
416                            0, 0, out, sizeof(out)/sizeof(WCHAR), (__ms_va_list *)args );
417         ok(!lstrcmpW(s_sp002sp003, out),"failed out=[%s]\n", wine_dbgstr_w(out));
418         ok(r==13,"failed: r=%d\n",r);
419         r = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, fmt_1oou4oou,
420                            0, 0, out, sizeof(out)/sizeof(WCHAR), (__ms_va_list *)args );
421         ok(!lstrcmpW(s_sp002sp001, out),"failed out=[%s]\n", wine_dbgstr_w(out));
422         ok(r==12,"failed: r=%d\n",r);
423     }
424
425     /* change of pace... test the low byte of dwflags */
426
427     /* line feed */
428     r = doitW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, fmt_hi_lf, 0,
429         0, out, sizeof(out)/sizeof(WCHAR));
430     ok(!lstrcmpW(s_hi_sp, out), "failed out=%s\n", wine_dbgstr_w(out));
431     ok(r==3,"failed: r=%d\n", r);
432
433     /* carriage return line feed */
434     r = doitW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, fmt_hi_crlf, 0,
435         0, out, sizeof(out)/sizeof(WCHAR));
436     ok(!lstrcmpW(s_hi_sp, out), "failed out=%s\n", wine_dbgstr_w(out));
437     ok(r==3,"failed: r=%d\n", r);
438
439     /* carriage return */
440     r = doitW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, fmt_cr, 0,
441         0, out, sizeof(out)/sizeof(WCHAR));
442     ok(!lstrcmpW(s_sp, out), "failed out=%s\n", wine_dbgstr_w(out));
443     ok(r==1,"failed: r=%d\n", r);
444
445     /* double carriage return line feed */
446     r = doitW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, fmt_crcrlf, 0,
447         0, out, sizeof(out)/sizeof(WCHAR));
448     ok(!lstrcmpW(s_2sp, out), "failed out=%s\n", wine_dbgstr_w(out));
449     ok(r==2,"failed: r=%d\n", r);
450 }
451
452 static void test_message_from_string(void)
453 {
454     CHAR out[0x100] = {0};
455     DWORD r;
456     static const char init_buf[] = {'x', 'x', 'x', 'x', 'x', 'x'};
457     static const WCHAR szwTest[] = { 't','e','s','t',0};
458
459     /* the basics */
460     r = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, "test", 0,
461         0, out, sizeof(out)/sizeof(CHAR),NULL);
462     ok(!strcmp("test", out),"failed out=[%s]\n",out);
463     ok(r==4,"failed: r=%d\n",r);
464
465     /* null string, crashes on Windows */
466     if (0)
467     {
468         SetLastError(0xdeadbeef);
469         memcpy(out, init_buf, sizeof(init_buf));
470         FormatMessageA(FORMAT_MESSAGE_FROM_STRING, NULL, 0,
471             0, out, sizeof(out)/sizeof(CHAR), NULL);
472     }
473
474     /* empty string */
475     SetLastError(0xdeadbeef);
476     memcpy(out, init_buf, sizeof(init_buf));
477     r = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, "", 0,
478         0, out, sizeof(out)/sizeof(CHAR), NULL);
479     ok(!memcmp(out, init_buf, sizeof(init_buf)) ||
480        broken(!strcmp("", out)), /* Win9x */
481        "Expected the buffer to be untouched\n");
482     ok(r==0, "succeeded: r=%d\n", r);
483     ok(GetLastError()==0xdeadbeef,
484        "last error %u\n", GetLastError());
485
486     /* format placeholder with no specifier */
487     SetLastError(0xdeadbeef);
488     memcpy(out, init_buf, sizeof(init_buf));
489     r = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, "%", 0,
490         0, out, sizeof(out)/sizeof(CHAR), NULL);
491     ok(!memcmp(out, init_buf, sizeof(init_buf)),
492        "Expected the buffer to be untouched\n");
493     ok(r==0, "succeeded: r=%d\n", r);
494     ok(GetLastError()==ERROR_INVALID_PARAMETER,
495        "last error %u\n", GetLastError());
496
497     /* test string with format placeholder with no specifier */
498     SetLastError(0xdeadbeef);
499     memcpy(out, init_buf, sizeof(init_buf));
500     r = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, "test%", 0,
501         0, out, sizeof(out)/sizeof(CHAR), NULL);
502     ok(!memcmp(out, init_buf, sizeof(init_buf)),
503        "Expected the buffer to be untouched\n");
504     ok(r==0, "succeeded: r=%d\n", r);
505     ok(GetLastError()==ERROR_INVALID_PARAMETER,
506        "last error %u\n", GetLastError());
507
508     /* insertion with no variadic arguments */
509     SetLastError(0xdeadbeef);
510     memcpy(out, init_buf, sizeof(init_buf));
511     r = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, "%1", 0,
512         0, out, sizeof(out)/sizeof(CHAR), NULL);
513     ok(!memcmp(out, init_buf, sizeof(init_buf)) ||
514        broken(!strcmp("%1", out)), /* Win9x */
515        "Expected the buffer to be untouched\n");
516     ok(r==0 ||
517        broken(r==2), /* Win9x */
518        "succeeded: r=%d\n", r);
519     ok(GetLastError()==ERROR_INVALID_PARAMETER ||
520        broken(GetLastError()==0xdeadbeef), /* Win9x */
521        "last error %u\n", GetLastError());
522
523     SetLastError(0xdeadbeef);
524     memcpy(out, init_buf, sizeof(init_buf));
525     r = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, "%1", 0,
526         0, out, sizeof(out)/sizeof(CHAR), NULL);
527     ok(!memcmp(out, init_buf, sizeof(init_buf)) ||
528        broken(!strcmp("%1", out)), /* Win9x */
529        "Expected the buffer to be untouched\n");
530     ok(r==0 ||
531        broken(r==2), /* Win9x */
532        "succeeded: r=%d\n", r);
533     ok(GetLastError()==ERROR_INVALID_PARAMETER ||
534        broken(GetLastError()==0xdeadbeef), /* Win9x */
535        "last error %u\n", GetLastError());
536
537     /* using the format feature */
538     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!s!", 0,
539         0, out, sizeof(out)/sizeof(CHAR), "test");
540     ok(!strcmp("test", out),"failed out=[%s]\n",out);
541     ok(r==4,"failed: r=%d\n",r);
542
543     /* no format */
544     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1", 0,
545         0, out, sizeof(out)/sizeof(CHAR), "test");
546     ok(!strcmp("test", out),"failed out=[%s]\n",out);
547     ok(r==4,"failed: r=%d\n",r);
548
549     /* two pieces */
550     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1%2", 0,
551         0, out, sizeof(out)/sizeof(CHAR), "te","st");
552     ok(!strcmp("test", out),"failed out=[%s]\n",out);
553     ok(r==4,"failed: r=%d\n",r);
554
555     /* three pieces */
556     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1%3%2%1", 0,
557         0, out, sizeof(out)/sizeof(CHAR), "t","s","e");
558     ok(!strcmp("test", out),"failed out=[%s]\n",out);
559     ok(r==4,"failed: r=%d\n",r);
560
561     /* s doesn't seem to work in format strings */
562     r = doit(FORMAT_MESSAGE_FROM_STRING, "%!s!", 0,
563         0, out, sizeof(out)/sizeof(CHAR), "test");
564     ok(!strcmp("!s!", out),"failed out=[%s]\n",out);
565     ok(r==3,"failed: r=%d\n",r);
566
567     /* ls is unicode */
568     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!ls!", 0,
569         0, out, sizeof(out)/sizeof(CHAR), szwTest);
570     ok(!strcmp("test", out),"failed out=[%s]\n",out);
571     ok(r==4,"failed: r=%d\n",r);
572
573     /* S is unicode */
574     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!S!", 0,
575         0, out, sizeof(out)/sizeof(CHAR), szwTest);
576     ok(!strcmp("test", out),"failed out=[%s]\n",out);
577     ok(r==4,"failed: r=%d\n",r);
578
579     /* ws is unicode */
580     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!ws!", 0,
581         0, out, sizeof(out)/sizeof(CHAR), szwTest);
582     ok(!strcmp("test", out),"failed out=[%s]\n",out);
583     ok(r==4,"failed: r=%d\n",r);
584
585     /* as characters */
586     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!c!%2!c!%3!c!%1!c!", 0,
587         0, out, sizeof(out)/sizeof(CHAR), 't','e','s');
588     ok(!strcmp("test", out),"failed out=[%s]\n",out);
589     ok(r==4,"failed: r=%d\n",r);
590
591     /* lc is unicode */
592     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!lc!%2!lc!%3!lc!%1!lc!", 0,
593         0, out, sizeof(out)/sizeof(CHAR), 't','e','s');
594     ok(!strcmp("test", out),"failed out=[%s]\n",out);
595     ok(r==4,"failed: r=%d\n",r);
596
597     /* wc is unicode */
598     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!wc!%2!wc!%3!wc!%1!wc!", 0,
599         0, out, sizeof(out)/sizeof(CHAR), 't','e','s');
600     ok(!strcmp("test", out),"failed out=[%s]\n",out);
601     ok(r==4,"failed: r=%d\n",r);
602
603     /* C is unicode */
604     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!C!%2!C!%3!C!%1!C!", 0,
605         0, out, sizeof(out)/sizeof(CHAR), 't','e','s');
606     ok(!strcmp("test", out),"failed out=[%s]\n",out);
607     ok(r==4,"failed: r=%d\n",r);
608
609     /* some numbers */
610     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!d!%2!d!%3!d!", 0,
611         0, out, sizeof(out)/sizeof(CHAR), 1,2,3);
612     ok(!strcmp("123", out),"failed out=[%s]\n",out);
613     ok(r==3,"failed: r=%d\n",r);
614
615     /* a single digit with some spacing */
616     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!4d!", 0,
617         0, out, sizeof(out)/sizeof(CHAR), 1);
618     ok(!strcmp("   1", out),"failed out=[%s]\n",out);
619     ok(r==4,"failed: r=%d\n",r);
620
621     /* a single digit, left justified */
622     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!-4d!", 0,
623         0, out, sizeof(out)/sizeof(CHAR), 1);
624     ok(!strcmp("1   ", out),"failed out=[%s]\n",out);
625     ok(r==4,"failed: r=%d\n",r);
626
627     /* two digit decimal number */
628     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!4d!", 0,
629         0, out, sizeof(out)/sizeof(CHAR), 11);
630     ok(!strcmp("  11", out),"failed out=[%s]\n",out);
631     ok(r==4,"failed: r=%d\n",r);
632
633     /* a hex number */
634     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!4x!", 0,
635         0, out, sizeof(out)/sizeof(CHAR), 11);
636     ok(!strcmp("   b", out),"failed out=[%s]\n",out);
637     ok(r==4,"failed: r=%d\n",r);
638
639     /* a hex number, upper case */
640     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!4X!", 0,
641         0, out, sizeof(out)/sizeof(CHAR), 11);
642     ok(!strcmp("   B", out),"failed out=[%s]\n",out);
643     ok(r==4,"failed: r=%d\n",r);
644
645     /* a hex number, upper case, left justified */
646     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!-4X!", 0,
647         0, out, sizeof(out)/sizeof(CHAR), 11);
648     ok(!strcmp("B   ", out),"failed out=[%s]\n",out);
649     ok(r==4,"failed: r=%d\n",r);
650
651     /* a long hex number, upper case */
652     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!4X!", 0,
653         0, out, sizeof(out)/sizeof(CHAR), 0x1ab);
654     ok(!strcmp(" 1AB", out),"failed out=[%s]\n",out);
655     ok(r==4,"failed: r=%d\n",r);
656
657     /* two percent... */
658     r = doit(FORMAT_MESSAGE_FROM_STRING, " %%%% ", 0,
659         0, out, sizeof(out)/sizeof(CHAR));
660     ok(!strcmp(" %% ", out),"failed out=[%s]\n",out);
661     ok(r==4,"failed: r=%d\n",r);
662
663     /* periods are special cases */
664     r = doit(FORMAT_MESSAGE_FROM_STRING, " %.%. %1!d!", 0,
665         0, out, sizeof(out)/sizeof(CHAR), 0x1ab);
666     ok(!strcmp(" .. 427", out),"failed out=[%s]\n",out);
667     ok(r==7,"failed: r=%d\n",r);
668
669     /* %0 ends the line */
670     r = doit(FORMAT_MESSAGE_FROM_STRING, "test%0test", 0,
671         0, out, sizeof(out)/sizeof(CHAR));
672     ok(!strcmp("test", out),"failed out=[%s]\n",out);
673     ok(r==4,"failed: r=%d\n",r);
674
675     /* %! prints an exclamation */
676     r = doit(FORMAT_MESSAGE_FROM_STRING, "yah%!%0   ", 0,
677         0, out, sizeof(out)/sizeof(CHAR));
678     ok(!strcmp("yah!", out),"failed out=[%s]\n",out);
679     ok(r==4,"failed: r=%d\n",r);
680
681     /* %space */
682     r = doit(FORMAT_MESSAGE_FROM_STRING, "% %   ", 0,
683         0, out, sizeof(out)/sizeof(CHAR));
684     ok(!strcmp("    ", out),"failed out=[%s]\n",out);
685     ok(r==4,"failed: r=%d\n",r);
686
687     /* %n yields \r\n, %r yields \r, %t yields \t */
688     r = doit(FORMAT_MESSAGE_FROM_STRING, "%n%r%t", 0,
689         0, out, sizeof(out)/sizeof(CHAR));
690     ok(!strcmp("\r\n\r\t", out),"failed out=[%s]\n",out);
691     ok(r==4,"failed: r=%d\n",r);
692
693     /* line feed */
694     r = doit(FORMAT_MESSAGE_FROM_STRING, "hi\n", 0,
695         0, out, sizeof(out)/sizeof(CHAR));
696     ok(!strcmp("hi\r\n", out),"failed out=[%s]\n",out);
697     ok(r==4,"failed: r=%d\n",r);
698
699     /* carriage return line feed */
700     r = doit(FORMAT_MESSAGE_FROM_STRING, "hi\r\n", 0,
701         0, out, sizeof(out)/sizeof(CHAR));
702     ok(!strcmp("hi\r\n", out),"failed out=[%s]\n",out);
703     ok(r==4,"failed: r=%d\n",r);
704
705     /* carriage return */
706     r = doit(FORMAT_MESSAGE_FROM_STRING, "\r", 0,
707         0, out, sizeof(out)/sizeof(CHAR));
708     ok(!strcmp("\r\n", out),"failed out=[%s]\n",out);
709     ok(r==2,"failed: r=%d\n",r);
710
711     /* double carriage return line feed */
712     r = doit(FORMAT_MESSAGE_FROM_STRING, "\r\r\n", 0,
713         0, out, sizeof(out)/sizeof(CHAR));
714     ok(!strcmp("\r\n\r\n", out),"failed out=[%s]\n",out);
715     ok(r==4,"failed: r=%d\n",r);
716
717     /* precision and width */
718
719     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!3s!",
720              0, 0, out, sizeof(out), "t" );
721     ok(!strcmp("  t", out),"failed out=[%s]\n",out);
722     ok(r==3, "failed: r=%d\n",r);
723     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!*s!",
724              0, 0, out, sizeof(out), 4, "t");
725     if (!strcmp("*s",out)) win_skip( "width/precision not supported\n" );
726     else
727     {
728         ok(!strcmp( "   t", out),"failed out=[%s]\n",out);
729         ok(r==4,"failed: r=%d\n",r);
730         r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!4.2u!",
731                  0, 0, out, sizeof(out), 3 );
732         ok(!strcmp( "  03", out),"failed out=[%s]\n",out);
733         ok(r==4,"failed: r=%d\n",r);
734         r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!*.*u!",
735                  0, 0, out, sizeof(out), 5, 3, 1 );
736         ok(!strcmp( "  001", out),"failed out=[%s]\n",out);
737         ok(r==5,"failed: r=%d\n",r);
738         r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!*.*u!,%1!*.*u!",
739                  0, 0, out, sizeof(out), 5, 3, 1, 4, 2 );
740         ok(!strcmp( "  001, 0002", out),"failed out=[%s]\n",out);
741         ok(r==11,"failed: r=%d\n",r);
742         r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!*.*u!,%3!*.*u!",
743                  0, 0, out, sizeof(out), 5, 3, 1, 6, 4, 2 );
744         /* older Win versions marked as broken even though this is arguably the correct behavior */
745         /* but the new (brain-damaged) behavior is specified on MSDN */
746         ok(!strcmp( "  001,  0002", out) ||
747            broken(!strcmp("  001,000004", out)), /* NT4/Win2k */
748            "failed out=[%s]\n",out);
749         ok(r==12,"failed: r=%d\n",r);
750         /* args are not counted the same way with an argument array */
751         {
752             ULONG_PTR args[] = { 6, 4, 2, 5, 3, 1 };
753             r = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
754                                "%1!*.*u!,%1!*.*u!", 0, 0, out, sizeof(out), (__ms_va_list *)args );
755             ok(!strcmp("  0002, 00003", out),"failed out=[%s]\n",out);
756             ok(r==13,"failed: r=%d\n",r);
757             r = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
758                                "%1!*.*u!,%4!*.*u!", 0, 0, out, sizeof(out), (__ms_va_list *)args );
759             ok(!strcmp("  0002,  001", out),"failed out=[%s]\n",out);
760             ok(r==12,"failed: r=%d\n",r);
761         }
762     }
763
764     /* change of pace... test the low byte of dwflags */
765
766     /* line feed */
767     r = doit(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, "hi\n", 0,
768         0, out, sizeof(out)/sizeof(CHAR));
769     ok(!strcmp("hi ", out) ||
770        broken(!strcmp("hi\r\n", out)), /* Win9x */
771        "failed out=[%s]\n",out);
772     ok(r==3 ||
773        broken(r==4), /* Win9x */
774        "failed: r=%d\n",r);
775
776     /* carriage return line feed */
777     r = doit(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, "hi\r\n", 0,
778         0, out, sizeof(out)/sizeof(CHAR));
779     ok(!strcmp("hi ", out),"failed out=[%s]\n",out);
780     ok(r==3,"failed: r=%d\n",r);
781
782     /* carriage return */
783     r = doit(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, "\r", 0,
784         0, out, sizeof(out)/sizeof(CHAR));
785     ok(!strcmp(" ", out),"failed out=[%s]\n",out);
786     ok(r==1,"failed: r=%d\n",r);
787
788     /* double carriage return line feed */
789     r = doit(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, "\r\r\n", 0,
790         0, out, sizeof(out)/sizeof(CHAR));
791     ok(!strcmp("  ", out),"failed out=[%s]\n",out);
792     ok(r==2,"failed: r=%d\n",r);
793 }
794
795 static void test_message_ignore_inserts(void)
796 {
797     static const char init_buf[] = {'x', 'x', 'x', 'x', 'x'};
798
799     DWORD ret;
800     CHAR out[256];
801
802     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, "test", 0, 0, out,
803                          sizeof(out)/sizeof(CHAR), NULL);
804     ok(ret == 4, "Expected FormatMessageA to return 4, got %d\n", ret);
805     ok(!strcmp("test", out), "Expected output string \"test\", got %s\n", out);
806
807     /* The %0 escape sequence is handled. */
808     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, "test%0", 0, 0, out,
809                          sizeof(out)/sizeof(CHAR), NULL);
810     ok(ret == 4, "Expected FormatMessageA to return 4, got %d\n", ret);
811     ok(!strcmp("test", out), "Expected output string \"test\", got %s\n", out);
812
813     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, "test%0test", 0, 0, out,
814                          sizeof(out)/sizeof(CHAR), NULL);
815     ok(ret == 4, "Expected FormatMessageA to return 4, got %d\n", ret);
816     ok(!strcmp("test", out), "Expected output string \"test\", got %s\n", out);
817
818     /* While FormatMessageA returns 0 in this case, no last error code is set. */
819     SetLastError(0xdeadbeef);
820     memcpy(out, init_buf, sizeof(init_buf));
821     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, "%0test", 0, 0, out,
822                          sizeof(out)/sizeof(CHAR), NULL);
823     ok(ret == 0, "Expected FormatMessageA to return 0, got %d\n", ret);
824     ok(!memcmp(out, init_buf, sizeof(init_buf)) ||
825        broken(!strcmp("", out)), /* Win9x */
826        "Expected the output buffer to be untouched\n");
827     ok(GetLastError() == 0xdeadbeef, "Expected GetLastError() to return 0xdeadbeef, got %u\n", GetLastError());
828
829     /* Insert sequences are ignored. */
830     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, "test%1%2!*.*s!%99", 0, 0, out,
831                          sizeof(out)/sizeof(CHAR), NULL);
832     ok(ret == 17, "Expected FormatMessageA to return 17, got %d\n", ret);
833     ok(!strcmp("test%1%2!*.*s!%99", out), "Expected output string \"test%%1%%2!*.*s!%%99\", got %s\n", out);
834
835     /* Only the "%n", "%r", and "%t" escape sequences are processed. */
836     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, "%%% %.%!", 0, 0, out,
837                          sizeof(out)/sizeof(CHAR), NULL);
838     ok(ret == 8 ||
839        broken(ret == 7) /* Win9x */,
840        "Expected FormatMessageA to return 8, got %d\n", ret);
841     ok(!strcmp("%%% %.%!", out) ||
842        broken(!strcmp("%%% %.!", out)) /* Win9x */,
843        "Expected output string \"%%%%%% %%.%%!\", got %s\n", out);
844
845     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, "%n%r%t", 0, 0, out,
846                          sizeof(out)/sizeof(CHAR), NULL);
847     ok(ret == 4, "Expected FormatMessageA to return 4, got %d\n", ret);
848     ok(!strcmp("\r\n\r\t", out), "Expected output string \"\\r\\n\\r\\t\", got %s\n", out);
849
850     /* CRLF characters are processed normally. */
851     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, "hi\n", 0, 0, out,
852                          sizeof(out)/sizeof(CHAR), NULL);
853     ok(ret == 4, "Expected FormatMessageA to return 4, got %d\n", ret);
854     ok(!strcmp("hi\r\n", out), "Expected output string \"hi\\r\\n\", got %s\n", out);
855
856     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, "hi\r\n", 0, 0, out,
857                          sizeof(out)/sizeof(CHAR), NULL);
858     ok(ret == 4, "Expected FormatMessageA to return 4, got %d\n", ret);
859     ok(!strcmp("hi\r\n", out), "Expected output string \"hi\\r\\n\", got %s\n", out);
860
861     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, "\r", 0, 0, out,
862                          sizeof(out)/sizeof(CHAR), NULL);
863     ok(ret == 2, "Expected FormatMessageA to return 2, got %d\n", ret);
864     ok(!strcmp("\r\n", out), "Expected output string \"\\r\\n\", got %s\n", out);
865
866     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, "\r\r\n", 0, 0, out,
867                          sizeof(out)/sizeof(CHAR), NULL);
868     ok(ret == 4, "Expected FormatMessageA to return 4, got %d\n", ret);
869     ok(!strcmp("\r\n\r\n", out), "Expected output string \"\\r\\n\\r\\n\", got %s\n", out);
870
871     /* The width parameter is handled the same also. */
872     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS |
873                          FORMAT_MESSAGE_MAX_WIDTH_MASK, "hi\n", 0, 0, out,
874                          sizeof(out)/sizeof(CHAR), NULL);
875     ok(!strcmp("hi ", out) ||
876        broken(!strcmp("hi\r\n", out)), /* Win9x */
877        "Expected output string \"hi \", got %s\n", out);
878     ok(ret == 3 ||
879        broken(ret == 4), /* Win9x */
880        "Expected FormatMessageA to return 3, got %d\n", ret);
881
882     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS |
883                          FORMAT_MESSAGE_MAX_WIDTH_MASK, "hi\r\n", 0, 0, out,
884                          sizeof(out)/sizeof(CHAR), NULL);
885     ok(ret == 3, "Expected FormatMessageA to return 3, got %d\n", ret);
886     ok(!strcmp("hi ", out), "Expected output string \"hi \", got %s\n", out);
887
888     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS |
889                          FORMAT_MESSAGE_MAX_WIDTH_MASK, "\r", 0, 0, out,
890                          sizeof(out)/sizeof(CHAR), NULL);
891     ok(ret == 1, "Expected FormatMessageA to return 1, got %d\n", ret);
892     ok(!strcmp(" ", out), "Expected output string \" \", got %s\n", out);
893
894     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS |
895                          FORMAT_MESSAGE_MAX_WIDTH_MASK, "\r\r\n", 0, 0, out,
896                          sizeof(out)/sizeof(CHAR), NULL);
897     ok(ret == 2, "Expected FormatMessageA to return 2, got %d\n", ret);
898     ok(!strcmp("  ", out), "Expected output string \"  \", got %s\n", out);
899 }
900
901 static void test_message_ignore_inserts_wide(void)
902 {
903     static const WCHAR test[] = {'t','e','s','t',0};
904     static const WCHAR empty[] = {0};
905     static const WCHAR fmt_t0[] = {'t','e','s','t','%','0',0};
906     static const WCHAR fmt_t0t[] = {'t','e','s','t','%','0','t','e','s','t',0};
907     static const WCHAR fmt_0t[] = {'%','0','t','e','s','t',0};
908     static const WCHAR fmt_t12oos99[] = {'t','e','s','t','%','1','%','2','!','*','.','*','s','!','%','9','9',0};
909     static const WCHAR fmt_pctspacedot[] = {'%','%','%',' ','%','.','%','!',0};
910     static const WCHAR fmt_nrt[] = {'%','n','%','r','%','t',0};
911     static const WCHAR fmt_hi_lf[]   = {'h','i','\n',0};
912     static const WCHAR fmt_hi_crlf[] = {'h','i','\r','\n',0};
913     static const WCHAR fmt_cr[]      = {'\r',0};
914     static const WCHAR fmt_crcrlf[]  = {'\r','\r','\n',0};
915
916     static const WCHAR s_nrt[] = {'\r','\n','\r','\t',0};
917     static const WCHAR s_hi_crlf[] = {'h','i','\r','\n',0};
918     static const WCHAR s_crlf[] = {'\r','\n',0};
919     static const WCHAR s_crlfcrlf[] = {'\r','\n','\r','\n',0};
920     static const WCHAR s_hi_sp[] = {'h','i',' ',0};
921     static const WCHAR s_sp[] = {' ',0};
922     static const WCHAR s_2sp[] = {' ',' ',0};
923
924     DWORD ret;
925     WCHAR out[256];
926
927     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, test, 0, 0, out,
928                          sizeof(out)/sizeof(WCHAR), NULL);
929     ok(ret == 4, "Expected FormatMessageW to return 4, got %d\n", ret);
930     ok(!lstrcmpW(test, out), "Expected output string \"test\", got %s\n", wine_dbgstr_w(out));
931
932     /* The %0 escape sequence is handled. */
933     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, fmt_t0, 0, 0, out,
934                          sizeof(out)/sizeof(WCHAR), NULL);
935     ok(ret == 4, "Expected FormatMessageW to return 4, got %d\n", ret);
936     ok(!lstrcmpW(test, out), "Expected output string \"test\", got %s\n", wine_dbgstr_w(out));
937
938     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, fmt_t0t, 0, 0, out,
939                          sizeof(out)/sizeof(WCHAR), NULL);
940     ok(ret == 4, "Expected FormatMessageW to return 4, got %d\n", ret);
941     ok(!lstrcmpW(test, out), "Expected output string \"test\", got %s\n", wine_dbgstr_w(out));
942
943     /* While FormatMessageA returns 0 in this case, no last error code is set. */
944     SetLastError(0xdeadbeef);
945     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, fmt_0t, 0, 0, out,
946                          sizeof(out)/sizeof(WCHAR), NULL);
947     ok(ret == 0, "Expected FormatMessageW to return 0, got %d\n", ret);
948     ok(!lstrcmpW(empty, out), "Expected the output buffer to be the empty string, got %s\n", wine_dbgstr_w(out));
949     ok(GetLastError() == 0xdeadbeef, "Expected GetLastError() to return 0xdeadbeef, got %u\n", GetLastError());
950
951     /* Insert sequences are ignored. */
952     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, fmt_t12oos99, 0, 0, out,
953                          sizeof(out)/sizeof(WCHAR), NULL);
954     ok(ret == 17, "Expected FormatMessageW to return 17, got %d\n", ret);
955     ok(!lstrcmpW(fmt_t12oos99, out), "Expected output string \"test%%1%%2!*.*s!%%99\", got %s\n", wine_dbgstr_w(out));
956
957     /* Only the "%n", "%r", and "%t" escape sequences are processed. */
958     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, fmt_pctspacedot, 0, 0, out,
959                          sizeof(out)/sizeof(WCHAR), NULL);
960     ok(ret == 8, "Expected FormatMessageW to return 8, got %d\n", ret);
961     ok(!lstrcmpW(fmt_pctspacedot, out), "Expected output string \"%%%%%% %%.%%!\", got %s\n", wine_dbgstr_w(out));
962
963     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, fmt_nrt, 0, 0, out,
964                          sizeof(out)/sizeof(WCHAR), NULL);
965     ok(ret == 4, "Expected FormatMessageW to return 4, got %d\n", ret);
966     ok(!lstrcmpW(s_nrt, out), "Expected output string \"\\r\\n\\r\\t\", got %s\n", wine_dbgstr_w(out));
967
968     /* CRLF characters are processed normally. */
969     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, fmt_hi_lf, 0, 0, out,
970                          sizeof(out)/sizeof(WCHAR), NULL);
971     ok(ret == 4, "Expected FormatMessageW to return 4, got %d\n", ret);
972     ok(!lstrcmpW(s_hi_crlf, out), "Expected output string \"hi\\r\\n\", got %s\n", wine_dbgstr_w(out));
973
974     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, fmt_hi_crlf, 0, 0, out,
975                          sizeof(out)/sizeof(WCHAR), NULL);
976     ok(ret == 4, "Expected FormatMessageW to return 4, got %d\n", ret);
977     ok(!lstrcmpW(s_hi_crlf, out), "Expected output string \"hi\\r\\n\", got %s\n", wine_dbgstr_w(out));
978
979     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, fmt_cr, 0, 0, out,
980                          sizeof(out)/sizeof(WCHAR), NULL);
981     ok(ret == 2, "Expected FormatMessageW to return 2, got %d\n", ret);
982     ok(!lstrcmpW(s_crlf, out), "Expected output string \"\\r\\n\", got %s\n", wine_dbgstr_w(out));
983
984     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, fmt_crcrlf, 0, 0, out,
985                          sizeof(out)/sizeof(WCHAR), NULL);
986     ok(ret == 4, "Expected FormatMessageW to return 4, got %d\n", ret);
987     ok(!lstrcmpW(s_crlfcrlf, out), "Expected output string \"\\r\\n\\r\\n\", got %s\n", wine_dbgstr_w(out));
988
989     /* The width parameter is handled the same also. */
990     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS |
991                          FORMAT_MESSAGE_MAX_WIDTH_MASK, fmt_hi_lf, 0, 0, out,
992                          sizeof(out)/sizeof(WCHAR), NULL);
993     ok(ret == 3, "Expected FormatMessageW to return 3, got %d\n", ret);
994     ok(!lstrcmpW(s_hi_sp, out), "Expected output string \"hi \", got %s\n", wine_dbgstr_w(out));
995
996     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS |
997                          FORMAT_MESSAGE_MAX_WIDTH_MASK, fmt_hi_crlf, 0, 0, out,
998                          sizeof(out)/sizeof(WCHAR), NULL);
999     ok(ret == 3, "Expected FormatMessageW to return 3, got %d\n", ret);
1000     ok(!lstrcmpW(s_hi_sp, out), "Expected output string \"hi \", got %s\n", wine_dbgstr_w(out));
1001
1002     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS |
1003                          FORMAT_MESSAGE_MAX_WIDTH_MASK, fmt_cr, 0, 0, out,
1004                          sizeof(out)/sizeof(WCHAR), NULL);
1005     ok(ret == 1, "Expected FormatMessageW to return 1, got %d\n", ret);
1006     ok(!lstrcmpW(s_sp, out), "Expected output string \" \", got %s\n", wine_dbgstr_w(out));
1007
1008     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS |
1009                          FORMAT_MESSAGE_MAX_WIDTH_MASK, fmt_crcrlf, 0, 0, out,
1010                          sizeof(out)/sizeof(WCHAR), NULL);
1011     ok(ret == 2, "Expected FormatMessageW to return 2, got %d\n", ret);
1012     ok(!lstrcmpW(s_2sp, out), "Expected output string \"  \", got %s\n", wine_dbgstr_w(out));
1013 }
1014
1015 static void test_message_insufficient_buffer(void)
1016 {
1017     static const char init_buf[] = {'x', 'x', 'x', 'x', 'x'};
1018     static const char expected_buf[] = {'x', 'x', 'x', 'x', 'x'};
1019     DWORD ret;
1020     CHAR out[5];
1021
1022     SetLastError(0xdeadbeef);
1023     memcpy(out, init_buf, sizeof(init_buf));
1024     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, "test", 0, 0, out, 0, NULL);
1025     ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
1026     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
1027        "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n",
1028        GetLastError());
1029     ok(!memcmp(expected_buf, out, sizeof(expected_buf)),
1030        "Expected the buffer to be untouched\n");
1031
1032     SetLastError(0xdeadbeef);
1033     memcpy(out, init_buf, sizeof(init_buf));
1034     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, "test", 0, 0, out, 1, NULL);
1035     ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
1036     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
1037        "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n",
1038        GetLastError());
1039     ok(!memcmp(expected_buf, out, sizeof(expected_buf)),
1040        "Expected the buffer to be untouched\n");
1041
1042     SetLastError(0xdeadbeef);
1043     memcpy(out, init_buf, sizeof(init_buf));
1044     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, "test", 0, 0, out, sizeof(out)/sizeof(out[0]) - 1, NULL);
1045     ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
1046     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
1047        "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n",
1048        GetLastError());
1049     ok(!memcmp(expected_buf, out, sizeof(expected_buf)),
1050        "Expected the buffer to be untouched\n");
1051 }
1052
1053 static void test_message_insufficient_buffer_wide(void)
1054 {
1055     static const WCHAR test[] = {'t','e','s','t',0};
1056     static const WCHAR init_buf[] = {'x', 'x', 'x', 'x', 'x'};
1057     static const WCHAR expected_buf[] = {'x', 'x', 'x', 'x', 'x'};
1058     static const WCHAR broken_buf[] = {0, 'x', 'x', 'x', 'x'};
1059     static const WCHAR broken2_buf[] = {'t','e','s',0,'x'};
1060
1061     DWORD ret;
1062     WCHAR out[5];
1063
1064     SetLastError(0xdeadbeef);
1065     memcpy(out, init_buf, sizeof(init_buf));
1066     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, test, 0, 0, out, 0, NULL);
1067     ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
1068     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
1069        "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n",
1070        GetLastError());
1071     ok(!memcmp(expected_buf, out, sizeof(expected_buf)),
1072        "Expected the buffer to be untouched\n");
1073
1074     /* Windows Server 2003 and newer report failure but copy a
1075      * truncated string to the buffer for non-zero buffer sizes. */
1076     SetLastError(0xdeadbeef);
1077     memcpy(out, init_buf, sizeof(init_buf));
1078     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, test, 0, 0, out, 1, NULL);
1079     ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
1080     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
1081        "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n",
1082        GetLastError());
1083     ok(!memcmp(expected_buf, out, sizeof(expected_buf)) ||
1084        broken(!memcmp(broken_buf, out, sizeof(broken_buf))), /* W2K3+ */
1085        "Expected the buffer to be untouched\n");
1086
1087     SetLastError(0xdeadbeef);
1088     memcpy(out, init_buf, sizeof(init_buf));
1089     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, test, 0, 0, out, sizeof(out)/sizeof(out[0]) - 1, NULL);
1090     ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
1091     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
1092        "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n",
1093        GetLastError());
1094     ok(!memcmp(expected_buf, out, sizeof(expected_buf)) ||
1095        broken(!memcmp(broken2_buf, out, sizeof(broken2_buf))), /* W2K3+ */
1096        "Expected the buffer to be untouched\n");
1097 }
1098
1099 static void test_message_null_buffer(void)
1100 {
1101     DWORD ret, error;
1102
1103     /* Without FORMAT_MESSAGE_ALLOCATE_BUFFER, only the specified buffer size is checked. */
1104     SetLastError(0xdeadbeef);
1105     ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, 0, 0, NULL, 0, NULL);
1106     error = GetLastError();
1107     ok(!ret, "FormatMessageA returned %u\n", ret);
1108     ok(error == ERROR_INSUFFICIENT_BUFFER ||
1109        error == ERROR_INVALID_PARAMETER, /* win9x */
1110        "last error %u\n", error);
1111
1112     SetLastError(0xdeadbeef);
1113     ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, 0, 0, NULL, 1, NULL);
1114     error = GetLastError();
1115     ok(!ret, "FormatMessageA returned %u\n", ret);
1116     ok(error == ERROR_INSUFFICIENT_BUFFER ||
1117        error == ERROR_INVALID_PARAMETER, /* win9x */
1118        "last error %u\n", error);
1119
1120     if (0) /* crashes on Windows */
1121     {
1122         SetLastError(0xdeadbeef);
1123         FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, 0, 0, NULL, 256, NULL);
1124     }
1125
1126     SetLastError(0xdeadbeef);
1127     ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, 0, 0, NULL, 0, NULL);
1128     error = GetLastError();
1129     ok(!ret, "FormatMessageA returned %u\n", ret);
1130     ok(error == ERROR_NOT_ENOUGH_MEMORY ||
1131        error == ERROR_INVALID_PARAMETER, /* win9x */
1132        "last error %u\n", error);
1133
1134     SetLastError(0xdeadbeef);
1135     ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, 0, 0, NULL, 1, NULL);
1136     error = GetLastError();
1137     ok(!ret, "FormatMessageA returned %u\n", ret);
1138     ok(error == ERROR_NOT_ENOUGH_MEMORY ||
1139        error == ERROR_INVALID_PARAMETER, /* win9x */
1140        "last error %u\n", error);
1141
1142     SetLastError(0xdeadbeef);
1143     ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, 0, 0, NULL, 256, NULL);
1144     error = GetLastError();
1145     ok(!ret, "FormatMessageA returned %u\n", ret);
1146     ok(error == ERROR_NOT_ENOUGH_MEMORY ||
1147        error == ERROR_INVALID_PARAMETER, /* win9x */
1148        "last error %u\n", error);
1149 }
1150
1151 static void test_message_null_buffer_wide(void)
1152 {
1153     DWORD ret, error;
1154
1155     SetLastError(0xdeadbeef);
1156     ret = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, 0, 0, NULL, 0, NULL);
1157     error = GetLastError();
1158     ok(!ret, "FormatMessageW returned %u\n", ret);
1159     ok(error == ERROR_INVALID_PARAMETER, "last error %u\n", error);
1160
1161     SetLastError(0xdeadbeef);
1162     ret = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, 0, 0, NULL, 1, NULL);
1163     error = GetLastError();
1164     ok(!ret, "FormatMessageW returned %u\n", ret);
1165     ok(error == ERROR_INVALID_PARAMETER, "last error %u\n", error);
1166
1167     SetLastError(0xdeadbeef);
1168     ret = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, 0, 0, NULL, 256, NULL);
1169     error = GetLastError();
1170     ok(!ret, "FormatMessageW returned %u\n", ret);
1171     ok(error == ERROR_INVALID_PARAMETER, "last error %u\n", error);
1172
1173     SetLastError(0xdeadbeef);
1174     ret = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, 0, 0, NULL, 0, NULL);
1175     error = GetLastError();
1176     ok(!ret, "FormatMessageW returned %u\n", ret);
1177     ok(error == ERROR_INVALID_PARAMETER, "last error %u\n", error);
1178
1179     SetLastError(0xdeadbeef);
1180     ret = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, 0, 0, NULL, 1, NULL);
1181     error = GetLastError();
1182     ok(!ret, "FormatMessageW returned %u\n", ret);
1183     ok(error == ERROR_INVALID_PARAMETER, "last error %u\n", error);
1184
1185     SetLastError(0xdeadbeef);
1186     ret = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, 0, 0, NULL, 256, NULL);
1187     error = GetLastError();
1188     ok(!ret, "FormatMessageW returned %u\n", ret);
1189     ok(error == ERROR_INVALID_PARAMETER, "last error %u\n", error);
1190 }
1191
1192 static void test_message_allocate_buffer(void)
1193 {
1194     DWORD ret;
1195     char *buf;
1196
1197     /* While MSDN suggests that FormatMessageA allocates a buffer whose size is
1198      * the larger of the output string and the requested buffer size, the tests
1199      * will not try to determine the actual size of the buffer allocated, as
1200      * the return value of LocalSize cannot be trusted for the purpose, and it should
1201      * in any case be safe for FormatMessageA to allocate in the manner that
1202      * MSDN suggests. */
1203
1204     SetLastError(0xdeadbeef);
1205     buf = (char *)0xdeadbeef;
1206     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
1207                          "", 0, 0, (char *)&buf, 0, NULL);
1208     ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
1209     ok(buf == NULL, "Expected output buffer pointer to be NULL\n");
1210     ok(GetLastError() == 0xdeadbeef,
1211        "Expected last error to be untouched, got %u\n", GetLastError());
1212
1213     buf = (char *)0xdeadbeef;
1214     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
1215                          "test", 0, 0, (char *)&buf, 0, NULL);
1216     ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
1217     ok(buf != NULL && buf != (char *)0xdeadbeef,
1218        "Expected output buffer pointer to be valid\n");
1219     if (buf != NULL && buf != (char *)0xdeadbeef)
1220     {
1221         ok(!strcmp("test", buf),
1222            "Expected buffer to contain \"test\", got %s\n", buf);
1223         LocalFree(buf);
1224     }
1225
1226     buf = (char *)0xdeadbeef;
1227     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
1228                          "test", 0, 0, (char *)&buf, strlen("test"), NULL);
1229     ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
1230     ok(buf != NULL && buf != (char *)0xdeadbeef,
1231        "Expected output buffer pointer to be valid\n");
1232     if (buf != NULL && buf != (char *)0xdeadbeef)
1233     {
1234         ok(!strcmp("test", buf),
1235            "Expected buffer to contain \"test\", got %s\n", buf);
1236         LocalFree(buf);
1237     }
1238
1239     buf = (char *)0xdeadbeef;
1240     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
1241                          "test", 0, 0, (char *)&buf, strlen("test") + 1, NULL);
1242     ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
1243     ok(buf != NULL && buf != (char *)0xdeadbeef,
1244        "Expected output buffer pointer to be valid\n");
1245    if (buf != NULL && buf != (char *)0xdeadbeef)
1246     {
1247         ok(!strcmp("test", buf),
1248            "Expected buffer to contain \"test\", got %s\n", buf);
1249         LocalFree(buf);
1250     }
1251
1252     buf = (char *)0xdeadbeef;
1253     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
1254                          "test", 0, 0, (char *)&buf, strlen("test") + 2, NULL);
1255     ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
1256     ok(buf != NULL && buf != (char *)0xdeadbeef,
1257        "Expected output buffer pointer to be valid\n");
1258     if (buf != NULL && buf != (char *)0xdeadbeef)
1259     {
1260         ok(!strcmp("test", buf),
1261            "Expected buffer to contain \"test\", got %s\n", buf);
1262         LocalFree(buf);
1263     }
1264
1265     buf = (char *)0xdeadbeef;
1266     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
1267                          "test", 0, 0, (char *)&buf, 1024, NULL);
1268     ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
1269     ok(buf != NULL && buf != (char *)0xdeadbeef,
1270        "Expected output buffer pointer to be valid\n");
1271     if (buf != NULL && buf != (char *)0xdeadbeef)
1272     {
1273         ok(!strcmp("test", buf),
1274            "Expected buffer to contain \"test\", got %s\n", buf);
1275         LocalFree(buf);
1276     }
1277 }
1278
1279 static void test_message_allocate_buffer_wide(void)
1280 {
1281     static const WCHAR empty[] = {0};
1282     static const WCHAR test[] = {'t','e','s','t',0};
1283
1284     DWORD ret;
1285     WCHAR *buf;
1286
1287     /* While MSDN suggests that FormatMessageW allocates a buffer whose size is
1288      * the larger of the output string and the requested buffer size, the tests
1289      * will not try to determine the actual size of the buffer allocated, as
1290      * the return value of LocalSize cannot be trusted for the purpose, and it should
1291      * in any case be safe for FormatMessageW to allocate in the manner that
1292      * MSDN suggests. */
1293
1294     if (0) /* crashes on Windows */
1295     {
1296         buf = (WCHAR *)0xdeadbeef;
1297         FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
1298                              NULL, 0, 0, (WCHAR *)&buf, 0, NULL);
1299     }
1300
1301     SetLastError(0xdeadbeef);
1302     buf = (WCHAR *)0xdeadbeef;
1303     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
1304                          empty, 0, 0, (WCHAR *)&buf, 0, NULL);
1305     ok(ret == 0, "Expected FormatMessageW to return 0, got %u\n", ret);
1306     ok(buf == NULL, "Expected output buffer pointer to be NULL\n");
1307     ok(GetLastError() == 0xdeadbeef,
1308        "Expected last error to be untouched, got %u\n", GetLastError());
1309
1310     buf = (WCHAR *)0xdeadbeef;
1311     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
1312                          test, 0, 0, (WCHAR *)&buf, 0, NULL);
1313     ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
1314     ok(buf != NULL && buf != (WCHAR *)0xdeadbeef,
1315        "Expected output buffer pointer to be valid\n");
1316     if (buf != NULL && buf != (WCHAR *)0xdeadbeef)
1317     {
1318         ok(!lstrcmpW(test, buf),
1319            "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf));
1320         LocalFree(buf);
1321     }
1322
1323     buf = (WCHAR *)0xdeadbeef;
1324     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
1325                          test, 0, 0, (WCHAR *)&buf, sizeof(test)/sizeof(WCHAR) - 1, NULL);
1326     ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
1327     ok(buf != NULL && buf != (WCHAR *)0xdeadbeef,
1328        "Expected output buffer pointer to be valid\n");
1329     if (buf != NULL && buf != (WCHAR *)0xdeadbeef)
1330     {
1331         ok(!lstrcmpW(test, buf),
1332            "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf));
1333         LocalFree(buf);
1334     }
1335
1336     buf = (WCHAR *)0xdeadbeef;
1337     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
1338                          test, 0, 0, (WCHAR *)&buf, sizeof(test)/sizeof(WCHAR), NULL);
1339     ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
1340     ok(buf != NULL && buf != (WCHAR *)0xdeadbeef,
1341        "Expected output buffer pointer to be valid\n");
1342     if (buf != NULL && buf != (WCHAR *)0xdeadbeef)
1343     {
1344         ok(!lstrcmpW(test, buf),
1345            "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf));
1346         LocalFree(buf);
1347     }
1348
1349     buf = (WCHAR *)0xdeadbeef;
1350     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
1351                          test, 0, 0, (WCHAR *)&buf, sizeof(test)/sizeof(WCHAR) + 1, NULL);
1352     ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
1353     ok(buf != NULL && buf != (WCHAR *)0xdeadbeef,
1354        "Expected output buffer pointer to be valid\n");
1355     if (buf != NULL && buf != (WCHAR *)0xdeadbeef)
1356     {
1357         ok(!lstrcmpW(test, buf),
1358            "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf));
1359         LocalFree(buf);
1360     }
1361
1362     buf = (WCHAR *)0xdeadbeef;
1363     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
1364                          test, 0, 0, (WCHAR *)&buf, 1024, NULL);
1365     ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
1366     ok(buf != NULL && buf != (WCHAR *)0xdeadbeef,
1367        "Expected output buffer pointer to be valid\n");
1368     if (buf != NULL && buf != (WCHAR *)0xdeadbeef)
1369     {
1370         ok(!lstrcmpW(test, buf),
1371            "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf));
1372         LocalFree(buf);
1373     }
1374 }
1375
1376 static void test_message_from_hmodule(void)
1377 {
1378     DWORD ret, error;
1379     HMODULE h;
1380     CHAR out[0x100] = {0};
1381
1382     h = GetModuleHandle("kernel32.dll");
1383     ok(h != 0, "GetModuleHandle failed\n");
1384
1385     /*Test existing messageID; as the message strings from wine's kernel32 differ from windows' kernel32 we don't compare
1386     the strings but only test that FormatMessage doesn't return 0*/
1387     ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 7/*=ERROR_ARENA_TRASHED*/,
1388                          MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), out, sizeof(out)/sizeof(CHAR), NULL);
1389     ok(ret != 0, "FormatMessageA returned 0\n");
1390
1391     /* Test a message string with an insertion without passing any variadic arguments. */
1392     ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 193 /* ERROR_BAD_EXE_FORMAT */,
1393                          MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), out, sizeof(out)/sizeof(CHAR), NULL);
1394     ok(ret == 0 ||
1395        broken(ret != 0), /* Win9x */
1396        "FormatMessageA returned non-zero\n");
1397
1398     ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE |
1399                          FORMAT_MESSAGE_ARGUMENT_ARRAY, h, 193 /* ERROR_BAD_EXE_FORMAT */,
1400                          MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), out, sizeof(out)/sizeof(CHAR), NULL);
1401     ok(ret == 0 ||
1402        broken(ret != 0), /* Win9x */
1403        "FormatMessageA returned non-zero\n");
1404
1405     /*Test nonexistent messageID with varying language ID's Note: FormatMessageW behaves the same*/
1406     SetLastError(0xdeadbeef);
1407     ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 3044,
1408                          MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), out, sizeof(out)/sizeof(CHAR), NULL);
1409     error = GetLastError();
1410     ok(ret == 0, "FormatMessageA returned %u instead of 0\n", ret);
1411     ok(error == ERROR_MR_MID_NOT_FOUND || error == ERROR_MUI_FILE_NOT_FOUND, "last error %u\n", error);
1412
1413     SetLastError(0xdeadbeef);
1414     ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 3044,
1415                          MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), out, sizeof(out)/sizeof(CHAR), NULL);
1416     error = GetLastError();
1417     ok(ret == 0, "FormatMessageA returned %u instead of 0\n", ret);
1418     ok(error == ERROR_MR_MID_NOT_FOUND || error == ERROR_MUI_FILE_NOT_LOADED, "last error %u\n", error);
1419
1420     SetLastError(0xdeadbeef);
1421     ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 3044,
1422                          MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT), out, sizeof(out)/sizeof(CHAR), NULL);
1423     error = GetLastError();
1424     ok(ret == 0, "FormatMessageA returned %u instead of 0\n", ret);
1425     ok(error == ERROR_MR_MID_NOT_FOUND || error == ERROR_MUI_FILE_NOT_LOADED, "last error %u\n", error);
1426
1427     SetLastError(0xdeadbeef);
1428     ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 3044,
1429                          MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), out, sizeof(out)/sizeof(CHAR), NULL);
1430     error = GetLastError();
1431     ok(ret == 0, "FormatMessageA returned %u instead of 0\n", ret);
1432     ok(error == ERROR_RESOURCE_LANG_NOT_FOUND ||
1433        error == ERROR_MR_MID_NOT_FOUND ||
1434        error == ERROR_MUI_FILE_NOT_FOUND ||
1435        error == ERROR_MUI_FILE_NOT_LOADED,
1436        "last error %u\n", error);
1437
1438     SetLastError(0xdeadbeef);
1439     ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 3044,
1440                          MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_UK), out, sizeof(out)/sizeof(CHAR), NULL);
1441     error = GetLastError();
1442     ok(ret == 0, "FormatMessageA returned %u instead of 0\n", ret);
1443     ok(error == ERROR_RESOURCE_LANG_NOT_FOUND ||
1444        error == ERROR_MR_MID_NOT_FOUND ||
1445        error == ERROR_MUI_FILE_NOT_FOUND ||
1446        error == ERROR_MUI_FILE_NOT_LOADED,
1447        "last error %u\n", error);
1448 }
1449
1450 static void test_message_invalid_flags(void)
1451 {
1452     static const char init_buf[] = {'x', 'x', 'x', 'x', 'x'};
1453
1454     DWORD ret;
1455     CHAR out[5];
1456     char *ptr;
1457
1458     SetLastError(0xdeadbeef);
1459     memcpy(out, init_buf, sizeof(init_buf));
1460     ret = FormatMessageA(0, "test", 0, 0, out, sizeof(out)/sizeof(CHAR), NULL);
1461     ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
1462     ok(!memcmp(out, init_buf, sizeof(init_buf)),
1463        "Expected the output buffer to be untouched\n");
1464     ok(GetLastError() == ERROR_INVALID_PARAMETER,
1465        "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1466        GetLastError());
1467
1468     SetLastError(0xdeadbeef);
1469     ptr = (char *)0xdeadbeef;
1470     ret = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER, "test", 0, 0, (char *)&ptr, 0, NULL);
1471     ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
1472     ok(ptr == NULL ||
1473        broken(ptr == (char *)0xdeadbeef), /* Win9x */
1474        "Expected output pointer to be initialized to NULL, got %p\n", ptr);
1475     ok(GetLastError() == ERROR_INVALID_PARAMETER,
1476        "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1477        GetLastError());
1478
1479     SetLastError(0xdeadbeef);
1480     memcpy(out, init_buf, sizeof(init_buf));
1481     ret = FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS, "test", 0, 0, out, sizeof(out)/sizeof(CHAR), NULL);
1482     ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
1483     ok(!memcmp(out, init_buf, sizeof(init_buf)),
1484        "Expected the output buffer to be untouched\n");
1485     ok(GetLastError() == ERROR_INVALID_PARAMETER,
1486        "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1487        GetLastError());
1488
1489     SetLastError(0xdeadbeef);
1490     memcpy(out, init_buf, sizeof(init_buf));
1491     ret = FormatMessageA(FORMAT_MESSAGE_ARGUMENT_ARRAY, "test", 0, 0, out, sizeof(out)/sizeof(CHAR), NULL);
1492     ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
1493     ok(!memcmp(out, init_buf, sizeof(init_buf)),
1494        "Expected the output buffer to be untouched\n");
1495     ok(GetLastError() == ERROR_INVALID_PARAMETER,
1496        "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1497        GetLastError());
1498
1499     SetLastError(0xdeadbeef);
1500     memcpy(out, init_buf, sizeof(init_buf));
1501     ret = FormatMessageA(FORMAT_MESSAGE_MAX_WIDTH_MASK, "test", 0, 0, out, sizeof(out)/sizeof(CHAR), NULL);
1502     ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
1503     ok(!memcmp(out, init_buf, sizeof(init_buf)),
1504        "Expected the output buffer to be untouched\n");
1505     ok(GetLastError() == ERROR_INVALID_PARAMETER,
1506        "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1507        GetLastError());
1508
1509     /* Simultaneously setting FORMAT_MESSAGE_FROM_STRING with other source
1510      * flags is apparently permissible, and FORMAT_MESSAGE_FROM_STRING takes
1511      * precedence in this case. */
1512
1513     memcpy(out, init_buf, sizeof(init_buf));
1514     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_FROM_SYSTEM,
1515                          "test", 0, 0, out, sizeof(out)/sizeof(CHAR), NULL);
1516     ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
1517     ok(!strcmp("test", out),
1518        "Expected the output buffer to be untouched\n");
1519
1520     memcpy(out, init_buf, sizeof(init_buf));
1521     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_FROM_HMODULE,
1522                          "test", 0, 0, out, sizeof(out)/sizeof(CHAR), NULL);
1523     ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
1524     ok(!strcmp("test", out),
1525        "Expected the output buffer to be untouched\n");
1526
1527     memcpy(out, init_buf, sizeof(init_buf));
1528     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_FROM_HMODULE |
1529                          FORMAT_MESSAGE_FROM_SYSTEM, "test", 0, 0, out,
1530                          sizeof(out)/sizeof(CHAR), NULL);
1531     ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
1532     ok(!strcmp("test", out),
1533        "Expected the output buffer to be untouched\n");
1534 }
1535
1536 static void test_message_invalid_flags_wide(void)
1537 {
1538     static const WCHAR init_buf[] = {'x', 'x', 'x', 'x', 'x'};
1539     static const WCHAR test[] = {'t','e','s','t',0};
1540
1541     DWORD ret;
1542     WCHAR out[5];
1543     WCHAR *ptr;
1544
1545     SetLastError(0xdeadbeef);
1546     memcpy(out, init_buf, sizeof(init_buf));
1547     ret = FormatMessageW(0, test, 0, 0, out, sizeof(out)/sizeof(WCHAR), NULL);
1548     ok(ret == 0, "Expected FormatMessageW to return 0, got %u\n", ret);
1549     ok(!memcmp(out, init_buf, sizeof(init_buf)),
1550        "Expected the output buffer to be untouched\n");
1551     ok(GetLastError() == ERROR_INVALID_PARAMETER,
1552        "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1553        GetLastError());
1554
1555     SetLastError(0xdeadbeef);
1556     ptr = (WCHAR *)0xdeadbeef;
1557     ret = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER, test, 0, 0, (WCHAR *)&ptr, 0, NULL);
1558     ok(ret == 0, "Expected FormatMessageW to return 0, got %u\n", ret);
1559     ok(ptr == NULL, "Expected output pointer to be initialized to NULL, got %p\n", ptr);
1560     ok(GetLastError() == ERROR_INVALID_PARAMETER,
1561        "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1562        GetLastError());
1563
1564     SetLastError(0xdeadbeef);
1565     memcpy(out, init_buf, sizeof(init_buf));
1566     ret = FormatMessageW(FORMAT_MESSAGE_IGNORE_INSERTS, test, 0, 0, out, sizeof(out)/sizeof(WCHAR), NULL);
1567     ok(ret == 0, "Expected FormatMessageW to return 0, got %u\n", ret);
1568     ok(!memcmp(out, init_buf, sizeof(init_buf)),
1569        "Expected the output buffer to be untouched\n");
1570     ok(GetLastError() == ERROR_INVALID_PARAMETER,
1571        "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1572        GetLastError());
1573
1574     SetLastError(0xdeadbeef);
1575     memcpy(out, init_buf, sizeof(init_buf));
1576     ret = FormatMessageW(FORMAT_MESSAGE_ARGUMENT_ARRAY, test, 0, 0, out, sizeof(out)/sizeof(WCHAR), NULL);
1577     ok(ret == 0, "Expected FormatMessageW to return 0, got %u\n", ret);
1578     ok(!memcmp(out, init_buf, sizeof(init_buf)),
1579        "Expected the output buffer to be untouched\n");
1580     ok(GetLastError() == ERROR_INVALID_PARAMETER,
1581        "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1582        GetLastError());
1583
1584     SetLastError(0xdeadbeef);
1585     memcpy(out, init_buf, sizeof(init_buf));
1586     ret = FormatMessageW(FORMAT_MESSAGE_MAX_WIDTH_MASK, test, 0, 0, out, sizeof(out)/sizeof(WCHAR), NULL);
1587     ok(ret == 0, "Expected FormatMessageW to return 0, got %u\n", ret);
1588     ok(!memcmp(out, init_buf, sizeof(init_buf)),
1589        "Expected the output buffer to be untouched\n");
1590     ok(GetLastError() == ERROR_INVALID_PARAMETER,
1591        "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1592        GetLastError());
1593
1594     /* Simultaneously setting FORMAT_MESSAGE_FROM_STRING with other source
1595      * flags is apparently permissible, and FORMAT_MESSAGE_FROM_STRING takes
1596      * precedence in this case. */
1597
1598     memcpy(out, init_buf, sizeof(init_buf));
1599     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_FROM_SYSTEM,
1600                          test, 0, 0, out, sizeof(out)/sizeof(WCHAR), NULL);
1601     ok(ret == 4, "Expected FormatMessageW to return 4, got %u\n", ret);
1602     ok(!lstrcmpW(test, out),
1603        "Expected the output buffer to be untouched\n");
1604
1605     memcpy(out, init_buf, sizeof(init_buf));
1606     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_FROM_HMODULE,
1607                          test, 0, 0, out, sizeof(out)/sizeof(WCHAR), NULL);
1608     ok(ret == 4, "Expected FormatMessageW to return 4, got %u\n", ret);
1609     ok(!lstrcmpW(test, out),
1610        "Expected the output buffer to be untouched\n");
1611
1612     memcpy(out, init_buf, sizeof(init_buf));
1613     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_FROM_HMODULE |
1614                          FORMAT_MESSAGE_FROM_SYSTEM, test, 0, 0, out,
1615                          sizeof(out)/sizeof(WCHAR), NULL);
1616     ok(ret == 4, "Expected FormatMessageW to return 4, got %u\n", ret);
1617     ok(!lstrcmpW(test, out),
1618        "Expected the output buffer to be untouched\n");
1619 }
1620
1621 START_TEST(format_msg)
1622 {
1623     DWORD ret;
1624
1625     test_message_from_string();
1626     test_message_ignore_inserts();
1627     test_message_insufficient_buffer();
1628     test_message_null_buffer();
1629     test_message_allocate_buffer();
1630     test_message_from_hmodule();
1631     test_message_invalid_flags();
1632
1633     SetLastError(0xdeadbeef);
1634     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, NULL, 0, 0, NULL, 0, NULL);
1635     if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1636     {
1637         win_skip("FormatMessageW is not implemented\n");
1638         return;
1639     }
1640
1641     test_message_from_string_wide();
1642     test_message_ignore_inserts_wide();
1643     test_message_insufficient_buffer_wide();
1644     test_message_null_buffer_wide();
1645     test_message_allocate_buffer_wide();
1646     test_message_invalid_flags_wide();
1647 }