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
22 #include "wine/test.h"
27 static DWORD __cdecl
doit(DWORD flags
, LPCVOID src
, DWORD msg_id
, DWORD lang_id
,
28 LPSTR out
, DWORD outsize
, ... )
33 __ms_va_start(list
, outsize
);
34 r
= FormatMessageA(flags
, src
, msg_id
,
35 lang_id
, out
, outsize
, &list
);
40 static DWORD __cdecl
doitW(DWORD flags
, LPCVOID src
, DWORD msg_id
, DWORD lang_id
,
41 LPWSTR out
, DWORD outsize
, ... )
46 __ms_va_start(list
, outsize
);
47 r
= FormatMessageW(flags
, src
, msg_id
,
48 lang_id
, out
, outsize
, &list
);
53 static void test_message_from_string_wide(void)
55 static const WCHAR test
[] = {'t','e','s','t',0};
56 static const WCHAR empty
[] = {0};
57 static const WCHAR te
[] = {'t','e',0};
58 static const WCHAR st
[] = {'s','t',0};
59 static const WCHAR t
[] = {'t',0};
60 static const WCHAR e
[] = {'e',0};
61 static const WCHAR s
[] = {'s',0};
62 static const WCHAR fmt_null
[] = {'%',0};
63 static const WCHAR fmt_tnull
[] = {'t','e','s','t','%',0};
64 static const WCHAR fmt_1
[] = {'%','1',0};
65 static const WCHAR fmt_12
[] = {'%','1','%','2',0};
66 static const WCHAR fmt_123
[] = {'%','1','%','3','%','2','%','1',0};
67 static const WCHAR fmt_123c
[] = {'%','1','!','c','!','%','2','!','c','!','%','3','!','c','!','%','1','!','c','!',0};
68 static const WCHAR fmt_123lc
[] = {'%','1','!','l','c','!','%','2','!','l','c','!','%','3','!','l','c','!','%','1','!','l','c','!',0};
69 static const WCHAR fmt_123wc
[] = {'%','1','!','w','c','!','%','2','!','w','c','!','%','3','!','w','c','!','%','1','!','w','c','!',0};
70 static const WCHAR fmt_123C
[] = {'%','1','!','C','!','%','2','!','C','!','%','3','!','C','!','%','1','!','C','!',0};
71 static const WCHAR fmt_123d
[] = {'%','1','!','d','!','%','2','!','d','!','%','3','!','d','!',0};
72 static const WCHAR fmt_1s
[] = {'%','1','!','s','!',0};
73 static const WCHAR fmt_s
[] = {'%','!','s','!',0};
74 static const WCHAR fmt_ls
[] = {'%','!','l','s','!',0};
75 static const WCHAR fmt_ws
[] = {'%','!','w','s','!',0};
76 static const WCHAR fmt_S
[] = {'%','!','S','!',0};
77 static const WCHAR fmt_14d
[] = {'%','1','!','4','d','!',0};
78 static const WCHAR fmt_14x
[] = {'%','1','!','4','x','!',0};
79 static const WCHAR fmt_14X
[] = {'%','1','!','4','X','!',0};
80 static const WCHAR fmt_1_4X
[] = {'%','1','!','-','4','X','!',0};
81 static const WCHAR fmt_1_4d
[] = {'%','1','!','-','4','d','!',0};
82 static const WCHAR fmt_2pct
[] = {' ','%','%','%','%',' ',0};
83 static const WCHAR fmt_2dot1d
[] = {' ', '%','.','%','.',' ',' ','%','1','!','d','!',0};
84 static const WCHAR fmt_t0t
[] = {'t','e','s','t','%','0','t','e','s','t',0};
85 static const WCHAR fmt_yah
[] = {'y','a','h','%','!','%','0',' ',' ',' ',0};
86 static const WCHAR fmt_space
[] = {'%',' ','%',' ',' ',' ',0};
87 static const WCHAR fmt_nrt
[] = {'%','n','%','r','%','t',0};
88 static const WCHAR fmt_hi_lf
[] = {'h','i','\n',0};
89 static const WCHAR fmt_hi_crlf
[] = {'h','i','\r','\n',0};
90 static const WCHAR fmt_cr
[] = {'\r',0};
91 static const WCHAR fmt_crcrlf
[] = {'\r','\r','\n',0};
92 static const WCHAR fmt_13s
[] = {'%','1','!','3','s','!',0};
93 static const WCHAR fmt_1os
[] = {'%','1','!','*','s','!',0};
94 static const WCHAR fmt_142u
[] = {'%','1','!','4','.','2','u','!',0};
95 static const WCHAR fmt_1oou
[] = {'%','1','!','*','.','*','u','!',0};
96 static const WCHAR fmt_1oou1oou
[] = {'%','1','!','*','.','*','u','!',',','%','1','!','*','.','*','u','!',0};
97 static const WCHAR fmt_1oou3oou
[] = {'%','1','!','*','.','*','u','!',',','%','3','!','*','.','*','u','!',0};
98 static const WCHAR fmt_1oou4oou
[] = {'%','1','!','*','.','*','u','!',',','%','4','!','*','.','*','u','!',0};
100 static const WCHAR s_123d
[] = {'1','2','3',0};
101 static const WCHAR s_14d
[] = {' ',' ',' ','1',0};
102 static const WCHAR s_14x
[] = {' ',' ',' ','b',0};
103 static const WCHAR s_14X
[] = {' ',' ',' ','B',0};
104 static const WCHAR s_1_4X
[] = {'B',' ',' ',' ',0};
105 static const WCHAR s_14d2
[] = {' ',' ','1','1',0};
106 static const WCHAR s_1_4d
[] = {'1',' ',' ',' ',0};
107 static const WCHAR s_1AB
[] = {' ','1','A','B',0};
108 static const WCHAR s_2pct
[] = {' ','%','%',' ',0};
109 static const WCHAR s_2dot147
[] = {' ','.','.',' ',' ','4','2','7',0};
110 static const WCHAR s_yah
[] = {'y','a','h','!',0};
111 static const WCHAR s_space
[] = {' ',' ',' ',' ',0};
112 static const WCHAR s_nrt
[] = {'\r','\n','\r','\t',0};
113 static const WCHAR s_hi_crlf
[] = {'h','i','\r','\n',0};
114 static const WCHAR s_crlf
[] = {'\r','\n',0};
115 static const WCHAR s_crlfcrlf
[] = {'\r','\n','\r','\n',0};
116 static const WCHAR s_hi_sp
[] = {'h','i',' ',0};
117 static const WCHAR s_sp
[] = {' ',0};
118 static const WCHAR s_2sp
[] = {' ',' ',0};
119 static const WCHAR s_spt
[] = {' ',' ','t',0};
120 static const WCHAR s_sp3t
[] = {' ',' ',' ','t',0};
121 static const WCHAR s_sp03
[] = {' ',' ','0','3',0};
122 static const WCHAR s_sp001
[] = {' ',' ','0','0','1',0};
123 static const WCHAR s_sp001002
[] = {' ',' ','0','0','1',',',' ','0','0','0','2',0};
124 static const WCHAR s_sp001sp002
[] = {' ',' ','0','0','1',',',' ',' ','0','0','0','2',0};
125 static const WCHAR s_sp002sp001
[] = {' ',' ','0','0','0','2',',',' ',' ','0','0','1',0};
126 static const WCHAR s_sp002sp003
[] = {' ',' ','0','0','0','2',',',' ','0','0','0','0','3',0};
127 static const WCHAR s_sp001004
[] = {' ',' ','0','0','1',',','0','0','0','0','0','4',0};
129 static const WCHAR init_buf
[] = {'x', 'x', 'x', 'x', 'x', 'x'};
130 static const WCHAR broken_buf
[] = {'t','e','s','t','x','x'};
132 WCHAR out
[0x100] = {0};
136 r
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
, test
, 0,
137 0, out
, sizeof(out
)/sizeof(WCHAR
), NULL
);
138 ok(!lstrcmpW(test
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
139 ok(r
==4, "failed: r=%d\n", r
);
141 /* null string, crashes on Windows */
144 SetLastError(0xdeadbeef);
145 memcpy(out
, init_buf
, sizeof(init_buf
));
146 r
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
, NULL
, 0,
147 0, out
, sizeof(out
)/sizeof(WCHAR
), NULL
);
151 SetLastError(0xdeadbeef);
152 memcpy(out
, init_buf
, sizeof(init_buf
));
153 r
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
, empty
, 0,
154 0, out
, sizeof(out
)/sizeof(WCHAR
), 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,
164 0, out
, sizeof(out
)/sizeof(WCHAR
), NULL
);
165 error
= GetLastError();
166 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)),
167 "Expected the buffer to be unchanged\n");
168 ok(r
==0, "succeeded: r=%d\n", r
);
169 ok(error
==ERROR_INVALID_PARAMETER
, "last error %u\n", error
);
171 /* test string with format placeholder with no specifier */
172 SetLastError(0xdeadbeef);
173 memcpy(out
, init_buf
, sizeof(init_buf
));
174 r
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
, fmt_tnull
, 0,
175 0, out
, sizeof(out
)/sizeof(WCHAR
), NULL
);
176 error
= GetLastError();
177 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)) ||
178 broken(!memcmp(out
, broken_buf
, sizeof(broken_buf
))), /* W2K3+ */
179 "Expected the buffer to be unchanged\n");
180 ok(r
==0, "succeeded: r=%d\n", r
);
181 ok(error
==ERROR_INVALID_PARAMETER
, "last error %u\n", error
);
183 /* insertion with no variadic arguments */
184 SetLastError(0xdeadbeef);
185 memcpy(out
, init_buf
, sizeof(init_buf
));
186 r
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
, fmt_1
, 0,
187 0, out
, sizeof(out
)/sizeof(WCHAR
), NULL
);
188 error
= GetLastError();
189 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)),
190 "Expected the buffer to be unchanged\n");
191 ok(r
==0, "succeeded: r=%d\n", r
);
192 ok(error
==ERROR_INVALID_PARAMETER
, "last error %u\n", error
);
194 SetLastError(0xdeadbeef);
195 memcpy(out
, init_buf
, sizeof(init_buf
));
196 r
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ARGUMENT_ARRAY
, fmt_1
, 0,
197 0, out
, sizeof(out
)/sizeof(WCHAR
), NULL
);
198 error
= GetLastError();
199 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)),
200 "Expected the buffer to be unchanged\n");
201 ok(r
==0, "succeeded: r=%d\n", r
);
202 ok(error
==ERROR_INVALID_PARAMETER
, "last error %u\n", error
);
204 /* using the format feature */
205 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_1s
, 0,
206 0, out
, sizeof(out
)/sizeof(WCHAR
), test
);
207 ok(!lstrcmpW(test
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
208 ok(r
==4,"failed: r=%d\n", r
);
211 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_1
, 0,
212 0, out
, sizeof(out
)/sizeof(WCHAR
), test
);
213 ok(!lstrcmpW(test
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
214 ok(r
==4,"failed: r=%d\n", r
);
217 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_12
, 0,
218 0, out
, sizeof(out
)/sizeof(WCHAR
), te
, st
);
219 ok(!lstrcmpW(test
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
220 ok(r
==4,"failed: r=%d\n", r
);
223 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_123
, 0,
224 0, out
, sizeof(out
)/sizeof(WCHAR
), t
, s
, e
);
225 ok(!lstrcmpW(test
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
226 ok(r
==4,"failed: r=%d\n", r
);
228 /* s doesn't seem to work in format strings */
229 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_s
, 0,
230 0, out
, sizeof(out
)/sizeof(WCHAR
), test
);
231 ok(!lstrcmpW(&fmt_s
[1], out
), "failed out=%s\n", wine_dbgstr_w(out
));
232 ok(r
==3, "failed: r=%d\n", r
);
235 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_ls
, 0,
236 0, out
, sizeof(out
)/sizeof(WCHAR
), test
);
237 ok(!lstrcmpW(&fmt_ls
[1], out
), "failed out=%s\n", wine_dbgstr_w(out
));
238 ok(r
==4, "failed: r=%d\n", r
);
241 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_S
, 0,
242 0, out
, sizeof(out
)/sizeof(WCHAR
), test
);
243 ok(!lstrcmpW(&fmt_S
[1], out
), "failed out=%s\n", wine_dbgstr_w(out
));
244 ok(r
==3, "failed: r=%d\n", r
);
247 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_ws
, 0,
248 0, out
, sizeof(out
)/sizeof(WCHAR
), test
);
249 ok(!lstrcmpW(&fmt_ws
[1], out
), "failed out=%s\n", wine_dbgstr_w(out
));
250 ok(r
==4, "failed: r=%d\n", r
);
253 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_123c
, 0,
254 0, out
, sizeof(out
)/sizeof(WCHAR
), 't', 'e', 's');
255 ok(!lstrcmpW(test
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
256 ok(r
==4,"failed: r=%d\n", r
);
259 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_123lc
, 0,
260 0, out
, sizeof(out
)/sizeof(WCHAR
), 't', 'e', 's');
261 ok(!lstrcmpW(test
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
262 ok(r
==4,"failed: r=%d\n", r
);
265 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_123wc
, 0,
266 0, out
, sizeof(out
)/sizeof(WCHAR
), 't', 'e', 's');
267 ok(!lstrcmpW(test
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
268 ok(r
==4,"failed: r=%d\n", r
);
271 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_123C
, 0,
272 0, out
, sizeof(out
)/sizeof(WCHAR
), 't', 'e', 's');
273 ok(!lstrcmpW(test
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
274 ok(r
==4,"failed: r=%d\n", r
);
277 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_123d
, 0,
278 0, out
, sizeof(out
)/sizeof(WCHAR
), 1, 2, 3);
279 ok(!lstrcmpW(s_123d
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
280 ok(r
==3,"failed: r=%d\n", r
);
282 /* a single digit with some spacing */
283 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_14d
, 0,
284 0, out
, sizeof(out
)/sizeof(WCHAR
), 1);
285 ok(!lstrcmpW(s_14d
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
287 /* a single digit, left justified */
288 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_1_4d
, 0,
289 0, out
, sizeof(out
)/sizeof(CHAR
), 1);
290 ok(!lstrcmpW(s_1_4d
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
291 ok(r
==4,"failed: r=%d\n", r
);
293 /* two digit decimal number */
294 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_14d
, 0,
295 0, out
, sizeof(out
)/sizeof(WCHAR
), 11);
296 ok(!lstrcmpW(s_14d2
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
297 ok(r
==4,"failed: r=%d\n", r
);
300 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_14x
, 0,
301 0, out
, sizeof(out
)/sizeof(WCHAR
), 11);
302 ok(!lstrcmpW(s_14x
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
303 ok(r
==4,"failed: r=%d\n", r
);
305 /* a hex number, upper case */
306 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_14X
, 0,
307 0, out
, sizeof(out
)/sizeof(WCHAR
), 11);
308 ok(!lstrcmpW(s_14X
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
309 ok(r
==4,"failed: r=%d\n", r
);
311 /* a hex number, upper case, left justified */
312 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_1_4X
, 0,
313 0, out
, sizeof(out
)/sizeof(WCHAR
), 11);
314 ok(!lstrcmpW(s_1_4X
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
315 ok(r
==4,"failed: r=%d\n", r
);
317 /* a long hex number, upper case */
318 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_14X
, 0,
319 0, out
, sizeof(out
)/sizeof(WCHAR
), 0x1ab);
320 ok(!lstrcmpW(s_1AB
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
321 ok(r
==4,"failed: r=%d\n", r
);
324 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_2pct
, 0,
325 0, out
, sizeof(out
)/sizeof(WCHAR
));
326 ok(!lstrcmpW(s_2pct
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
327 ok(r
==4,"failed: r=%d\n", r
);
329 /* periods are special cases */
330 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_2dot1d
, 0,
331 0, out
, sizeof(out
)/sizeof(WCHAR
), 0x1ab);
332 ok(!lstrcmpW(s_2dot147
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
333 ok(r
==8,"failed: r=%d\n", r
);
335 /* %0 ends the line */
336 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_t0t
, 0,
337 0, out
, sizeof(out
)/sizeof(WCHAR
));
338 ok(!lstrcmpW(test
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
339 ok(r
==4,"failed: r=%d\n", r
);
341 /* %! prints an exclamation */
342 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_yah
, 0,
343 0, out
, sizeof(out
)/sizeof(WCHAR
));
344 ok(!lstrcmpW(s_yah
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
345 ok(r
==4,"failed: r=%d\n", r
);
348 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_space
, 0,
349 0, out
, sizeof(out
)/sizeof(WCHAR
));
350 ok(!lstrcmpW(s_space
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
351 ok(r
==4,"failed: r=%d\n", r
);
353 /* %n yields \r\n, %r yields \r, %t yields \t */
354 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_nrt
, 0,
355 0, out
, sizeof(out
)/sizeof(WCHAR
));
356 ok(!lstrcmpW(s_nrt
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
357 ok(r
==4,"failed: r=%d\n", r
);
360 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_hi_lf
, 0,
361 0, out
, sizeof(out
)/sizeof(WCHAR
));
362 ok(!lstrcmpW(s_hi_crlf
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
363 ok(r
==4,"failed: r=%d\n", r
);
365 /* carriage return line feed */
366 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_hi_crlf
, 0,
367 0, out
, sizeof(out
)/sizeof(WCHAR
));
368 ok(!lstrcmpW(s_hi_crlf
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
369 ok(r
==4,"failed: r=%d\n", r
);
371 /* carriage return */
372 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_cr
, 0,
373 0, out
, sizeof(out
)/sizeof(WCHAR
));
374 ok(!lstrcmpW(s_crlf
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
375 ok(r
==2,"failed: r=%d\n", r
);
377 /* double carriage return line feed */
378 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_crcrlf
, 0,
379 0, out
, sizeof(out
)/sizeof(WCHAR
));
380 ok(!lstrcmpW(s_crlfcrlf
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
381 ok(r
==4,"failed: r=%d\n", r
);
383 /* precision and width */
385 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_13s
,
386 0, 0, out
, sizeof(out
)/sizeof(WCHAR
), t
);
387 ok(!lstrcmpW(s_spt
, out
),"failed out=[%s]\n", wine_dbgstr_w(out
));
388 ok(r
==3, "failed: r=%d\n",r
);
389 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_1os
,
390 0, 0, out
, sizeof(out
)/sizeof(WCHAR
), 4, t
);
391 ok(!lstrcmpW( s_sp3t
, out
),"failed out=[%s]\n", wine_dbgstr_w(out
));
392 ok(r
==4,"failed: r=%d\n",r
);
393 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_142u
,
394 0, 0, out
, sizeof(out
)/sizeof(WCHAR
), 3 );
395 ok(!lstrcmpW( s_sp03
, out
),"failed out=[%s]\n", wine_dbgstr_w(out
));
396 ok(r
==4,"failed: r=%d\n",r
);
397 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_1oou
,
398 0, 0, out
, sizeof(out
)/sizeof(WCHAR
), 5, 3, 1 );
399 ok(!lstrcmpW( s_sp001
, out
),"failed out=[%s]\n", wine_dbgstr_w(out
));
400 ok(r
==5,"failed: r=%d\n",r
);
401 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_1oou1oou
,
402 0, 0, out
, sizeof(out
)/sizeof(WCHAR
), 5, 3, 1, 4, 2 );
403 ok(!lstrcmpW( s_sp001002
, out
),"failed out=[%s]\n", wine_dbgstr_w(out
));
404 ok(r
==11,"failed: r=%d\n",r
);
405 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_1oou3oou
,
406 0, 0, out
, sizeof(out
)/sizeof(WCHAR
), 5, 3, 1, 6, 4, 2 );
407 ok(!lstrcmpW( s_sp001sp002
, out
) ||
408 broken(!lstrcmpW(s_sp001004
, out
)), /* NT4/Win2k */
409 "failed out=[%s]\n", wine_dbgstr_w(out
));
410 ok(r
==12,"failed: r=%d\n",r
);
411 /* args are not counted the same way with an argument array */
413 ULONG_PTR args
[] = { 6, 4, 2, 5, 3, 1 };
414 r
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ARGUMENT_ARRAY
, fmt_1oou1oou
,
415 0, 0, out
, sizeof(out
)/sizeof(WCHAR
), (__ms_va_list
*)args
);
416 ok(!lstrcmpW(s_sp002sp003
, out
),"failed out=[%s]\n", wine_dbgstr_w(out
));
417 ok(r
==13,"failed: r=%d\n",r
);
418 r
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ARGUMENT_ARRAY
, fmt_1oou4oou
,
419 0, 0, out
, sizeof(out
)/sizeof(WCHAR
), (__ms_va_list
*)args
);
420 ok(!lstrcmpW(s_sp002sp001
, out
),"failed out=[%s]\n", wine_dbgstr_w(out
));
421 ok(r
==12,"failed: r=%d\n",r
);
424 /* change of pace... test the low byte of dwflags */
427 r
= doitW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_MAX_WIDTH_MASK
, fmt_hi_lf
, 0,
428 0, out
, sizeof(out
)/sizeof(WCHAR
));
429 ok(!lstrcmpW(s_hi_sp
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
430 ok(r
==3,"failed: r=%d\n", r
);
432 /* carriage return line feed */
433 r
= doitW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_MAX_WIDTH_MASK
, fmt_hi_crlf
, 0,
434 0, out
, sizeof(out
)/sizeof(WCHAR
));
435 ok(!lstrcmpW(s_hi_sp
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
436 ok(r
==3,"failed: r=%d\n", r
);
438 /* carriage return */
439 r
= doitW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_MAX_WIDTH_MASK
, fmt_cr
, 0,
440 0, out
, sizeof(out
)/sizeof(WCHAR
));
441 ok(!lstrcmpW(s_sp
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
442 ok(r
==1,"failed: r=%d\n", r
);
444 /* double carriage return line feed */
445 r
= doitW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_MAX_WIDTH_MASK
, fmt_crcrlf
, 0,
446 0, out
, sizeof(out
)/sizeof(WCHAR
));
447 ok(!lstrcmpW(s_2sp
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
448 ok(r
==2,"failed: r=%d\n", r
);
451 static void test_message_from_string(void)
453 CHAR out
[0x100] = {0};
455 static const char init_buf
[] = {'x', 'x', 'x', 'x', 'x', 'x'};
456 static const WCHAR szwTest
[] = { 't','e','s','t',0};
459 r
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
, "test", 0,
460 0, out
, sizeof(out
)/sizeof(CHAR
),NULL
);
461 ok(!strcmp("test", out
),"failed out=[%s]\n",out
);
462 ok(r
==4,"failed: r=%d\n",r
);
464 /* null string, crashes on Windows */
467 SetLastError(0xdeadbeef);
468 memcpy(out
, init_buf
, sizeof(init_buf
));
469 r
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
, NULL
, 0,
470 0, out
, sizeof(out
)/sizeof(CHAR
), NULL
);
474 SetLastError(0xdeadbeef);
475 memcpy(out
, init_buf
, sizeof(init_buf
));
476 r
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
, "", 0,
477 0, out
, sizeof(out
)/sizeof(CHAR
), NULL
);
478 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)) ||
479 broken(!strcmp("", out
)), /* Win9x */
480 "Expected the buffer to be untouched\n");
481 ok(r
==0, "succeeded: r=%d\n", r
);
482 ok(GetLastError()==0xdeadbeef,
483 "last error %u\n", GetLastError());
485 /* format placeholder with no specifier */
486 SetLastError(0xdeadbeef);
487 memcpy(out
, init_buf
, sizeof(init_buf
));
488 r
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
, "%", 0,
489 0, out
, sizeof(out
)/sizeof(CHAR
), NULL
);
490 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)),
491 "Expected the buffer to be untouched\n");
492 ok(r
==0, "succeeded: r=%d\n", r
);
493 ok(GetLastError()==ERROR_INVALID_PARAMETER
,
494 "last error %u\n", GetLastError());
496 /* test string with format placeholder with no specifier */
497 SetLastError(0xdeadbeef);
498 memcpy(out
, init_buf
, sizeof(init_buf
));
499 r
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
, "test%", 0,
500 0, out
, sizeof(out
)/sizeof(CHAR
), NULL
);
501 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)),
502 "Expected the buffer to be untouched\n");
503 ok(r
==0, "succeeded: r=%d\n", r
);
504 ok(GetLastError()==ERROR_INVALID_PARAMETER
,
505 "last error %u\n", GetLastError());
507 /* insertion with no variadic arguments */
508 SetLastError(0xdeadbeef);
509 memcpy(out
, init_buf
, sizeof(init_buf
));
510 r
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
, "%1", 0,
511 0, out
, sizeof(out
)/sizeof(CHAR
), NULL
);
512 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)) ||
513 broken(!strcmp("%1", out
)), /* Win9x */
514 "Expected the buffer to be untouched\n");
516 broken(r
==2), /* Win9x */
517 "succeeded: r=%d\n", r
);
518 ok(GetLastError()==ERROR_INVALID_PARAMETER
||
519 broken(GetLastError()==0xdeadbeef), /* Win9x */
520 "last error %u\n", GetLastError());
522 SetLastError(0xdeadbeef);
523 memcpy(out
, init_buf
, sizeof(init_buf
));
524 r
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ARGUMENT_ARRAY
, "%1", 0,
525 0, out
, sizeof(out
)/sizeof(CHAR
), NULL
);
526 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)) ||
527 broken(!strcmp("%1", out
)), /* Win9x */
528 "Expected the buffer to be untouched\n");
530 broken(r
==2), /* Win9x */
531 "succeeded: r=%d\n", r
);
532 ok(GetLastError()==ERROR_INVALID_PARAMETER
||
533 broken(GetLastError()==0xdeadbeef), /* Win9x */
534 "last error %u\n", GetLastError());
536 /* using the format feature */
537 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!s!", 0,
538 0, out
, sizeof(out
)/sizeof(CHAR
), "test");
539 ok(!strcmp("test", out
),"failed out=[%s]\n",out
);
540 ok(r
==4,"failed: r=%d\n",r
);
543 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1", 0,
544 0, out
, sizeof(out
)/sizeof(CHAR
), "test");
545 ok(!strcmp("test", out
),"failed out=[%s]\n",out
);
546 ok(r
==4,"failed: r=%d\n",r
);
549 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1%2", 0,
550 0, out
, sizeof(out
)/sizeof(CHAR
), "te","st");
551 ok(!strcmp("test", out
),"failed out=[%s]\n",out
);
552 ok(r
==4,"failed: r=%d\n",r
);
555 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1%3%2%1", 0,
556 0, out
, sizeof(out
)/sizeof(CHAR
), "t","s","e");
557 ok(!strcmp("test", out
),"failed out=[%s]\n",out
);
558 ok(r
==4,"failed: r=%d\n",r
);
560 /* s doesn't seem to work in format strings */
561 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%!s!", 0,
562 0, out
, sizeof(out
)/sizeof(CHAR
), "test");
563 ok(!strcmp("!s!", out
),"failed out=[%s]\n",out
);
564 ok(r
==3,"failed: r=%d\n",r
);
567 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!ls!", 0,
568 0, out
, sizeof(out
)/sizeof(CHAR
), szwTest
);
569 ok(!strcmp("test", out
),"failed out=[%s]\n",out
);
570 ok(r
==4,"failed: r=%d\n",r
);
573 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!S!", 0,
574 0, out
, sizeof(out
)/sizeof(CHAR
), szwTest
);
575 ok(!strcmp("test", out
),"failed out=[%s]\n",out
);
576 ok(r
==4,"failed: r=%d\n",r
);
579 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!ws!", 0,
580 0, out
, sizeof(out
)/sizeof(CHAR
), szwTest
);
581 ok(!strcmp("test", out
),"failed out=[%s]\n",out
);
582 ok(r
==4,"failed: r=%d\n",r
);
585 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!c!%2!c!%3!c!%1!c!", 0,
586 0, out
, sizeof(out
)/sizeof(CHAR
), 't','e','s');
587 ok(!strcmp("test", out
),"failed out=[%s]\n",out
);
588 ok(r
==4,"failed: r=%d\n",r
);
591 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!lc!%2!lc!%3!lc!%1!lc!", 0,
592 0, out
, sizeof(out
)/sizeof(CHAR
), 't','e','s');
593 ok(!strcmp("test", out
),"failed out=[%s]\n",out
);
594 ok(r
==4,"failed: r=%d\n",r
);
597 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!wc!%2!wc!%3!wc!%1!wc!", 0,
598 0, out
, sizeof(out
)/sizeof(CHAR
), 't','e','s');
599 ok(!strcmp("test", out
),"failed out=[%s]\n",out
);
600 ok(r
==4,"failed: r=%d\n",r
);
603 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!C!%2!C!%3!C!%1!C!", 0,
604 0, out
, sizeof(out
)/sizeof(CHAR
), 't','e','s');
605 ok(!strcmp("test", out
),"failed out=[%s]\n",out
);
606 ok(r
==4,"failed: r=%d\n",r
);
609 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!d!%2!d!%3!d!", 0,
610 0, out
, sizeof(out
)/sizeof(CHAR
), 1,2,3);
611 ok(!strcmp("123", out
),"failed out=[%s]\n",out
);
612 ok(r
==3,"failed: r=%d\n",r
);
614 /* a single digit with some spacing */
615 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!4d!", 0,
616 0, out
, sizeof(out
)/sizeof(CHAR
), 1);
617 ok(!strcmp(" 1", out
),"failed out=[%s]\n",out
);
618 ok(r
==4,"failed: r=%d\n",r
);
620 /* a single digit, left justified */
621 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!-4d!", 0,
622 0, out
, sizeof(out
)/sizeof(CHAR
), 1);
623 ok(!strcmp("1 ", out
),"failed out=[%s]\n",out
);
624 ok(r
==4,"failed: r=%d\n",r
);
626 /* two digit decimal number */
627 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!4d!", 0,
628 0, out
, sizeof(out
)/sizeof(CHAR
), 11);
629 ok(!strcmp(" 11", out
),"failed out=[%s]\n",out
);
630 ok(r
==4,"failed: r=%d\n",r
);
633 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!4x!", 0,
634 0, out
, sizeof(out
)/sizeof(CHAR
), 11);
635 ok(!strcmp(" b", out
),"failed out=[%s]\n",out
);
636 ok(r
==4,"failed: r=%d\n",r
);
638 /* a hex number, upper case */
639 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!4X!", 0,
640 0, out
, sizeof(out
)/sizeof(CHAR
), 11);
641 ok(!strcmp(" B", out
),"failed out=[%s]\n",out
);
642 ok(r
==4,"failed: r=%d\n",r
);
644 /* a hex number, upper case, left justified */
645 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!-4X!", 0,
646 0, out
, sizeof(out
)/sizeof(CHAR
), 11);
647 ok(!strcmp("B ", out
),"failed out=[%s]\n",out
);
648 ok(r
==4,"failed: r=%d\n",r
);
650 /* a long hex number, upper case */
651 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!4X!", 0,
652 0, out
, sizeof(out
)/sizeof(CHAR
), 0x1ab);
653 ok(!strcmp(" 1AB", out
),"failed out=[%s]\n",out
);
654 ok(r
==4,"failed: r=%d\n",r
);
657 r
= doit(FORMAT_MESSAGE_FROM_STRING
, " %%%% ", 0,
658 0, out
, sizeof(out
)/sizeof(CHAR
));
659 ok(!strcmp(" %% ", out
),"failed out=[%s]\n",out
);
660 ok(r
==4,"failed: r=%d\n",r
);
662 /* periods are special cases */
663 r
= doit(FORMAT_MESSAGE_FROM_STRING
, " %.%. %1!d!", 0,
664 0, out
, sizeof(out
)/sizeof(CHAR
), 0x1ab);
665 ok(!strcmp(" .. 427", out
),"failed out=[%s]\n",out
);
666 ok(r
==7,"failed: r=%d\n",r
);
668 /* %0 ends the line */
669 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "test%0test", 0,
670 0, out
, sizeof(out
)/sizeof(CHAR
));
671 ok(!strcmp("test", out
),"failed out=[%s]\n",out
);
672 ok(r
==4,"failed: r=%d\n",r
);
674 /* %! prints an exclamation */
675 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "yah%!%0 ", 0,
676 0, out
, sizeof(out
)/sizeof(CHAR
));
677 ok(!strcmp("yah!", out
),"failed out=[%s]\n",out
);
678 ok(r
==4,"failed: r=%d\n",r
);
681 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "% % ", 0,
682 0, out
, sizeof(out
)/sizeof(CHAR
));
683 ok(!strcmp(" ", out
),"failed out=[%s]\n",out
);
684 ok(r
==4,"failed: r=%d\n",r
);
686 /* %n yields \r\n, %r yields \r, %t yields \t */
687 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%n%r%t", 0,
688 0, out
, sizeof(out
)/sizeof(CHAR
));
689 ok(!strcmp("\r\n\r\t", out
),"failed out=[%s]\n",out
);
690 ok(r
==4,"failed: r=%d\n",r
);
693 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "hi\n", 0,
694 0, out
, sizeof(out
)/sizeof(CHAR
));
695 ok(!strcmp("hi\r\n", out
),"failed out=[%s]\n",out
);
696 ok(r
==4,"failed: r=%d\n",r
);
698 /* carriage return line feed */
699 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "hi\r\n", 0,
700 0, out
, sizeof(out
)/sizeof(CHAR
));
701 ok(!strcmp("hi\r\n", out
),"failed out=[%s]\n",out
);
702 ok(r
==4,"failed: r=%d\n",r
);
704 /* carriage return */
705 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "\r", 0,
706 0, out
, sizeof(out
)/sizeof(CHAR
));
707 ok(!strcmp("\r\n", out
),"failed out=[%s]\n",out
);
708 ok(r
==2,"failed: r=%d\n",r
);
710 /* double carriage return line feed */
711 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "\r\r\n", 0,
712 0, out
, sizeof(out
)/sizeof(CHAR
));
713 ok(!strcmp("\r\n\r\n", out
),"failed out=[%s]\n",out
);
714 ok(r
==4,"failed: r=%d\n",r
);
716 /* precision and width */
718 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!3s!",
719 0, 0, out
, sizeof(out
), "t" );
720 ok(!strcmp(" t", out
),"failed out=[%s]\n",out
);
721 ok(r
==3, "failed: r=%d\n",r
);
722 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!*s!",
723 0, 0, out
, sizeof(out
), 4, "t");
724 if (!strcmp("*s",out
)) win_skip( "width/precision not supported\n" );
727 ok(!strcmp( " t", out
),"failed out=[%s]\n",out
);
728 ok(r
==4,"failed: r=%d\n",r
);
729 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!4.2u!",
730 0, 0, out
, sizeof(out
), 3 );
731 ok(!strcmp( " 03", out
),"failed out=[%s]\n",out
);
732 ok(r
==4,"failed: r=%d\n",r
);
733 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!*.*u!",
734 0, 0, out
, sizeof(out
), 5, 3, 1 );
735 ok(!strcmp( " 001", out
),"failed out=[%s]\n",out
);
736 ok(r
==5,"failed: r=%d\n",r
);
737 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!*.*u!,%1!*.*u!",
738 0, 0, out
, sizeof(out
), 5, 3, 1, 4, 2 );
739 ok(!strcmp( " 001, 0002", out
),"failed out=[%s]\n",out
);
740 ok(r
==11,"failed: r=%d\n",r
);
741 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!*.*u!,%3!*.*u!",
742 0, 0, out
, sizeof(out
), 5, 3, 1, 6, 4, 2 );
743 /* older Win versions marked as broken even though this is arguably the correct behavior */
744 /* but the new (brain-damaged) behavior is specified on MSDN */
745 ok(!strcmp( " 001, 0002", out
) ||
746 broken(!strcmp(" 001,000004", out
)), /* NT4/Win2k */
747 "failed out=[%s]\n",out
);
748 ok(r
==12,"failed: r=%d\n",r
);
749 /* args are not counted the same way with an argument array */
751 ULONG_PTR args
[] = { 6, 4, 2, 5, 3, 1 };
752 r
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ARGUMENT_ARRAY
,
753 "%1!*.*u!,%1!*.*u!", 0, 0, out
, sizeof(out
), (__ms_va_list
*)args
);
754 ok(!strcmp(" 0002, 00003", out
),"failed out=[%s]\n",out
);
755 ok(r
==13,"failed: r=%d\n",r
);
756 r
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ARGUMENT_ARRAY
,
757 "%1!*.*u!,%4!*.*u!", 0, 0, out
, sizeof(out
), (__ms_va_list
*)args
);
758 ok(!strcmp(" 0002, 001", out
),"failed out=[%s]\n",out
);
759 ok(r
==12,"failed: r=%d\n",r
);
763 /* change of pace... test the low byte of dwflags */
766 r
= doit(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_MAX_WIDTH_MASK
, "hi\n", 0,
767 0, out
, sizeof(out
)/sizeof(CHAR
));
768 ok(!strcmp("hi ", out
) ||
769 broken(!strcmp("hi\r\n", out
)), /* Win9x */
770 "failed out=[%s]\n",out
);
772 broken(r
==4), /* Win9x */
775 /* carriage return line feed */
776 r
= doit(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_MAX_WIDTH_MASK
, "hi\r\n", 0,
777 0, out
, sizeof(out
)/sizeof(CHAR
));
778 ok(!strcmp("hi ", out
),"failed out=[%s]\n",out
);
779 ok(r
==3,"failed: r=%d\n",r
);
781 /* carriage return */
782 r
= doit(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_MAX_WIDTH_MASK
, "\r", 0,
783 0, out
, sizeof(out
)/sizeof(CHAR
));
784 ok(!strcmp(" ", out
),"failed out=[%s]\n",out
);
785 ok(r
==1,"failed: r=%d\n",r
);
787 /* double carriage return line feed */
788 r
= doit(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_MAX_WIDTH_MASK
, "\r\r\n", 0,
789 0, out
, sizeof(out
)/sizeof(CHAR
));
790 ok(!strcmp(" ", out
),"failed out=[%s]\n",out
);
791 ok(r
==2,"failed: r=%d\n",r
);
794 static void test_message_ignore_inserts(void)
796 static const char init_buf
[] = {'x', 'x', 'x', 'x', 'x'};
801 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, "test", 0, 0, out
,
802 sizeof(out
)/sizeof(CHAR
), NULL
);
803 ok(ret
== 4, "Expected FormatMessageA to return 4, got %d\n", ret
);
804 ok(!strcmp("test", out
), "Expected output string \"test\", got %s\n", out
);
806 /* The %0 escape sequence is handled. */
807 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, "test%0", 0, 0, out
,
808 sizeof(out
)/sizeof(CHAR
), NULL
);
809 ok(ret
== 4, "Expected FormatMessageA to return 4, got %d\n", ret
);
810 ok(!strcmp("test", out
), "Expected output string \"test\", got %s\n", out
);
812 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, "test%0test", 0, 0, out
,
813 sizeof(out
)/sizeof(CHAR
), NULL
);
814 ok(ret
== 4, "Expected FormatMessageA to return 4, got %d\n", ret
);
815 ok(!strcmp("test", out
), "Expected output string \"test\", got %s\n", out
);
817 /* While FormatMessageA returns 0 in this case, no last error code is set. */
818 SetLastError(0xdeadbeef);
819 memcpy(out
, init_buf
, sizeof(init_buf
));
820 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, "%0test", 0, 0, out
,
821 sizeof(out
)/sizeof(CHAR
), NULL
);
822 ok(ret
== 0, "Expected FormatMessageA to return 0, got %d\n", ret
);
823 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)) ||
824 broken(!strcmp("", out
)), /* Win9x */
825 "Expected the output buffer to be untouched\n");
826 ok(GetLastError() == 0xdeadbeef, "Expected GetLastError() to return 0xdeadbeef, got %u\n", GetLastError());
828 /* Insert sequences are ignored. */
829 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, "test%1%2!*.*s!%99", 0, 0, out
,
830 sizeof(out
)/sizeof(CHAR
), NULL
);
831 ok(ret
== 17, "Expected FormatMessageA to return 17, got %d\n", ret
);
832 ok(!strcmp("test%1%2!*.*s!%99", out
), "Expected output string \"test%%1%%2!*.*s!%%99\", got %s\n", out
);
834 /* Only the "%n", "%r", and "%t" escape sequences are processed. */
835 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, "%%% %.%!", 0, 0, out
,
836 sizeof(out
)/sizeof(CHAR
), NULL
);
838 broken(ret
== 7) /* Win9x */,
839 "Expected FormatMessageA to return 8, got %d\n", ret
);
840 ok(!strcmp("%%% %.%!", out
) ||
841 broken(!strcmp("%%% %.!", out
)) /* Win9x */,
842 "Expected output string \"%%%%%% %%.%%!\", got %s\n", out
);
844 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, "%n%r%t", 0, 0, out
,
845 sizeof(out
)/sizeof(CHAR
), NULL
);
846 ok(ret
== 4, "Expected FormatMessageA to return 4, got %d\n", ret
);
847 ok(!strcmp("\r\n\r\t", out
), "Expected output string \"\\r\\n\\r\\t\", got %s\n", out
);
849 /* CRLF characters are processed normally. */
850 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, "hi\n", 0, 0, out
,
851 sizeof(out
)/sizeof(CHAR
), NULL
);
852 ok(ret
== 4, "Expected FormatMessageA to return 4, got %d\n", ret
);
853 ok(!strcmp("hi\r\n", out
), "Expected output string \"hi\\r\\n\", got %s\n", out
);
855 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, "hi\r\n", 0, 0, out
,
856 sizeof(out
)/sizeof(CHAR
), NULL
);
857 ok(ret
== 4, "Expected FormatMessageA to return 4, got %d\n", ret
);
858 ok(!strcmp("hi\r\n", out
), "Expected output string \"hi\\r\\n\", got %s\n", out
);
860 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, "\r", 0, 0, out
,
861 sizeof(out
)/sizeof(CHAR
), NULL
);
862 ok(ret
== 2, "Expected FormatMessageA to return 2, got %d\n", ret
);
863 ok(!strcmp("\r\n", out
), "Expected output string \"\\r\\n\", got %s\n", out
);
865 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, "\r\r\n", 0, 0, out
,
866 sizeof(out
)/sizeof(CHAR
), NULL
);
867 ok(ret
== 4, "Expected FormatMessageA to return 4, got %d\n", ret
);
868 ok(!strcmp("\r\n\r\n", out
), "Expected output string \"\\r\\n\\r\\n\", got %s\n", out
);
870 /* The width parameter is handled the same also. */
871 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
|
872 FORMAT_MESSAGE_MAX_WIDTH_MASK
, "hi\n", 0, 0, out
,
873 sizeof(out
)/sizeof(CHAR
), NULL
);
874 ok(!strcmp("hi ", out
) ||
875 broken(!strcmp("hi\r\n", out
)), /* Win9x */
876 "Expected output string \"hi \", got %s\n", out
);
878 broken(ret
== 4), /* Win9x */
879 "Expected FormatMessageA to return 3, got %d\n", ret
);
881 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
|
882 FORMAT_MESSAGE_MAX_WIDTH_MASK
, "hi\r\n", 0, 0, out
,
883 sizeof(out
)/sizeof(CHAR
), NULL
);
884 ok(ret
== 3, "Expected FormatMessageA to return 3, got %d\n", ret
);
885 ok(!strcmp("hi ", out
), "Expected output string \"hi \", got %s\n", out
);
887 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
|
888 FORMAT_MESSAGE_MAX_WIDTH_MASK
, "\r", 0, 0, out
,
889 sizeof(out
)/sizeof(CHAR
), NULL
);
890 ok(ret
== 1, "Expected FormatMessageA to return 1, got %d\n", ret
);
891 ok(!strcmp(" ", out
), "Expected output string \" \", got %s\n", out
);
893 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
|
894 FORMAT_MESSAGE_MAX_WIDTH_MASK
, "\r\r\n", 0, 0, out
,
895 sizeof(out
)/sizeof(CHAR
), NULL
);
896 ok(ret
== 2, "Expected FormatMessageA to return 2, got %d\n", ret
);
897 ok(!strcmp(" ", out
), "Expected output string \" \", got %s\n", out
);
900 static void test_message_ignore_inserts_wide(void)
902 static const WCHAR test
[] = {'t','e','s','t',0};
903 static const WCHAR empty
[] = {0};
904 static const WCHAR fmt_t0
[] = {'t','e','s','t','%','0',0};
905 static const WCHAR fmt_t0t
[] = {'t','e','s','t','%','0','t','e','s','t',0};
906 static const WCHAR fmt_0t
[] = {'%','0','t','e','s','t',0};
907 static const WCHAR fmt_t12oos99
[] = {'t','e','s','t','%','1','%','2','!','*','.','*','s','!','%','9','9',0};
908 static const WCHAR fmt_pctspacedot
[] = {'%','%','%',' ','%','.','%','!',0};
909 static const WCHAR fmt_nrt
[] = {'%','n','%','r','%','t',0};
910 static const WCHAR fmt_hi_lf
[] = {'h','i','\n',0};
911 static const WCHAR fmt_hi_crlf
[] = {'h','i','\r','\n',0};
912 static const WCHAR fmt_cr
[] = {'\r',0};
913 static const WCHAR fmt_crcrlf
[] = {'\r','\r','\n',0};
915 static const WCHAR s_nrt
[] = {'\r','\n','\r','\t',0};
916 static const WCHAR s_hi_crlf
[] = {'h','i','\r','\n',0};
917 static const WCHAR s_crlf
[] = {'\r','\n',0};
918 static const WCHAR s_crlfcrlf
[] = {'\r','\n','\r','\n',0};
919 static const WCHAR s_hi_sp
[] = {'h','i',' ',0};
920 static const WCHAR s_sp
[] = {' ',0};
921 static const WCHAR s_2sp
[] = {' ',' ',0};
926 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, test
, 0, 0, out
,
927 sizeof(out
)/sizeof(WCHAR
), NULL
);
928 ok(ret
== 4, "Expected FormatMessageW to return 4, got %d\n", ret
);
929 ok(!lstrcmpW(test
, out
), "Expected output string \"test\", got %s\n", wine_dbgstr_w(out
));
931 /* The %0 escape sequence is handled. */
932 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, fmt_t0
, 0, 0, out
,
933 sizeof(out
)/sizeof(WCHAR
), NULL
);
934 ok(ret
== 4, "Expected FormatMessageW to return 4, got %d\n", ret
);
935 ok(!lstrcmpW(test
, out
), "Expected output string \"test\", got %s\n", wine_dbgstr_w(out
));
937 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, fmt_t0t
, 0, 0, out
,
938 sizeof(out
)/sizeof(WCHAR
), NULL
);
939 ok(ret
== 4, "Expected FormatMessageW to return 4, got %d\n", ret
);
940 ok(!lstrcmpW(test
, out
), "Expected output string \"test\", got %s\n", wine_dbgstr_w(out
));
942 /* While FormatMessageA returns 0 in this case, no last error code is set. */
943 SetLastError(0xdeadbeef);
944 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, fmt_0t
, 0, 0, out
,
945 sizeof(out
)/sizeof(WCHAR
), NULL
);
946 ok(ret
== 0, "Expected FormatMessageW to return 0, got %d\n", ret
);
947 ok(!lstrcmpW(empty
, out
), "Expected the output buffer to be the empty string, got %s\n", wine_dbgstr_w(out
));
948 ok(GetLastError() == 0xdeadbeef, "Expected GetLastError() to return 0xdeadbeef, got %u\n", GetLastError());
950 /* Insert sequences are ignored. */
951 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, fmt_t12oos99
, 0, 0, out
,
952 sizeof(out
)/sizeof(WCHAR
), NULL
);
953 ok(ret
== 17, "Expected FormatMessageW to return 17, got %d\n", ret
);
954 ok(!lstrcmpW(fmt_t12oos99
, out
), "Expected output string \"test%%1%%2!*.*s!%%99\", got %s\n", wine_dbgstr_w(out
));
956 /* Only the "%n", "%r", and "%t" escape sequences are processed. */
957 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, fmt_pctspacedot
, 0, 0, out
,
958 sizeof(out
)/sizeof(WCHAR
), NULL
);
959 ok(ret
== 8, "Expected FormatMessageW to return 8, got %d\n", ret
);
960 ok(!lstrcmpW(fmt_pctspacedot
, out
), "Expected output string \"%%%%%% %%.%%!\", got %s\n", wine_dbgstr_w(out
));
962 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, fmt_nrt
, 0, 0, out
,
963 sizeof(out
)/sizeof(WCHAR
), NULL
);
964 ok(ret
== 4, "Expected FormatMessageW to return 4, got %d\n", ret
);
965 ok(!lstrcmpW(s_nrt
, out
), "Expected output string \"\\r\\n\\r\\t\", got %s\n", wine_dbgstr_w(out
));
967 /* CRLF characters are processed normally. */
968 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, fmt_hi_lf
, 0, 0, out
,
969 sizeof(out
)/sizeof(WCHAR
), NULL
);
970 ok(ret
== 4, "Expected FormatMessageW to return 4, got %d\n", ret
);
971 ok(!lstrcmpW(s_hi_crlf
, out
), "Expected output string \"hi\\r\\n\", got %s\n", wine_dbgstr_w(out
));
973 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, fmt_hi_crlf
, 0, 0, out
,
974 sizeof(out
)/sizeof(WCHAR
), NULL
);
975 ok(ret
== 4, "Expected FormatMessageW to return 4, got %d\n", ret
);
976 ok(!lstrcmpW(s_hi_crlf
, out
), "Expected output string \"hi\\r\\n\", got %s\n", wine_dbgstr_w(out
));
978 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, fmt_cr
, 0, 0, out
,
979 sizeof(out
)/sizeof(WCHAR
), NULL
);
980 ok(ret
== 2, "Expected FormatMessageW to return 2, got %d\n", ret
);
981 ok(!lstrcmpW(s_crlf
, out
), "Expected output string \"\\r\\n\", got %s\n", wine_dbgstr_w(out
));
983 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, fmt_crcrlf
, 0, 0, out
,
984 sizeof(out
)/sizeof(WCHAR
), NULL
);
985 ok(ret
== 4, "Expected FormatMessageW to return 4, got %d\n", ret
);
986 ok(!lstrcmpW(s_crlfcrlf
, out
), "Expected output string \"\\r\\n\\r\\n\", got %s\n", wine_dbgstr_w(out
));
988 /* The width parameter is handled the same also. */
989 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
|
990 FORMAT_MESSAGE_MAX_WIDTH_MASK
, fmt_hi_lf
, 0, 0, out
,
991 sizeof(out
)/sizeof(WCHAR
), NULL
);
992 ok(ret
== 3, "Expected FormatMessageW to return 3, got %d\n", ret
);
993 ok(!lstrcmpW(s_hi_sp
, out
), "Expected output string \"hi \", 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_hi_crlf
, 0, 0, out
,
997 sizeof(out
)/sizeof(WCHAR
), NULL
);
998 ok(ret
== 3, "Expected FormatMessageW to return 3, got %d\n", ret
);
999 ok(!lstrcmpW(s_hi_sp
, out
), "Expected output string \"hi \", got %s\n", wine_dbgstr_w(out
));
1001 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
|
1002 FORMAT_MESSAGE_MAX_WIDTH_MASK
, fmt_cr
, 0, 0, out
,
1003 sizeof(out
)/sizeof(WCHAR
), NULL
);
1004 ok(ret
== 1, "Expected FormatMessageW to return 1, got %d\n", ret
);
1005 ok(!lstrcmpW(s_sp
, out
), "Expected output string \" \", got %s\n", wine_dbgstr_w(out
));
1007 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
|
1008 FORMAT_MESSAGE_MAX_WIDTH_MASK
, fmt_crcrlf
, 0, 0, out
,
1009 sizeof(out
)/sizeof(WCHAR
), NULL
);
1010 ok(ret
== 2, "Expected FormatMessageW to return 2, got %d\n", ret
);
1011 ok(!lstrcmpW(s_2sp
, out
), "Expected output string \" \", got %s\n", wine_dbgstr_w(out
));
1014 static void test_message_insufficient_buffer(void)
1016 static const char init_buf
[] = {'x', 'x', 'x', 'x', 'x'};
1017 static const char expected_buf
[] = {'x', 'x', 'x', 'x', 'x'};
1021 SetLastError(0xdeadbeef);
1022 memcpy(out
, init_buf
, sizeof(init_buf
));
1023 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
, "test", 0, 0, out
, 0, NULL
);
1024 ok(ret
== 0, "Expected FormatMessageA to return 0, got %u\n", ret
);
1025 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
1026 "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n",
1028 ok(!memcmp(expected_buf
, out
, sizeof(expected_buf
)),
1029 "Expected the buffer to be untouched\n");
1031 SetLastError(0xdeadbeef);
1032 memcpy(out
, init_buf
, sizeof(init_buf
));
1033 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
, "test", 0, 0, out
, 1, NULL
);
1034 ok(ret
== 0, "Expected FormatMessageA to return 0, got %u\n", ret
);
1035 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
1036 "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n",
1038 ok(!memcmp(expected_buf
, out
, sizeof(expected_buf
)),
1039 "Expected the buffer to be untouched\n");
1041 SetLastError(0xdeadbeef);
1042 memcpy(out
, init_buf
, sizeof(init_buf
));
1043 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
, "test", 0, 0, out
, sizeof(out
)/sizeof(out
[0]) - 1, NULL
);
1044 ok(ret
== 0, "Expected FormatMessageA to return 0, got %u\n", ret
);
1045 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
1046 "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n",
1048 ok(!memcmp(expected_buf
, out
, sizeof(expected_buf
)),
1049 "Expected the buffer to be untouched\n");
1052 static void test_message_insufficient_buffer_wide(void)
1054 static const WCHAR test
[] = {'t','e','s','t',0};
1055 static const WCHAR init_buf
[] = {'x', 'x', 'x', 'x', 'x'};
1056 static const WCHAR expected_buf
[] = {'x', 'x', 'x', 'x', 'x'};
1057 static const WCHAR broken_buf
[] = {0, 'x', 'x', 'x', 'x'};
1058 static const WCHAR broken2_buf
[] = {'t','e','s',0,'x'};
1063 SetLastError(0xdeadbeef);
1064 memcpy(out
, init_buf
, sizeof(init_buf
));
1065 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
, test
, 0, 0, out
, 0, NULL
);
1066 ok(ret
== 0, "Expected FormatMessageA to return 0, got %u\n", ret
);
1067 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
1068 "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n",
1070 ok(!memcmp(expected_buf
, out
, sizeof(expected_buf
)),
1071 "Expected the buffer to be untouched\n");
1073 /* Windows Server 2003 and newer report failure but copy a
1074 * truncated string to the buffer for non-zero buffer sizes. */
1075 SetLastError(0xdeadbeef);
1076 memcpy(out
, init_buf
, sizeof(init_buf
));
1077 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
, test
, 0, 0, out
, 1, NULL
);
1078 ok(ret
== 0, "Expected FormatMessageA to return 0, got %u\n", ret
);
1079 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
1080 "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n",
1082 ok(!memcmp(expected_buf
, out
, sizeof(expected_buf
)) ||
1083 broken(!memcmp(broken_buf
, out
, sizeof(broken_buf
))), /* W2K3+ */
1084 "Expected the buffer to be untouched\n");
1086 SetLastError(0xdeadbeef);
1087 memcpy(out
, init_buf
, sizeof(init_buf
));
1088 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
, test
, 0, 0, out
, sizeof(out
)/sizeof(out
[0]) - 1, NULL
);
1089 ok(ret
== 0, "Expected FormatMessageA to return 0, got %u\n", ret
);
1090 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
1091 "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n",
1093 ok(!memcmp(expected_buf
, out
, sizeof(expected_buf
)) ||
1094 broken(!memcmp(broken2_buf
, out
, sizeof(broken2_buf
))), /* W2K3+ */
1095 "Expected the buffer to be untouched\n");
1098 static void test_message_null_buffer(void)
1102 /* Without FORMAT_MESSAGE_ALLOCATE_BUFFER, only the specified buffer size is checked. */
1103 SetLastError(0xdeadbeef);
1104 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, 0, 0, NULL
, 0, NULL
);
1105 error
= GetLastError();
1106 ok(!ret
, "FormatMessageA returned %u\n", ret
);
1107 ok(error
== ERROR_INSUFFICIENT_BUFFER
||
1108 error
== ERROR_INVALID_PARAMETER
, /* win9x */
1109 "last error %u\n", error
);
1111 SetLastError(0xdeadbeef);
1112 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, 0, 0, NULL
, 1, NULL
);
1113 error
= GetLastError();
1114 ok(!ret
, "FormatMessageA returned %u\n", ret
);
1115 ok(error
== ERROR_INSUFFICIENT_BUFFER
||
1116 error
== ERROR_INVALID_PARAMETER
, /* win9x */
1117 "last error %u\n", error
);
1119 if (0) /* crashes on Windows */
1121 SetLastError(0xdeadbeef);
1122 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, 0, 0, NULL
, 256, NULL
);
1123 error
= GetLastError();
1124 ok(!ret
, "FormatMessageA returned %u\n", ret
);
1125 trace("last error %u\n", error
);
1128 SetLastError(0xdeadbeef);
1129 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_ALLOCATE_BUFFER
, NULL
, 0, 0, NULL
, 0, NULL
);
1130 error
= GetLastError();
1131 ok(!ret
, "FormatMessageA returned %u\n", ret
);
1132 ok(error
== ERROR_NOT_ENOUGH_MEMORY
||
1133 error
== ERROR_INVALID_PARAMETER
, /* win9x */
1134 "last error %u\n", error
);
1136 SetLastError(0xdeadbeef);
1137 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_ALLOCATE_BUFFER
, NULL
, 0, 0, NULL
, 1, NULL
);
1138 error
= GetLastError();
1139 ok(!ret
, "FormatMessageA returned %u\n", ret
);
1140 ok(error
== ERROR_NOT_ENOUGH_MEMORY
||
1141 error
== ERROR_INVALID_PARAMETER
, /* win9x */
1142 "last error %u\n", error
);
1144 SetLastError(0xdeadbeef);
1145 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_ALLOCATE_BUFFER
, NULL
, 0, 0, NULL
, 256, NULL
);
1146 error
= GetLastError();
1147 ok(!ret
, "FormatMessageA returned %u\n", ret
);
1148 ok(error
== ERROR_NOT_ENOUGH_MEMORY
||
1149 error
== ERROR_INVALID_PARAMETER
, /* win9x */
1150 "last error %u\n", error
);
1153 static void test_message_null_buffer_wide(void)
1157 SetLastError(0xdeadbeef);
1158 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, 0, 0, NULL
, 0, NULL
);
1159 error
= GetLastError();
1160 ok(!ret
, "FormatMessageW returned %u\n", ret
);
1161 ok(error
== ERROR_INVALID_PARAMETER
, "last error %u\n", error
);
1163 SetLastError(0xdeadbeef);
1164 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, 0, 0, NULL
, 1, NULL
);
1165 error
= GetLastError();
1166 ok(!ret
, "FormatMessageW returned %u\n", ret
);
1167 ok(error
== ERROR_INVALID_PARAMETER
, "last error %u\n", error
);
1169 SetLastError(0xdeadbeef);
1170 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, 0, 0, NULL
, 256, NULL
);
1171 error
= GetLastError();
1172 ok(!ret
, "FormatMessageW returned %u\n", ret
);
1173 ok(error
== ERROR_INVALID_PARAMETER
, "last error %u\n", error
);
1175 SetLastError(0xdeadbeef);
1176 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_ALLOCATE_BUFFER
, NULL
, 0, 0, NULL
, 0, NULL
);
1177 error
= GetLastError();
1178 ok(!ret
, "FormatMessageW returned %u\n", ret
);
1179 ok(error
== ERROR_INVALID_PARAMETER
, "last error %u\n", error
);
1181 SetLastError(0xdeadbeef);
1182 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_ALLOCATE_BUFFER
, NULL
, 0, 0, NULL
, 1, NULL
);
1183 error
= GetLastError();
1184 ok(!ret
, "FormatMessageW returned %u\n", ret
);
1185 ok(error
== ERROR_INVALID_PARAMETER
, "last error %u\n", error
);
1187 SetLastError(0xdeadbeef);
1188 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_ALLOCATE_BUFFER
, NULL
, 0, 0, NULL
, 256, NULL
);
1189 error
= GetLastError();
1190 ok(!ret
, "FormatMessageW returned %u\n", ret
);
1191 ok(error
== ERROR_INVALID_PARAMETER
, "last error %u\n", error
);
1194 static void test_message_allocate_buffer(void)
1199 /* While MSDN suggests that FormatMessageA allocates a buffer whose size is
1200 * the larger of the output string and the requested buffer size, the tests
1201 * will not try to determine the actual size of the buffer allocated, as
1202 * the return value of LocalSize cannot be trusted for the purpose, and it should
1203 * in any case be safe for FormatMessageA to allocate in the manner that
1206 SetLastError(0xdeadbeef);
1207 buf
= (char *)0xdeadbeef;
1208 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ALLOCATE_BUFFER
,
1209 "", 0, 0, (char *)&buf
, 0, NULL
);
1210 ok(ret
== 0, "Expected FormatMessageA to return 0, got %u\n", ret
);
1211 ok(buf
== NULL
, "Expected output buffer pointer to be NULL\n");
1212 ok(GetLastError() == 0xdeadbeef,
1213 "Expected last error to be untouched, got %u\n", GetLastError());
1215 buf
= (char *)0xdeadbeef;
1216 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ALLOCATE_BUFFER
,
1217 "test", 0, 0, (char *)&buf
, 0, NULL
);
1218 ok(ret
== 4, "Expected FormatMessageA to return 4, got %u\n", ret
);
1219 ok(buf
!= NULL
&& buf
!= (char *)0xdeadbeef,
1220 "Expected output buffer pointer to be valid\n");
1221 if (buf
!= NULL
&& buf
!= (char *)0xdeadbeef)
1223 ok(!strcmp("test", buf
),
1224 "Expected buffer to contain \"test\", got %s\n", buf
);
1228 buf
= (char *)0xdeadbeef;
1229 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ALLOCATE_BUFFER
,
1230 "test", 0, 0, (char *)&buf
, strlen("test"), NULL
);
1231 ok(ret
== 4, "Expected FormatMessageA to return 4, got %u\n", ret
);
1232 ok(buf
!= NULL
&& buf
!= (char *)0xdeadbeef,
1233 "Expected output buffer pointer to be valid\n");
1234 if (buf
!= NULL
&& buf
!= (char *)0xdeadbeef)
1236 ok(!strcmp("test", buf
),
1237 "Expected buffer to contain \"test\", got %s\n", buf
);
1241 buf
= (char *)0xdeadbeef;
1242 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ALLOCATE_BUFFER
,
1243 "test", 0, 0, (char *)&buf
, strlen("test") + 1, NULL
);
1244 ok(ret
== 4, "Expected FormatMessageA to return 4, got %u\n", ret
);
1245 ok(buf
!= NULL
&& buf
!= (char *)0xdeadbeef,
1246 "Expected output buffer pointer to be valid\n");
1247 if (buf
!= NULL
&& buf
!= (char *)0xdeadbeef)
1249 ok(!strcmp("test", buf
),
1250 "Expected buffer to contain \"test\", got %s\n", buf
);
1254 buf
= (char *)0xdeadbeef;
1255 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ALLOCATE_BUFFER
,
1256 "test", 0, 0, (char *)&buf
, strlen("test") + 2, NULL
);
1257 ok(ret
== 4, "Expected FormatMessageA to return 4, got %u\n", ret
);
1258 ok(buf
!= NULL
&& buf
!= (char *)0xdeadbeef,
1259 "Expected output buffer pointer to be valid\n");
1260 if (buf
!= NULL
&& buf
!= (char *)0xdeadbeef)
1262 ok(!strcmp("test", buf
),
1263 "Expected buffer to contain \"test\", got %s\n", buf
);
1267 buf
= (char *)0xdeadbeef;
1268 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ALLOCATE_BUFFER
,
1269 "test", 0, 0, (char *)&buf
, 1024, NULL
);
1270 ok(ret
== 4, "Expected FormatMessageA to return 4, got %u\n", ret
);
1271 ok(buf
!= NULL
&& buf
!= (char *)0xdeadbeef,
1272 "Expected output buffer pointer to be valid\n");
1273 if (buf
!= NULL
&& buf
!= (char *)0xdeadbeef)
1275 ok(!strcmp("test", buf
),
1276 "Expected buffer to contain \"test\", got %s\n", buf
);
1281 static void test_message_allocate_buffer_wide(void)
1283 static const WCHAR empty
[] = {0};
1284 static const WCHAR test
[] = {'t','e','s','t',0};
1289 /* While MSDN suggests that FormatMessageW allocates a buffer whose size is
1290 * the larger of the output string and the requested buffer size, the tests
1291 * will not try to determine the actual size of the buffer allocated, as
1292 * the return value of LocalSize cannot be trusted for the purpose, and it should
1293 * in any case be safe for FormatMessageW to allocate in the manner that
1296 if (0) /* crashes on Windows */
1298 buf
= (WCHAR
*)0xdeadbeef;
1299 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ALLOCATE_BUFFER
,
1300 NULL
, 0, 0, (WCHAR
*)&buf
, 0, NULL
);
1303 SetLastError(0xdeadbeef);
1304 buf
= (WCHAR
*)0xdeadbeef;
1305 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ALLOCATE_BUFFER
,
1306 empty
, 0, 0, (WCHAR
*)&buf
, 0, NULL
);
1307 ok(ret
== 0, "Expected FormatMessageW to return 0, got %u\n", ret
);
1308 ok(buf
== NULL
, "Expected output buffer pointer to be NULL\n");
1309 ok(GetLastError() == 0xdeadbeef,
1310 "Expected last error to be untouched, got %u\n", GetLastError());
1312 buf
= (WCHAR
*)0xdeadbeef;
1313 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ALLOCATE_BUFFER
,
1314 test
, 0, 0, (WCHAR
*)&buf
, 0, NULL
);
1315 ok(ret
== 4, "Expected FormatMessageA to return 4, got %u\n", ret
);
1316 ok(buf
!= NULL
&& buf
!= (WCHAR
*)0xdeadbeef,
1317 "Expected output buffer pointer to be valid\n");
1318 if (buf
!= NULL
&& buf
!= (WCHAR
*)0xdeadbeef)
1320 ok(!lstrcmpW(test
, buf
),
1321 "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf
));
1325 buf
= (WCHAR
*)0xdeadbeef;
1326 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ALLOCATE_BUFFER
,
1327 test
, 0, 0, (WCHAR
*)&buf
, sizeof(test
)/sizeof(WCHAR
) - 1, NULL
);
1328 ok(ret
== 4, "Expected FormatMessageA to return 4, got %u\n", ret
);
1329 ok(buf
!= NULL
&& buf
!= (WCHAR
*)0xdeadbeef,
1330 "Expected output buffer pointer to be valid\n");
1331 if (buf
!= NULL
&& buf
!= (WCHAR
*)0xdeadbeef)
1333 ok(!lstrcmpW(test
, buf
),
1334 "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf
));
1338 buf
= (WCHAR
*)0xdeadbeef;
1339 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ALLOCATE_BUFFER
,
1340 test
, 0, 0, (WCHAR
*)&buf
, sizeof(test
)/sizeof(WCHAR
), NULL
);
1341 ok(ret
== 4, "Expected FormatMessageA to return 4, got %u\n", ret
);
1342 ok(buf
!= NULL
&& buf
!= (WCHAR
*)0xdeadbeef,
1343 "Expected output buffer pointer to be valid\n");
1344 if (buf
!= NULL
&& buf
!= (WCHAR
*)0xdeadbeef)
1346 ok(!lstrcmpW(test
, buf
),
1347 "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf
));
1351 buf
= (WCHAR
*)0xdeadbeef;
1352 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ALLOCATE_BUFFER
,
1353 test
, 0, 0, (WCHAR
*)&buf
, sizeof(test
)/sizeof(WCHAR
) + 1, NULL
);
1354 ok(ret
== 4, "Expected FormatMessageA to return 4, got %u\n", ret
);
1355 ok(buf
!= NULL
&& buf
!= (WCHAR
*)0xdeadbeef,
1356 "Expected output buffer pointer to be valid\n");
1357 if (buf
!= NULL
&& buf
!= (WCHAR
*)0xdeadbeef)
1359 ok(!lstrcmpW(test
, buf
),
1360 "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf
));
1364 buf
= (WCHAR
*)0xdeadbeef;
1365 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ALLOCATE_BUFFER
,
1366 test
, 0, 0, (WCHAR
*)&buf
, 1024, NULL
);
1367 ok(ret
== 4, "Expected FormatMessageA to return 4, got %u\n", ret
);
1368 ok(buf
!= NULL
&& buf
!= (WCHAR
*)0xdeadbeef,
1369 "Expected output buffer pointer to be valid\n");
1370 if (buf
!= NULL
&& buf
!= (WCHAR
*)0xdeadbeef)
1372 ok(!lstrcmpW(test
, buf
),
1373 "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf
));
1378 static void test_message_from_hmodule(void)
1382 CHAR out
[0x100] = {0};
1384 h
= GetModuleHandle("kernel32.dll");
1385 ok(h
!= 0, "GetModuleHandle failed\n");
1387 /*Test existing messageID; as the message strings from wine's kernel32 differ from windows' kernel32 we don't compare
1388 the strings but only test that FormatMessage doesn't return 0*/
1389 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_FROM_HMODULE
, h
, 7/*=ERROR_ARENA_TRASHED*/,
1390 MAKELANGID(LANG_NEUTRAL
, SUBLANG_NEUTRAL
), out
, sizeof(out
)/sizeof(CHAR
), NULL
);
1391 ok(ret
!= 0, "FormatMessageA returned 0\n");
1393 /* Test a message string with an insertion without passing any variadic arguments. */
1394 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_FROM_HMODULE
, h
, 193 /* ERROR_BAD_EXE_FORMAT */,
1395 MAKELANGID(LANG_NEUTRAL
, SUBLANG_NEUTRAL
), out
, sizeof(out
)/sizeof(CHAR
), NULL
);
1397 broken(ret
!= 0), /* Win9x */
1398 "FormatMessageA returned non-zero\n");
1400 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_FROM_HMODULE
|
1401 FORMAT_MESSAGE_ARGUMENT_ARRAY
, h
, 193 /* ERROR_BAD_EXE_FORMAT */,
1402 MAKELANGID(LANG_NEUTRAL
, SUBLANG_NEUTRAL
), out
, sizeof(out
)/sizeof(CHAR
), NULL
);
1404 broken(ret
!= 0), /* Win9x */
1405 "FormatMessageA returned non-zero\n");
1407 /*Test nonexistent messageID with varying language ID's Note: FormatMessageW behaves the same*/
1408 SetLastError(0xdeadbeef);
1409 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_FROM_HMODULE
, h
, 3044,
1410 MAKELANGID(LANG_NEUTRAL
, SUBLANG_NEUTRAL
), out
, sizeof(out
)/sizeof(CHAR
), NULL
);
1411 error
= GetLastError();
1412 ok(ret
== 0, "FormatMessageA returned %u instead of 0\n", ret
);
1413 ok(error
== ERROR_MR_MID_NOT_FOUND
|| error
== ERROR_MUI_FILE_NOT_FOUND
, "last error %u\n", error
);
1415 SetLastError(0xdeadbeef);
1416 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_FROM_HMODULE
, h
, 3044,
1417 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
), out
, sizeof(out
)/sizeof(CHAR
), NULL
);
1418 error
= GetLastError();
1419 ok(ret
== 0, "FormatMessageA returned %u instead of 0\n", ret
);
1420 ok(error
== ERROR_MR_MID_NOT_FOUND
|| error
== ERROR_MUI_FILE_NOT_LOADED
, "last error %u\n", error
);
1422 SetLastError(0xdeadbeef);
1423 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_FROM_HMODULE
, h
, 3044,
1424 MAKELANGID(LANG_NEUTRAL
, SUBLANG_SYS_DEFAULT
), out
, sizeof(out
)/sizeof(CHAR
), NULL
);
1425 error
= GetLastError();
1426 ok(ret
== 0, "FormatMessageA returned %u instead of 0\n", ret
);
1427 ok(error
== ERROR_MR_MID_NOT_FOUND
|| error
== ERROR_MUI_FILE_NOT_LOADED
, "last error %u\n", error
);
1429 SetLastError(0xdeadbeef);
1430 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_FROM_HMODULE
, h
, 3044,
1431 MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), out
, sizeof(out
)/sizeof(CHAR
), NULL
);
1432 error
= GetLastError();
1433 ok(ret
== 0, "FormatMessageA returned %u instead of 0\n", ret
);
1434 ok(error
== ERROR_RESOURCE_LANG_NOT_FOUND
||
1435 error
== ERROR_MR_MID_NOT_FOUND
||
1436 error
== ERROR_MUI_FILE_NOT_FOUND
||
1437 error
== ERROR_MUI_FILE_NOT_LOADED
,
1438 "last error %u\n", error
);
1440 SetLastError(0xdeadbeef);
1441 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_FROM_HMODULE
, h
, 3044,
1442 MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_UK
), out
, sizeof(out
)/sizeof(CHAR
), NULL
);
1443 error
= GetLastError();
1444 ok(ret
== 0, "FormatMessageA returned %u instead of 0\n", ret
);
1445 ok(error
== ERROR_RESOURCE_LANG_NOT_FOUND
||
1446 error
== ERROR_MR_MID_NOT_FOUND
||
1447 error
== ERROR_MUI_FILE_NOT_FOUND
||
1448 error
== ERROR_MUI_FILE_NOT_LOADED
,
1449 "last error %u\n", error
);
1452 static void test_message_invalid_flags(void)
1454 static const char init_buf
[] = {'x', 'x', 'x', 'x', 'x'};
1460 SetLastError(0xdeadbeef);
1461 memcpy(out
, init_buf
, sizeof(init_buf
));
1462 ret
= FormatMessageA(0, "test", 0, 0, out
, sizeof(out
)/sizeof(CHAR
), NULL
);
1463 ok(ret
== 0, "Expected FormatMessageA to return 0, got %u\n", ret
);
1464 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)),
1465 "Expected the output buffer to be untouched\n");
1466 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1467 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1470 SetLastError(0xdeadbeef);
1471 ptr
= (char *)0xdeadbeef;
1472 ret
= FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER
, "test", 0, 0, (char *)&ptr
, 0, NULL
);
1473 ok(ret
== 0, "Expected FormatMessageA to return 0, got %u\n", ret
);
1475 broken(ptr
== (char *)0xdeadbeef), /* Win9x */
1476 "Expected output pointer to be initialized to NULL, got %p\n", ptr
);
1477 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1478 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1481 SetLastError(0xdeadbeef);
1482 memcpy(out
, init_buf
, sizeof(init_buf
));
1483 ret
= FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS
, "test", 0, 0, out
, sizeof(out
)/sizeof(CHAR
), NULL
);
1484 ok(ret
== 0, "Expected FormatMessageA to return 0, got %u\n", ret
);
1485 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)),
1486 "Expected the output buffer to be untouched\n");
1487 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1488 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1491 SetLastError(0xdeadbeef);
1492 memcpy(out
, init_buf
, sizeof(init_buf
));
1493 ret
= FormatMessageA(FORMAT_MESSAGE_ARGUMENT_ARRAY
, "test", 0, 0, out
, sizeof(out
)/sizeof(CHAR
), NULL
);
1494 ok(ret
== 0, "Expected FormatMessageA to return 0, got %u\n", ret
);
1495 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)),
1496 "Expected the output buffer to be untouched\n");
1497 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1498 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1501 SetLastError(0xdeadbeef);
1502 memcpy(out
, init_buf
, sizeof(init_buf
));
1503 ret
= FormatMessageA(FORMAT_MESSAGE_MAX_WIDTH_MASK
, "test", 0, 0, out
, sizeof(out
)/sizeof(CHAR
), NULL
);
1504 ok(ret
== 0, "Expected FormatMessageA to return 0, got %u\n", ret
);
1505 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)),
1506 "Expected the output buffer to be untouched\n");
1507 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1508 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1511 /* Simultaneously setting FORMAT_MESSAGE_FROM_STRING with other source
1512 * flags is apparently permissible, and FORMAT_MESSAGE_FROM_STRING takes
1513 * precedence in this case. */
1515 memcpy(out
, init_buf
, sizeof(init_buf
));
1516 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_FROM_SYSTEM
,
1517 "test", 0, 0, out
, sizeof(out
)/sizeof(CHAR
), NULL
);
1518 ok(ret
== 4, "Expected FormatMessageA to return 4, got %u\n", ret
);
1519 ok(!strcmp("test", out
),
1520 "Expected the output buffer to be untouched\n");
1522 memcpy(out
, init_buf
, sizeof(init_buf
));
1523 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_FROM_HMODULE
,
1524 "test", 0, 0, out
, sizeof(out
)/sizeof(CHAR
), NULL
);
1525 ok(ret
== 4, "Expected FormatMessageA to return 4, got %u\n", ret
);
1526 ok(!strcmp("test", out
),
1527 "Expected the output buffer to be untouched\n");
1529 memcpy(out
, init_buf
, sizeof(init_buf
));
1530 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_FROM_HMODULE
|
1531 FORMAT_MESSAGE_FROM_SYSTEM
, "test", 0, 0, out
,
1532 sizeof(out
)/sizeof(CHAR
), NULL
);
1533 ok(ret
== 4, "Expected FormatMessageA to return 4, got %u\n", ret
);
1534 ok(!strcmp("test", out
),
1535 "Expected the output buffer to be untouched\n");
1538 static void test_message_invalid_flags_wide(void)
1540 static const WCHAR init_buf
[] = {'x', 'x', 'x', 'x', 'x'};
1541 static const WCHAR test
[] = {'t','e','s','t',0};
1547 SetLastError(0xdeadbeef);
1548 memcpy(out
, init_buf
, sizeof(init_buf
));
1549 ret
= FormatMessageW(0, test
, 0, 0, out
, sizeof(out
)/sizeof(WCHAR
), NULL
);
1550 ok(ret
== 0, "Expected FormatMessageW to return 0, got %u\n", ret
);
1551 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)),
1552 "Expected the output buffer to be untouched\n");
1553 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1554 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1557 SetLastError(0xdeadbeef);
1558 ptr
= (WCHAR
*)0xdeadbeef;
1559 ret
= FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER
, test
, 0, 0, (WCHAR
*)&ptr
, 0, NULL
);
1560 ok(ret
== 0, "Expected FormatMessageW to return 0, got %u\n", ret
);
1561 ok(ptr
== NULL
, "Expected output pointer to be initialized to NULL, got %p\n", ptr
);
1562 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1563 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1566 SetLastError(0xdeadbeef);
1567 memcpy(out
, init_buf
, sizeof(init_buf
));
1568 ret
= FormatMessageW(FORMAT_MESSAGE_IGNORE_INSERTS
, test
, 0, 0, out
, sizeof(out
)/sizeof(WCHAR
), NULL
);
1569 ok(ret
== 0, "Expected FormatMessageW to return 0, got %u\n", ret
);
1570 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)),
1571 "Expected the output buffer to be untouched\n");
1572 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1573 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1576 SetLastError(0xdeadbeef);
1577 memcpy(out
, init_buf
, sizeof(init_buf
));
1578 ret
= FormatMessageW(FORMAT_MESSAGE_ARGUMENT_ARRAY
, test
, 0, 0, out
, sizeof(out
)/sizeof(WCHAR
), NULL
);
1579 ok(ret
== 0, "Expected FormatMessageW to return 0, got %u\n", ret
);
1580 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)),
1581 "Expected the output buffer to be untouched\n");
1582 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1583 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1586 SetLastError(0xdeadbeef);
1587 memcpy(out
, init_buf
, sizeof(init_buf
));
1588 ret
= FormatMessageW(FORMAT_MESSAGE_MAX_WIDTH_MASK
, test
, 0, 0, out
, sizeof(out
)/sizeof(WCHAR
), NULL
);
1589 ok(ret
== 0, "Expected FormatMessageW to return 0, got %u\n", ret
);
1590 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)),
1591 "Expected the output buffer to be untouched\n");
1592 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1593 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1596 /* Simultaneously setting FORMAT_MESSAGE_FROM_STRING with other source
1597 * flags is apparently permissible, and FORMAT_MESSAGE_FROM_STRING takes
1598 * precedence in this case. */
1600 memcpy(out
, init_buf
, sizeof(init_buf
));
1601 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_FROM_SYSTEM
,
1602 test
, 0, 0, out
, sizeof(out
)/sizeof(WCHAR
), NULL
);
1603 ok(ret
== 4, "Expected FormatMessageW to return 4, got %u\n", ret
);
1604 ok(!lstrcmpW(test
, out
),
1605 "Expected the output buffer to be untouched\n");
1607 memcpy(out
, init_buf
, sizeof(init_buf
));
1608 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_FROM_HMODULE
,
1609 test
, 0, 0, out
, sizeof(out
)/sizeof(WCHAR
), NULL
);
1610 ok(ret
== 4, "Expected FormatMessageW to return 4, got %u\n", ret
);
1611 ok(!lstrcmpW(test
, out
),
1612 "Expected the output buffer to be untouched\n");
1614 memcpy(out
, init_buf
, sizeof(init_buf
));
1615 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_FROM_HMODULE
|
1616 FORMAT_MESSAGE_FROM_SYSTEM
, test
, 0, 0, out
,
1617 sizeof(out
)/sizeof(WCHAR
), NULL
);
1618 ok(ret
== 4, "Expected FormatMessageW to return 4, got %u\n", ret
);
1619 ok(!lstrcmpW(test
, out
),
1620 "Expected the output buffer to be untouched\n");
1623 START_TEST(format_msg
)
1627 test_message_from_string();
1628 test_message_ignore_inserts();
1629 test_message_insufficient_buffer();
1630 test_message_null_buffer();
1631 test_message_allocate_buffer();
1632 test_message_from_hmodule();
1633 test_message_invalid_flags();
1635 SetLastError(0xdeadbeef);
1636 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
, NULL
, 0, 0, NULL
, 0, NULL
);
1637 if (!ret
&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
1639 win_skip("FormatMessageW is not implemented\n");
1643 test_message_from_string_wide();
1644 test_message_ignore_inserts_wide();
1645 test_message_insufficient_buffer_wide();
1646 test_message_null_buffer_wide();
1647 test_message_allocate_buffer_wide();
1648 test_message_invalid_flags_wide();