winemenubuilder: Fix encoder method argument.
[wine.git] / dlls / kernel32 / tests / format_msg.c
blob57ee78af9e8d8a6b4a752cbc87009d46bdac2ec0
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, 0, out, ARRAY_SIZE(out), NULL);
140 ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out));
141 ok(r==4, "failed: r=%d\n", r);
143 /* null string, crashes on Windows */
144 if (0)
146 SetLastError(0xdeadbeef);
147 memcpy(out, init_buf, sizeof(init_buf));
148 FormatMessageW(FORMAT_MESSAGE_FROM_STRING, NULL, 0, 0, out, ARRAY_SIZE(out), NULL);
151 /* empty string */
152 SetLastError(0xdeadbeef);
153 memcpy(out, init_buf, sizeof(init_buf));
154 r = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, empty, 0, 0, out, ARRAY_SIZE(out), NULL);
155 error = GetLastError();
156 ok(!lstrcmpW(empty, out), "failed out=%s\n", wine_dbgstr_w(out));
157 ok(r==0, "succeeded: r=%d\n", r);
158 ok(error==0xdeadbeef, "last error %u\n", error);
160 /* format placeholder with no specifier */
161 SetLastError(0xdeadbeef);
162 memcpy(out, init_buf, sizeof(init_buf));
163 r = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, fmt_null, 0, 0, out, ARRAY_SIZE(out), NULL);
164 error = GetLastError();
165 ok(!memcmp(out, init_buf, sizeof(init_buf)),
166 "Expected the buffer to be unchanged\n");
167 ok(r==0, "succeeded: r=%d\n", r);
168 ok(error==ERROR_INVALID_PARAMETER, "last error %u\n", error);
170 /* test string with format placeholder with no specifier */
171 SetLastError(0xdeadbeef);
172 memcpy(out, init_buf, sizeof(init_buf));
173 r = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, fmt_tnull, 0, 0, out, ARRAY_SIZE(out), NULL);
174 error = GetLastError();
175 ok(!memcmp(out, init_buf, sizeof(init_buf)) ||
176 broken(!memcmp(out, broken_buf, sizeof(broken_buf))), /* W2K3+ */
177 "Expected the buffer to be unchanged\n");
178 ok(r==0, "succeeded: r=%d\n", r);
179 ok(error==ERROR_INVALID_PARAMETER, "last error %u\n", error);
181 /* insertion with no variadic arguments */
182 SetLastError(0xdeadbeef);
183 memcpy(out, init_buf, sizeof(init_buf));
184 r = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, fmt_1, 0, 0, out, ARRAY_SIZE(out), NULL);
185 error = GetLastError();
186 ok(!memcmp(out, init_buf, sizeof(init_buf)),
187 "Expected the buffer to be unchanged\n");
188 ok(r==0, "succeeded: r=%d\n", r);
189 ok(error==ERROR_INVALID_PARAMETER, "last error %u\n", error);
191 SetLastError(0xdeadbeef);
192 memcpy(out, init_buf, sizeof(init_buf));
193 r = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, fmt_1, 0,
194 0, out, ARRAY_SIZE(out), NULL);
195 error = GetLastError();
196 ok(!memcmp(out, init_buf, sizeof(init_buf)),
197 "Expected the buffer to be unchanged\n");
198 ok(r==0, "succeeded: r=%d\n", r);
199 ok(error==ERROR_INVALID_PARAMETER, "last error %u\n", error);
201 /* using the format feature */
202 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1s, 0, 0, out, ARRAY_SIZE(out), test);
203 ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out));
204 ok(r==4,"failed: r=%d\n", r);
206 /* no format */
207 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1, 0, 0, out, ARRAY_SIZE(out), test);
208 ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out));
209 ok(r==4,"failed: r=%d\n", r);
211 /* two pieces */
212 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_12, 0, 0, out, ARRAY_SIZE(out), te, st);
213 ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out));
214 ok(r==4,"failed: r=%d\n", r);
216 /* three pieces */
217 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_123, 0, 0, out, ARRAY_SIZE(out), t, s, e);
218 ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out));
219 ok(r==4,"failed: r=%d\n", r);
221 /* s doesn't seem to work in format strings */
222 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_s, 0, 0, out, ARRAY_SIZE(out), test);
223 ok(!lstrcmpW(&fmt_s[1], out), "failed out=%s\n", wine_dbgstr_w(out));
224 ok(r==3, "failed: r=%d\n", r);
226 /* nor ls */
227 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_ls, 0, 0, out, ARRAY_SIZE(out), test);
228 ok(!lstrcmpW(&fmt_ls[1], out), "failed out=%s\n", wine_dbgstr_w(out));
229 ok(r==4, "failed: r=%d\n", r);
231 /* nor S */
232 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_S, 0, 0, out, ARRAY_SIZE(out), test);
233 ok(!lstrcmpW(&fmt_S[1], out), "failed out=%s\n", wine_dbgstr_w(out));
234 ok(r==3, "failed: r=%d\n", r);
236 /* nor ws */
237 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_ws, 0, 0, out, ARRAY_SIZE(out), test);
238 ok(!lstrcmpW(&fmt_ws[1], out), "failed out=%s\n", wine_dbgstr_w(out));
239 ok(r==4, "failed: r=%d\n", r);
241 /* as characters */
242 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_123c, 0, 0, out, ARRAY_SIZE(out), 't', 'e', 's');
243 ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out));
244 ok(r==4,"failed: r=%d\n", r);
246 /* lc is unicode */
247 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_123lc, 0, 0, out, ARRAY_SIZE(out), 't', 'e', 's');
248 ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out));
249 ok(r==4,"failed: r=%d\n", r);
251 /* wc is unicode */
252 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_123wc, 0, 0, out, ARRAY_SIZE(out), 't', 'e', 's');
253 ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out));
254 ok(r==4,"failed: r=%d\n", r);
256 /* C is unicode */
257 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_123C, 0, 0, out, ARRAY_SIZE(out), '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 /* some numbers */
262 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_123d, 0, 0, out, ARRAY_SIZE(out), 1, 2, 3);
263 ok(!lstrcmpW(s_123d, out), "failed out=%s\n", wine_dbgstr_w(out));
264 ok(r==3,"failed: r=%d\n", r);
266 /* a single digit with some spacing */
267 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_14d, 0, 0, out, ARRAY_SIZE(out), 1);
268 ok(!lstrcmpW(s_14d, out), "failed out=%s\n", wine_dbgstr_w(out));
269 ok(r==4,"failed: r=%d\n", r);
271 /* a single digit, left justified */
272 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1_4d, 0, 0, out, ARRAY_SIZE(out), 1);
273 ok(!lstrcmpW(s_1_4d, out), "failed out=%s\n", wine_dbgstr_w(out));
274 ok(r==4,"failed: r=%d\n", r);
276 /* two digit decimal number */
277 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_14d, 0, 0, out, ARRAY_SIZE(out), 11);
278 ok(!lstrcmpW(s_14d2, out), "failed out=%s\n", wine_dbgstr_w(out));
279 ok(r==4,"failed: r=%d\n", r);
281 /* a hex number */
282 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_14x, 0, 0, out, ARRAY_SIZE(out), 11);
283 ok(!lstrcmpW(s_14x, out), "failed out=%s\n", wine_dbgstr_w(out));
284 ok(r==4,"failed: r=%d\n", r);
286 /* a hex number, upper case */
287 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_14X, 0, 0, out, ARRAY_SIZE(out), 11);
288 ok(!lstrcmpW(s_14X, out), "failed out=%s\n", wine_dbgstr_w(out));
289 ok(r==4,"failed: r=%d\n", r);
291 /* a hex number, upper case, left justified */
292 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1_4X, 0, 0, out, ARRAY_SIZE(out), 11);
293 ok(!lstrcmpW(s_1_4X, out), "failed out=%s\n", wine_dbgstr_w(out));
294 ok(r==4,"failed: r=%d\n", r);
296 /* a long hex number, upper case */
297 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_14X, 0, 0, out, ARRAY_SIZE(out), 0x1ab);
298 ok(!lstrcmpW(s_1AB, out), "failed out=%s\n", wine_dbgstr_w(out));
299 ok(r==4,"failed: r=%d\n", r);
301 /* two percent... */
302 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_2pct, 0, 0, out, ARRAY_SIZE(out));
303 ok(!lstrcmpW(s_2pct, out), "failed out=%s\n", wine_dbgstr_w(out));
304 ok(r==4,"failed: r=%d\n", r);
306 /* periods are special cases */
307 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_2dot1d, 0, 0, out, ARRAY_SIZE(out), 0x1ab);
308 ok(!lstrcmpW(s_2dot147, out), "failed out=%s\n", wine_dbgstr_w(out));
309 ok(r==8,"failed: r=%d\n", r);
311 /* %0 ends the line */
312 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_t0t, 0, 0, out, ARRAY_SIZE(out));
313 ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out));
314 ok(r==4,"failed: r=%d\n", r);
316 /* %! prints an exclamation */
317 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_yah, 0, 0, out, ARRAY_SIZE(out));
318 ok(!lstrcmpW(s_yah, out), "failed out=%s\n", wine_dbgstr_w(out));
319 ok(r==4,"failed: r=%d\n", r);
321 /* %space */
322 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_space, 0, 0, out, ARRAY_SIZE(out));
323 ok(!lstrcmpW(s_space, out), "failed out=%s\n", wine_dbgstr_w(out));
324 ok(r==4,"failed: r=%d\n", r);
326 /* %n yields \r\n, %r yields \r, %t yields \t */
327 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_nrt, 0, 0, out, ARRAY_SIZE(out));
328 ok(!lstrcmpW(s_nrt, out), "failed out=%s\n", wine_dbgstr_w(out));
329 ok(r==4,"failed: r=%d\n", r);
331 /* line feed */
332 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_hi_lf, 0, 0, out, ARRAY_SIZE(out));
333 ok(!lstrcmpW(s_hi_crlf, out), "failed out=%s\n", wine_dbgstr_w(out));
334 ok(r==4,"failed: r=%d\n", r);
336 /* carriage return line feed */
337 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_hi_crlf, 0, 0, out, ARRAY_SIZE(out));
338 ok(!lstrcmpW(s_hi_crlf, out), "failed out=%s\n", wine_dbgstr_w(out));
339 ok(r==4,"failed: r=%d\n", r);
341 /* carriage return */
342 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_cr, 0, 0, out, ARRAY_SIZE(out));
343 ok(!lstrcmpW(s_crlf, out), "failed out=%s\n", wine_dbgstr_w(out));
344 ok(r==2,"failed: r=%d\n", r);
346 /* double carriage return line feed */
347 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_crcrlf, 0, 0, out, ARRAY_SIZE(out));
348 ok(!lstrcmpW(s_crlfcrlf, out), "failed out=%s\n", wine_dbgstr_w(out));
349 ok(r==4,"failed: r=%d\n", r);
351 /* null string as argument */
352 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1, 0, 0, out, ARRAY_SIZE(out), NULL);
353 ok(!lstrcmpW(s_null, out),"failed out=[%s]\n", wine_dbgstr_w(out));
354 ok(r==6,"failed: r=%d\n",r);
356 /* precision and width */
358 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_13s, 0, 0, out, ARRAY_SIZE(out), t );
359 ok(!lstrcmpW(s_spt, out),"failed out=[%s]\n", wine_dbgstr_w(out));
360 ok(r==3, "failed: r=%d\n",r);
361 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1os, 0, 0, out, ARRAY_SIZE(out), 4, t );
362 ok(!lstrcmpW( s_sp3t, out),"failed out=[%s]\n", wine_dbgstr_w(out));
363 ok(r==4,"failed: r=%d\n",r);
364 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_142u, 0, 0, out, ARRAY_SIZE(out), 3 );
365 ok(!lstrcmpW( s_sp03, out),"failed out=[%s]\n", wine_dbgstr_w(out));
366 ok(r==4,"failed: r=%d\n",r);
367 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1oou, 0, 0, out, ARRAY_SIZE(out), 5, 3, 1 );
368 ok(!lstrcmpW( s_sp001, out),"failed out=[%s]\n", wine_dbgstr_w(out));
369 ok(r==5,"failed: r=%d\n",r);
370 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1oou1oou, 0, 0, out, ARRAY_SIZE(out),
371 5, 3, 1, 4, 2 );
372 ok(!lstrcmpW( s_sp001002, out),"failed out=[%s]\n", wine_dbgstr_w(out));
373 ok(r==11,"failed: r=%d\n",r);
374 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1oou3oou, 0, 0, out, ARRAY_SIZE(out),
375 5, 3, 1, 6, 4, 2 );
376 ok(!lstrcmpW( s_sp001sp002, out) ||
377 broken(!lstrcmpW(s_sp001004, out)), /* NT4/Win2k */
378 "failed out=[%s]\n", wine_dbgstr_w(out));
379 ok(r==12,"failed: r=%d\n",r);
380 /* args are not counted the same way with an argument array */
382 ULONG_PTR args[] = { 6, 4, 2, 5, 3, 1 };
383 r = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, fmt_1oou1oou,
384 0, 0, out, ARRAY_SIZE(out), (__ms_va_list *)args );
385 ok(!lstrcmpW(s_sp002sp003, out),"failed out=[%s]\n", wine_dbgstr_w(out));
386 ok(r==13,"failed: r=%d\n",r);
387 r = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, fmt_1oou4oou,
388 0, 0, out, ARRAY_SIZE(out), (__ms_va_list *)args );
389 ok(!lstrcmpW(s_sp002sp001, out),"failed out=[%s]\n", wine_dbgstr_w(out));
390 ok(r==12,"failed: r=%d\n",r);
393 /* change of pace... test the low byte of dwflags */
395 /* line feed */
396 r = doitW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, fmt_hi_lf, 0,
397 0, out, ARRAY_SIZE(out));
398 ok(!lstrcmpW(s_hi_sp, out), "failed out=%s\n", wine_dbgstr_w(out));
399 ok(r==3,"failed: r=%d\n", r);
401 /* carriage return line feed */
402 r = doitW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, fmt_hi_crlf, 0,
403 0, out, ARRAY_SIZE(out));
404 ok(!lstrcmpW(s_hi_sp, out), "failed out=%s\n", wine_dbgstr_w(out));
405 ok(r==3,"failed: r=%d\n", r);
407 /* carriage return */
408 r = doitW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, fmt_cr, 0,
409 0, out, ARRAY_SIZE(out));
410 ok(!lstrcmpW(s_sp, out), "failed out=%s\n", wine_dbgstr_w(out));
411 ok(r==1,"failed: r=%d\n", r);
413 /* double carriage return line feed */
414 r = doitW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, fmt_crcrlf, 0,
415 0, out, ARRAY_SIZE(out));
416 ok(!lstrcmpW(s_2sp, out), "failed out=%s\n", wine_dbgstr_w(out));
417 ok(r==2,"failed: r=%d\n", r);
420 static void test_message_from_string(void)
422 CHAR out[0x100] = {0};
423 DWORD r;
424 static const char init_buf[] = {'x', 'x', 'x', 'x', 'x', 'x'};
425 static const WCHAR szwTest[] = { 't','e','s','t',0};
427 /* the basics */
428 r = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, "test", 0, 0, out, ARRAY_SIZE(out),NULL);
429 ok(!strcmp("test", out),"failed out=[%s]\n",out);
430 ok(r==4,"failed: r=%d\n",r);
432 /* null string, crashes on Windows */
433 if (0)
435 SetLastError(0xdeadbeef);
436 memcpy(out, init_buf, sizeof(init_buf));
437 FormatMessageA(FORMAT_MESSAGE_FROM_STRING, NULL, 0, 0, out, ARRAY_SIZE(out), NULL);
440 /* empty string */
441 SetLastError(0xdeadbeef);
442 memcpy(out, init_buf, sizeof(init_buf));
443 r = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, "", 0, 0, out, ARRAY_SIZE(out), NULL);
444 ok(!memcmp(out, init_buf, sizeof(init_buf)), "Expected the buffer to be untouched\n");
445 ok(r==0, "succeeded: r=%d\n", r);
446 ok(GetLastError()==0xdeadbeef,
447 "last error %u\n", GetLastError());
449 /* format placeholder with no specifier */
450 SetLastError(0xdeadbeef);
451 memcpy(out, init_buf, sizeof(init_buf));
452 r = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, "%", 0, 0, out, ARRAY_SIZE(out), NULL);
453 ok(!memcmp(out, init_buf, sizeof(init_buf)),
454 "Expected the buffer to be untouched\n");
455 ok(r==0, "succeeded: r=%d\n", r);
456 ok(GetLastError()==ERROR_INVALID_PARAMETER,
457 "last error %u\n", GetLastError());
459 /* test string with format placeholder with no specifier */
460 SetLastError(0xdeadbeef);
461 memcpy(out, init_buf, sizeof(init_buf));
462 r = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, "test%", 0, 0, out, ARRAY_SIZE(out), NULL);
463 ok(!memcmp(out, init_buf, sizeof(init_buf)),
464 "Expected the buffer to be untouched\n");
465 ok(r==0, "succeeded: r=%d\n", r);
466 ok(GetLastError()==ERROR_INVALID_PARAMETER,
467 "last error %u\n", GetLastError());
469 /* insertion with no variadic arguments */
470 SetLastError(0xdeadbeef);
471 memcpy(out, init_buf, sizeof(init_buf));
472 r = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, "%1", 0, 0, out, ARRAY_SIZE(out), NULL);
473 ok(!memcmp(out, init_buf, sizeof(init_buf)), "Expected the buffer to be untouched\n");
474 ok(r==0, "succeeded: r=%d\n", r);
475 ok(GetLastError()==ERROR_INVALID_PARAMETER, "last error %u\n", GetLastError());
477 SetLastError(0xdeadbeef);
478 memcpy(out, init_buf, sizeof(init_buf));
479 r = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, "%1", 0,
480 0, out, ARRAY_SIZE(out), NULL);
481 ok(!memcmp(out, init_buf, sizeof(init_buf)), "Expected the buffer to be untouched\n");
482 ok(r==0, "succeeded: r=%d\n", r);
483 ok(GetLastError()==ERROR_INVALID_PARAMETER, "last error %u\n", GetLastError());
485 /* using the format feature */
486 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!s!", 0, 0, out, ARRAY_SIZE(out), "test");
487 ok(!strcmp("test", out),"failed out=[%s]\n",out);
488 ok(r==4,"failed: r=%d\n",r);
490 /* no format */
491 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1", 0, 0, out, ARRAY_SIZE(out), "test");
492 ok(!strcmp("test", out),"failed out=[%s]\n",out);
493 ok(r==4,"failed: r=%d\n",r);
495 /* two pieces */
496 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1%2", 0, 0, out, ARRAY_SIZE(out), "te","st");
497 ok(!strcmp("test", out),"failed out=[%s]\n",out);
498 ok(r==4,"failed: r=%d\n",r);
500 /* three pieces */
501 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1%3%2%1", 0, 0, out, ARRAY_SIZE(out), "t","s","e");
502 ok(!strcmp("test", out),"failed out=[%s]\n",out);
503 ok(r==4,"failed: r=%d\n",r);
505 /* s doesn't seem to work in format strings */
506 r = doit(FORMAT_MESSAGE_FROM_STRING, "%!s!", 0, 0, out, ARRAY_SIZE(out), "test");
507 ok(!strcmp("!s!", out),"failed out=[%s]\n",out);
508 ok(r==3,"failed: r=%d\n",r);
510 /* ls is unicode */
511 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!ls!", 0, 0, out, ARRAY_SIZE(out), szwTest);
512 ok(!strcmp("test", out),"failed out=[%s]\n",out);
513 ok(r==4,"failed: r=%d\n",r);
515 /* S is unicode */
516 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!S!", 0, 0, out, ARRAY_SIZE(out), szwTest);
517 ok(!strcmp("test", out),"failed out=[%s]\n",out);
518 ok(r==4,"failed: r=%d\n",r);
520 /* ws is unicode */
521 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!ws!", 0, 0, out, ARRAY_SIZE(out), szwTest);
522 ok(!strcmp("test", out),"failed out=[%s]\n",out);
523 ok(r==4,"failed: r=%d\n",r);
525 /* as characters */
526 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!c!%2!c!%3!c!%1!c!", 0, 0, out, ARRAY_SIZE(out),
527 't','e','s');
528 ok(!strcmp("test", out),"failed out=[%s]\n",out);
529 ok(r==4,"failed: r=%d\n",r);
531 /* lc is unicode */
532 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!lc!%2!lc!%3!lc!%1!lc!", 0, 0, out, ARRAY_SIZE(out),
533 't','e','s');
534 ok(!strcmp("test", out),"failed out=[%s]\n",out);
535 ok(r==4,"failed: r=%d\n",r);
537 /* wc is unicode */
538 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!wc!%2!wc!%3!wc!%1!wc!", 0, 0, out, ARRAY_SIZE(out),
539 't','e','s');
540 ok(!strcmp("test", out),"failed out=[%s]\n",out);
541 ok(r==4,"failed: r=%d\n",r);
543 /* C is unicode */
544 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!C!%2!C!%3!C!%1!C!", 0, 0, out, ARRAY_SIZE(out),
545 't','e','s');
546 ok(!strcmp("test", out),"failed out=[%s]\n",out);
547 ok(r==4,"failed: r=%d\n",r);
549 /* some numbers */
550 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!d!%2!d!%3!d!", 0, 0, out, ARRAY_SIZE(out), 1,2,3);
551 ok(!strcmp("123", out),"failed out=[%s]\n",out);
552 ok(r==3,"failed: r=%d\n",r);
554 /* a single digit with some spacing */
555 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!4d!", 0, 0, out, ARRAY_SIZE(out), 1);
556 ok(!strcmp(" 1", out),"failed out=[%s]\n",out);
557 ok(r==4,"failed: r=%d\n",r);
559 /* a single digit, left justified */
560 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!-4d!", 0, 0, out, ARRAY_SIZE(out), 1);
561 ok(!strcmp("1 ", out),"failed out=[%s]\n",out);
562 ok(r==4,"failed: r=%d\n",r);
564 /* two digit decimal number */
565 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!4d!", 0, 0, out, ARRAY_SIZE(out), 11);
566 ok(!strcmp(" 11", out),"failed out=[%s]\n",out);
567 ok(r==4,"failed: r=%d\n",r);
569 /* a hex number */
570 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!4x!", 0, 0, out, ARRAY_SIZE(out), 11);
571 ok(!strcmp(" b", out),"failed out=[%s]\n",out);
572 ok(r==4,"failed: r=%d\n",r);
574 /* a hex number, upper case */
575 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!4X!", 0, 0, out, ARRAY_SIZE(out), 11);
576 ok(!strcmp(" B", out),"failed out=[%s]\n",out);
577 ok(r==4,"failed: r=%d\n",r);
579 /* a hex number, upper case, left justified */
580 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!-4X!", 0, 0, out, ARRAY_SIZE(out), 11);
581 ok(!strcmp("B ", out),"failed out=[%s]\n",out);
582 ok(r==4,"failed: r=%d\n",r);
584 /* a long hex number, upper case */
585 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!4X!", 0, 0, out, ARRAY_SIZE(out), 0x1ab);
586 ok(!strcmp(" 1AB", out),"failed out=[%s]\n",out);
587 ok(r==4,"failed: r=%d\n",r);
589 /* two percent... */
590 r = doit(FORMAT_MESSAGE_FROM_STRING, " %%%% ", 0, 0, out, ARRAY_SIZE(out));
591 ok(!strcmp(" %% ", out),"failed out=[%s]\n",out);
592 ok(r==4,"failed: r=%d\n",r);
594 /* periods are special cases */
595 r = doit(FORMAT_MESSAGE_FROM_STRING, " %.%. %1!d!", 0, 0, out, ARRAY_SIZE(out), 0x1ab);
596 ok(!strcmp(" .. 427", out),"failed out=[%s]\n",out);
597 ok(r==7,"failed: r=%d\n",r);
599 /* %0 ends the line */
600 r = doit(FORMAT_MESSAGE_FROM_STRING, "test%0test", 0, 0, out, ARRAY_SIZE(out));
601 ok(!strcmp("test", out),"failed out=[%s]\n",out);
602 ok(r==4,"failed: r=%d\n",r);
604 /* %! prints an exclamation */
605 r = doit(FORMAT_MESSAGE_FROM_STRING, "yah%!%0 ", 0, 0, out, ARRAY_SIZE(out));
606 ok(!strcmp("yah!", out),"failed out=[%s]\n",out);
607 ok(r==4,"failed: r=%d\n",r);
609 /* %space */
610 r = doit(FORMAT_MESSAGE_FROM_STRING, "% % ", 0, 0, out, ARRAY_SIZE(out));
611 ok(!strcmp(" ", out),"failed out=[%s]\n",out);
612 ok(r==4,"failed: r=%d\n",r);
614 /* %n yields \r\n, %r yields \r, %t yields \t */
615 r = doit(FORMAT_MESSAGE_FROM_STRING, "%n%r%t", 0, 0, out, ARRAY_SIZE(out));
616 ok(!strcmp("\r\n\r\t", out),"failed out=[%s]\n",out);
617 ok(r==4,"failed: r=%d\n",r);
619 /* line feed */
620 r = doit(FORMAT_MESSAGE_FROM_STRING, "hi\n", 0, 0, out, ARRAY_SIZE(out));
621 ok(!strcmp("hi\r\n", out),"failed out=[%s]\n",out);
622 ok(r==4,"failed: r=%d\n",r);
624 /* carriage return line feed */
625 r = doit(FORMAT_MESSAGE_FROM_STRING, "hi\r\n", 0, 0, out, ARRAY_SIZE(out));
626 ok(!strcmp("hi\r\n", out),"failed out=[%s]\n",out);
627 ok(r==4,"failed: r=%d\n",r);
629 /* carriage return */
630 r = doit(FORMAT_MESSAGE_FROM_STRING, "\r", 0, 0, out, ARRAY_SIZE(out));
631 ok(!strcmp("\r\n", out),"failed out=[%s]\n",out);
632 ok(r==2,"failed: r=%d\n",r);
634 /* double carriage return line feed */
635 r = doit(FORMAT_MESSAGE_FROM_STRING, "\r\r\n", 0, 0, out, ARRAY_SIZE(out));
636 ok(!strcmp("\r\n\r\n", out),"failed out=[%s]\n",out);
637 ok(r==4,"failed: r=%d\n",r);
639 /* null string as argument */
640 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1", 0, 0, out, ARRAY_SIZE(out), NULL);
641 ok(!strcmp("(null)", out),"failed out=[%s]\n",out);
642 ok(r==6,"failed: r=%d\n",r);
644 /* precision and width */
646 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!3s!",
647 0, 0, out, sizeof(out), "t" );
648 ok(!strcmp(" t", out),"failed out=[%s]\n",out);
649 ok(r==3, "failed: r=%d\n",r);
650 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!*s!",
651 0, 0, out, sizeof(out), 4, "t");
652 if (!strcmp("*s",out)) win_skip( "width/precision not supported\n" );
653 else
655 ok(!strcmp( " t", out),"failed out=[%s]\n",out);
656 ok(r==4,"failed: r=%d\n",r);
657 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!4.2u!",
658 0, 0, out, sizeof(out), 3 );
659 ok(!strcmp( " 03", out),"failed out=[%s]\n",out);
660 ok(r==4,"failed: r=%d\n",r);
661 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!*.*u!",
662 0, 0, out, sizeof(out), 5, 3, 1 );
663 ok(!strcmp( " 001", out),"failed out=[%s]\n",out);
664 ok(r==5,"failed: r=%d\n",r);
665 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!*.*u!,%1!*.*u!",
666 0, 0, out, sizeof(out), 5, 3, 1, 4, 2 );
667 ok(!strcmp( " 001, 0002", out),"failed out=[%s]\n",out);
668 ok(r==11,"failed: r=%d\n",r);
669 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!*.*u!,%3!*.*u!",
670 0, 0, out, sizeof(out), 5, 3, 1, 6, 4, 2 );
671 /* older Win versions marked as broken even though this is arguably the correct behavior */
672 /* but the new (brain-damaged) behavior is specified on MSDN */
673 ok(!strcmp( " 001, 0002", out) ||
674 broken(!strcmp(" 001,000004", out)), /* NT4/Win2k */
675 "failed out=[%s]\n",out);
676 ok(r==12,"failed: r=%d\n",r);
677 /* args are not counted the same way with an argument array */
679 ULONG_PTR args[] = { 6, 4, 2, 5, 3, 1 };
680 r = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
681 "%1!*.*u!,%1!*.*u!", 0, 0, out, sizeof(out), (__ms_va_list *)args );
682 ok(!strcmp(" 0002, 00003", out),"failed out=[%s]\n",out);
683 ok(r==13,"failed: r=%d\n",r);
684 r = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
685 "%1!*.*u!,%4!*.*u!", 0, 0, out, sizeof(out), (__ms_va_list *)args );
686 ok(!strcmp(" 0002, 001", out),"failed out=[%s]\n",out);
687 ok(r==12,"failed: r=%d\n",r);
691 /* change of pace... test the low byte of dwflags */
693 /* line feed */
694 r = doit(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, "hi\n", 0,
695 0, out, ARRAY_SIZE(out));
696 ok(!strcmp("hi ", out), "failed out=[%s]\n",out);
697 ok(r==3, "failed: r=%d\n",r);
699 /* carriage return line feed */
700 r = doit(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, "hi\r\n", 0,
701 0, out, ARRAY_SIZE(out));
702 ok(!strcmp("hi ", out),"failed out=[%s]\n",out);
703 ok(r==3,"failed: r=%d\n",r);
705 /* carriage return */
706 r = doit(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, "\r", 0,
707 0, out, ARRAY_SIZE(out));
708 ok(!strcmp(" ", out),"failed out=[%s]\n",out);
709 ok(r==1,"failed: r=%d\n",r);
711 /* double carriage return line feed */
712 r = doit(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, "\r\r\n", 0,
713 0, out, ARRAY_SIZE(out));
714 ok(!strcmp(" ", out),"failed out=[%s]\n",out);
715 ok(r==2,"failed: r=%d\n",r);
718 static void test_message_ignore_inserts(void)
720 static const char init_buf[] = {'x', 'x', 'x', 'x', 'x'};
722 DWORD ret;
723 CHAR out[256];
725 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, "test", 0, 0, out,
726 ARRAY_SIZE(out), NULL);
727 ok(ret == 4, "Expected FormatMessageA to return 4, got %d\n", ret);
728 ok(!strcmp("test", out), "Expected output string \"test\", got %s\n", out);
730 /* The %0 escape sequence is handled. */
731 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, "test%0", 0, 0, out,
732 ARRAY_SIZE(out), NULL);
733 ok(ret == 4, "Expected FormatMessageA to return 4, got %d\n", ret);
734 ok(!strcmp("test", out), "Expected output string \"test\", got %s\n", out);
736 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, "test%0test", 0, 0, out,
737 ARRAY_SIZE(out), NULL);
738 ok(ret == 4, "Expected FormatMessageA to return 4, got %d\n", ret);
739 ok(!strcmp("test", out), "Expected output string \"test\", got %s\n", out);
741 /* While FormatMessageA returns 0 in this case, no last error code is set. */
742 SetLastError(0xdeadbeef);
743 memcpy(out, init_buf, sizeof(init_buf));
744 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, "%0test", 0, 0, out,
745 ARRAY_SIZE(out), NULL);
746 ok(ret == 0, "Expected FormatMessageA to return 0, got %d\n", ret);
747 ok(!memcmp(out, init_buf, sizeof(init_buf)), "Expected the output buffer to be untouched\n");
748 ok(GetLastError() == 0xdeadbeef, "Expected GetLastError() to return 0xdeadbeef, got %u\n", GetLastError());
750 /* Insert sequences are ignored. */
751 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, "test%1%2!*.*s!%99", 0, 0, out,
752 ARRAY_SIZE(out), NULL);
753 ok(ret == 17, "Expected FormatMessageA to return 17, got %d\n", ret);
754 ok(!strcmp("test%1%2!*.*s!%99", out), "Expected output string \"test%%1%%2!*.*s!%%99\", got %s\n", out);
756 /* Only the "%n", "%r", and "%t" escape sequences are processed. */
757 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, "%%% %.%!", 0, 0, out,
758 ARRAY_SIZE(out), NULL);
759 ok(ret == 8, "Expected FormatMessageA to return 8, got %d\n", ret);
760 ok(!strcmp("%%% %.%!", out), "Expected output string \"%%%%%% %%.%%!\", got %s\n", out);
762 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, "%n%r%t", 0, 0, out,
763 ARRAY_SIZE(out), NULL);
764 ok(ret == 4, "Expected FormatMessageA to return 4, got %d\n", ret);
765 ok(!strcmp("\r\n\r\t", out), "Expected output string \"\\r\\n\\r\\t\", got %s\n", out);
767 /* CRLF characters are processed normally. */
768 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, "hi\n", 0, 0, out,
769 ARRAY_SIZE(out), NULL);
770 ok(ret == 4, "Expected FormatMessageA to return 4, got %d\n", ret);
771 ok(!strcmp("hi\r\n", out), "Expected output string \"hi\\r\\n\", got %s\n", out);
773 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, "hi\r\n", 0, 0, out,
774 ARRAY_SIZE(out), NULL);
775 ok(ret == 4, "Expected FormatMessageA to return 4, got %d\n", ret);
776 ok(!strcmp("hi\r\n", out), "Expected output string \"hi\\r\\n\", got %s\n", out);
778 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, "\r", 0, 0, out,
779 ARRAY_SIZE(out), NULL);
780 ok(ret == 2, "Expected FormatMessageA to return 2, got %d\n", ret);
781 ok(!strcmp("\r\n", out), "Expected output string \"\\r\\n\", got %s\n", out);
783 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, "\r\r\n", 0, 0, out,
784 ARRAY_SIZE(out), NULL);
785 ok(ret == 4, "Expected FormatMessageA to return 4, got %d\n", ret);
786 ok(!strcmp("\r\n\r\n", out), "Expected output string \"\\r\\n\\r\\n\", got %s\n", out);
788 /* The width parameter is handled the same also. */
789 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS |
790 FORMAT_MESSAGE_MAX_WIDTH_MASK, "hi\n", 0, 0, out, ARRAY_SIZE(out), NULL);
791 ok(!strcmp("hi ", out), "Expected output string \"hi \", got %s\n", out);
792 ok(ret == 3, "Expected FormatMessageA to return 3, got %d\n", ret);
794 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS |
795 FORMAT_MESSAGE_MAX_WIDTH_MASK, "hi\r\n", 0, 0, out, ARRAY_SIZE(out), NULL);
796 ok(ret == 3, "Expected FormatMessageA to return 3, got %d\n", ret);
797 ok(!strcmp("hi ", out), "Expected output string \"hi \", got %s\n", out);
799 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS |
800 FORMAT_MESSAGE_MAX_WIDTH_MASK, "\r", 0, 0, out, ARRAY_SIZE(out), NULL);
801 ok(ret == 1, "Expected FormatMessageA to return 1, got %d\n", ret);
802 ok(!strcmp(" ", out), "Expected output string \" \", got %s\n", out);
804 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS |
805 FORMAT_MESSAGE_MAX_WIDTH_MASK, "\r\r\n", 0, 0, out, ARRAY_SIZE(out), NULL);
806 ok(ret == 2, "Expected FormatMessageA to return 2, got %d\n", ret);
807 ok(!strcmp(" ", out), "Expected output string \" \", got %s\n", out);
810 static void test_message_ignore_inserts_wide(void)
812 static const WCHAR test[] = {'t','e','s','t',0};
813 static const WCHAR empty[] = {0};
814 static const WCHAR fmt_t0[] = {'t','e','s','t','%','0',0};
815 static const WCHAR fmt_t0t[] = {'t','e','s','t','%','0','t','e','s','t',0};
816 static const WCHAR fmt_0t[] = {'%','0','t','e','s','t',0};
817 static const WCHAR fmt_t12oos99[] = {'t','e','s','t','%','1','%','2','!','*','.','*','s','!','%','9','9',0};
818 static const WCHAR fmt_pctspacedot[] = {'%','%','%',' ','%','.','%','!',0};
819 static const WCHAR fmt_nrt[] = {'%','n','%','r','%','t',0};
820 static const WCHAR fmt_hi_lf[] = {'h','i','\n',0};
821 static const WCHAR fmt_hi_crlf[] = {'h','i','\r','\n',0};
822 static const WCHAR fmt_cr[] = {'\r',0};
823 static const WCHAR fmt_crcrlf[] = {'\r','\r','\n',0};
825 static const WCHAR s_nrt[] = {'\r','\n','\r','\t',0};
826 static const WCHAR s_hi_crlf[] = {'h','i','\r','\n',0};
827 static const WCHAR s_crlf[] = {'\r','\n',0};
828 static const WCHAR s_crlfcrlf[] = {'\r','\n','\r','\n',0};
829 static const WCHAR s_hi_sp[] = {'h','i',' ',0};
830 static const WCHAR s_sp[] = {' ',0};
831 static const WCHAR s_2sp[] = {' ',' ',0};
833 DWORD ret;
834 WCHAR out[256];
836 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, test, 0, 0, out,
837 ARRAY_SIZE(out), NULL);
838 ok(ret == 4, "Expected FormatMessageW to return 4, got %d\n", ret);
839 ok(!lstrcmpW(test, out), "Expected output string \"test\", got %s\n", wine_dbgstr_w(out));
841 /* The %0 escape sequence is handled. */
842 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, fmt_t0, 0, 0, out,
843 ARRAY_SIZE(out), NULL);
844 ok(ret == 4, "Expected FormatMessageW to return 4, got %d\n", ret);
845 ok(!lstrcmpW(test, out), "Expected output string \"test\", got %s\n", wine_dbgstr_w(out));
847 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, fmt_t0t, 0, 0, out,
848 ARRAY_SIZE(out), NULL);
849 ok(ret == 4, "Expected FormatMessageW to return 4, got %d\n", ret);
850 ok(!lstrcmpW(test, out), "Expected output string \"test\", got %s\n", wine_dbgstr_w(out));
852 /* While FormatMessageA returns 0 in this case, no last error code is set. */
853 SetLastError(0xdeadbeef);
854 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, fmt_0t, 0, 0, out,
855 ARRAY_SIZE(out), NULL);
856 ok(ret == 0, "Expected FormatMessageW to return 0, got %d\n", ret);
857 ok(!lstrcmpW(empty, out), "Expected the output buffer to be the empty string, got %s\n", wine_dbgstr_w(out));
858 ok(GetLastError() == 0xdeadbeef, "Expected GetLastError() to return 0xdeadbeef, got %u\n", GetLastError());
860 /* Insert sequences are ignored. */
861 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, fmt_t12oos99, 0, 0, out,
862 ARRAY_SIZE(out), NULL);
863 ok(ret == 17, "Expected FormatMessageW to return 17, got %d\n", ret);
864 ok(!lstrcmpW(fmt_t12oos99, out), "Expected output string \"test%%1%%2!*.*s!%%99\", got %s\n", wine_dbgstr_w(out));
866 /* Only the "%n", "%r", and "%t" escape sequences are processed. */
867 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, fmt_pctspacedot, 0, 0, out,
868 ARRAY_SIZE(out), NULL);
869 ok(ret == 8, "Expected FormatMessageW to return 8, got %d\n", ret);
870 ok(!lstrcmpW(fmt_pctspacedot, out), "Expected output string \"%%%%%% %%.%%!\", got %s\n", wine_dbgstr_w(out));
872 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, fmt_nrt, 0, 0, out,
873 ARRAY_SIZE(out), NULL);
874 ok(ret == 4, "Expected FormatMessageW to return 4, got %d\n", ret);
875 ok(!lstrcmpW(s_nrt, out), "Expected output string \"\\r\\n\\r\\t\", got %s\n", wine_dbgstr_w(out));
877 /* CRLF characters are processed normally. */
878 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, fmt_hi_lf, 0, 0, out,
879 ARRAY_SIZE(out), NULL);
880 ok(ret == 4, "Expected FormatMessageW to return 4, got %d\n", ret);
881 ok(!lstrcmpW(s_hi_crlf, out), "Expected output string \"hi\\r\\n\", got %s\n", wine_dbgstr_w(out));
883 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, fmt_hi_crlf, 0, 0, out,
884 ARRAY_SIZE(out), NULL);
885 ok(ret == 4, "Expected FormatMessageW to return 4, got %d\n", ret);
886 ok(!lstrcmpW(s_hi_crlf, out), "Expected output string \"hi\\r\\n\", got %s\n", wine_dbgstr_w(out));
888 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, fmt_cr, 0, 0, out,
889 ARRAY_SIZE(out), NULL);
890 ok(ret == 2, "Expected FormatMessageW to return 2, got %d\n", ret);
891 ok(!lstrcmpW(s_crlf, out), "Expected output string \"\\r\\n\", got %s\n", wine_dbgstr_w(out));
893 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, fmt_crcrlf, 0, 0, out,
894 ARRAY_SIZE(out), NULL);
895 ok(ret == 4, "Expected FormatMessageW to return 4, got %d\n", ret);
896 ok(!lstrcmpW(s_crlfcrlf, out), "Expected output string \"\\r\\n\\r\\n\", got %s\n", wine_dbgstr_w(out));
898 /* The width parameter is handled the same also. */
899 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS |
900 FORMAT_MESSAGE_MAX_WIDTH_MASK, fmt_hi_lf, 0, 0, out,
901 ARRAY_SIZE(out), NULL);
902 ok(ret == 3, "Expected FormatMessageW to return 3, got %d\n", ret);
903 ok(!lstrcmpW(s_hi_sp, out), "Expected output string \"hi \", got %s\n", wine_dbgstr_w(out));
905 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS |
906 FORMAT_MESSAGE_MAX_WIDTH_MASK, fmt_hi_crlf, 0, 0, out,
907 ARRAY_SIZE(out), NULL);
908 ok(ret == 3, "Expected FormatMessageW to return 3, got %d\n", ret);
909 ok(!lstrcmpW(s_hi_sp, out), "Expected output string \"hi \", got %s\n", wine_dbgstr_w(out));
911 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS |
912 FORMAT_MESSAGE_MAX_WIDTH_MASK, fmt_cr, 0, 0, out, ARRAY_SIZE(out), NULL);
913 ok(ret == 1, "Expected FormatMessageW to return 1, got %d\n", ret);
914 ok(!lstrcmpW(s_sp, out), "Expected output string \" \", got %s\n", wine_dbgstr_w(out));
916 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS |
917 FORMAT_MESSAGE_MAX_WIDTH_MASK, fmt_crcrlf, 0, 0, out,
918 ARRAY_SIZE(out), NULL);
919 ok(ret == 2, "Expected FormatMessageW to return 2, got %d\n", ret);
920 ok(!lstrcmpW(s_2sp, out), "Expected output string \" \", got %s\n", wine_dbgstr_w(out));
923 static void test_message_wrap(void)
925 DWORD ret;
926 int i;
927 CHAR in[300], out[300], ref[300];
929 /* No need for wrapping */
930 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 20,
931 "short long line", 0, 0, out, sizeof(out), NULL);
932 ok(ret == 15, "Expected FormatMessageW to return 15, got %d\n", ret);
933 ok(!strcmp("short long line", out),"failed out=[%s]\n",out);
935 /* Wrap the last word */
936 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 11,
937 "short long line", 0, 0, out, sizeof(out), NULL);
938 ok(ret == 16, "Expected FormatMessageW to return 16, got %d\n", ret);
939 ok(!strcmp("short long\r\nline", out),"failed out=[%s]\n",out);
941 /* Wrap the very last word */
942 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 20,
943 "short long long line", 0, 0, out, sizeof(out), NULL);
944 ok(ret == 21, "Expected FormatMessageW to return 21, got %d\n", ret);
945 ok(!strcmp("short long long\r\nline", out),"failed out=[%s]\n",out);
947 /* Strictly less than 10 characters per line! */
948 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 10,
949 "short long line", 0, 0, out, sizeof(out), NULL);
950 ok(ret == 16, "Expected FormatMessageW to return 16, got %d\n", ret);
951 ok(!strcmp("short\r\nlong line", out),"failed out=[%s]\n",out);
953 /* Handling of duplicate spaces */
954 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 16,
955 "short long line", 0, 0, out, sizeof(out), NULL);
956 ok(ret == 16, "Expected FormatMessageW to return 16, got %d\n", ret);
957 ok(!strcmp("short long\r\nline", out),"failed out=[%s]\n",out);
959 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 16,
960 "short long wordlongerthanaline", 0, 0, out, sizeof(out), NULL);
961 ok(ret == 33, "Expected FormatMessageW to return 33, got %d\n", ret);
962 ok(!strcmp("short long\r\nwordlongerthanal\r\nine", out),"failed out=[%s]\n",out);
964 /* Breaking in the middle of spaces */
965 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 12,
966 "short long line", 0, 0, out, sizeof(out), NULL);
967 ok(ret == 18, "Expected FormatMessageW to return 18, got %d\n", ret);
968 ok(!strcmp("short long\r\n line", out),"failed out=[%s]\n",out);
970 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 12,
971 "short long wordlongerthanaline", 0, 0, out, sizeof(out), NULL);
972 ok(ret == 35, "Expected FormatMessageW to return 35, got %d\n", ret);
973 ok(!strcmp("short long\r\n\r\nwordlongerth\r\nanaline", out),"failed out=[%s]\n",out);
975 /* Handling of start-of-string spaces */
976 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 15,
977 " short line", 0, 0, out, sizeof(out), NULL);
978 ok(ret == 13, "Expected FormatMessageW to return 13, got %d\n", ret);
979 ok(!strcmp(" short line", out),"failed out=[%s]\n",out);
981 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 11,
982 " shortlong line", 0, 0, out, sizeof(out), NULL);
983 ok(ret == 17, "Expected FormatMessageW to return 17, got %d\n", ret);
984 ok(!strcmp("\r\nshortlong\r\nline", out),"failed out=[%s]\n",out);
986 /* Handling of start-of-line spaces */
987 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 11,
988 "l1%n shortlong line", 0, 0, out, sizeof(out), NULL);
989 ok(ret == 21, "Expected FormatMessageW to return 21, got %d\n", ret);
990 ok(!strcmp("l1\r\n\r\nshortlong\r\nline", out),"failed out=[%s]\n",out);
992 /* Pure space wrapping */
993 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 5,
994 " ", 0, 0, out, sizeof(out), NULL);
995 ok(ret == 7, "Expected FormatMessageW to return 7, got %d\n", ret);
996 ok(!strcmp("\r\n\r\n\r\n ", out),"failed out=[%s]\n",out);
998 /* Handling of trailing spaces */
999 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 5,
1000 "l1 ", 0, 0, out, sizeof(out), NULL);
1001 ok(ret == 10, "Expected FormatMessageW to return 10, got %d\n", ret);
1002 ok(!strcmp("l1\r\n\r\n\r\n ", out),"failed out=[%s]\n",out);
1004 /* Word that just fills the line */
1005 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 8,
1006 "shortlon", 0, 0, out, sizeof(out), NULL);
1007 ok(ret == 10, "Expected FormatMessageW to return 10, got %d\n", ret);
1008 ok(!strcmp("shortlon\r\n", out),"failed out=[%s]\n",out);
1010 /* Word longer than the line */
1011 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 8,
1012 "shortlongline", 0, 0, out, sizeof(out), NULL);
1013 ok(ret == 15, "Expected FormatMessageW to return 15, got %d\n", ret);
1014 ok(!strcmp("shortlon\r\ngline", out),"failed out=[%s]\n",out);
1016 /* Wrap the line multiple times */
1017 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 7,
1018 "short long line", 0, 0, out, sizeof(out), NULL);
1019 ok(ret == 17, "Expected FormatMessageW to return 17, got %d\n", ret);
1020 ok(!strcmp("short\r\nlong\r\nline", out),"failed out=[%s]\n",out);
1022 /* '\n's in the source are ignored */
1023 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 11,
1024 "short\nlong line", 0, 0, out, sizeof(out), NULL);
1025 ok(ret == 16, "Expected FormatMessageW to return 16, got %d\n", ret);
1026 ok(!strcmp("short long\r\nline", out),"failed out=[%s]\n",out);
1028 /* Wrap even before a '%n' */
1029 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 8,
1030 "shortlon%n", 0, 0, out, sizeof(out), NULL);
1031 ok(ret == 12, "Expected FormatMessageW to return 12, got %d\n", ret);
1032 ok(!strcmp("shortlon\r\n\r\n", out),"failed out=[%s]\n",out);
1034 /* '%n's count as starting a new line and combine with line wrapping */
1035 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 10,
1036 "short%nlong line", 0, 0, out, sizeof(out), NULL);
1037 ok(ret == 16, "Expected FormatMessageW to return 16, got %d\n", ret);
1038 ok(!strcmp("short\r\nlong line", out),"failed out=[%s]\n",out);
1040 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 8,
1041 "short%nlong line", 0, 0, out, sizeof(out), NULL);
1042 ok(ret == 17, "Expected FormatMessageW to return 17, got %d\n", ret);
1043 ok(!strcmp("short\r\nlong\r\nline", out),"failed out=[%s]\n",out);
1045 /* '%r's also count as starting a new line and all */
1046 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 10,
1047 "short%rlong line", 0, 0, out, sizeof(out), NULL);
1048 ok(ret == 15, "Expected FormatMessageW to return 15, got %d\n", ret);
1049 ok(!strcmp("short\rlong line", out),"failed out=[%s]\n",out);
1051 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 8,
1052 "short%rlong line", 0, 0, out, sizeof(out), NULL);
1053 ok(ret == 16, "Expected FormatMessageW to return 16, got %d\n", ret);
1054 ok(!strcmp("short\rlong\r\nline", out),"failed out=[%s]\n",out);
1056 /* IGNORE_INSERTS does not prevent line wrapping or disable '%n' */
1057 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS | 8,
1058 "short%nlong line%1", 0, 0, out, sizeof(out), NULL);
1059 ok(ret == 19, "Expected FormatMessageW to return 19, got %d\n", ret);
1060 ok(!strcmp("short\r\nlong\r\nline%1", out),"failed out=[%s]\n",out);
1062 /* MAX_WIDTH_MASK is the same as specifying an infinite line width */
1063 strcpy(in, "first line%n");
1064 strcpy(ref, "first line\r\n");
1065 for (i=0; i < 26; i++)
1067 strcat(in, "123456789 ");
1068 strcat(ref, "123456789 ");
1070 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK,
1071 in, 0, 0, out, sizeof(out), NULL);
1072 ok(ret == 272, "Expected FormatMessageW to return 272, got %d\n", ret);
1073 ok(!strcmp(ref, out),"failed out=[%s]\n",out);
1075 /* Wrapping and non-space characters */
1076 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 11,
1077 "short long\tline", 0, 0, out, sizeof(out), NULL);
1078 ok(ret == 16, "Expected FormatMessageW to return 16, got %d\n", ret);
1079 ok(!strcmp("short\r\nlong\tline", out),"failed out=[%s]\n",out);
1081 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 11,
1082 "short long-line", 0, 0, out, sizeof(out), NULL);
1083 ok(ret == 16, "Expected FormatMessageW to return 16, got %d\n", ret);
1084 ok(!strcmp("short\r\nlong-line", out),"failed out=[%s]\n",out);
1086 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 11,
1087 "short long_line", 0, 0, out, sizeof(out), NULL);
1088 ok(ret == 16, "Expected FormatMessageW to return 16, got %d\n", ret);
1089 ok(!strcmp("short\r\nlong_line", out),"failed out=[%s]\n",out);
1091 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 11,
1092 "short long.line", 0, 0, out, sizeof(out), NULL);
1093 ok(ret == 16, "Expected FormatMessageW to return 16, got %d\n", ret);
1094 ok(!strcmp("short\r\nlong.line", out),"failed out=[%s]\n",out);
1096 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 11,
1097 "short long,line", 0, 0, out, sizeof(out), NULL);
1098 ok(ret == 16, "Expected FormatMessageW to return 16, got %d\n", ret);
1099 ok(!strcmp("short\r\nlong,line", out),"failed out=[%s]\n",out);
1101 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 11,
1102 "short long!line", 0, 0, out, sizeof(out), NULL);
1103 ok(ret == 16, "Expected FormatMessageW to return 16, got %d\n", ret);
1104 ok(!strcmp("short\r\nlong!line", out),"failed out=[%s]\n",out);
1106 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 11,
1107 "short long?line", 0, 0, out, sizeof(out), NULL);
1108 ok(ret == 16, "Expected FormatMessageW to return 16, got %d\n", ret);
1109 ok(!strcmp("short\r\nlong?line", out),"failed out=[%s]\n",out);
1112 static void test_message_insufficient_buffer(void)
1114 static const char init_buf[] = {'x', 'x', 'x', 'x', 'x'};
1115 static const char expected_buf[] = {'x', 'x', 'x', 'x', 'x'};
1116 DWORD ret;
1117 CHAR out[5];
1119 SetLastError(0xdeadbeef);
1120 memcpy(out, init_buf, sizeof(init_buf));
1121 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, "test", 0, 0, out, 0, NULL);
1122 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
1123 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
1124 "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n",
1125 GetLastError());
1126 ok(!memcmp(expected_buf, out, sizeof(expected_buf)),
1127 "Expected the buffer to be untouched\n");
1129 SetLastError(0xdeadbeef);
1130 memcpy(out, init_buf, sizeof(init_buf));
1131 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, "test", 0, 0, out, 1, NULL);
1132 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
1133 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
1134 "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n",
1135 GetLastError());
1136 ok(!memcmp(expected_buf, out, sizeof(expected_buf)),
1137 "Expected the buffer to be untouched\n");
1139 SetLastError(0xdeadbeef);
1140 memcpy(out, init_buf, sizeof(init_buf));
1141 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, "test", 0, 0, out, ARRAY_SIZE(out) - 1, NULL);
1142 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
1143 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
1144 "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n",
1145 GetLastError());
1146 ok(!memcmp(expected_buf, out, sizeof(expected_buf)),
1147 "Expected the buffer to be untouched\n");
1150 static void test_message_insufficient_buffer_wide(void)
1152 static const WCHAR test[] = {'t','e','s','t',0};
1153 static const WCHAR init_buf[] = {'x', 'x', 'x', 'x', 'x'};
1154 static const WCHAR expected_buf[] = {'x', 'x', 'x', 'x', 'x'};
1155 static const WCHAR broken_buf[] = {0, 'x', 'x', 'x', 'x'};
1156 static const WCHAR broken2_buf[] = {'t','e','s',0,'x'};
1158 DWORD ret;
1159 WCHAR out[5];
1161 SetLastError(0xdeadbeef);
1162 memcpy(out, init_buf, sizeof(init_buf));
1163 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, test, 0, 0, out, 0, NULL);
1164 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
1165 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
1166 "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n",
1167 GetLastError());
1168 ok(!memcmp(expected_buf, out, sizeof(expected_buf)),
1169 "Expected the buffer to be untouched\n");
1171 /* Windows Server 2003 and newer report failure but copy a
1172 * truncated string to the buffer for non-zero buffer sizes. */
1173 SetLastError(0xdeadbeef);
1174 memcpy(out, init_buf, sizeof(init_buf));
1175 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, test, 0, 0, out, 1, NULL);
1176 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
1177 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
1178 "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n",
1179 GetLastError());
1180 ok(!memcmp(expected_buf, out, sizeof(expected_buf)) ||
1181 broken(!memcmp(broken_buf, out, sizeof(broken_buf))), /* W2K3+ */
1182 "Expected the buffer to be untouched\n");
1184 SetLastError(0xdeadbeef);
1185 memcpy(out, init_buf, sizeof(init_buf));
1186 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, test, 0, 0, out, ARRAY_SIZE(out) - 1, NULL);
1187 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
1188 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
1189 "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n",
1190 GetLastError());
1191 ok(!memcmp(expected_buf, out, sizeof(expected_buf)) ||
1192 broken(!memcmp(broken2_buf, out, sizeof(broken2_buf))), /* W2K3+ */
1193 "Expected the buffer to be untouched\n");
1196 static void test_message_null_buffer(void)
1198 DWORD ret, error;
1200 /* Without FORMAT_MESSAGE_ALLOCATE_BUFFER, only the specified buffer size is checked. */
1201 SetLastError(0xdeadbeef);
1202 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, 0, 0, NULL, 0, NULL);
1203 error = GetLastError();
1204 ok(!ret, "FormatMessageA returned %u\n", ret);
1205 ok(error == ERROR_INSUFFICIENT_BUFFER, "last error %u\n", error);
1207 SetLastError(0xdeadbeef);
1208 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, 0, 0, NULL, 1, NULL);
1209 error = GetLastError();
1210 ok(!ret, "FormatMessageA returned %u\n", ret);
1211 ok(error == ERROR_INSUFFICIENT_BUFFER, "last error %u\n", error);
1213 if (0) /* crashes on Windows */
1215 SetLastError(0xdeadbeef);
1216 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, 0, 0, NULL, 256, NULL);
1219 SetLastError(0xdeadbeef);
1220 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, 0, 0, NULL, 0, NULL);
1221 error = GetLastError();
1222 ok(!ret, "FormatMessageA returned %u\n", ret);
1223 ok(error == ERROR_NOT_ENOUGH_MEMORY, "last error %u\n", error);
1225 SetLastError(0xdeadbeef);
1226 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, 0, 0, NULL, 1, NULL);
1227 error = GetLastError();
1228 ok(!ret, "FormatMessageA returned %u\n", ret);
1229 ok(error == ERROR_NOT_ENOUGH_MEMORY, "last error %u\n", error);
1231 SetLastError(0xdeadbeef);
1232 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, 0, 0, NULL, 256, NULL);
1233 error = GetLastError();
1234 ok(!ret, "FormatMessageA returned %u\n", ret);
1235 ok(error == ERROR_NOT_ENOUGH_MEMORY, "last error %u\n", error);
1238 static void test_message_null_buffer_wide(void)
1240 DWORD ret, error;
1242 SetLastError(0xdeadbeef);
1243 ret = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, 0, 0, NULL, 0, NULL);
1244 error = GetLastError();
1245 ok(!ret, "FormatMessageW returned %u\n", ret);
1246 ok(error == ERROR_INVALID_PARAMETER, "last error %u\n", error);
1248 SetLastError(0xdeadbeef);
1249 ret = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, 0, 0, NULL, 1, NULL);
1250 error = GetLastError();
1251 ok(!ret, "FormatMessageW returned %u\n", ret);
1252 ok(error == ERROR_INVALID_PARAMETER, "last error %u\n", error);
1254 SetLastError(0xdeadbeef);
1255 ret = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, 0, 0, NULL, 256, NULL);
1256 error = GetLastError();
1257 ok(!ret, "FormatMessageW returned %u\n", ret);
1258 ok(error == ERROR_INVALID_PARAMETER, "last error %u\n", error);
1260 SetLastError(0xdeadbeef);
1261 ret = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, 0, 0, NULL, 0, NULL);
1262 error = GetLastError();
1263 ok(!ret, "FormatMessageW returned %u\n", ret);
1264 ok(error == ERROR_INVALID_PARAMETER, "last error %u\n", error);
1266 SetLastError(0xdeadbeef);
1267 ret = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, 0, 0, NULL, 1, NULL);
1268 error = GetLastError();
1269 ok(!ret, "FormatMessageW returned %u\n", ret);
1270 ok(error == ERROR_INVALID_PARAMETER, "last error %u\n", error);
1272 SetLastError(0xdeadbeef);
1273 ret = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, 0, 0, NULL, 256, NULL);
1274 error = GetLastError();
1275 ok(!ret, "FormatMessageW returned %u\n", ret);
1276 ok(error == ERROR_INVALID_PARAMETER, "last error %u\n", error);
1279 static void test_message_allocate_buffer(void)
1281 DWORD ret;
1282 char *buf;
1284 /* While MSDN suggests that FormatMessageA allocates a buffer whose size is
1285 * the larger of the output string and the requested buffer size, the tests
1286 * will not try to determine the actual size of the buffer allocated, as
1287 * the return value of LocalSize cannot be trusted for the purpose, and it should
1288 * in any case be safe for FormatMessageA to allocate in the manner that
1289 * MSDN suggests. */
1291 SetLastError(0xdeadbeef);
1292 buf = (char *)0xdeadbeef;
1293 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
1294 "", 0, 0, (char *)&buf, 0, NULL);
1295 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
1296 ok(buf == NULL, "Expected output buffer pointer to be NULL\n");
1297 ok(GetLastError() == 0xdeadbeef,
1298 "Expected last error to be untouched, got %u\n", GetLastError());
1300 buf = (char *)0xdeadbeef;
1301 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
1302 "test", 0, 0, (char *)&buf, 0, NULL);
1303 ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
1304 ok(buf != NULL && buf != (char *)0xdeadbeef,
1305 "Expected output buffer pointer to be valid\n");
1306 if (buf != NULL && buf != (char *)0xdeadbeef)
1308 ok(!strcmp("test", buf),
1309 "Expected buffer to contain \"test\", got %s\n", buf);
1310 LocalFree(buf);
1313 buf = (char *)0xdeadbeef;
1314 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
1315 "test", 0, 0, (char *)&buf, strlen("test"), NULL);
1316 ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
1317 ok(buf != NULL && buf != (char *)0xdeadbeef,
1318 "Expected output buffer pointer to be valid\n");
1319 if (buf != NULL && buf != (char *)0xdeadbeef)
1321 ok(!strcmp("test", buf),
1322 "Expected buffer to contain \"test\", got %s\n", buf);
1323 LocalFree(buf);
1326 buf = (char *)0xdeadbeef;
1327 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
1328 "test", 0, 0, (char *)&buf, strlen("test") + 1, NULL);
1329 ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
1330 ok(buf != NULL && buf != (char *)0xdeadbeef,
1331 "Expected output buffer pointer to be valid\n");
1332 if (buf != NULL && buf != (char *)0xdeadbeef)
1334 ok(!strcmp("test", buf),
1335 "Expected buffer to contain \"test\", got %s\n", buf);
1336 LocalFree(buf);
1339 buf = (char *)0xdeadbeef;
1340 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
1341 "test", 0, 0, (char *)&buf, strlen("test") + 2, NULL);
1342 ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
1343 ok(buf != NULL && buf != (char *)0xdeadbeef,
1344 "Expected output buffer pointer to be valid\n");
1345 if (buf != NULL && buf != (char *)0xdeadbeef)
1347 ok(!strcmp("test", buf),
1348 "Expected buffer to contain \"test\", got %s\n", buf);
1349 LocalFree(buf);
1352 buf = (char *)0xdeadbeef;
1353 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
1354 "test", 0, 0, (char *)&buf, 1024, NULL);
1355 ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
1356 ok(buf != NULL && buf != (char *)0xdeadbeef,
1357 "Expected output buffer pointer to be valid\n");
1358 if (buf != NULL && buf != (char *)0xdeadbeef)
1360 ok(!strcmp("test", buf),
1361 "Expected buffer to contain \"test\", got %s\n", buf);
1362 LocalFree(buf);
1366 static void test_message_allocate_buffer_wide(void)
1368 static const WCHAR empty[] = {0};
1369 static const WCHAR test[] = {'t','e','s','t',0};
1371 DWORD ret;
1372 WCHAR *buf;
1374 /* While MSDN suggests that FormatMessageW allocates a buffer whose size is
1375 * the larger of the output string and the requested buffer size, the tests
1376 * will not try to determine the actual size of the buffer allocated, as
1377 * the return value of LocalSize cannot be trusted for the purpose, and it should
1378 * in any case be safe for FormatMessageW to allocate in the manner that
1379 * MSDN suggests. */
1381 if (0) /* crashes on Windows */
1383 buf = (WCHAR *)0xdeadbeef;
1384 FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
1385 NULL, 0, 0, (WCHAR *)&buf, 0, NULL);
1388 SetLastError(0xdeadbeef);
1389 buf = (WCHAR *)0xdeadbeef;
1390 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
1391 empty, 0, 0, (WCHAR *)&buf, 0, NULL);
1392 ok(ret == 0, "Expected FormatMessageW to return 0, got %u\n", ret);
1393 ok(buf == NULL, "Expected output buffer pointer to be NULL\n");
1394 ok(GetLastError() == 0xdeadbeef,
1395 "Expected last error to be untouched, got %u\n", GetLastError());
1397 buf = (WCHAR *)0xdeadbeef;
1398 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
1399 test, 0, 0, (WCHAR *)&buf, 0, NULL);
1400 ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
1401 ok(buf != NULL && buf != (WCHAR *)0xdeadbeef,
1402 "Expected output buffer pointer to be valid\n");
1403 if (buf != NULL && buf != (WCHAR *)0xdeadbeef)
1405 ok(!lstrcmpW(test, buf),
1406 "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf));
1407 LocalFree(buf);
1410 buf = (WCHAR *)0xdeadbeef;
1411 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
1412 test, 0, 0, (WCHAR *)&buf, ARRAY_SIZE(test) - 1, NULL);
1413 ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
1414 ok(buf != NULL && buf != (WCHAR *)0xdeadbeef,
1415 "Expected output buffer pointer to be valid\n");
1416 if (buf != NULL && buf != (WCHAR *)0xdeadbeef)
1418 ok(!lstrcmpW(test, buf),
1419 "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf));
1420 LocalFree(buf);
1423 buf = (WCHAR *)0xdeadbeef;
1424 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
1425 test, 0, 0, (WCHAR *)&buf, ARRAY_SIZE(test), NULL);
1426 ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
1427 ok(buf != NULL && buf != (WCHAR *)0xdeadbeef,
1428 "Expected output buffer pointer to be valid\n");
1429 if (buf != NULL && buf != (WCHAR *)0xdeadbeef)
1431 ok(!lstrcmpW(test, buf),
1432 "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf));
1433 LocalFree(buf);
1436 buf = (WCHAR *)0xdeadbeef;
1437 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
1438 test, 0, 0, (WCHAR *)&buf, ARRAY_SIZE(test) + 1, NULL);
1439 ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
1440 ok(buf != NULL && buf != (WCHAR *)0xdeadbeef,
1441 "Expected output buffer pointer to be valid\n");
1442 if (buf != NULL && buf != (WCHAR *)0xdeadbeef)
1444 ok(!lstrcmpW(test, buf),
1445 "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf));
1446 LocalFree(buf);
1449 buf = (WCHAR *)0xdeadbeef;
1450 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
1451 test, 0, 0, (WCHAR *)&buf, 1024, NULL);
1452 ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
1453 ok(buf != NULL && buf != (WCHAR *)0xdeadbeef,
1454 "Expected output buffer pointer to be valid\n");
1455 if (buf != NULL && buf != (WCHAR *)0xdeadbeef)
1457 ok(!lstrcmpW(test, buf),
1458 "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf));
1459 LocalFree(buf);
1463 static void test_message_from_hmodule(void)
1465 DWORD ret, error;
1466 HMODULE h;
1467 CHAR out[0x100] = {0};
1469 h = GetModuleHandleA("kernel32.dll");
1470 ok(h != 0, "GetModuleHandle failed\n");
1472 /*Test existing messageID; as the message strings from wine's kernel32 differ from windows' kernel32 we don't compare
1473 the strings but only test that FormatMessage doesn't return 0*/
1474 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 7/*=ERROR_ARENA_TRASHED*/,
1475 MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), out, ARRAY_SIZE(out), NULL);
1476 ok(ret != 0, "FormatMessageA returned 0\n");
1478 /* Test HRESULT. It's not documented but in practice _com_error::ErrorMessage relies on this. */
1479 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 0x80070005 /* E_ACCESSDENIED */,
1480 MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), out, ARRAY_SIZE(out), NULL);
1481 ok(ret != 0, "FormatMessageA returned 0\n");
1483 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, TRUST_E_NOSIGNATURE,
1484 MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), out, ARRAY_SIZE(out), NULL);
1485 ok(ret != 0, "FormatMessageA returned 0\n");
1487 /* Test a message string with an insertion without passing any variadic arguments. */
1488 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 193 /* ERROR_BAD_EXE_FORMAT */,
1489 MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), out, ARRAY_SIZE(out), NULL);
1490 ok(ret == 0, "FormatMessageA returned non-zero\n");
1492 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE |
1493 FORMAT_MESSAGE_ARGUMENT_ARRAY, h, 193 /* ERROR_BAD_EXE_FORMAT */,
1494 MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), out, ARRAY_SIZE(out), NULL);
1495 ok(ret == 0, "FormatMessageA returned non-zero\n");
1497 /*Test nonexistent messageID with varying language IDs Note: FormatMessageW behaves the same*/
1498 SetLastError(0xdeadbeef);
1499 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 3044,
1500 MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), out, ARRAY_SIZE(out), NULL);
1501 error = GetLastError();
1502 ok(ret == 0, "FormatMessageA returned %u instead of 0\n", ret);
1503 ok(error == ERROR_MR_MID_NOT_FOUND || error == ERROR_MUI_FILE_NOT_FOUND, "last error %u\n", error);
1505 SetLastError(0xdeadbeef);
1506 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 3044,
1507 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), out, ARRAY_SIZE(out), NULL);
1508 error = GetLastError();
1509 ok(ret == 0, "FormatMessageA returned %u instead of 0\n", ret);
1510 ok(error == ERROR_MR_MID_NOT_FOUND || error == ERROR_MUI_FILE_NOT_LOADED, "last error %u\n", error);
1512 SetLastError(0xdeadbeef);
1513 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 3044,
1514 MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT), out, ARRAY_SIZE(out), NULL);
1515 error = GetLastError();
1516 ok(ret == 0, "FormatMessageA returned %u instead of 0\n", ret);
1517 ok(error == ERROR_MR_MID_NOT_FOUND || error == ERROR_MUI_FILE_NOT_LOADED, "last error %u\n", error);
1519 SetLastError(0xdeadbeef);
1520 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 3044,
1521 MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), out, ARRAY_SIZE(out), NULL);
1522 error = GetLastError();
1523 ok(ret == 0, "FormatMessageA returned %u instead of 0\n", ret);
1524 ok(error == ERROR_RESOURCE_LANG_NOT_FOUND ||
1525 error == ERROR_MR_MID_NOT_FOUND ||
1526 error == ERROR_MUI_FILE_NOT_FOUND ||
1527 error == ERROR_MUI_FILE_NOT_LOADED,
1528 "last error %u\n", error);
1530 SetLastError(0xdeadbeef);
1531 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 3044,
1532 MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_UK), out, ARRAY_SIZE(out), NULL);
1533 error = GetLastError();
1534 ok(ret == 0, "FormatMessageA returned %u instead of 0\n", ret);
1535 ok(error == ERROR_RESOURCE_LANG_NOT_FOUND ||
1536 error == ERROR_MR_MID_NOT_FOUND ||
1537 error == ERROR_MUI_FILE_NOT_FOUND ||
1538 error == ERROR_MUI_FILE_NOT_LOADED,
1539 "last error %u\n", error);
1542 static void test_message_invalid_flags(void)
1544 static const char init_buf[] = {'x', 'x', 'x', 'x', 'x'};
1546 DWORD ret;
1547 CHAR out[5];
1548 char *ptr;
1550 SetLastError(0xdeadbeef);
1551 memcpy(out, init_buf, sizeof(init_buf));
1552 ret = FormatMessageA(0, "test", 0, 0, out, ARRAY_SIZE(out), NULL);
1553 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
1554 ok(!memcmp(out, init_buf, sizeof(init_buf)),
1555 "Expected the output buffer to be untouched\n");
1556 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1557 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1558 GetLastError());
1560 SetLastError(0xdeadbeef);
1561 ptr = (char *)0xdeadbeef;
1562 ret = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER, "test", 0, 0, (char *)&ptr, 0, NULL);
1563 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
1564 ok(ptr == NULL, "Expected output pointer to be initialized to NULL, got %p\n", ptr);
1565 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1566 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1567 GetLastError());
1569 SetLastError(0xdeadbeef);
1570 memcpy(out, init_buf, sizeof(init_buf));
1571 ret = FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS, "test", 0, 0, out, ARRAY_SIZE(out), NULL);
1572 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
1573 ok(!memcmp(out, init_buf, sizeof(init_buf)),
1574 "Expected the output buffer to be untouched\n");
1575 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1576 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1577 GetLastError());
1579 SetLastError(0xdeadbeef);
1580 memcpy(out, init_buf, sizeof(init_buf));
1581 ret = FormatMessageA(FORMAT_MESSAGE_ARGUMENT_ARRAY, "test", 0, 0, out, ARRAY_SIZE(out), NULL);
1582 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
1583 ok(!memcmp(out, init_buf, sizeof(init_buf)),
1584 "Expected the output buffer to be untouched\n");
1585 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1586 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1587 GetLastError());
1589 SetLastError(0xdeadbeef);
1590 memcpy(out, init_buf, sizeof(init_buf));
1591 ret = FormatMessageA(FORMAT_MESSAGE_MAX_WIDTH_MASK, "test", 0, 0, out, ARRAY_SIZE(out), NULL);
1592 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret);
1593 ok(!memcmp(out, init_buf, sizeof(init_buf)),
1594 "Expected the output buffer to be untouched\n");
1595 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1596 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1597 GetLastError());
1599 /* Simultaneously setting FORMAT_MESSAGE_FROM_STRING with other source
1600 * flags is apparently permissible, and FORMAT_MESSAGE_FROM_STRING takes
1601 * precedence in this case. */
1603 memcpy(out, init_buf, sizeof(init_buf));
1604 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_FROM_SYSTEM,
1605 "test", 0, 0, out, ARRAY_SIZE(out), NULL);
1606 ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
1607 ok(!strcmp("test", out),
1608 "Expected the output buffer to be untouched\n");
1610 memcpy(out, init_buf, sizeof(init_buf));
1611 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_FROM_HMODULE,
1612 "test", 0, 0, out, ARRAY_SIZE(out), NULL);
1613 ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
1614 ok(!strcmp("test", out),
1615 "Expected the output buffer to be untouched\n");
1617 memcpy(out, init_buf, sizeof(init_buf));
1618 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_FROM_HMODULE |
1619 FORMAT_MESSAGE_FROM_SYSTEM, "test", 0, 0, out, ARRAY_SIZE(out), NULL);
1620 ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret);
1621 ok(!strcmp("test", out),
1622 "Expected the output buffer to be untouched\n");
1625 static void test_message_invalid_flags_wide(void)
1627 static const WCHAR init_buf[] = {'x', 'x', 'x', 'x', 'x'};
1628 static const WCHAR test[] = {'t','e','s','t',0};
1630 DWORD ret;
1631 WCHAR out[5];
1632 WCHAR *ptr;
1634 SetLastError(0xdeadbeef);
1635 memcpy(out, init_buf, sizeof(init_buf));
1636 ret = FormatMessageW(0, test, 0, 0, out, ARRAY_SIZE(out), NULL);
1637 ok(ret == 0, "Expected FormatMessageW to return 0, got %u\n", ret);
1638 ok(!memcmp(out, init_buf, sizeof(init_buf)),
1639 "Expected the output buffer to be untouched\n");
1640 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1641 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1642 GetLastError());
1644 SetLastError(0xdeadbeef);
1645 ptr = (WCHAR *)0xdeadbeef;
1646 ret = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER, test, 0, 0, (WCHAR *)&ptr, 0, NULL);
1647 ok(ret == 0, "Expected FormatMessageW to return 0, got %u\n", ret);
1648 ok(ptr == NULL, "Expected output pointer to be initialized to NULL, got %p\n", ptr);
1649 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1650 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1651 GetLastError());
1653 SetLastError(0xdeadbeef);
1654 memcpy(out, init_buf, sizeof(init_buf));
1655 ret = FormatMessageW(FORMAT_MESSAGE_IGNORE_INSERTS, test, 0, 0, out, ARRAY_SIZE(out), NULL);
1656 ok(ret == 0, "Expected FormatMessageW to return 0, got %u\n", ret);
1657 ok(!memcmp(out, init_buf, sizeof(init_buf)),
1658 "Expected the output buffer to be untouched\n");
1659 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1660 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1661 GetLastError());
1663 SetLastError(0xdeadbeef);
1664 memcpy(out, init_buf, sizeof(init_buf));
1665 ret = FormatMessageW(FORMAT_MESSAGE_ARGUMENT_ARRAY, test, 0, 0, out, ARRAY_SIZE(out), NULL);
1666 ok(ret == 0, "Expected FormatMessageW to return 0, got %u\n", ret);
1667 ok(!memcmp(out, init_buf, sizeof(init_buf)),
1668 "Expected the output buffer to be untouched\n");
1669 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1670 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1671 GetLastError());
1673 SetLastError(0xdeadbeef);
1674 memcpy(out, init_buf, sizeof(init_buf));
1675 ret = FormatMessageW(FORMAT_MESSAGE_MAX_WIDTH_MASK, test, 0, 0, out, ARRAY_SIZE(out), NULL);
1676 ok(ret == 0, "Expected FormatMessageW to return 0, got %u\n", ret);
1677 ok(!memcmp(out, init_buf, sizeof(init_buf)),
1678 "Expected the output buffer to be untouched\n");
1679 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1680 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1681 GetLastError());
1683 /* Simultaneously setting FORMAT_MESSAGE_FROM_STRING with other source
1684 * flags is apparently permissible, and FORMAT_MESSAGE_FROM_STRING takes
1685 * precedence in this case. */
1687 memcpy(out, init_buf, sizeof(init_buf));
1688 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_FROM_SYSTEM,
1689 test, 0, 0, out, ARRAY_SIZE(out), NULL);
1690 ok(ret == 4, "Expected FormatMessageW to return 4, got %u\n", ret);
1691 ok(!lstrcmpW(test, out),
1692 "Expected the output buffer to be untouched\n");
1694 memcpy(out, init_buf, sizeof(init_buf));
1695 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_FROM_HMODULE,
1696 test, 0, 0, out, ARRAY_SIZE(out), NULL);
1697 ok(ret == 4, "Expected FormatMessageW to return 4, got %u\n", ret);
1698 ok(!lstrcmpW(test, out),
1699 "Expected the output buffer to be untouched\n");
1701 memcpy(out, init_buf, sizeof(init_buf));
1702 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_FROM_HMODULE |
1703 FORMAT_MESSAGE_FROM_SYSTEM, test, 0, 0, out, ARRAY_SIZE(out), NULL);
1704 ok(ret == 4, "Expected FormatMessageW to return 4, got %u\n", ret);
1705 ok(!lstrcmpW(test, out),
1706 "Expected the output buffer to be untouched\n");
1709 static void test_message_from_64bit_number(void)
1711 static const WCHAR I64d[] = {'%', '1', '!', 'I', '6', '4', 'd', '!', 0};
1712 static const WCHAR I64u[] = {'%', '1', '!', 'I', '6', '4', 'u', '!', 0};
1713 WCHAR outW[0x100], expW[0x100];
1714 char outA[0x100];
1715 DWORD r;
1716 static const struct
1718 UINT64 number;
1719 const char expected[32];
1720 int len;
1721 } unsigned_tests[] =
1723 { 0, "0", 1 },
1724 { 1234567890, "1234567890", 10},
1725 { ULL(0xFFFFFFFF,0xFFFFFFFF), "18446744073709551615", 20 },
1726 { ULL(0x7FFFFFFF,0xFFFFFFFF), "9223372036854775807", 19 },
1728 static const struct
1730 INT64 number;
1731 const char expected[32];
1732 int len;
1733 } signed_tests[] =
1735 { 0, "0" , 1},
1736 { 1234567890, "1234567890", 10 },
1737 { -1, "-1", 2},
1738 { ULL(0xFFFFFFFF,0xFFFFFFFF), "-1", 2},
1739 { ULL(0x7FFFFFFF,0xFFFFFFFF), "9223372036854775807", 19 },
1740 { -ULL(0x7FFFFFFF,0xFFFFFFFF), "-9223372036854775807", 20},
1742 int i;
1744 for (i = 0; i < ARRAY_SIZE(unsigned_tests); i++)
1746 r = doitW(FORMAT_MESSAGE_FROM_STRING, I64u, 0, 0, outW, ARRAY_SIZE(outW),
1747 unsigned_tests[i].number);
1748 MultiByteToWideChar(CP_ACP, 0, unsigned_tests[i].expected, -1, expW, ARRAY_SIZE(expW));
1749 todo_wine {
1750 ok(!lstrcmpW(outW, expW),"[%d] failed, expected %s, got %s\n", i,
1751 unsigned_tests[i].expected, wine_dbgstr_w(outW));
1752 ok(r == unsigned_tests[i].len,"[%d] failed: r=%d\n", i, r);
1754 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!I64u!",
1755 0, 0, outA, sizeof(outA), unsigned_tests[i].number);
1756 todo_wine {
1757 ok(!strcmp(outA, unsigned_tests[i].expected),"[%d] failed, expected %s, got %s\n", i,
1758 unsigned_tests[i].expected, outA);
1759 ok(r == unsigned_tests[i].len,"[%d] failed: r=%d\n", i, r);
1763 for (i = 0; i < ARRAY_SIZE(signed_tests); i++)
1765 r = doitW(FORMAT_MESSAGE_FROM_STRING, I64d, 0, 0, outW, ARRAY_SIZE(outW),
1766 signed_tests[i].number);
1767 MultiByteToWideChar(CP_ACP, 0, signed_tests[i].expected, -1, expW, ARRAY_SIZE(expW));
1768 todo_wine {
1769 ok(!lstrcmpW(outW, expW),"[%d] failed, expected %s, got %s\n", i,
1770 signed_tests[i].expected, wine_dbgstr_w(outW));
1771 ok(r == signed_tests[i].len,"[%d] failed: r=%d\n", i, r);
1773 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!I64d!",
1774 0, 0, outA, sizeof(outA), signed_tests[i].number);
1775 todo_wine {
1776 ok(!strcmp(outA, signed_tests[i].expected),"[%d] failed, expected %s, got %s\n", i,
1777 signed_tests[i].expected, outA);
1778 ok(r == signed_tests[i].len,"[%d] failed: r=%d\n", i, r);
1783 START_TEST(format_msg)
1785 DWORD ret;
1787 test_message_from_string();
1788 test_message_ignore_inserts();
1789 test_message_wrap();
1790 test_message_insufficient_buffer();
1791 test_message_null_buffer();
1792 test_message_allocate_buffer();
1793 test_message_from_hmodule();
1794 test_message_invalid_flags();
1796 SetLastError(0xdeadbeef);
1797 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, NULL, 0, 0, NULL, 0, NULL);
1798 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1800 win_skip("FormatMessageW is not implemented\n");
1801 return;
1804 test_message_from_string_wide();
1805 test_message_ignore_inserts_wide();
1806 test_message_insufficient_buffer_wide();
1807 test_message_null_buffer_wide();
1808 test_message_allocate_buffer_wide();
1809 test_message_invalid_flags_wide();
1810 test_message_from_64bit_number();