kernel32/tests: Use WINAPIV calling convention for variadic functions.
[wine.git] / dlls / kernel32 / tests / format_msg.c
blob7098805ea79f7571e885546a2f271e10f5dd9747
1 /* Unit test suite for FormatMessageA/W
3 * Copyright 2002 Mike McCormack for CodeWeavers
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.
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.
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
20 #include <stdarg.h>
22 #include "wine/test.h"
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winnls.h"
27 #define ULL(a,b) (((ULONG64)(a) << 32) | (b))
29 static DWORD WINAPIV doit(DWORD flags, LPCVOID src, DWORD msg_id, DWORD lang_id,
30 LPSTR out, DWORD outsize, ... )
32 __ms_va_list list;
33 DWORD r;
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;
42 static DWORD WINAPIV doitW(DWORD flags, LPCVOID src, DWORD msg_id, DWORD lang_id,
43 LPWSTR out, DWORD outsize, ... )
45 __ms_va_list list;
46 DWORD r;
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;
55 static void test_message_from_string_wide(void)
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};
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};
132 static const WCHAR init_buf[] = {'x', 'x', 'x', 'x', 'x', 'x'};
133 static const WCHAR broken_buf[] = {'t','e','s','t','x','x'};
135 WCHAR out[0x100] = {0};
136 DWORD r, error;
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);
144 /* null string, crashes on Windows */
145 if (0)
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
393 /* precision and width */
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 */
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);
434 /* change of pace... test the low byte of dwflags */
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);
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);
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);
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);
461 static void test_message_from_string(void)
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};
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);
474 /* null string, crashes on Windows */
475 if (0)
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);
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());
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());
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());
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());
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());
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
718 /* precision and width */
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
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 */
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);
765 /* change of pace... test the low byte of dwflags */
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);
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);
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);
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);
792 static void test_message_ignore_inserts(void)
794 static const char init_buf[] = {'x', 'x', 'x', 'x', 'x'};
796 DWORD ret;
797 CHAR out[256];
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);
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);
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);
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());
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
888 static void test_message_ignore_inserts_wide(void)
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};
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};
911 DWORD ret;
912 WCHAR out[256];
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));
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));
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));
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());
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
1002 static void test_message_wrap(void)
1004 DWORD ret;
1005 int i;
1006 CHAR in[300], out[300], ref[300];
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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++)
1146 strcat(in, "123456789 ");
1147 strcat(ref, "123456789 ");
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);
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);
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);
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);
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);
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);
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);
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);
1191 static void test_message_insufficient_buffer(void)
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];
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");
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");
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");
1229 static void test_message_insufficient_buffer_wide(void)
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'};
1237 DWORD ret;
1238 WCHAR out[5];
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");
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");
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");
1275 static void test_message_null_buffer(void)
1277 DWORD ret, error;
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);
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);
1292 if (0) /* crashes on Windows */
1294 SetLastError(0xdeadbeef);
1295 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, 0, 0, NULL, 256, NULL);
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);
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);
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);
1317 static void test_message_null_buffer_wide(void)
1319 DWORD ret, error;
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);
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);
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);
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);
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);
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);
1358 static void test_message_allocate_buffer(void)
1360 DWORD ret;
1361 char *buf;
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. */
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());
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)
1387 ok(!strcmp("test", buf),
1388 "Expected buffer to contain \"test\", got %s\n", buf);
1389 LocalFree(buf);
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)
1400 ok(!strcmp("test", buf),
1401 "Expected buffer to contain \"test\", got %s\n", buf);
1402 LocalFree(buf);
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)
1413 ok(!strcmp("test", buf),
1414 "Expected buffer to contain \"test\", got %s\n", buf);
1415 LocalFree(buf);
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)
1426 ok(!strcmp("test", buf),
1427 "Expected buffer to contain \"test\", got %s\n", buf);
1428 LocalFree(buf);
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)
1439 ok(!strcmp("test", buf),
1440 "Expected buffer to contain \"test\", got %s\n", buf);
1441 LocalFree(buf);
1445 static void test_message_allocate_buffer_wide(void)
1447 static const WCHAR empty[] = {0};
1448 static const WCHAR test[] = {'t','e','s','t',0};
1450 DWORD ret;
1451 WCHAR *buf;
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. */
1460 if (0) /* crashes on Windows */
1462 buf = (WCHAR *)0xdeadbeef;
1463 FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
1464 NULL, 0, 0, (WCHAR *)&buf, 0, NULL);
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());
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)
1484 ok(!lstrcmpW(test, buf),
1485 "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf));
1486 LocalFree(buf);
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)
1497 ok(!lstrcmpW(test, buf),
1498 "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf));
1499 LocalFree(buf);
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)
1510 ok(!lstrcmpW(test, buf),
1511 "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf));
1512 LocalFree(buf);
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)
1523 ok(!lstrcmpW(test, buf),
1524 "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf));
1525 LocalFree(buf);
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)
1536 ok(!lstrcmpW(test, buf),
1537 "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf));
1538 LocalFree(buf);
1542 static void test_message_from_hmodule(void)
1544 DWORD ret, error;
1545 HMODULE h;
1546 CHAR out[0x100] = {0};
1548 h = GetModuleHandleA("kernel32.dll");
1549 ok(h != 0, "GetModuleHandle failed\n");
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");
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");
1562 /* Test a message string with an insertion without passing any variadic arguments. */
1563 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, 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");
1567 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE |
1568 FORMAT_MESSAGE_ARGUMENT_ARRAY, h, 193 /* ERROR_BAD_EXE_FORMAT */,
1569 MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), out, sizeof(out)/sizeof(CHAR), NULL);
1570 ok(ret == 0, "FormatMessageA returned non-zero\n");
1572 /*Test nonexistent messageID with varying language IDs Note: FormatMessageW behaves the same*/
1573 SetLastError(0xdeadbeef);
1574 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 3044,
1575 MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), out, sizeof(out)/sizeof(CHAR), NULL);
1576 error = GetLastError();
1577 ok(ret == 0, "FormatMessageA returned %u instead of 0\n", ret);
1578 ok(error == ERROR_MR_MID_NOT_FOUND || error == ERROR_MUI_FILE_NOT_FOUND, "last error %u\n", error);
1580 SetLastError(0xdeadbeef);
1581 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 3044,
1582 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), out, sizeof(out)/sizeof(CHAR), NULL);
1583 error = GetLastError();
1584 ok(ret == 0, "FormatMessageA returned %u instead of 0\n", ret);
1585 ok(error == ERROR_MR_MID_NOT_FOUND || error == ERROR_MUI_FILE_NOT_LOADED, "last error %u\n", error);
1587 SetLastError(0xdeadbeef);
1588 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 3044,
1589 MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT), out, sizeof(out)/sizeof(CHAR), NULL);
1590 error = GetLastError();
1591 ok(ret == 0, "FormatMessageA returned %u instead of 0\n", ret);
1592 ok(error == ERROR_MR_MID_NOT_FOUND || error == ERROR_MUI_FILE_NOT_LOADED, "last error %u\n", error);
1594 SetLastError(0xdeadbeef);
1595 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 3044,
1596 MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), out, sizeof(out)/sizeof(CHAR), NULL);
1597 error = GetLastError();
1598 ok(ret == 0, "FormatMessageA returned %u instead of 0\n", ret);
1599 ok(error == ERROR_RESOURCE_LANG_NOT_FOUND ||
1600 error == ERROR_MR_MID_NOT_FOUND ||
1601 error == ERROR_MUI_FILE_NOT_FOUND ||
1602 error == ERROR_MUI_FILE_NOT_LOADED,
1603 "last error %u\n", error);
1605 SetLastError(0xdeadbeef);
1606 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 3044,
1607 MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_UK), out, sizeof(out)/sizeof(CHAR), NULL);
1608 error = GetLastError();
1609 ok(ret == 0, "FormatMessageA returned %u instead of 0\n", ret);
1610 ok(error == ERROR_RESOURCE_LANG_NOT_FOUND ||
1611 error == ERROR_MR_MID_NOT_FOUND ||
1612 error == ERROR_MUI_FILE_NOT_FOUND ||
1613 error == ERROR_MUI_FILE_NOT_LOADED,
1614 "last error %u\n", error);
1617 static void test_message_invalid_flags(void)
1619 static const char init_buf[] = {'x', 'x', 'x', 'x', 'x'};
1621 DWORD ret;
1622 CHAR out[5];
1623 char *ptr;
1625 SetLastError(0xdeadbeef);
1626 memcpy(out, init_buf, sizeof(init_buf));
1627 ret = FormatMessageA(0, "test", 0, 0, out, sizeof(out)/sizeof(CHAR), NULL);
1628 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
1629 ok(!memcmp(out, init_buf, sizeof(init_buf)),
1630 "Expected the output buffer to be untouched\n");
1631 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1632 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1633 GetLastError());
1635 SetLastError(0xdeadbeef);
1636 ptr = (char *)0xdeadbeef;
1637 ret = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER, "test", 0, 0, (char *)&ptr, 0, NULL);
1638 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
1639 ok(ptr == NULL, "Expected output pointer to be initialized to NULL, got %p\n", ptr);
1640 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1641 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1642 GetLastError());
1644 SetLastError(0xdeadbeef);
1645 memcpy(out, init_buf, sizeof(init_buf));
1646 ret = FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS, "test", 0, 0, out, sizeof(out)/sizeof(CHAR), NULL);
1647 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
1648 ok(!memcmp(out, init_buf, sizeof(init_buf)),
1649 "Expected the output buffer to be untouched\n");
1650 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1651 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1652 GetLastError());
1654 SetLastError(0xdeadbeef);
1655 memcpy(out, init_buf, sizeof(init_buf));
1656 ret = FormatMessageA(FORMAT_MESSAGE_ARGUMENT_ARRAY, "test", 0, 0, out, sizeof(out)/sizeof(CHAR), NULL);
1657 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
1658 ok(!memcmp(out, init_buf, sizeof(init_buf)),
1659 "Expected the output buffer to be untouched\n");
1660 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1661 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1662 GetLastError());
1664 SetLastError(0xdeadbeef);
1665 memcpy(out, init_buf, sizeof(init_buf));
1666 ret = FormatMessageA(FORMAT_MESSAGE_MAX_WIDTH_MASK, "test", 0, 0, out, sizeof(out)/sizeof(CHAR), NULL);
1667 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
1668 ok(!memcmp(out, init_buf, sizeof(init_buf)),
1669 "Expected the output buffer to be untouched\n");
1670 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1671 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1672 GetLastError());
1674 /* Simultaneously setting FORMAT_MESSAGE_FROM_STRING with other source
1675 * flags is apparently permissible, and FORMAT_MESSAGE_FROM_STRING takes
1676 * precedence in this case. */
1678 memcpy(out, init_buf, sizeof(init_buf));
1679 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_FROM_SYSTEM,
1680 "test", 0, 0, out, sizeof(out)/sizeof(CHAR), NULL);
1681 ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
1682 ok(!strcmp("test", out),
1683 "Expected the output buffer to be untouched\n");
1685 memcpy(out, init_buf, sizeof(init_buf));
1686 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_FROM_HMODULE,
1687 "test", 0, 0, out, sizeof(out)/sizeof(CHAR), NULL);
1688 ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
1689 ok(!strcmp("test", out),
1690 "Expected the output buffer to be untouched\n");
1692 memcpy(out, init_buf, sizeof(init_buf));
1693 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_FROM_HMODULE |
1694 FORMAT_MESSAGE_FROM_SYSTEM, "test", 0, 0, out,
1695 sizeof(out)/sizeof(CHAR), NULL);
1696 ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
1697 ok(!strcmp("test", out),
1698 "Expected the output buffer to be untouched\n");
1701 static void test_message_invalid_flags_wide(void)
1703 static const WCHAR init_buf[] = {'x', 'x', 'x', 'x', 'x'};
1704 static const WCHAR test[] = {'t','e','s','t',0};
1706 DWORD ret;
1707 WCHAR out[5];
1708 WCHAR *ptr;
1710 SetLastError(0xdeadbeef);
1711 memcpy(out, init_buf, sizeof(init_buf));
1712 ret = FormatMessageW(0, test, 0, 0, out, sizeof(out)/sizeof(WCHAR), NULL);
1713 ok(ret == 0, "Expected FormatMessageW to return 0, got %u\n", ret);
1714 ok(!memcmp(out, init_buf, sizeof(init_buf)),
1715 "Expected the output buffer to be untouched\n");
1716 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1717 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1718 GetLastError());
1720 SetLastError(0xdeadbeef);
1721 ptr = (WCHAR *)0xdeadbeef;
1722 ret = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER, test, 0, 0, (WCHAR *)&ptr, 0, NULL);
1723 ok(ret == 0, "Expected FormatMessageW to return 0, got %u\n", ret);
1724 ok(ptr == NULL, "Expected output pointer to be initialized to NULL, got %p\n", ptr);
1725 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1726 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1727 GetLastError());
1729 SetLastError(0xdeadbeef);
1730 memcpy(out, init_buf, sizeof(init_buf));
1731 ret = FormatMessageW(FORMAT_MESSAGE_IGNORE_INSERTS, test, 0, 0, out, sizeof(out)/sizeof(WCHAR), NULL);
1732 ok(ret == 0, "Expected FormatMessageW to return 0, got %u\n", ret);
1733 ok(!memcmp(out, init_buf, sizeof(init_buf)),
1734 "Expected the output buffer to be untouched\n");
1735 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1736 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1737 GetLastError());
1739 SetLastError(0xdeadbeef);
1740 memcpy(out, init_buf, sizeof(init_buf));
1741 ret = FormatMessageW(FORMAT_MESSAGE_ARGUMENT_ARRAY, test, 0, 0, out, sizeof(out)/sizeof(WCHAR), NULL);
1742 ok(ret == 0, "Expected FormatMessageW to return 0, got %u\n", ret);
1743 ok(!memcmp(out, init_buf, sizeof(init_buf)),
1744 "Expected the output buffer to be untouched\n");
1745 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1746 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1747 GetLastError());
1749 SetLastError(0xdeadbeef);
1750 memcpy(out, init_buf, sizeof(init_buf));
1751 ret = FormatMessageW(FORMAT_MESSAGE_MAX_WIDTH_MASK, test, 0, 0, out, sizeof(out)/sizeof(WCHAR), NULL);
1752 ok(ret == 0, "Expected FormatMessageW to return 0, got %u\n", ret);
1753 ok(!memcmp(out, init_buf, sizeof(init_buf)),
1754 "Expected the output buffer to be untouched\n");
1755 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1756 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1757 GetLastError());
1759 /* Simultaneously setting FORMAT_MESSAGE_FROM_STRING with other source
1760 * flags is apparently permissible, and FORMAT_MESSAGE_FROM_STRING takes
1761 * precedence in this case. */
1763 memcpy(out, init_buf, sizeof(init_buf));
1764 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_FROM_SYSTEM,
1765 test, 0, 0, out, sizeof(out)/sizeof(WCHAR), NULL);
1766 ok(ret == 4, "Expected FormatMessageW to return 4, got %u\n", ret);
1767 ok(!lstrcmpW(test, out),
1768 "Expected the output buffer to be untouched\n");
1770 memcpy(out, init_buf, sizeof(init_buf));
1771 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_FROM_HMODULE,
1772 test, 0, 0, out, sizeof(out)/sizeof(WCHAR), NULL);
1773 ok(ret == 4, "Expected FormatMessageW to return 4, got %u\n", ret);
1774 ok(!lstrcmpW(test, out),
1775 "Expected the output buffer to be untouched\n");
1777 memcpy(out, init_buf, sizeof(init_buf));
1778 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_FROM_HMODULE |
1779 FORMAT_MESSAGE_FROM_SYSTEM, test, 0, 0, out,
1780 sizeof(out)/sizeof(WCHAR), NULL);
1781 ok(ret == 4, "Expected FormatMessageW to return 4, got %u\n", ret);
1782 ok(!lstrcmpW(test, out),
1783 "Expected the output buffer to be untouched\n");
1786 static void test_message_from_64bit_number(void)
1788 static const WCHAR I64d[] = {'%', '1', '!', 'I', '6', '4', 'd', '!', 0};
1789 static const WCHAR I64u[] = {'%', '1', '!', 'I', '6', '4', 'u', '!', 0};
1790 WCHAR outW[0x100], expW[0x100];
1791 char outA[0x100];
1792 DWORD r;
1793 static const struct
1795 UINT64 number;
1796 const char expected[32];
1797 int len;
1798 } unsigned_tests[] =
1800 { 0, "0", 1 },
1801 { 1234567890, "1234567890", 10},
1802 { ULL(0xFFFFFFFF,0xFFFFFFFF), "18446744073709551615", 20 },
1803 { ULL(0x7FFFFFFF,0xFFFFFFFF), "9223372036854775807", 19 },
1805 static const struct
1807 INT64 number;
1808 const char expected[32];
1809 int len;
1810 } signed_tests[] =
1812 { 0, "0" , 1},
1813 { 1234567890, "1234567890", 10 },
1814 { -1, "-1", 2},
1815 { ULL(0xFFFFFFFF,0xFFFFFFFF), "-1", 2},
1816 { ULL(0x7FFFFFFF,0xFFFFFFFF), "9223372036854775807", 19 },
1817 { -ULL(0x7FFFFFFF,0xFFFFFFFF), "-9223372036854775807", 20},
1819 int i;
1821 for (i = 0; i < sizeof(unsigned_tests) / sizeof(unsigned_tests[0]); i++)
1823 r = doitW(FORMAT_MESSAGE_FROM_STRING, I64u,
1824 0, 0, outW, sizeof(outW) / sizeof(WCHAR), unsigned_tests[i].number);
1825 MultiByteToWideChar(CP_ACP, 0, unsigned_tests[i].expected, -1, expW, sizeof(expW) / sizeof(WCHAR));
1826 todo_wine {
1827 ok(!lstrcmpW(outW, expW),"[%d] failed, expected %s, got %s\n", i,
1828 unsigned_tests[i].expected, wine_dbgstr_w(outW));
1829 ok(r == unsigned_tests[i].len,"[%d] failed: r=%d\n", i, r);
1831 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!I64u!",
1832 0, 0, outA, sizeof(outA), unsigned_tests[i].number);
1833 todo_wine {
1834 ok(!strcmp(outA, unsigned_tests[i].expected),"[%d] failed, expected %s, got %s\n", i,
1835 unsigned_tests[i].expected, outA);
1836 ok(r == unsigned_tests[i].len,"[%d] failed: r=%d\n", i, r);
1840 for (i = 0; i < sizeof(signed_tests) / sizeof(signed_tests[0]); i++)
1842 r = doitW(FORMAT_MESSAGE_FROM_STRING, I64d,
1843 0, 0, outW, sizeof(outW) / sizeof(WCHAR), signed_tests[i].number);
1844 MultiByteToWideChar(CP_ACP, 0, signed_tests[i].expected, -1, expW, sizeof(expW) / sizeof(WCHAR));
1845 todo_wine {
1846 ok(!lstrcmpW(outW, expW),"[%d] failed, expected %s, got %s\n", i,
1847 signed_tests[i].expected, wine_dbgstr_w(outW));
1848 ok(r == signed_tests[i].len,"[%d] failed: r=%d\n", i, r);
1850 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!I64d!",
1851 0, 0, outA, sizeof(outA), signed_tests[i].number);
1852 todo_wine {
1853 ok(!strcmp(outA, signed_tests[i].expected),"[%d] failed, expected %s, got %s\n", i,
1854 signed_tests[i].expected, outA);
1855 ok(r == signed_tests[i].len,"[%d] failed: r=%d\n", i, r);
1860 START_TEST(format_msg)
1862 DWORD ret;
1864 test_message_from_string();
1865 test_message_ignore_inserts();
1866 test_message_wrap();
1867 test_message_insufficient_buffer();
1868 test_message_null_buffer();
1869 test_message_allocate_buffer();
1870 test_message_from_hmodule();
1871 test_message_invalid_flags();
1873 SetLastError(0xdeadbeef);
1874 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, NULL, 0, 0, NULL, 0, NULL);
1875 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1877 win_skip("FormatMessageW is not implemented\n");
1878 return;
1881 test_message_from_string_wide();
1882 test_message_ignore_inserts_wide();
1883 test_message_insufficient_buffer_wide();
1884 test_message_null_buffer_wide();
1885 test_message_allocate_buffer_wide();
1886 test_message_invalid_flags_wide();
1887 test_message_from_64bit_number();