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