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