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