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