kernel32: Update the Dutch (Suriname) NLS file.
[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 te[]          = {'t','e',0};
57     static const WCHAR st[]          = {'s','t',0};
58     static const WCHAR t[]           = {'t',0};
59     static const WCHAR e[]           = {'e',0};
60     static const WCHAR s[]           = {'s',0};
61     static const WCHAR fmt_1[]       = {'%','1',0};
62     static const WCHAR fmt_12[]      = {'%','1','%','2',0};
63     static const WCHAR fmt_123[]     = {'%','1','%','3','%','2','%','1',0};
64     static const WCHAR fmt_123c[]    = {'%','1','!','c','!','%','2','!','c','!','%','3','!','c','!','%','1','!','c','!',0};
65     static const WCHAR fmt_123lc[]   = {'%','1','!','l','c','!','%','2','!','l','c','!','%','3','!','l','c','!','%','1','!','l','c','!',0};
66     static const WCHAR fmt_123wc[]   = {'%','1','!','w','c','!','%','2','!','w','c','!','%','3','!','w','c','!','%','1','!','w','c','!',0};
67     static const WCHAR fmt_123C[]    = {'%','1','!','C','!','%','2','!','C','!','%','3','!','C','!','%','1','!','C','!',0};
68     static const WCHAR fmt_123d[]    = {'%','1','!','d','!','%','2','!','d','!','%','3','!','d','!',0};
69     static const WCHAR fmt_1s[]      = {'%','1','!','s','!',0};
70     static const WCHAR fmt_s[]       = {'%','!','s','!',0};
71     static const WCHAR fmt_ls[]      = {'%','!','l','s','!',0};
72     static const WCHAR fmt_ws[]      = {'%','!','w','s','!',0};
73     static const WCHAR fmt_S[]       = {'%','!','S','!',0};
74     static const WCHAR fmt_14d[]     = {'%','1','!','4','d','!',0};
75     static const WCHAR fmt_14x[]     = {'%','1','!','4','x','!',0};
76     static const WCHAR fmt_14X[]     = {'%','1','!','4','X','!',0};
77     static const WCHAR fmt_1_4X[]    = {'%','1','!','-','4','X','!',0};
78     static const WCHAR fmt_1_4d[]    = {'%','1','!','-','4','d','!',0};
79     static const WCHAR fmt_2pct[]    = {' ','%','%','%','%',' ',0};
80     static const WCHAR fmt_2dot1d[]  = {' ', '%','.','%','.',' ',' ','%','1','!','d','!',0};
81     static const WCHAR fmt_t0t[]     = {'t','e','s','t','%','0','t','e','s','t',0};
82     static const WCHAR fmt_yah[]     = {'y','a','h','%','!','%','0',' ',' ',' ',0};
83     static const WCHAR fmt_space[]   = {'%',' ','%',' ',' ',' ',0};
84     static const WCHAR fmt_hi_lf[]   = {'h','i','\n',0};
85     static const WCHAR fmt_hi_crlf[] = {'h','i','\r','\n',0};
86     static const WCHAR fmt_cr[]      = {'\r',0};
87     static const WCHAR fmt_crcrlf[]  = {'\r','\r','\n',0};
88     static const WCHAR fmt_13s[]     = {'%','1','!','3','s','!',0};
89     static const WCHAR fmt_1os[]     = {'%','1','!','*','s','!',0};
90     static const WCHAR fmt_142u[]    = {'%','1','!','4','.','2','u','!',0};
91     static const WCHAR fmt_1oou[]    = {'%','1','!','*','.','*','u','!',0};
92     static const WCHAR fmt_1oou1oou[] = {'%','1','!','*','.','*','u','!',',','%','1','!','*','.','*','u','!',0};
93     static const WCHAR fmt_1oou3oou[] = {'%','1','!','*','.','*','u','!',',','%','3','!','*','.','*','u','!',0};
94     static const WCHAR fmt_1oou4oou[] = {'%','1','!','*','.','*','u','!',',','%','4','!','*','.','*','u','!',0};
95
96     static const WCHAR s_123d[]      = {'1','2','3',0};
97     static const WCHAR s_14d[]       = {' ',' ',' ','1',0};
98     static const WCHAR s_14x[]       = {' ',' ',' ','b',0};
99     static const WCHAR s_14X[]       = {' ',' ',' ','B',0};
100     static const WCHAR s_1_4X[]      = {'B',' ',' ',' ',0};
101     static const WCHAR s_14d2[]      = {' ',' ','1','1',0};
102     static const WCHAR s_1_4d[]      = {'1',' ',' ',' ',0};
103     static const WCHAR s_1AB[]       = {' ','1','A','B',0};
104     static const WCHAR s_2pct[]      = {' ','%','%',' ',0};
105     static const WCHAR s_2dot147[]   = {' ','.','.',' ',' ','4','2','7',0};
106     static const WCHAR s_yah[]       = {'y','a','h','!',0};
107     static const WCHAR s_space[]     = {' ',' ',' ',' ',0};
108     static const WCHAR s_hi_crlf[]   = {'h','i','\r','\n',0};
109     static const WCHAR s_crlf[]      = {'\r','\n',0};
110     static const WCHAR s_crlfcrlf[]  = {'\r','\n','\r','\n',0};
111     static const WCHAR s_hi_sp[]     = {'h','i',' ',0};
112     static const WCHAR s_sp[]        = {' ',0};
113     static const WCHAR s_2sp[]       = {' ',' ',0};
114     static const WCHAR s_spt[]       = {' ',' ','t',0};
115     static const WCHAR s_sp3t[]      = {' ',' ',' ','t',0};
116     static const WCHAR s_sp03[]      = {' ',' ','0','3',0};
117     static const WCHAR s_sp001[]     = {' ',' ','0','0','1',0};
118     static const WCHAR s_sp001002[]  = {' ',' ','0','0','1',',',' ','0','0','0','2',0};
119     static const WCHAR s_sp001sp002[] = {' ',' ','0','0','1',',',' ',' ','0','0','0','2',0};
120     static const WCHAR s_sp002sp001[] = {' ',' ','0','0','0','2',',',' ',' ','0','0','1',0};
121     static const WCHAR s_sp002sp003[] = {' ',' ','0','0','0','2',',',' ','0','0','0','0','3',0};
122     static const WCHAR s_sp001004[]   = {' ',' ','0','0','1',',','0','0','0','0','0','4',0};
123
124     WCHAR out[0x100] = {0};
125     DWORD r, error;
126
127     SetLastError(0xdeadbeef);
128     r = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, NULL, 0, 0, NULL, 0, NULL);
129     error = GetLastError();
130     if (!r && error == ERROR_CALL_NOT_IMPLEMENTED)
131     {
132         win_skip("FormatMessageW is not implemented\n");
133         return;
134     }
135
136     /* the basics */
137     r = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, test, 0,
138         0, out, sizeof(out)/sizeof(WCHAR), NULL);
139     ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out));
140     ok(r==4, "failed: r=%d\n", r);
141
142     /* using the format feature */
143     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1s, 0,
144         0, out, sizeof(out)/sizeof(WCHAR), test);
145     ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out));
146     ok(r==4,"failed: r=%d\n", r);
147
148     /* no format */
149     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1, 0,
150         0, out, sizeof(out)/sizeof(WCHAR), test);
151     ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out));
152     ok(r==4,"failed: r=%d\n", r);
153
154     /* two pieces */
155     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_12, 0,
156         0, out, sizeof(out)/sizeof(WCHAR), te, st);
157     ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out));
158     ok(r==4,"failed: r=%d\n", r);
159
160     /* three pieces */
161     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_123, 0,
162         0, out, sizeof(out)/sizeof(WCHAR), t, s, e);
163     ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out));
164     ok(r==4,"failed: r=%d\n", r);
165
166     /* s doesn't seem to work in format strings */
167     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_s, 0,
168         0, out, sizeof(out)/sizeof(WCHAR), test);
169     ok(!lstrcmpW(&fmt_s[1], out), "failed out=%s\n", wine_dbgstr_w(out));
170     ok(r==3, "failed: r=%d\n", r);
171
172     /* nor ls */
173     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_ls, 0,
174         0, out, sizeof(out)/sizeof(WCHAR), test);
175     ok(!lstrcmpW(&fmt_ls[1], out), "failed out=%s\n", wine_dbgstr_w(out));
176     ok(r==4, "failed: r=%d\n", r);
177
178     /* nor S */
179     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_S, 0,
180         0, out, sizeof(out)/sizeof(WCHAR), test);
181     ok(!lstrcmpW(&fmt_S[1], out), "failed out=%s\n", wine_dbgstr_w(out));
182     ok(r==3, "failed: r=%d\n", r);
183
184     /* nor ws */
185     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_ws, 0,
186         0, out, sizeof(out)/sizeof(WCHAR), test);
187     ok(!lstrcmpW(&fmt_ws[1], out), "failed out=%s\n", wine_dbgstr_w(out));
188     ok(r==4, "failed: r=%d\n", r);
189
190     /* as characters */
191     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_123c, 0,
192         0, out, sizeof(out)/sizeof(WCHAR), 't', 'e', 's');
193     ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out));
194     ok(r==4,"failed: r=%d\n", r);
195
196     /* lc is unicode */
197     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_123lc, 0,
198         0, out, sizeof(out)/sizeof(WCHAR), 't', 'e', 's');
199     ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out));
200     ok(r==4,"failed: r=%d\n", r);
201
202     /* wc is unicode */
203     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_123wc, 0,
204         0, out, sizeof(out)/sizeof(WCHAR), 't', 'e', 's');
205     ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out));
206     ok(r==4,"failed: r=%d\n", r);
207
208     /* C is unicode */
209     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_123C, 0,
210         0, out, sizeof(out)/sizeof(WCHAR), 't', 'e', 's');
211     ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out));
212     ok(r==4,"failed: r=%d\n", r);
213
214     /* some numbers */
215     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_123d, 0,
216         0, out, sizeof(out)/sizeof(WCHAR), 1, 2, 3);
217     ok(!lstrcmpW(s_123d, out), "failed out=%s\n", wine_dbgstr_w(out));
218     ok(r==3,"failed: r=%d\n", r);
219
220     /* a single digit with some spacing */
221     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_14d, 0,
222         0, out, sizeof(out)/sizeof(WCHAR), 1);
223     ok(!lstrcmpW(s_14d, out), "failed out=%s\n", wine_dbgstr_w(out));
224
225     /* a single digit, left justified */
226     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1_4d, 0,
227         0, out, sizeof(out)/sizeof(CHAR), 1);
228     ok(!lstrcmpW(s_1_4d, out), "failed out=%s\n", wine_dbgstr_w(out));
229     ok(r==4,"failed: r=%d\n", r);
230
231     /* two digit decimal number */
232     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_14d, 0,
233         0, out, sizeof(out)/sizeof(WCHAR), 11);
234     ok(!lstrcmpW(s_14d2, out), "failed out=%s\n", wine_dbgstr_w(out));
235     ok(r==4,"failed: r=%d\n", r);
236
237     /* a hex number */
238     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_14x, 0,
239         0, out, sizeof(out)/sizeof(WCHAR), 11);
240     ok(!lstrcmpW(s_14x, out), "failed out=%s\n", wine_dbgstr_w(out));
241     ok(r==4,"failed: r=%d\n", r);
242
243     /* a hex number, upper case */
244     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_14X, 0,
245         0, out, sizeof(out)/sizeof(WCHAR), 11);
246     ok(!lstrcmpW(s_14X, out), "failed out=%s\n", wine_dbgstr_w(out));
247     ok(r==4,"failed: r=%d\n", r);
248
249     /* a hex number, upper case, left justified */
250     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1_4X, 0,
251         0, out, sizeof(out)/sizeof(WCHAR), 11);
252     ok(!lstrcmpW(s_1_4X, out), "failed out=%s\n", wine_dbgstr_w(out));
253     ok(r==4,"failed: r=%d\n", r);
254
255     /* a long hex number, upper case */
256     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_14X, 0,
257         0, out, sizeof(out)/sizeof(WCHAR), 0x1ab);
258     ok(!lstrcmpW(s_1AB, out), "failed out=%s\n", wine_dbgstr_w(out));
259     ok(r==4,"failed: r=%d\n", r);
260
261     /* two percent... */
262     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_2pct, 0,
263         0, out, sizeof(out)/sizeof(WCHAR));
264     ok(!lstrcmpW(s_2pct, out), "failed out=%s\n", wine_dbgstr_w(out));
265     ok(r==4,"failed: r=%d\n", r);
266
267     /* periods are special cases */
268     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_2dot1d, 0,
269         0, out, sizeof(out)/sizeof(WCHAR), 0x1ab);
270     ok(!lstrcmpW(s_2dot147, out), "failed out=%s\n", wine_dbgstr_w(out));
271     ok(r==8,"failed: r=%d\n", r);
272
273     /* %0 ends the line */
274     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_t0t, 0,
275         0, out, sizeof(out)/sizeof(WCHAR));
276     ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out));
277     ok(r==4,"failed: r=%d\n", r);
278
279     /* %! prints an exclamation */
280     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_yah, 0,
281         0, out, sizeof(out)/sizeof(WCHAR));
282     ok(!lstrcmpW(s_yah, out), "failed out=%s\n", wine_dbgstr_w(out));
283     ok(r==4,"failed: r=%d\n", r);
284
285     /* %space */
286     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_space, 0,
287         0, out, sizeof(out)/sizeof(WCHAR));
288     ok(!lstrcmpW(s_space, out), "failed out=%s\n", wine_dbgstr_w(out));
289     ok(r==4,"failed: r=%d\n", r);
290
291     /* line feed */
292     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_hi_lf, 0,
293         0, out, sizeof(out)/sizeof(WCHAR));
294     ok(!lstrcmpW(s_hi_crlf, out), "failed out=%s\n", wine_dbgstr_w(out));
295     ok(r==4,"failed: r=%d\n", r);
296
297     /* carriage return line feed */
298     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_hi_crlf, 0,
299         0, out, sizeof(out)/sizeof(WCHAR));
300     ok(!lstrcmpW(s_hi_crlf, out), "failed out=%s\n", wine_dbgstr_w(out));
301     ok(r==4,"failed: r=%d\n", r);
302
303     /* carriage return */
304     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_cr, 0,
305         0, out, sizeof(out)/sizeof(WCHAR));
306     ok(!lstrcmpW(s_crlf, out), "failed out=%s\n", wine_dbgstr_w(out));
307     ok(r==2,"failed: r=%d\n", r);
308
309     /* double carriage return line feed */
310     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_crcrlf, 0,
311         0, out, sizeof(out)/sizeof(WCHAR));
312     ok(!lstrcmpW(s_crlfcrlf, out), "failed out=%s\n", wine_dbgstr_w(out));
313     ok(r==4,"failed: r=%d\n", r);
314
315     /* precision and width */
316
317     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_13s,
318               0, 0, out, sizeof(out)/sizeof(WCHAR), t );
319     ok(!lstrcmpW(s_spt, out),"failed out=[%s]\n", wine_dbgstr_w(out));
320     ok(r==3, "failed: r=%d\n",r);
321     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1os,
322               0, 0, out, sizeof(out)/sizeof(WCHAR), 4, t );
323     ok(!lstrcmpW( s_sp3t, out),"failed out=[%s]\n", wine_dbgstr_w(out));
324     ok(r==4,"failed: r=%d\n",r);
325     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_142u,
326               0, 0, out, sizeof(out)/sizeof(WCHAR), 3 );
327     ok(!lstrcmpW( s_sp03, out),"failed out=[%s]\n", wine_dbgstr_w(out));
328     ok(r==4,"failed: r=%d\n",r);
329     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1oou,
330               0, 0, out, sizeof(out)/sizeof(WCHAR), 5, 3, 1 );
331     ok(!lstrcmpW( s_sp001, out),"failed out=[%s]\n", wine_dbgstr_w(out));
332     ok(r==5,"failed: r=%d\n",r);
333     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1oou1oou,
334               0, 0, out, sizeof(out)/sizeof(WCHAR), 5, 3, 1, 4, 2 );
335     ok(!lstrcmpW( s_sp001002, out),"failed out=[%s]\n", wine_dbgstr_w(out));
336     ok(r==11,"failed: r=%d\n",r);
337     r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1oou3oou,
338               0, 0, out, sizeof(out)/sizeof(WCHAR), 5, 3, 1, 6, 4, 2 );
339     ok(!lstrcmpW( s_sp001sp002, out) || broken(!lstrcmpW(s_sp001004, out)),
340        "failed out=[%s]\n", wine_dbgstr_w(out));
341     ok(r==12,"failed: r=%d\n",r);
342     /* args are not counted the same way with an argument array */
343     {
344         ULONG_PTR args[] = { 6, 4, 2, 5, 3, 1 };
345         r = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, fmt_1oou1oou,
346                            0, 0, out, sizeof(out)/sizeof(WCHAR), (__ms_va_list *)args );
347         ok(!lstrcmpW(s_sp002sp003, out),"failed out=[%s]\n", wine_dbgstr_w(out));
348         ok(r==13,"failed: r=%d\n",r);
349         r = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, fmt_1oou4oou,
350                            0, 0, out, sizeof(out)/sizeof(WCHAR), (__ms_va_list *)args );
351         ok(!lstrcmpW(s_sp002sp001, out),"failed out=[%s]\n", wine_dbgstr_w(out));
352         ok(r==12,"failed: r=%d\n",r);
353     }
354
355     /* change of pace... test the low byte of dwflags */
356
357     /* line feed */
358     r = doitW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, fmt_hi_lf, 0,
359         0, out, sizeof(out)/sizeof(WCHAR));
360     ok(!lstrcmpW(s_hi_sp, out) || !lstrcmpW(s_hi_crlf, out), "failed out=%s\n", wine_dbgstr_w(out));
361     ok(r==3 || r==4,"failed: r=%d\n", r);
362
363     /* carriage return line feed */
364     r = doitW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, fmt_hi_crlf, 0,
365         0, out, sizeof(out)/sizeof(WCHAR));
366     ok(!lstrcmpW(s_hi_sp, out), "failed out=%s\n", wine_dbgstr_w(out));
367     ok(r==3,"failed: r=%d\n", r);
368
369     /* carriage return */
370     r = doitW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, fmt_cr, 0,
371         0, out, sizeof(out)/sizeof(WCHAR));
372     ok(!lstrcmpW(s_sp, out), "failed out=%s\n", wine_dbgstr_w(out));
373     ok(r==1,"failed: r=%d\n", r);
374
375     /* double carriage return line feed */
376     r = doitW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, fmt_crcrlf, 0,
377         0, out, sizeof(out)/sizeof(WCHAR));
378     ok(!lstrcmpW(s_2sp, out), "failed out=%s\n", wine_dbgstr_w(out));
379     ok(r==2,"failed: r=%d\n", r);
380 }
381
382 static void test_message_from_string(void)
383 {
384     CHAR out[0x100] = {0};
385     DWORD r;
386     static const WCHAR szwTest[] = { 't','e','s','t',0};
387
388     /* the basics */
389     r = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, "test", 0,
390         0, out, sizeof(out)/sizeof(CHAR),NULL);
391     ok(!strcmp("test", out),"failed out=[%s]\n",out);
392     ok(r==4,"failed: r=%d\n",r);
393
394     /* using the format feature */
395     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!s!", 0,
396         0, out, sizeof(out)/sizeof(CHAR), "test");
397     ok(!strcmp("test", out),"failed out=[%s]\n",out);
398     ok(r==4,"failed: r=%d\n",r);
399
400     /* no format */
401     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1", 0,
402         0, out, sizeof(out)/sizeof(CHAR), "test");
403     ok(!strcmp("test", out),"failed out=[%s]\n",out);
404     ok(r==4,"failed: r=%d\n",r);
405
406     /* two pieces */
407     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1%2", 0,
408         0, out, sizeof(out)/sizeof(CHAR), "te","st");
409     ok(!strcmp("test", out),"failed out=[%s]\n",out);
410     ok(r==4,"failed: r=%d\n",r);
411
412     /* three pieces */
413     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1%3%2%1", 0,
414         0, out, sizeof(out)/sizeof(CHAR), "t","s","e");
415     ok(!strcmp("test", out),"failed out=[%s]\n",out);
416     ok(r==4,"failed: r=%d\n",r);
417
418     /* s doesn't seem to work in format strings */
419     r = doit(FORMAT_MESSAGE_FROM_STRING, "%!s!", 0,
420         0, out, sizeof(out)/sizeof(CHAR), "test");
421     ok(!strcmp("!s!", out),"failed out=[%s]\n",out);
422     ok(r==3,"failed: r=%d\n",r);
423
424     /* ls is unicode */
425     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!ls!", 0,
426         0, out, sizeof(out)/sizeof(CHAR), szwTest);
427     ok(!strcmp("test", out),"failed out=[%s]\n",out);
428     ok(r==4,"failed: r=%d\n",r);
429
430     /* S is unicode */
431     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!S!", 0,
432         0, out, sizeof(out)/sizeof(CHAR), szwTest);
433     ok(!strcmp("test", out),"failed out=[%s]\n",out);
434     ok(r==4,"failed: r=%d\n",r);
435
436     /* ws is unicode */
437     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!ws!", 0,
438         0, out, sizeof(out)/sizeof(CHAR), szwTest);
439     ok(!strcmp("test", out),"failed out=[%s]\n",out);
440     ok(r==4,"failed: r=%d\n",r);
441
442     /* as characters */
443     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!c!%2!c!%3!c!%1!c!", 0,
444         0, out, sizeof(out)/sizeof(CHAR), 't','e','s');
445     ok(!strcmp("test", out),"failed out=[%s]\n",out);
446     ok(r==4,"failed: r=%d\n",r);
447
448     /* lc is unicode */
449     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!lc!%2!lc!%3!lc!%1!lc!", 0,
450         0, out, sizeof(out)/sizeof(CHAR), 't','e','s');
451     ok(!strcmp("test", out),"failed out=[%s]\n",out);
452     ok(r==4,"failed: r=%d\n",r);
453
454     /* wc is unicode */
455     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!wc!%2!wc!%3!wc!%1!wc!", 0,
456         0, out, sizeof(out)/sizeof(CHAR), 't','e','s');
457     ok(!strcmp("test", out),"failed out=[%s]\n",out);
458     ok(r==4,"failed: r=%d\n",r);
459
460     /* C is unicode */
461     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!C!%2!C!%3!C!%1!C!", 0,
462         0, out, sizeof(out)/sizeof(CHAR), 't','e','s');
463     ok(!strcmp("test", out),"failed out=[%s]\n",out);
464     ok(r==4,"failed: r=%d\n",r);
465
466     /* some numbers */
467     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!d!%2!d!%3!d!", 0,
468         0, out, sizeof(out)/sizeof(CHAR), 1,2,3);
469     ok(!strcmp("123", out),"failed out=[%s]\n",out);
470     ok(r==3,"failed: r=%d\n",r);
471
472     /* a single digit with some spacing */
473     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!4d!", 0,
474         0, out, sizeof(out)/sizeof(CHAR), 1);
475     ok(!strcmp("   1", out),"failed out=[%s]\n",out);
476     ok(r==4,"failed: r=%d\n",r);
477
478     /* a single digit, left justified */
479     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!-4d!", 0,
480         0, out, sizeof(out)/sizeof(CHAR), 1);
481     ok(!strcmp("1   ", out),"failed out=[%s]\n",out);
482     ok(r==4,"failed: r=%d\n",r);
483
484     /* two digit decimal number */
485     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!4d!", 0,
486         0, out, sizeof(out)/sizeof(CHAR), 11);
487     ok(!strcmp("  11", out),"failed out=[%s]\n",out);
488     ok(r==4,"failed: r=%d\n",r);
489
490     /* a hex number */
491     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!4x!", 0,
492         0, out, sizeof(out)/sizeof(CHAR), 11);
493     ok(!strcmp("   b", out),"failed out=[%s]\n",out);
494     ok(r==4,"failed: r=%d\n",r);
495
496     /* a hex number, upper case */
497     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!4X!", 0,
498         0, out, sizeof(out)/sizeof(CHAR), 11);
499     ok(!strcmp("   B", out),"failed out=[%s]\n",out);
500     ok(r==4,"failed: r=%d\n",r);
501
502     /* a hex number, upper case, left justified */
503     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!-4X!", 0,
504         0, out, sizeof(out)/sizeof(CHAR), 11);
505     ok(!strcmp("B   ", out),"failed out=[%s]\n",out);
506     ok(r==4,"failed: r=%d\n",r);
507
508     /* a long hex number, upper case */
509     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!4X!", 0,
510         0, out, sizeof(out)/sizeof(CHAR), 0x1ab);
511     ok(!strcmp(" 1AB", out),"failed out=[%s]\n",out);
512     ok(r==4,"failed: r=%d\n",r);
513
514     /* two percent... */
515     r = doit(FORMAT_MESSAGE_FROM_STRING, " %%%% ", 0,
516         0, out, sizeof(out)/sizeof(CHAR));
517     ok(!strcmp(" %% ", out),"failed out=[%s]\n",out);
518     ok(r==4,"failed: r=%d\n",r);
519
520     /* periods are special cases */
521     r = doit(FORMAT_MESSAGE_FROM_STRING, " %.%. %1!d!", 0,
522         0, out, sizeof(out)/sizeof(CHAR), 0x1ab);
523     ok(!strcmp(" .. 427", out),"failed out=[%s]\n",out);
524     ok(r==7,"failed: r=%d\n",r);
525
526     /* %0 ends the line */
527     r = doit(FORMAT_MESSAGE_FROM_STRING, "test%0test", 0,
528         0, out, sizeof(out)/sizeof(CHAR));
529     ok(!strcmp("test", out),"failed out=[%s]\n",out);
530     ok(r==4,"failed: r=%d\n",r);
531
532     /* %! prints an exclamation */
533     r = doit(FORMAT_MESSAGE_FROM_STRING, "yah%!%0   ", 0,
534         0, out, sizeof(out)/sizeof(CHAR));
535     ok(!strcmp("yah!", out),"failed out=[%s]\n",out);
536     ok(r==4,"failed: r=%d\n",r);
537
538     /* %space */
539     r = doit(FORMAT_MESSAGE_FROM_STRING, "% %   ", 0,
540         0, out, sizeof(out)/sizeof(CHAR));
541     ok(!strcmp("    ", out),"failed out=[%s]\n",out);
542     ok(r==4,"failed: r=%d\n",r);
543
544     /* line feed */
545     r = doit(FORMAT_MESSAGE_FROM_STRING, "hi\n", 0,
546         0, out, sizeof(out)/sizeof(CHAR));
547     ok(!strcmp("hi\r\n", out),"failed out=[%s]\n",out);
548     ok(r==4,"failed: r=%d\n",r);
549
550     /* carriage return line feed */
551     r = doit(FORMAT_MESSAGE_FROM_STRING, "hi\r\n", 0,
552         0, out, sizeof(out)/sizeof(CHAR));
553     ok(!strcmp("hi\r\n", out),"failed out=[%s]\n",out);
554     ok(r==4,"failed: r=%d\n",r);
555
556     /* carriage return */
557     r = doit(FORMAT_MESSAGE_FROM_STRING, "\r", 0,
558         0, out, sizeof(out)/sizeof(CHAR));
559     ok(!strcmp("\r\n", out),"failed out=[%s]\n",out);
560     ok(r==2,"failed: r=%d\n",r);
561
562     /* double carriage return line feed */
563     r = doit(FORMAT_MESSAGE_FROM_STRING, "\r\r\n", 0,
564         0, out, sizeof(out)/sizeof(CHAR));
565     ok(!strcmp("\r\n\r\n", out),"failed out=[%s]\n",out);
566     ok(r==4,"failed: r=%d\n",r);
567
568     /* precision and width */
569
570     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!3s!",
571              0, 0, out, sizeof(out), "t" );
572     ok(!strcmp("  t", out),"failed out=[%s]\n",out);
573     ok(r==3, "failed: r=%d\n",r);
574     r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!*s!",
575              0, 0, out, sizeof(out), 4, "t");
576     if (!strcmp("*s",out)) win_skip( "width/precision not supported\n" );
577     else
578     {
579         ok(!strcmp( "   t", out),"failed out=[%s]\n",out);
580         ok(r==4,"failed: r=%d\n",r);
581         r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!4.2u!",
582                  0, 0, out, sizeof(out), 3 );
583         ok(!strcmp( "  03", out),"failed out=[%s]\n",out);
584         ok(r==4,"failed: r=%d\n",r);
585         r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!*.*u!",
586                  0, 0, out, sizeof(out), 5, 3, 1 );
587         ok(!strcmp( "  001", out),"failed out=[%s]\n",out);
588         ok(r==5,"failed: r=%d\n",r);
589         r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!*.*u!,%1!*.*u!",
590                  0, 0, out, sizeof(out), 5, 3, 1, 4, 2 );
591         ok(!strcmp( "  001, 0002", out),"failed out=[%s]\n",out);
592         ok(r==11,"failed: r=%d\n",r);
593         r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!*.*u!,%3!*.*u!",
594                  0, 0, out, sizeof(out), 5, 3, 1, 6, 4, 2 );
595         /* older Win versions marked as broken even though this is arguably the correct behavior */
596         /* but the new (brain-damaged) behavior is specified on MSDN */
597         ok(!strcmp( "  001,  0002", out) || broken(!strcmp("  001,000004", out)),
598            "failed out=[%s]\n",out);
599         ok(r==12,"failed: r=%d\n",r);
600         /* args are not counted the same way with an argument array */
601         {
602             ULONG_PTR args[] = { 6, 4, 2, 5, 3, 1 };
603             r = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
604                                "%1!*.*u!,%1!*.*u!", 0, 0, out, sizeof(out), (__ms_va_list *)args );
605             ok(!strcmp("  0002, 00003", out),"failed out=[%s]\n",out);
606             ok(r==13,"failed: r=%d\n",r);
607             r = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
608                                "%1!*.*u!,%4!*.*u!", 0, 0, out, sizeof(out), (__ms_va_list *)args );
609             ok(!strcmp("  0002,  001", out),"failed out=[%s]\n",out);
610             ok(r==12,"failed: r=%d\n",r);
611         }
612     }
613
614     /* change of pace... test the low byte of dwflags */
615
616     /* line feed */
617     r = doit(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, "hi\n", 0,
618         0, out, sizeof(out)/sizeof(CHAR));
619     ok(!strcmp("hi ", out) || !strcmp("hi\r\n", out),"failed out=[%s]\n",out);
620     ok(r==3 || r==4,"failed: r=%d\n",r);
621
622     /* carriage return line feed */
623     r = doit(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, "hi\r\n", 0,
624         0, out, sizeof(out)/sizeof(CHAR));
625     ok(!strcmp("hi ", out),"failed out=[%s]\n",out);
626     ok(r==3,"failed: r=%d\n",r);
627
628     /* carriage return */
629     r = doit(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, "\r", 0,
630         0, out, sizeof(out)/sizeof(CHAR));
631     ok(!strcmp(" ", out),"failed out=[%s]\n",out);
632     ok(r==1,"failed: r=%d\n",r);
633
634     /* double carriage return line feed */
635     r = doit(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, "\r\r\n", 0,
636         0, out, sizeof(out)/sizeof(CHAR));
637     ok(!strcmp("  ", out),"failed out=[%s]\n",out);
638     ok(r==2,"failed: r=%d\n",r);
639 }
640
641 static void test_message_insufficient_buffer(void)
642 {
643     static const char init_buf[] = {'x', 'x', 'x', 'x', 'x'};
644     static const char expected_buf[] = {'x', 'x', 'x', 'x', 'x'};
645     DWORD ret;
646     CHAR out[5];
647
648     SetLastError(0xdeadbeef);
649     memcpy(out, init_buf, sizeof(init_buf));
650     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, "test", 0, 0, out, 0, NULL);
651     ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
652     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
653        "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n",
654        GetLastError());
655     ok(!memcmp(expected_buf, out, sizeof(expected_buf)),
656        "Expected the buffer to be untouched\n");
657
658     SetLastError(0xdeadbeef);
659     memcpy(out, init_buf, sizeof(init_buf));
660     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, "test", 0, 0, out, 1, NULL);
661     ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
662     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
663        "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n",
664        GetLastError());
665     ok(!memcmp(expected_buf, out, sizeof(expected_buf)),
666        "Expected the buffer to be untouched\n");
667
668     SetLastError(0xdeadbeef);
669     memcpy(out, init_buf, sizeof(init_buf));
670     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, "test", 0, 0, out, sizeof(out)/sizeof(out[0]) - 1, NULL);
671     ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
672     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
673        "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n",
674        GetLastError());
675     ok(!memcmp(expected_buf, out, sizeof(expected_buf)),
676        "Expected the buffer to be untouched\n");
677 }
678
679 static void test_message_insufficient_buffer_wide(void)
680 {
681     static const WCHAR test[] = {'t','e','s','t',0};
682     static const WCHAR init_buf[] = {'x', 'x', 'x', 'x', 'x'};
683     static const WCHAR expected_buf[] = {'x', 'x', 'x', 'x', 'x'};
684     static const WCHAR broken_buf[] = {0, 'x', 'x', 'x', 'x'};
685     static const WCHAR broken2_buf[] = {'t','e','s',0,'x'};
686
687     DWORD ret;
688     WCHAR out[5];
689
690     SetLastError(0xdeadbeef);
691     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, NULL, 0, 0, NULL, 0, NULL);
692     if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
693     {
694         win_skip("FormatMessageW is not implemented\n");
695         return;
696     }
697
698     SetLastError(0xdeadbeef);
699     memcpy(out, init_buf, sizeof(init_buf));
700     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, test, 0, 0, out, 0, NULL);
701     ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
702     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
703        "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n",
704        GetLastError());
705     ok(!memcmp(expected_buf, out, sizeof(expected_buf)),
706        "Expected the buffer to be untouched\n");
707
708     /* Windows Server 2003 and newer report failure but copy a
709      * truncated string to the buffer for non-zero buffer sizes. */
710     SetLastError(0xdeadbeef);
711     memcpy(out, init_buf, sizeof(init_buf));
712     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, test, 0, 0, out, 1, NULL);
713     ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
714     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
715        "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n",
716        GetLastError());
717     ok(!memcmp(expected_buf, out, sizeof(expected_buf)) ||
718        broken(!memcmp(broken_buf, out, sizeof(broken_buf))), /* W2K3+ */
719        "Expected the buffer to be untouched\n");
720
721     SetLastError(0xdeadbeef);
722     memcpy(out, init_buf, sizeof(init_buf));
723     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, test, 0, 0, out, sizeof(out)/sizeof(out[0]) - 1, NULL);
724     ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
725     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
726        "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n",
727        GetLastError());
728     ok(!memcmp(expected_buf, out, sizeof(expected_buf)) ||
729        broken(!memcmp(broken2_buf, out, sizeof(broken2_buf))), /* W2K3+ */
730        "Expected the buffer to be untouched\n");
731 }
732
733 static void test_message_null_buffer(void)
734 {
735     DWORD ret, error;
736
737     /* Without FORMAT_MESSAGE_ALLOCATE_BUFFER, only the specified buffer size is checked. */
738     SetLastError(0xdeadbeef);
739     ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, 0, 0, NULL, 0, NULL);
740     error = GetLastError();
741     ok(!ret, "FormatMessageA returned %u\n", ret);
742     ok(error == ERROR_INSUFFICIENT_BUFFER ||
743        error == ERROR_INVALID_PARAMETER, /* win9x */
744        "last error %u\n", error);
745
746     SetLastError(0xdeadbeef);
747     ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, 0, 0, NULL, 1, NULL);
748     error = GetLastError();
749     ok(!ret, "FormatMessageA returned %u\n", ret);
750     ok(error == ERROR_INSUFFICIENT_BUFFER ||
751        error == ERROR_INVALID_PARAMETER, /* win9x */
752        "last error %u\n", error);
753
754     if (0) /* crashes on Windows */
755     {
756         SetLastError(0xdeadbeef);
757         ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, 0, 0, NULL, 256, NULL);
758         error = GetLastError();
759         ok(!ret, "FormatMessageA returned %u\n", ret);
760         trace("last error %u\n", error);
761     }
762
763     SetLastError(0xdeadbeef);
764     ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, 0, 0, NULL, 0, NULL);
765     error = GetLastError();
766     ok(!ret, "FormatMessageA returned %u\n", ret);
767     ok(error == ERROR_NOT_ENOUGH_MEMORY ||
768        error == ERROR_INVALID_PARAMETER, /* win9x */
769        "last error %u\n", error);
770
771     SetLastError(0xdeadbeef);
772     ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, 0, 0, NULL, 1, NULL);
773     error = GetLastError();
774     ok(!ret, "FormatMessageA returned %u\n", ret);
775     ok(error == ERROR_NOT_ENOUGH_MEMORY ||
776        error == ERROR_INVALID_PARAMETER, /* win9x */
777        "last error %u\n", error);
778
779     SetLastError(0xdeadbeef);
780     ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, 0, 0, NULL, 256, NULL);
781     error = GetLastError();
782     ok(!ret, "FormatMessageA returned %u\n", ret);
783     ok(error == ERROR_NOT_ENOUGH_MEMORY ||
784        error == ERROR_INVALID_PARAMETER, /* win9x */
785        "last error %u\n", error);
786 }
787
788 static void test_message_null_buffer_wide(void)
789 {
790     DWORD ret, error;
791
792     SetLastError(0xdeadbeef);
793     ret = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, 0, 0, NULL, 0, NULL);
794     error = GetLastError();
795     if (!ret && error == ERROR_CALL_NOT_IMPLEMENTED)
796     {
797         win_skip("FormatMessageW is not implemented\n");
798         return;
799     }
800
801     SetLastError(0xdeadbeef);
802     ret = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, 0, 0, NULL, 0, NULL);
803     error = GetLastError();
804     ok(!ret, "FormatMessageW returned %u\n", ret);
805     ok(error == ERROR_INVALID_PARAMETER, "last error %u\n", error);
806
807     SetLastError(0xdeadbeef);
808     ret = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, 0, 0, NULL, 1, NULL);
809     error = GetLastError();
810     ok(!ret, "FormatMessageW returned %u\n", ret);
811     ok(error == ERROR_INVALID_PARAMETER, "last error %u\n", error);
812
813     SetLastError(0xdeadbeef);
814     ret = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, 0, 0, NULL, 256, NULL);
815     error = GetLastError();
816     ok(!ret, "FormatMessageW returned %u\n", ret);
817     ok(error == ERROR_INVALID_PARAMETER, "last error %u\n", error);
818
819     SetLastError(0xdeadbeef);
820     ret = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, 0, 0, NULL, 0, NULL);
821     error = GetLastError();
822     ok(!ret, "FormatMessageW returned %u\n", ret);
823     ok(error == ERROR_INVALID_PARAMETER, "last error %u\n", error);
824
825     SetLastError(0xdeadbeef);
826     ret = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, 0, 0, NULL, 1, NULL);
827     error = GetLastError();
828     ok(!ret, "FormatMessageW returned %u\n", ret);
829     ok(error == ERROR_INVALID_PARAMETER, "last error %u\n", error);
830
831     SetLastError(0xdeadbeef);
832     ret = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, 0, 0, NULL, 256, NULL);
833     error = GetLastError();
834     ok(!ret, "FormatMessageW returned %u\n", ret);
835     ok(error == ERROR_INVALID_PARAMETER, "last error %u\n", error);
836 }
837
838 static void test_message_allocate_buffer(void)
839 {
840     DWORD ret;
841     char *buf;
842
843     /* While MSDN suggests that FormatMessageA allocates a buffer whose size is
844      * the larger of the output string and the requested buffer size, the tests
845      * will not try to determine the actual size of the buffer allocated, as
846      * the return value of LocalSize cannot be trusted for the purpose, and it should
847      * in any case be safe for FormatMessageA to allocate in the manner that
848      * MSDN suggests. */
849
850     buf = (char *)0xdeadbeef;
851     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
852                          "test", 0, 0, (char *)&buf, 0, NULL);
853     ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
854     ok(buf != NULL && buf != (char *)0xdeadbeef,
855        "Expected output buffer pointer to be valid\n");
856     if (buf != NULL && buf != (char *)0xdeadbeef)
857     {
858         ok(!strcmp("test", buf),
859            "Expected buffer to contain \"test\", got %s\n", buf);
860         LocalFree(buf);
861     }
862
863     buf = (char *)0xdeadbeef;
864     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
865                          "test", 0, 0, (char *)&buf, strlen("test"), NULL);
866     ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
867     ok(buf != NULL && buf != (char *)0xdeadbeef,
868        "Expected output buffer pointer to be valid\n");
869     if (buf != NULL && buf != (char *)0xdeadbeef)
870     {
871         ok(!strcmp("test", buf),
872            "Expected buffer to contain \"test\", got %s\n", buf);
873         LocalFree(buf);
874     }
875
876     buf = (char *)0xdeadbeef;
877     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
878                          "test", 0, 0, (char *)&buf, strlen("test") + 1, NULL);
879     ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
880     ok(buf != NULL && buf != (char *)0xdeadbeef,
881        "Expected output buffer pointer to be valid\n");
882    if (buf != NULL && buf != (char *)0xdeadbeef)
883     {
884         ok(!strcmp("test", buf),
885            "Expected buffer to contain \"test\", got %s\n", buf);
886         LocalFree(buf);
887     }
888
889     buf = (char *)0xdeadbeef;
890     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
891                          "test", 0, 0, (char *)&buf, strlen("test") + 2, NULL);
892     ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
893     ok(buf != NULL && buf != (char *)0xdeadbeef,
894        "Expected output buffer pointer to be valid\n");
895     if (buf != NULL && buf != (char *)0xdeadbeef)
896     {
897         ok(!strcmp("test", buf),
898            "Expected buffer to contain \"test\", got %s\n", buf);
899         LocalFree(buf);
900     }
901
902     buf = (char *)0xdeadbeef;
903     ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
904                          "test", 0, 0, (char *)&buf, 1024, NULL);
905     ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
906     ok(buf != NULL && buf != (char *)0xdeadbeef,
907        "Expected output buffer pointer to be valid\n");
908     if (buf != NULL && buf != (char *)0xdeadbeef)
909     {
910         ok(!strcmp("test", buf),
911            "Expected buffer to contain \"test\", got %s\n", buf);
912         LocalFree(buf);
913     }
914 }
915
916 static void test_message_allocate_buffer_wide(void)
917 {
918     static const WCHAR test[] = {'t','e','s','t',0};
919
920     DWORD ret;
921     WCHAR *buf;
922
923     SetLastError(0xdeadbeef);
924     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, NULL, 0, 0, NULL, 0, NULL);
925     if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
926     {
927         win_skip("FormatMessageW is not implemented\n");
928         return;
929     }
930
931     /* While MSDN suggests that FormatMessageA allocates a buffer whose size is
932      * the larger of the output string and the requested buffer size, the tests
933      * will not try to determine the actual size of the buffer allocated, as
934      * the return value of LocalSize cannot be trusted for the purpose, and it should
935      * in any case be safe for FormatMessageA to allocate in the manner that
936      * MSDN suggests. */
937
938     buf = (WCHAR *)0xdeadbeef;
939     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
940                          test, 0, 0, (WCHAR *)&buf, 0, NULL);
941     ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
942     ok(buf != NULL && buf != (WCHAR *)0xdeadbeef,
943        "Expected output buffer pointer to be valid\n");
944     if (buf != NULL && buf != (WCHAR *)0xdeadbeef)
945     {
946         ok(!lstrcmpW(test, buf),
947            "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf));
948         LocalFree(buf);
949     }
950
951     buf = (WCHAR *)0xdeadbeef;
952     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
953                          test, 0, 0, (WCHAR *)&buf, sizeof(test)/sizeof(WCHAR) - 1, NULL);
954     ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
955     ok(buf != NULL && buf != (WCHAR *)0xdeadbeef,
956        "Expected output buffer pointer to be valid\n");
957     if (buf != NULL && buf != (WCHAR *)0xdeadbeef)
958     {
959         ok(!lstrcmpW(test, buf),
960            "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf));
961         LocalFree(buf);
962     }
963
964     buf = (WCHAR *)0xdeadbeef;
965     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
966                          test, 0, 0, (WCHAR *)&buf, sizeof(test)/sizeof(WCHAR), NULL);
967     ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
968     ok(buf != NULL && buf != (WCHAR *)0xdeadbeef,
969        "Expected output buffer pointer to be valid\n");
970     if (buf != NULL && buf != (WCHAR *)0xdeadbeef)
971     {
972         ok(!lstrcmpW(test, buf),
973            "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf));
974         LocalFree(buf);
975     }
976
977     buf = (WCHAR *)0xdeadbeef;
978     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
979                          test, 0, 0, (WCHAR *)&buf, sizeof(test)/sizeof(WCHAR) + 1, NULL);
980     ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
981     ok(buf != NULL && buf != (WCHAR *)0xdeadbeef,
982        "Expected output buffer pointer to be valid\n");
983     if (buf != NULL && buf != (WCHAR *)0xdeadbeef)
984     {
985         ok(!lstrcmpW(test, buf),
986            "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf));
987         LocalFree(buf);
988     }
989
990     buf = (WCHAR *)0xdeadbeef;
991     ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
992                          test, 0, 0, (WCHAR *)&buf, 1024, NULL);
993     ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
994     ok(buf != NULL && buf != (WCHAR *)0xdeadbeef,
995        "Expected output buffer pointer to be valid\n");
996     if (buf != NULL && buf != (WCHAR *)0xdeadbeef)
997     {
998         ok(!lstrcmpW(test, buf),
999            "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf));
1000         LocalFree(buf);
1001     }
1002 }
1003
1004 static void test_message_from_hmodule(void)
1005 {
1006     DWORD ret, error;
1007     HMODULE h;
1008     CHAR out[0x100] = {0};
1009
1010     h = GetModuleHandle("kernel32.dll");
1011     ok(h != 0, "GetModuleHandle failed\n");
1012
1013     /*Test existing messageID; as the message strings from wine's kernel32 differ from windows' kernel32 we don't compare
1014     the strings but only test that FormatMessage doesn't return 0*/
1015     ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 7/*=ERROR_ARENA_TRASHED*/,
1016                          MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), out, sizeof(out)/sizeof(CHAR), NULL);
1017     ok(ret != 0, "FormatMessageA returned 0\n");
1018
1019     /*Test nonexistent messageID with varying language ID's Note: FormatMessageW behaves the same*/
1020     SetLastError(0xdeadbeef);
1021     ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 3044,
1022                          MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), out, sizeof(out)/sizeof(CHAR), NULL);
1023     error = GetLastError();
1024     ok(ret == 0, "FormatMessageA returned %u instead of 0\n", ret);
1025     ok(error == ERROR_MR_MID_NOT_FOUND || error == ERROR_MUI_FILE_NOT_FOUND, "last error %u\n", error);
1026
1027     SetLastError(0xdeadbeef);
1028     ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 3044,
1029                          MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), out, sizeof(out)/sizeof(CHAR), NULL);
1030     error = GetLastError();
1031     ok(ret == 0, "FormatMessageA returned %u instead of 0\n", ret);
1032     ok(error == ERROR_MR_MID_NOT_FOUND || error == ERROR_MUI_FILE_NOT_LOADED, "last error %u\n", error);
1033
1034     SetLastError(0xdeadbeef);
1035     ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 3044,
1036                          MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT), out, sizeof(out)/sizeof(CHAR), NULL);
1037     error = GetLastError();
1038     ok(ret == 0, "FormatMessageA returned %u instead of 0\n", ret);
1039     ok(error == ERROR_MR_MID_NOT_FOUND || error == ERROR_MUI_FILE_NOT_LOADED, "last error %u\n", error);
1040
1041     SetLastError(0xdeadbeef);
1042     ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 3044,
1043                          MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), out, sizeof(out)/sizeof(CHAR), NULL);
1044     error = GetLastError();
1045     ok(ret == 0, "FormatMessageA returned %u instead of 0\n", ret);
1046     ok(error == ERROR_RESOURCE_LANG_NOT_FOUND ||
1047        error == ERROR_MR_MID_NOT_FOUND ||
1048        error == ERROR_MUI_FILE_NOT_FOUND ||
1049        error == ERROR_MUI_FILE_NOT_LOADED,
1050        "last error %u\n", error);
1051
1052     SetLastError(0xdeadbeef);
1053     ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 3044,
1054                          MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_UK), out, sizeof(out)/sizeof(CHAR), NULL);
1055     error = GetLastError();
1056     ok(ret == 0, "FormatMessageA returned %u instead of 0\n", ret);
1057     ok(error == ERROR_RESOURCE_LANG_NOT_FOUND ||
1058        error == ERROR_MR_MID_NOT_FOUND ||
1059        error == ERROR_MUI_FILE_NOT_FOUND ||
1060        error == ERROR_MUI_FILE_NOT_LOADED,
1061        "last error %u\n", error);
1062 }
1063
1064 START_TEST(format_msg)
1065 {
1066     test_message_from_string();
1067     test_message_from_string_wide();
1068     test_message_insufficient_buffer();
1069     test_message_insufficient_buffer_wide();
1070     test_message_null_buffer();
1071     test_message_null_buffer_wide();
1072     test_message_allocate_buffer();
1073     test_message_allocate_buffer_wide();
1074     test_message_from_hmodule();
1075 }