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 #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
, ... )
35 __ms_va_start(list
, outsize
);
36 r
= FormatMessageA(flags
, src
, msg_id
,
37 lang_id
, out
, outsize
, &list
);
42 static DWORD WINAPIV
doitW(DWORD flags
, LPCVOID src
, DWORD msg_id
, DWORD lang_id
,
43 LPWSTR out
, DWORD outsize
, ... )
48 __ms_va_start(list
, outsize
);
49 r
= FormatMessageW(flags
, src
, msg_id
,
50 lang_id
, out
, outsize
, &list
);
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};
139 r
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
, test
, 0,
140 0, out
, sizeof(out
)/sizeof(WCHAR
), NULL
);
141 ok(!lstrcmpW(test
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
142 ok(r
==4, "failed: r=%d\n", r
);
144 /* null string, crashes on Windows */
147 SetLastError(0xdeadbeef);
148 memcpy(out
, init_buf
, sizeof(init_buf
));
149 FormatMessageW(FORMAT_MESSAGE_FROM_STRING
, NULL
, 0,
150 0, out
, sizeof(out
)/sizeof(WCHAR
), NULL
);
154 SetLastError(0xdeadbeef);
155 memcpy(out
, init_buf
, sizeof(init_buf
));
156 r
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
, empty
, 0,
157 0, out
, sizeof(out
)/sizeof(WCHAR
), NULL
);
158 error
= GetLastError();
159 ok(!lstrcmpW(empty
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
160 ok(r
==0, "succeeded: r=%d\n", r
);
161 ok(error
==0xdeadbeef, "last error %u\n", error
);
163 /* format placeholder with no specifier */
164 SetLastError(0xdeadbeef);
165 memcpy(out
, init_buf
, sizeof(init_buf
));
166 r
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
, fmt_null
, 0,
167 0, out
, sizeof(out
)/sizeof(WCHAR
), NULL
);
168 error
= GetLastError();
169 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)),
170 "Expected the buffer to be unchanged\n");
171 ok(r
==0, "succeeded: r=%d\n", r
);
172 ok(error
==ERROR_INVALID_PARAMETER
, "last error %u\n", error
);
174 /* test string with format placeholder with no specifier */
175 SetLastError(0xdeadbeef);
176 memcpy(out
, init_buf
, sizeof(init_buf
));
177 r
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
, fmt_tnull
, 0,
178 0, out
, sizeof(out
)/sizeof(WCHAR
), NULL
);
179 error
= GetLastError();
180 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)) ||
181 broken(!memcmp(out
, broken_buf
, sizeof(broken_buf
))), /* W2K3+ */
182 "Expected the buffer to be unchanged\n");
183 ok(r
==0, "succeeded: r=%d\n", r
);
184 ok(error
==ERROR_INVALID_PARAMETER
, "last error %u\n", error
);
186 /* insertion with no variadic arguments */
187 SetLastError(0xdeadbeef);
188 memcpy(out
, init_buf
, sizeof(init_buf
));
189 r
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
, fmt_1
, 0,
190 0, out
, sizeof(out
)/sizeof(WCHAR
), NULL
);
191 error
= GetLastError();
192 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)),
193 "Expected the buffer to be unchanged\n");
194 ok(r
==0, "succeeded: r=%d\n", r
);
195 ok(error
==ERROR_INVALID_PARAMETER
, "last error %u\n", error
);
197 SetLastError(0xdeadbeef);
198 memcpy(out
, init_buf
, sizeof(init_buf
));
199 r
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ARGUMENT_ARRAY
, fmt_1
, 0,
200 0, out
, sizeof(out
)/sizeof(WCHAR
), NULL
);
201 error
= GetLastError();
202 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)),
203 "Expected the buffer to be unchanged\n");
204 ok(r
==0, "succeeded: r=%d\n", r
);
205 ok(error
==ERROR_INVALID_PARAMETER
, "last error %u\n", error
);
207 /* using the format feature */
208 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_1s
, 0,
209 0, out
, sizeof(out
)/sizeof(WCHAR
), test
);
210 ok(!lstrcmpW(test
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
211 ok(r
==4,"failed: r=%d\n", r
);
214 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_1
, 0,
215 0, out
, sizeof(out
)/sizeof(WCHAR
), test
);
216 ok(!lstrcmpW(test
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
217 ok(r
==4,"failed: r=%d\n", r
);
220 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_12
, 0,
221 0, out
, sizeof(out
)/sizeof(WCHAR
), te
, st
);
222 ok(!lstrcmpW(test
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
223 ok(r
==4,"failed: r=%d\n", r
);
226 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_123
, 0,
227 0, out
, sizeof(out
)/sizeof(WCHAR
), t
, s
, e
);
228 ok(!lstrcmpW(test
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
229 ok(r
==4,"failed: r=%d\n", r
);
231 /* s doesn't seem to work in format strings */
232 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_s
, 0,
233 0, out
, sizeof(out
)/sizeof(WCHAR
), test
);
234 ok(!lstrcmpW(&fmt_s
[1], out
), "failed out=%s\n", wine_dbgstr_w(out
));
235 ok(r
==3, "failed: r=%d\n", r
);
238 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_ls
, 0,
239 0, out
, sizeof(out
)/sizeof(WCHAR
), test
);
240 ok(!lstrcmpW(&fmt_ls
[1], out
), "failed out=%s\n", wine_dbgstr_w(out
));
241 ok(r
==4, "failed: r=%d\n", r
);
244 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_S
, 0,
245 0, out
, sizeof(out
)/sizeof(WCHAR
), test
);
246 ok(!lstrcmpW(&fmt_S
[1], out
), "failed out=%s\n", wine_dbgstr_w(out
));
247 ok(r
==3, "failed: r=%d\n", r
);
250 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_ws
, 0,
251 0, out
, sizeof(out
)/sizeof(WCHAR
), test
);
252 ok(!lstrcmpW(&fmt_ws
[1], out
), "failed out=%s\n", wine_dbgstr_w(out
));
253 ok(r
==4, "failed: r=%d\n", r
);
256 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_123c
, 0,
257 0, out
, sizeof(out
)/sizeof(WCHAR
), 't', 'e', 's');
258 ok(!lstrcmpW(test
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
259 ok(r
==4,"failed: r=%d\n", r
);
262 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_123lc
, 0,
263 0, out
, sizeof(out
)/sizeof(WCHAR
), 't', 'e', 's');
264 ok(!lstrcmpW(test
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
265 ok(r
==4,"failed: r=%d\n", r
);
268 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_123wc
, 0,
269 0, out
, sizeof(out
)/sizeof(WCHAR
), 't', 'e', 's');
270 ok(!lstrcmpW(test
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
271 ok(r
==4,"failed: r=%d\n", r
);
274 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_123C
, 0,
275 0, out
, sizeof(out
)/sizeof(WCHAR
), 't', 'e', 's');
276 ok(!lstrcmpW(test
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
277 ok(r
==4,"failed: r=%d\n", r
);
280 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_123d
, 0,
281 0, out
, sizeof(out
)/sizeof(WCHAR
), 1, 2, 3);
282 ok(!lstrcmpW(s_123d
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
283 ok(r
==3,"failed: r=%d\n", r
);
285 /* a single digit with some spacing */
286 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_14d
, 0,
287 0, out
, sizeof(out
)/sizeof(WCHAR
), 1);
288 ok(!lstrcmpW(s_14d
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
289 ok(r
==4,"failed: r=%d\n", r
);
291 /* a single digit, left justified */
292 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_1_4d
, 0,
293 0, out
, sizeof(out
)/sizeof(CHAR
), 1);
294 ok(!lstrcmpW(s_1_4d
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
295 ok(r
==4,"failed: r=%d\n", r
);
297 /* two digit decimal number */
298 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_14d
, 0,
299 0, out
, sizeof(out
)/sizeof(WCHAR
), 11);
300 ok(!lstrcmpW(s_14d2
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
301 ok(r
==4,"failed: r=%d\n", r
);
304 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_14x
, 0,
305 0, out
, sizeof(out
)/sizeof(WCHAR
), 11);
306 ok(!lstrcmpW(s_14x
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
307 ok(r
==4,"failed: r=%d\n", r
);
309 /* a hex number, upper case */
310 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_14X
, 0,
311 0, out
, sizeof(out
)/sizeof(WCHAR
), 11);
312 ok(!lstrcmpW(s_14X
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
313 ok(r
==4,"failed: r=%d\n", r
);
315 /* a hex number, upper case, left justified */
316 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_1_4X
, 0,
317 0, out
, sizeof(out
)/sizeof(WCHAR
), 11);
318 ok(!lstrcmpW(s_1_4X
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
319 ok(r
==4,"failed: r=%d\n", r
);
321 /* a long hex number, upper case */
322 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_14X
, 0,
323 0, out
, sizeof(out
)/sizeof(WCHAR
), 0x1ab);
324 ok(!lstrcmpW(s_1AB
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
325 ok(r
==4,"failed: r=%d\n", r
);
328 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_2pct
, 0,
329 0, out
, sizeof(out
)/sizeof(WCHAR
));
330 ok(!lstrcmpW(s_2pct
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
331 ok(r
==4,"failed: r=%d\n", r
);
333 /* periods are special cases */
334 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_2dot1d
, 0,
335 0, out
, sizeof(out
)/sizeof(WCHAR
), 0x1ab);
336 ok(!lstrcmpW(s_2dot147
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
337 ok(r
==8,"failed: r=%d\n", r
);
339 /* %0 ends the line */
340 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_t0t
, 0,
341 0, out
, sizeof(out
)/sizeof(WCHAR
));
342 ok(!lstrcmpW(test
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
343 ok(r
==4,"failed: r=%d\n", r
);
345 /* %! prints an exclamation */
346 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_yah
, 0,
347 0, out
, sizeof(out
)/sizeof(WCHAR
));
348 ok(!lstrcmpW(s_yah
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
349 ok(r
==4,"failed: r=%d\n", r
);
352 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_space
, 0,
353 0, out
, sizeof(out
)/sizeof(WCHAR
));
354 ok(!lstrcmpW(s_space
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
355 ok(r
==4,"failed: r=%d\n", r
);
357 /* %n yields \r\n, %r yields \r, %t yields \t */
358 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_nrt
, 0,
359 0, out
, sizeof(out
)/sizeof(WCHAR
));
360 ok(!lstrcmpW(s_nrt
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
361 ok(r
==4,"failed: r=%d\n", r
);
364 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_hi_lf
, 0,
365 0, out
, sizeof(out
)/sizeof(WCHAR
));
366 ok(!lstrcmpW(s_hi_crlf
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
367 ok(r
==4,"failed: r=%d\n", r
);
369 /* carriage return line feed */
370 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_hi_crlf
, 0,
371 0, out
, sizeof(out
)/sizeof(WCHAR
));
372 ok(!lstrcmpW(s_hi_crlf
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
373 ok(r
==4,"failed: r=%d\n", r
);
375 /* carriage return */
376 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_cr
, 0,
377 0, out
, sizeof(out
)/sizeof(WCHAR
));
378 ok(!lstrcmpW(s_crlf
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
379 ok(r
==2,"failed: r=%d\n", r
);
381 /* double carriage return line feed */
382 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_crcrlf
, 0,
383 0, out
, sizeof(out
)/sizeof(WCHAR
));
384 ok(!lstrcmpW(s_crlfcrlf
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
385 ok(r
==4,"failed: r=%d\n", r
);
387 /* null string as argument */
388 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_1
, 0,
389 0, out
, sizeof(out
)/sizeof(WCHAR
), NULL
);
390 ok(!lstrcmpW(s_null
, out
),"failed out=[%s]\n", wine_dbgstr_w(out
));
391 ok(r
==6,"failed: r=%d\n",r
);
393 /* precision and width */
395 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_13s
,
396 0, 0, out
, sizeof(out
)/sizeof(WCHAR
), t
);
397 ok(!lstrcmpW(s_spt
, out
),"failed out=[%s]\n", wine_dbgstr_w(out
));
398 ok(r
==3, "failed: r=%d\n",r
);
399 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_1os
,
400 0, 0, out
, sizeof(out
)/sizeof(WCHAR
), 4, t
);
401 ok(!lstrcmpW( s_sp3t
, out
),"failed out=[%s]\n", wine_dbgstr_w(out
));
402 ok(r
==4,"failed: r=%d\n",r
);
403 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_142u
,
404 0, 0, out
, sizeof(out
)/sizeof(WCHAR
), 3 );
405 ok(!lstrcmpW( s_sp03
, out
),"failed out=[%s]\n", wine_dbgstr_w(out
));
406 ok(r
==4,"failed: r=%d\n",r
);
407 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_1oou
,
408 0, 0, out
, sizeof(out
)/sizeof(WCHAR
), 5, 3, 1 );
409 ok(!lstrcmpW( s_sp001
, out
),"failed out=[%s]\n", wine_dbgstr_w(out
));
410 ok(r
==5,"failed: r=%d\n",r
);
411 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_1oou1oou
,
412 0, 0, out
, sizeof(out
)/sizeof(WCHAR
), 5, 3, 1, 4, 2 );
413 ok(!lstrcmpW( s_sp001002
, out
),"failed out=[%s]\n", wine_dbgstr_w(out
));
414 ok(r
==11,"failed: r=%d\n",r
);
415 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, fmt_1oou3oou
,
416 0, 0, out
, sizeof(out
)/sizeof(WCHAR
), 5, 3, 1, 6, 4, 2 );
417 ok(!lstrcmpW( s_sp001sp002
, out
) ||
418 broken(!lstrcmpW(s_sp001004
, out
)), /* NT4/Win2k */
419 "failed out=[%s]\n", wine_dbgstr_w(out
));
420 ok(r
==12,"failed: r=%d\n",r
);
421 /* args are not counted the same way with an argument array */
423 ULONG_PTR args
[] = { 6, 4, 2, 5, 3, 1 };
424 r
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ARGUMENT_ARRAY
, fmt_1oou1oou
,
425 0, 0, out
, sizeof(out
)/sizeof(WCHAR
), (__ms_va_list
*)args
);
426 ok(!lstrcmpW(s_sp002sp003
, out
),"failed out=[%s]\n", wine_dbgstr_w(out
));
427 ok(r
==13,"failed: r=%d\n",r
);
428 r
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ARGUMENT_ARRAY
, fmt_1oou4oou
,
429 0, 0, out
, sizeof(out
)/sizeof(WCHAR
), (__ms_va_list
*)args
);
430 ok(!lstrcmpW(s_sp002sp001
, out
),"failed out=[%s]\n", wine_dbgstr_w(out
));
431 ok(r
==12,"failed: r=%d\n",r
);
434 /* change of pace... test the low byte of dwflags */
437 r
= doitW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_MAX_WIDTH_MASK
, fmt_hi_lf
, 0,
438 0, out
, sizeof(out
)/sizeof(WCHAR
));
439 ok(!lstrcmpW(s_hi_sp
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
440 ok(r
==3,"failed: r=%d\n", r
);
442 /* carriage return line feed */
443 r
= doitW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_MAX_WIDTH_MASK
, fmt_hi_crlf
, 0,
444 0, out
, sizeof(out
)/sizeof(WCHAR
));
445 ok(!lstrcmpW(s_hi_sp
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
446 ok(r
==3,"failed: r=%d\n", r
);
448 /* carriage return */
449 r
= doitW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_MAX_WIDTH_MASK
, fmt_cr
, 0,
450 0, out
, sizeof(out
)/sizeof(WCHAR
));
451 ok(!lstrcmpW(s_sp
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
452 ok(r
==1,"failed: r=%d\n", r
);
454 /* double carriage return line feed */
455 r
= doitW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_MAX_WIDTH_MASK
, fmt_crcrlf
, 0,
456 0, out
, sizeof(out
)/sizeof(WCHAR
));
457 ok(!lstrcmpW(s_2sp
, out
), "failed out=%s\n", wine_dbgstr_w(out
));
458 ok(r
==2,"failed: r=%d\n", r
);
461 static void test_message_from_string(void)
463 CHAR out
[0x100] = {0};
465 static const char init_buf
[] = {'x', 'x', 'x', 'x', 'x', 'x'};
466 static const WCHAR szwTest
[] = { 't','e','s','t',0};
469 r
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
, "test", 0,
470 0, out
, sizeof(out
)/sizeof(CHAR
),NULL
);
471 ok(!strcmp("test", out
),"failed out=[%s]\n",out
);
472 ok(r
==4,"failed: r=%d\n",r
);
474 /* null string, crashes on Windows */
477 SetLastError(0xdeadbeef);
478 memcpy(out
, init_buf
, sizeof(init_buf
));
479 FormatMessageA(FORMAT_MESSAGE_FROM_STRING
, NULL
, 0,
480 0, out
, sizeof(out
)/sizeof(CHAR
), NULL
);
484 SetLastError(0xdeadbeef);
485 memcpy(out
, init_buf
, sizeof(init_buf
));
486 r
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
, "", 0,
487 0, out
, sizeof(out
)/sizeof(CHAR
), NULL
);
488 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)), "Expected the buffer to be untouched\n");
489 ok(r
==0, "succeeded: r=%d\n", r
);
490 ok(GetLastError()==0xdeadbeef,
491 "last error %u\n", GetLastError());
493 /* format placeholder with no specifier */
494 SetLastError(0xdeadbeef);
495 memcpy(out
, init_buf
, sizeof(init_buf
));
496 r
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
, "%", 0,
497 0, out
, sizeof(out
)/sizeof(CHAR
), NULL
);
498 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)),
499 "Expected the buffer to be untouched\n");
500 ok(r
==0, "succeeded: r=%d\n", r
);
501 ok(GetLastError()==ERROR_INVALID_PARAMETER
,
502 "last error %u\n", GetLastError());
504 /* test string with format placeholder with no specifier */
505 SetLastError(0xdeadbeef);
506 memcpy(out
, init_buf
, sizeof(init_buf
));
507 r
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
, "test%", 0,
508 0, out
, sizeof(out
)/sizeof(CHAR
), NULL
);
509 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)),
510 "Expected the buffer to be untouched\n");
511 ok(r
==0, "succeeded: r=%d\n", r
);
512 ok(GetLastError()==ERROR_INVALID_PARAMETER
,
513 "last error %u\n", GetLastError());
515 /* insertion with no variadic arguments */
516 SetLastError(0xdeadbeef);
517 memcpy(out
, init_buf
, sizeof(init_buf
));
518 r
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
, "%1", 0,
519 0, out
, sizeof(out
)/sizeof(CHAR
), NULL
);
520 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)), "Expected the buffer to be untouched\n");
521 ok(r
==0, "succeeded: r=%d\n", r
);
522 ok(GetLastError()==ERROR_INVALID_PARAMETER
, "last error %u\n", GetLastError());
524 SetLastError(0xdeadbeef);
525 memcpy(out
, init_buf
, sizeof(init_buf
));
526 r
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ARGUMENT_ARRAY
, "%1", 0,
527 0, out
, sizeof(out
)/sizeof(CHAR
), NULL
);
528 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)), "Expected the buffer to be untouched\n");
529 ok(r
==0, "succeeded: r=%d\n", r
);
530 ok(GetLastError()==ERROR_INVALID_PARAMETER
, "last error %u\n", GetLastError());
532 /* using the format feature */
533 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!s!", 0,
534 0, out
, sizeof(out
)/sizeof(CHAR
), "test");
535 ok(!strcmp("test", out
),"failed out=[%s]\n",out
);
536 ok(r
==4,"failed: r=%d\n",r
);
539 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1", 0,
540 0, out
, sizeof(out
)/sizeof(CHAR
), "test");
541 ok(!strcmp("test", out
),"failed out=[%s]\n",out
);
542 ok(r
==4,"failed: r=%d\n",r
);
545 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1%2", 0,
546 0, out
, sizeof(out
)/sizeof(CHAR
), "te","st");
547 ok(!strcmp("test", out
),"failed out=[%s]\n",out
);
548 ok(r
==4,"failed: r=%d\n",r
);
551 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1%3%2%1", 0,
552 0, out
, sizeof(out
)/sizeof(CHAR
), "t","s","e");
553 ok(!strcmp("test", out
),"failed out=[%s]\n",out
);
554 ok(r
==4,"failed: r=%d\n",r
);
556 /* s doesn't seem to work in format strings */
557 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%!s!", 0,
558 0, out
, sizeof(out
)/sizeof(CHAR
), "test");
559 ok(!strcmp("!s!", out
),"failed out=[%s]\n",out
);
560 ok(r
==3,"failed: r=%d\n",r
);
563 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!ls!", 0,
564 0, out
, sizeof(out
)/sizeof(CHAR
), szwTest
);
565 ok(!strcmp("test", out
),"failed out=[%s]\n",out
);
566 ok(r
==4,"failed: r=%d\n",r
);
569 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!S!", 0,
570 0, out
, sizeof(out
)/sizeof(CHAR
), szwTest
);
571 ok(!strcmp("test", out
),"failed out=[%s]\n",out
);
572 ok(r
==4,"failed: r=%d\n",r
);
575 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!ws!", 0,
576 0, out
, sizeof(out
)/sizeof(CHAR
), szwTest
);
577 ok(!strcmp("test", out
),"failed out=[%s]\n",out
);
578 ok(r
==4,"failed: r=%d\n",r
);
581 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!c!%2!c!%3!c!%1!c!", 0,
582 0, out
, sizeof(out
)/sizeof(CHAR
), 't','e','s');
583 ok(!strcmp("test", out
),"failed out=[%s]\n",out
);
584 ok(r
==4,"failed: r=%d\n",r
);
587 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!lc!%2!lc!%3!lc!%1!lc!", 0,
588 0, out
, sizeof(out
)/sizeof(CHAR
), 't','e','s');
589 ok(!strcmp("test", out
),"failed out=[%s]\n",out
);
590 ok(r
==4,"failed: r=%d\n",r
);
593 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!wc!%2!wc!%3!wc!%1!wc!", 0,
594 0, out
, sizeof(out
)/sizeof(CHAR
), 't','e','s');
595 ok(!strcmp("test", out
),"failed out=[%s]\n",out
);
596 ok(r
==4,"failed: r=%d\n",r
);
599 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!C!%2!C!%3!C!%1!C!", 0,
600 0, out
, sizeof(out
)/sizeof(CHAR
), 't','e','s');
601 ok(!strcmp("test", out
),"failed out=[%s]\n",out
);
602 ok(r
==4,"failed: r=%d\n",r
);
605 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!d!%2!d!%3!d!", 0,
606 0, out
, sizeof(out
)/sizeof(CHAR
), 1,2,3);
607 ok(!strcmp("123", out
),"failed out=[%s]\n",out
);
608 ok(r
==3,"failed: r=%d\n",r
);
610 /* a single digit with some spacing */
611 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!4d!", 0,
612 0, out
, sizeof(out
)/sizeof(CHAR
), 1);
613 ok(!strcmp(" 1", out
),"failed out=[%s]\n",out
);
614 ok(r
==4,"failed: r=%d\n",r
);
616 /* a single digit, left justified */
617 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!-4d!", 0,
618 0, out
, sizeof(out
)/sizeof(CHAR
), 1);
619 ok(!strcmp("1 ", out
),"failed out=[%s]\n",out
);
620 ok(r
==4,"failed: r=%d\n",r
);
622 /* two digit decimal number */
623 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!4d!", 0,
624 0, out
, sizeof(out
)/sizeof(CHAR
), 11);
625 ok(!strcmp(" 11", out
),"failed out=[%s]\n",out
);
626 ok(r
==4,"failed: r=%d\n",r
);
629 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!4x!", 0,
630 0, out
, sizeof(out
)/sizeof(CHAR
), 11);
631 ok(!strcmp(" b", out
),"failed out=[%s]\n",out
);
632 ok(r
==4,"failed: r=%d\n",r
);
634 /* a hex number, upper case */
635 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!4X!", 0,
636 0, out
, sizeof(out
)/sizeof(CHAR
), 11);
637 ok(!strcmp(" B", out
),"failed out=[%s]\n",out
);
638 ok(r
==4,"failed: r=%d\n",r
);
640 /* a hex number, upper case, left justified */
641 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!-4X!", 0,
642 0, out
, sizeof(out
)/sizeof(CHAR
), 11);
643 ok(!strcmp("B ", out
),"failed out=[%s]\n",out
);
644 ok(r
==4,"failed: r=%d\n",r
);
646 /* a long hex number, upper case */
647 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!4X!", 0,
648 0, out
, sizeof(out
)/sizeof(CHAR
), 0x1ab);
649 ok(!strcmp(" 1AB", out
),"failed out=[%s]\n",out
);
650 ok(r
==4,"failed: r=%d\n",r
);
653 r
= doit(FORMAT_MESSAGE_FROM_STRING
, " %%%% ", 0,
654 0, out
, sizeof(out
)/sizeof(CHAR
));
655 ok(!strcmp(" %% ", out
),"failed out=[%s]\n",out
);
656 ok(r
==4,"failed: r=%d\n",r
);
658 /* periods are special cases */
659 r
= doit(FORMAT_MESSAGE_FROM_STRING
, " %.%. %1!d!", 0,
660 0, out
, sizeof(out
)/sizeof(CHAR
), 0x1ab);
661 ok(!strcmp(" .. 427", out
),"failed out=[%s]\n",out
);
662 ok(r
==7,"failed: r=%d\n",r
);
664 /* %0 ends the line */
665 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "test%0test", 0,
666 0, out
, sizeof(out
)/sizeof(CHAR
));
667 ok(!strcmp("test", out
),"failed out=[%s]\n",out
);
668 ok(r
==4,"failed: r=%d\n",r
);
670 /* %! prints an exclamation */
671 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "yah%!%0 ", 0,
672 0, out
, sizeof(out
)/sizeof(CHAR
));
673 ok(!strcmp("yah!", out
),"failed out=[%s]\n",out
);
674 ok(r
==4,"failed: r=%d\n",r
);
677 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "% % ", 0,
678 0, out
, sizeof(out
)/sizeof(CHAR
));
679 ok(!strcmp(" ", out
),"failed out=[%s]\n",out
);
680 ok(r
==4,"failed: r=%d\n",r
);
682 /* %n yields \r\n, %r yields \r, %t yields \t */
683 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%n%r%t", 0,
684 0, out
, sizeof(out
)/sizeof(CHAR
));
685 ok(!strcmp("\r\n\r\t", out
),"failed out=[%s]\n",out
);
686 ok(r
==4,"failed: r=%d\n",r
);
689 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "hi\n", 0,
690 0, out
, sizeof(out
)/sizeof(CHAR
));
691 ok(!strcmp("hi\r\n", out
),"failed out=[%s]\n",out
);
692 ok(r
==4,"failed: r=%d\n",r
);
694 /* carriage return line feed */
695 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "hi\r\n", 0,
696 0, out
, sizeof(out
)/sizeof(CHAR
));
697 ok(!strcmp("hi\r\n", out
),"failed out=[%s]\n",out
);
698 ok(r
==4,"failed: r=%d\n",r
);
700 /* carriage return */
701 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "\r", 0,
702 0, out
, sizeof(out
)/sizeof(CHAR
));
703 ok(!strcmp("\r\n", out
),"failed out=[%s]\n",out
);
704 ok(r
==2,"failed: r=%d\n",r
);
706 /* double carriage return line feed */
707 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "\r\r\n", 0,
708 0, out
, sizeof(out
)/sizeof(CHAR
));
709 ok(!strcmp("\r\n\r\n", out
),"failed out=[%s]\n",out
);
710 ok(r
==4,"failed: r=%d\n",r
);
712 /* null string as argument */
713 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1", 0,
714 0, out
, sizeof(out
)/sizeof(CHAR
), NULL
);
715 ok(!strcmp("(null)", out
),"failed out=[%s]\n",out
);
716 ok(r
==6,"failed: r=%d\n",r
);
718 /* precision and width */
720 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!3s!",
721 0, 0, out
, sizeof(out
), "t" );
722 ok(!strcmp(" t", out
),"failed out=[%s]\n",out
);
723 ok(r
==3, "failed: r=%d\n",r
);
724 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!*s!",
725 0, 0, out
, sizeof(out
), 4, "t");
726 if (!strcmp("*s",out
)) win_skip( "width/precision not supported\n" );
729 ok(!strcmp( " t", out
),"failed out=[%s]\n",out
);
730 ok(r
==4,"failed: r=%d\n",r
);
731 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!4.2u!",
732 0, 0, out
, sizeof(out
), 3 );
733 ok(!strcmp( " 03", out
),"failed out=[%s]\n",out
);
734 ok(r
==4,"failed: r=%d\n",r
);
735 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!*.*u!",
736 0, 0, out
, sizeof(out
), 5, 3, 1 );
737 ok(!strcmp( " 001", out
),"failed out=[%s]\n",out
);
738 ok(r
==5,"failed: r=%d\n",r
);
739 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!*.*u!,%1!*.*u!",
740 0, 0, out
, sizeof(out
), 5, 3, 1, 4, 2 );
741 ok(!strcmp( " 001, 0002", out
),"failed out=[%s]\n",out
);
742 ok(r
==11,"failed: r=%d\n",r
);
743 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!*.*u!,%3!*.*u!",
744 0, 0, out
, sizeof(out
), 5, 3, 1, 6, 4, 2 );
745 /* older Win versions marked as broken even though this is arguably the correct behavior */
746 /* but the new (brain-damaged) behavior is specified on MSDN */
747 ok(!strcmp( " 001, 0002", out
) ||
748 broken(!strcmp(" 001,000004", out
)), /* NT4/Win2k */
749 "failed out=[%s]\n",out
);
750 ok(r
==12,"failed: r=%d\n",r
);
751 /* args are not counted the same way with an argument array */
753 ULONG_PTR args
[] = { 6, 4, 2, 5, 3, 1 };
754 r
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ARGUMENT_ARRAY
,
755 "%1!*.*u!,%1!*.*u!", 0, 0, out
, sizeof(out
), (__ms_va_list
*)args
);
756 ok(!strcmp(" 0002, 00003", out
),"failed out=[%s]\n",out
);
757 ok(r
==13,"failed: r=%d\n",r
);
758 r
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ARGUMENT_ARRAY
,
759 "%1!*.*u!,%4!*.*u!", 0, 0, out
, sizeof(out
), (__ms_va_list
*)args
);
760 ok(!strcmp(" 0002, 001", out
),"failed out=[%s]\n",out
);
761 ok(r
==12,"failed: r=%d\n",r
);
765 /* change of pace... test the low byte of dwflags */
768 r
= doit(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_MAX_WIDTH_MASK
, "hi\n", 0,
769 0, out
, sizeof(out
)/sizeof(CHAR
));
770 ok(!strcmp("hi ", out
), "failed out=[%s]\n",out
);
771 ok(r
==3, "failed: r=%d\n",r
);
773 /* carriage return line feed */
774 r
= doit(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_MAX_WIDTH_MASK
, "hi\r\n", 0,
775 0, out
, sizeof(out
)/sizeof(CHAR
));
776 ok(!strcmp("hi ", out
),"failed out=[%s]\n",out
);
777 ok(r
==3,"failed: r=%d\n",r
);
779 /* carriage return */
780 r
= doit(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_MAX_WIDTH_MASK
, "\r", 0,
781 0, out
, sizeof(out
)/sizeof(CHAR
));
782 ok(!strcmp(" ", out
),"failed out=[%s]\n",out
);
783 ok(r
==1,"failed: r=%d\n",r
);
785 /* double carriage return line feed */
786 r
= doit(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_MAX_WIDTH_MASK
, "\r\r\n", 0,
787 0, out
, sizeof(out
)/sizeof(CHAR
));
788 ok(!strcmp(" ", out
),"failed out=[%s]\n",out
);
789 ok(r
==2,"failed: r=%d\n",r
);
792 static void test_message_ignore_inserts(void)
794 static const char init_buf
[] = {'x', 'x', 'x', 'x', 'x'};
799 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, "test", 0, 0, out
,
800 sizeof(out
)/sizeof(CHAR
), NULL
);
801 ok(ret
== 4, "Expected FormatMessageA to return 4, got %d\n", ret
);
802 ok(!strcmp("test", out
), "Expected output string \"test\", got %s\n", out
);
804 /* The %0 escape sequence is handled. */
805 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, "test%0", 0, 0, out
,
806 sizeof(out
)/sizeof(CHAR
), NULL
);
807 ok(ret
== 4, "Expected FormatMessageA to return 4, got %d\n", ret
);
808 ok(!strcmp("test", out
), "Expected output string \"test\", got %s\n", out
);
810 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, "test%0test", 0, 0, out
,
811 sizeof(out
)/sizeof(CHAR
), NULL
);
812 ok(ret
== 4, "Expected FormatMessageA to return 4, got %d\n", ret
);
813 ok(!strcmp("test", out
), "Expected output string \"test\", got %s\n", out
);
815 /* While FormatMessageA returns 0 in this case, no last error code is set. */
816 SetLastError(0xdeadbeef);
817 memcpy(out
, init_buf
, sizeof(init_buf
));
818 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, "%0test", 0, 0, out
,
819 sizeof(out
)/sizeof(CHAR
), NULL
);
820 ok(ret
== 0, "Expected FormatMessageA to return 0, got %d\n", ret
);
821 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)), "Expected the output buffer to be untouched\n");
822 ok(GetLastError() == 0xdeadbeef, "Expected GetLastError() to return 0xdeadbeef, got %u\n", GetLastError());
824 /* Insert sequences are ignored. */
825 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, "test%1%2!*.*s!%99", 0, 0, out
,
826 sizeof(out
)/sizeof(CHAR
), NULL
);
827 ok(ret
== 17, "Expected FormatMessageA to return 17, got %d\n", ret
);
828 ok(!strcmp("test%1%2!*.*s!%99", out
), "Expected output string \"test%%1%%2!*.*s!%%99\", got %s\n", out
);
830 /* Only the "%n", "%r", and "%t" escape sequences are processed. */
831 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, "%%% %.%!", 0, 0, out
,
832 sizeof(out
)/sizeof(CHAR
), NULL
);
833 ok(ret
== 8, "Expected FormatMessageA to return 8, got %d\n", ret
);
834 ok(!strcmp("%%% %.%!", out
), "Expected output string \"%%%%%% %%.%%!\", got %s\n", out
);
836 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, "%n%r%t", 0, 0, out
,
837 sizeof(out
)/sizeof(CHAR
), NULL
);
838 ok(ret
== 4, "Expected FormatMessageA to return 4, got %d\n", ret
);
839 ok(!strcmp("\r\n\r\t", out
), "Expected output string \"\\r\\n\\r\\t\", got %s\n", out
);
841 /* CRLF characters are processed normally. */
842 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, "hi\n", 0, 0, out
,
843 sizeof(out
)/sizeof(CHAR
), NULL
);
844 ok(ret
== 4, "Expected FormatMessageA to return 4, got %d\n", ret
);
845 ok(!strcmp("hi\r\n", out
), "Expected output string \"hi\\r\\n\", got %s\n", out
);
847 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, "hi\r\n", 0, 0, out
,
848 sizeof(out
)/sizeof(CHAR
), NULL
);
849 ok(ret
== 4, "Expected FormatMessageA to return 4, got %d\n", ret
);
850 ok(!strcmp("hi\r\n", out
), "Expected output string \"hi\\r\\n\", got %s\n", out
);
852 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, "\r", 0, 0, out
,
853 sizeof(out
)/sizeof(CHAR
), NULL
);
854 ok(ret
== 2, "Expected FormatMessageA to return 2, got %d\n", ret
);
855 ok(!strcmp("\r\n", out
), "Expected output string \"\\r\\n\", got %s\n", out
);
857 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, "\r\r\n", 0, 0, out
,
858 sizeof(out
)/sizeof(CHAR
), NULL
);
859 ok(ret
== 4, "Expected FormatMessageA to return 4, got %d\n", ret
);
860 ok(!strcmp("\r\n\r\n", out
), "Expected output string \"\\r\\n\\r\\n\", got %s\n", out
);
862 /* The width parameter is handled the same also. */
863 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
|
864 FORMAT_MESSAGE_MAX_WIDTH_MASK
, "hi\n", 0, 0, out
,
865 sizeof(out
)/sizeof(CHAR
), NULL
);
866 ok(!strcmp("hi ", out
), "Expected output string \"hi \", got %s\n", out
);
867 ok(ret
== 3, "Expected FormatMessageA to return 3, got %d\n", ret
);
869 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
|
870 FORMAT_MESSAGE_MAX_WIDTH_MASK
, "hi\r\n", 0, 0, out
,
871 sizeof(out
)/sizeof(CHAR
), NULL
);
872 ok(ret
== 3, "Expected FormatMessageA to return 3, got %d\n", ret
);
873 ok(!strcmp("hi ", out
), "Expected output string \"hi \", got %s\n", out
);
875 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
|
876 FORMAT_MESSAGE_MAX_WIDTH_MASK
, "\r", 0, 0, out
,
877 sizeof(out
)/sizeof(CHAR
), NULL
);
878 ok(ret
== 1, "Expected FormatMessageA to return 1, got %d\n", ret
);
879 ok(!strcmp(" ", out
), "Expected output string \" \", got %s\n", out
);
881 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
|
882 FORMAT_MESSAGE_MAX_WIDTH_MASK
, "\r\r\n", 0, 0, out
,
883 sizeof(out
)/sizeof(CHAR
), NULL
);
884 ok(ret
== 2, "Expected FormatMessageA to return 2, got %d\n", ret
);
885 ok(!strcmp(" ", out
), "Expected output string \" \", got %s\n", out
);
888 static void test_message_ignore_inserts_wide(void)
890 static const WCHAR test
[] = {'t','e','s','t',0};
891 static const WCHAR empty
[] = {0};
892 static const WCHAR fmt_t0
[] = {'t','e','s','t','%','0',0};
893 static const WCHAR fmt_t0t
[] = {'t','e','s','t','%','0','t','e','s','t',0};
894 static const WCHAR fmt_0t
[] = {'%','0','t','e','s','t',0};
895 static const WCHAR fmt_t12oos99
[] = {'t','e','s','t','%','1','%','2','!','*','.','*','s','!','%','9','9',0};
896 static const WCHAR fmt_pctspacedot
[] = {'%','%','%',' ','%','.','%','!',0};
897 static const WCHAR fmt_nrt
[] = {'%','n','%','r','%','t',0};
898 static const WCHAR fmt_hi_lf
[] = {'h','i','\n',0};
899 static const WCHAR fmt_hi_crlf
[] = {'h','i','\r','\n',0};
900 static const WCHAR fmt_cr
[] = {'\r',0};
901 static const WCHAR fmt_crcrlf
[] = {'\r','\r','\n',0};
903 static const WCHAR s_nrt
[] = {'\r','\n','\r','\t',0};
904 static const WCHAR s_hi_crlf
[] = {'h','i','\r','\n',0};
905 static const WCHAR s_crlf
[] = {'\r','\n',0};
906 static const WCHAR s_crlfcrlf
[] = {'\r','\n','\r','\n',0};
907 static const WCHAR s_hi_sp
[] = {'h','i',' ',0};
908 static const WCHAR s_sp
[] = {' ',0};
909 static const WCHAR s_2sp
[] = {' ',' ',0};
914 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, test
, 0, 0, out
,
915 sizeof(out
)/sizeof(WCHAR
), NULL
);
916 ok(ret
== 4, "Expected FormatMessageW to return 4, got %d\n", ret
);
917 ok(!lstrcmpW(test
, out
), "Expected output string \"test\", got %s\n", wine_dbgstr_w(out
));
919 /* The %0 escape sequence is handled. */
920 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, fmt_t0
, 0, 0, out
,
921 sizeof(out
)/sizeof(WCHAR
), NULL
);
922 ok(ret
== 4, "Expected FormatMessageW to return 4, got %d\n", ret
);
923 ok(!lstrcmpW(test
, out
), "Expected output string \"test\", got %s\n", wine_dbgstr_w(out
));
925 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, fmt_t0t
, 0, 0, out
,
926 sizeof(out
)/sizeof(WCHAR
), NULL
);
927 ok(ret
== 4, "Expected FormatMessageW to return 4, got %d\n", ret
);
928 ok(!lstrcmpW(test
, out
), "Expected output string \"test\", got %s\n", wine_dbgstr_w(out
));
930 /* While FormatMessageA returns 0 in this case, no last error code is set. */
931 SetLastError(0xdeadbeef);
932 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, fmt_0t
, 0, 0, out
,
933 sizeof(out
)/sizeof(WCHAR
), NULL
);
934 ok(ret
== 0, "Expected FormatMessageW to return 0, got %d\n", ret
);
935 ok(!lstrcmpW(empty
, out
), "Expected the output buffer to be the empty string, got %s\n", wine_dbgstr_w(out
));
936 ok(GetLastError() == 0xdeadbeef, "Expected GetLastError() to return 0xdeadbeef, got %u\n", GetLastError());
938 /* Insert sequences are ignored. */
939 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, fmt_t12oos99
, 0, 0, out
,
940 sizeof(out
)/sizeof(WCHAR
), NULL
);
941 ok(ret
== 17, "Expected FormatMessageW to return 17, got %d\n", ret
);
942 ok(!lstrcmpW(fmt_t12oos99
, out
), "Expected output string \"test%%1%%2!*.*s!%%99\", got %s\n", wine_dbgstr_w(out
));
944 /* Only the "%n", "%r", and "%t" escape sequences are processed. */
945 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, fmt_pctspacedot
, 0, 0, out
,
946 sizeof(out
)/sizeof(WCHAR
), NULL
);
947 ok(ret
== 8, "Expected FormatMessageW to return 8, got %d\n", ret
);
948 ok(!lstrcmpW(fmt_pctspacedot
, out
), "Expected output string \"%%%%%% %%.%%!\", got %s\n", wine_dbgstr_w(out
));
950 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, fmt_nrt
, 0, 0, out
,
951 sizeof(out
)/sizeof(WCHAR
), NULL
);
952 ok(ret
== 4, "Expected FormatMessageW to return 4, got %d\n", ret
);
953 ok(!lstrcmpW(s_nrt
, out
), "Expected output string \"\\r\\n\\r\\t\", got %s\n", wine_dbgstr_w(out
));
955 /* CRLF characters are processed normally. */
956 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, fmt_hi_lf
, 0, 0, out
,
957 sizeof(out
)/sizeof(WCHAR
), NULL
);
958 ok(ret
== 4, "Expected FormatMessageW to return 4, got %d\n", ret
);
959 ok(!lstrcmpW(s_hi_crlf
, out
), "Expected output string \"hi\\r\\n\", got %s\n", wine_dbgstr_w(out
));
961 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, fmt_hi_crlf
, 0, 0, out
,
962 sizeof(out
)/sizeof(WCHAR
), NULL
);
963 ok(ret
== 4, "Expected FormatMessageW to return 4, got %d\n", ret
);
964 ok(!lstrcmpW(s_hi_crlf
, out
), "Expected output string \"hi\\r\\n\", got %s\n", wine_dbgstr_w(out
));
966 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, fmt_cr
, 0, 0, out
,
967 sizeof(out
)/sizeof(WCHAR
), NULL
);
968 ok(ret
== 2, "Expected FormatMessageW to return 2, got %d\n", ret
);
969 ok(!lstrcmpW(s_crlf
, out
), "Expected output string \"\\r\\n\", got %s\n", wine_dbgstr_w(out
));
971 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
, fmt_crcrlf
, 0, 0, out
,
972 sizeof(out
)/sizeof(WCHAR
), NULL
);
973 ok(ret
== 4, "Expected FormatMessageW to return 4, got %d\n", ret
);
974 ok(!lstrcmpW(s_crlfcrlf
, out
), "Expected output string \"\\r\\n\\r\\n\", got %s\n", wine_dbgstr_w(out
));
976 /* The width parameter is handled the same also. */
977 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
|
978 FORMAT_MESSAGE_MAX_WIDTH_MASK
, fmt_hi_lf
, 0, 0, out
,
979 sizeof(out
)/sizeof(WCHAR
), NULL
);
980 ok(ret
== 3, "Expected FormatMessageW to return 3, got %d\n", ret
);
981 ok(!lstrcmpW(s_hi_sp
, out
), "Expected output string \"hi \", got %s\n", wine_dbgstr_w(out
));
983 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
|
984 FORMAT_MESSAGE_MAX_WIDTH_MASK
, fmt_hi_crlf
, 0, 0, out
,
985 sizeof(out
)/sizeof(WCHAR
), NULL
);
986 ok(ret
== 3, "Expected FormatMessageW to return 3, got %d\n", ret
);
987 ok(!lstrcmpW(s_hi_sp
, out
), "Expected output string \"hi \", got %s\n", wine_dbgstr_w(out
));
989 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
|
990 FORMAT_MESSAGE_MAX_WIDTH_MASK
, fmt_cr
, 0, 0, out
,
991 sizeof(out
)/sizeof(WCHAR
), NULL
);
992 ok(ret
== 1, "Expected FormatMessageW to return 1, got %d\n", ret
);
993 ok(!lstrcmpW(s_sp
, out
), "Expected output string \" \", got %s\n", wine_dbgstr_w(out
));
995 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
|
996 FORMAT_MESSAGE_MAX_WIDTH_MASK
, fmt_crcrlf
, 0, 0, out
,
997 sizeof(out
)/sizeof(WCHAR
), NULL
);
998 ok(ret
== 2, "Expected FormatMessageW to return 2, got %d\n", ret
);
999 ok(!lstrcmpW(s_2sp
, out
), "Expected output string \" \", got %s\n", wine_dbgstr_w(out
));
1002 static void test_message_wrap(void)
1006 CHAR in
[300], out
[300], ref
[300];
1008 /* No need for wrapping */
1009 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| 20,
1010 "short long line", 0, 0, out
, sizeof(out
), NULL
);
1011 ok(ret
== 15, "Expected FormatMessageW to return 15, got %d\n", ret
);
1012 ok(!strcmp("short long line", out
),"failed out=[%s]\n",out
);
1014 /* Wrap the last word */
1015 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| 11,
1016 "short long line", 0, 0, out
, sizeof(out
), NULL
);
1017 ok(ret
== 16, "Expected FormatMessageW to return 16, got %d\n", ret
);
1018 ok(!strcmp("short long\r\nline", out
),"failed out=[%s]\n",out
);
1020 /* Wrap the very last word */
1021 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| 20,
1022 "short long long line", 0, 0, out
, sizeof(out
), NULL
);
1023 ok(ret
== 21, "Expected FormatMessageW to return 21, got %d\n", ret
);
1024 ok(!strcmp("short long long\r\nline", out
),"failed out=[%s]\n",out
);
1026 /* Strictly less than 10 characters per line! */
1027 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| 10,
1028 "short long line", 0, 0, out
, sizeof(out
), NULL
);
1029 ok(ret
== 16, "Expected FormatMessageW to return 16, got %d\n", ret
);
1030 ok(!strcmp("short\r\nlong line", out
),"failed out=[%s]\n",out
);
1032 /* Handling of duplicate spaces */
1033 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| 16,
1034 "short long line", 0, 0, out
, sizeof(out
), NULL
);
1035 ok(ret
== 16, "Expected FormatMessageW to return 16, got %d\n", ret
);
1036 ok(!strcmp("short long\r\nline", out
),"failed out=[%s]\n",out
);
1038 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| 16,
1039 "short long wordlongerthanaline", 0, 0, out
, sizeof(out
), NULL
);
1040 ok(ret
== 33, "Expected FormatMessageW to return 33, got %d\n", ret
);
1041 ok(!strcmp("short long\r\nwordlongerthanal\r\nine", out
),"failed out=[%s]\n",out
);
1043 /* Breaking in the middle of spaces */
1044 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| 12,
1045 "short long line", 0, 0, out
, sizeof(out
), NULL
);
1046 ok(ret
== 18, "Expected FormatMessageW to return 18, got %d\n", ret
);
1047 ok(!strcmp("short long\r\n line", out
),"failed out=[%s]\n",out
);
1049 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| 12,
1050 "short long wordlongerthanaline", 0, 0, out
, sizeof(out
), NULL
);
1051 ok(ret
== 35, "Expected FormatMessageW to return 35, got %d\n", ret
);
1052 ok(!strcmp("short long\r\n\r\nwordlongerth\r\nanaline", out
),"failed out=[%s]\n",out
);
1054 /* Handling of start-of-string spaces */
1055 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| 15,
1056 " short line", 0, 0, out
, sizeof(out
), NULL
);
1057 ok(ret
== 13, "Expected FormatMessageW to return 13, got %d\n", ret
);
1058 ok(!strcmp(" short line", out
),"failed out=[%s]\n",out
);
1060 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| 11,
1061 " shortlong line", 0, 0, out
, sizeof(out
), NULL
);
1062 ok(ret
== 17, "Expected FormatMessageW to return 17, got %d\n", ret
);
1063 ok(!strcmp("\r\nshortlong\r\nline", out
),"failed out=[%s]\n",out
);
1065 /* Handling of start-of-line spaces */
1066 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| 11,
1067 "l1%n shortlong line", 0, 0, out
, sizeof(out
), NULL
);
1068 ok(ret
== 21, "Expected FormatMessageW to return 21, got %d\n", ret
);
1069 ok(!strcmp("l1\r\n\r\nshortlong\r\nline", out
),"failed out=[%s]\n",out
);
1071 /* Pure space wrapping */
1072 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| 5,
1073 " ", 0, 0, out
, sizeof(out
), NULL
);
1074 ok(ret
== 7, "Expected FormatMessageW to return 7, got %d\n", ret
);
1075 ok(!strcmp("\r\n\r\n\r\n ", out
),"failed out=[%s]\n",out
);
1077 /* Handling of trailing spaces */
1078 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| 5,
1079 "l1 ", 0, 0, out
, sizeof(out
), NULL
);
1080 ok(ret
== 10, "Expected FormatMessageW to return 10, got %d\n", ret
);
1081 ok(!strcmp("l1\r\n\r\n\r\n ", out
),"failed out=[%s]\n",out
);
1083 /* Word that just fills the line */
1084 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| 8,
1085 "shortlon", 0, 0, out
, sizeof(out
), NULL
);
1086 ok(ret
== 10, "Expected FormatMessageW to return 10, got %d\n", ret
);
1087 ok(!strcmp("shortlon\r\n", out
),"failed out=[%s]\n",out
);
1089 /* Word longer than the line */
1090 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| 8,
1091 "shortlongline", 0, 0, out
, sizeof(out
), NULL
);
1092 ok(ret
== 15, "Expected FormatMessageW to return 15, got %d\n", ret
);
1093 ok(!strcmp("shortlon\r\ngline", out
),"failed out=[%s]\n",out
);
1095 /* Wrap the line multiple times */
1096 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| 7,
1097 "short long line", 0, 0, out
, sizeof(out
), NULL
);
1098 ok(ret
== 17, "Expected FormatMessageW to return 17, got %d\n", ret
);
1099 ok(!strcmp("short\r\nlong\r\nline", out
),"failed out=[%s]\n",out
);
1101 /* '\n's in the source are ignored */
1102 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| 11,
1103 "short\nlong line", 0, 0, out
, sizeof(out
), NULL
);
1104 ok(ret
== 16, "Expected FormatMessageW to return 16, got %d\n", ret
);
1105 ok(!strcmp("short long\r\nline", out
),"failed out=[%s]\n",out
);
1107 /* Wrap even before a '%n' */
1108 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| 8,
1109 "shortlon%n", 0, 0, out
, sizeof(out
), NULL
);
1110 ok(ret
== 12, "Expected FormatMessageW to return 12, got %d\n", ret
);
1111 ok(!strcmp("shortlon\r\n\r\n", out
),"failed out=[%s]\n",out
);
1113 /* '%n's count as starting a new line and combine with line wrapping */
1114 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| 10,
1115 "short%nlong line", 0, 0, out
, sizeof(out
), NULL
);
1116 ok(ret
== 16, "Expected FormatMessageW to return 16, got %d\n", ret
);
1117 ok(!strcmp("short\r\nlong line", out
),"failed out=[%s]\n",out
);
1119 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| 8,
1120 "short%nlong line", 0, 0, out
, sizeof(out
), NULL
);
1121 ok(ret
== 17, "Expected FormatMessageW to return 17, got %d\n", ret
);
1122 ok(!strcmp("short\r\nlong\r\nline", out
),"failed out=[%s]\n",out
);
1124 /* '%r's also count as starting a new line and all */
1125 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| 10,
1126 "short%rlong line", 0, 0, out
, sizeof(out
), NULL
);
1127 ok(ret
== 15, "Expected FormatMessageW to return 15, got %d\n", ret
);
1128 ok(!strcmp("short\rlong line", out
),"failed out=[%s]\n",out
);
1130 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| 8,
1131 "short%rlong line", 0, 0, out
, sizeof(out
), NULL
);
1132 ok(ret
== 16, "Expected FormatMessageW to return 16, got %d\n", ret
);
1133 ok(!strcmp("short\rlong\r\nline", out
),"failed out=[%s]\n",out
);
1135 /* IGNORE_INSERTS does not prevent line wrapping or disable '%n' */
1136 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_IGNORE_INSERTS
| 8,
1137 "short%nlong line%1", 0, 0, out
, sizeof(out
), NULL
);
1138 ok(ret
== 19, "Expected FormatMessageW to return 19, got %d\n", ret
);
1139 ok(!strcmp("short\r\nlong\r\nline%1", out
),"failed out=[%s]\n",out
);
1141 /* MAX_WIDTH_MASK is the same as specifying an infinite line width */
1142 strcpy(in
, "first line%n");
1143 strcpy(ref
, "first line\r\n");
1144 for (i
=0; i
< 26; i
++)
1146 strcat(in
, "123456789 ");
1147 strcat(ref
, "123456789 ");
1149 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_MAX_WIDTH_MASK
,
1150 in
, 0, 0, out
, sizeof(out
), NULL
);
1151 ok(ret
== 272, "Expected FormatMessageW to return 272, got %d\n", ret
);
1152 ok(!strcmp(ref
, out
),"failed out=[%s]\n",out
);
1154 /* Wrapping and non-space characters */
1155 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| 11,
1156 "short long\tline", 0, 0, out
, sizeof(out
), NULL
);
1157 ok(ret
== 16, "Expected FormatMessageW to return 16, got %d\n", ret
);
1158 ok(!strcmp("short\r\nlong\tline", out
),"failed out=[%s]\n",out
);
1160 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| 11,
1161 "short long-line", 0, 0, out
, sizeof(out
), NULL
);
1162 ok(ret
== 16, "Expected FormatMessageW to return 16, got %d\n", ret
);
1163 ok(!strcmp("short\r\nlong-line", out
),"failed out=[%s]\n",out
);
1165 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| 11,
1166 "short long_line", 0, 0, out
, sizeof(out
), NULL
);
1167 ok(ret
== 16, "Expected FormatMessageW to return 16, got %d\n", ret
);
1168 ok(!strcmp("short\r\nlong_line", out
),"failed out=[%s]\n",out
);
1170 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| 11,
1171 "short long.line", 0, 0, out
, sizeof(out
), NULL
);
1172 ok(ret
== 16, "Expected FormatMessageW to return 16, got %d\n", ret
);
1173 ok(!strcmp("short\r\nlong.line", out
),"failed out=[%s]\n",out
);
1175 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| 11,
1176 "short long,line", 0, 0, out
, sizeof(out
), NULL
);
1177 ok(ret
== 16, "Expected FormatMessageW to return 16, got %d\n", ret
);
1178 ok(!strcmp("short\r\nlong,line", out
),"failed out=[%s]\n",out
);
1180 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| 11,
1181 "short long!line", 0, 0, out
, sizeof(out
), NULL
);
1182 ok(ret
== 16, "Expected FormatMessageW to return 16, got %d\n", ret
);
1183 ok(!strcmp("short\r\nlong!line", out
),"failed out=[%s]\n",out
);
1185 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| 11,
1186 "short long?line", 0, 0, out
, sizeof(out
), NULL
);
1187 ok(ret
== 16, "Expected FormatMessageW to return 16, got %d\n", ret
);
1188 ok(!strcmp("short\r\nlong?line", out
),"failed out=[%s]\n",out
);
1191 static void test_message_insufficient_buffer(void)
1193 static const char init_buf
[] = {'x', 'x', 'x', 'x', 'x'};
1194 static const char expected_buf
[] = {'x', 'x', 'x', 'x', 'x'};
1198 SetLastError(0xdeadbeef);
1199 memcpy(out
, init_buf
, sizeof(init_buf
));
1200 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
, "test", 0, 0, out
, 0, NULL
);
1201 ok(ret
== 0, "Expected FormatMessageA to return 0, got %u\n", ret
);
1202 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
1203 "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n",
1205 ok(!memcmp(expected_buf
, out
, sizeof(expected_buf
)),
1206 "Expected the buffer to be untouched\n");
1208 SetLastError(0xdeadbeef);
1209 memcpy(out
, init_buf
, sizeof(init_buf
));
1210 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
, "test", 0, 0, out
, 1, NULL
);
1211 ok(ret
== 0, "Expected FormatMessageA to return 0, got %u\n", ret
);
1212 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
1213 "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n",
1215 ok(!memcmp(expected_buf
, out
, sizeof(expected_buf
)),
1216 "Expected the buffer to be untouched\n");
1218 SetLastError(0xdeadbeef);
1219 memcpy(out
, init_buf
, sizeof(init_buf
));
1220 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
, "test", 0, 0, out
, sizeof(out
)/sizeof(out
[0]) - 1, NULL
);
1221 ok(ret
== 0, "Expected FormatMessageA to return 0, got %u\n", ret
);
1222 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
1223 "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n",
1225 ok(!memcmp(expected_buf
, out
, sizeof(expected_buf
)),
1226 "Expected the buffer to be untouched\n");
1229 static void test_message_insufficient_buffer_wide(void)
1231 static const WCHAR test
[] = {'t','e','s','t',0};
1232 static const WCHAR init_buf
[] = {'x', 'x', 'x', 'x', 'x'};
1233 static const WCHAR expected_buf
[] = {'x', 'x', 'x', 'x', 'x'};
1234 static const WCHAR broken_buf
[] = {0, 'x', 'x', 'x', 'x'};
1235 static const WCHAR broken2_buf
[] = {'t','e','s',0,'x'};
1240 SetLastError(0xdeadbeef);
1241 memcpy(out
, init_buf
, sizeof(init_buf
));
1242 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
, test
, 0, 0, out
, 0, NULL
);
1243 ok(ret
== 0, "Expected FormatMessageA to return 0, got %u\n", ret
);
1244 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
1245 "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n",
1247 ok(!memcmp(expected_buf
, out
, sizeof(expected_buf
)),
1248 "Expected the buffer to be untouched\n");
1250 /* Windows Server 2003 and newer report failure but copy a
1251 * truncated string to the buffer for non-zero buffer sizes. */
1252 SetLastError(0xdeadbeef);
1253 memcpy(out
, init_buf
, sizeof(init_buf
));
1254 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
, test
, 0, 0, out
, 1, NULL
);
1255 ok(ret
== 0, "Expected FormatMessageA to return 0, got %u\n", ret
);
1256 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
1257 "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n",
1259 ok(!memcmp(expected_buf
, out
, sizeof(expected_buf
)) ||
1260 broken(!memcmp(broken_buf
, out
, sizeof(broken_buf
))), /* W2K3+ */
1261 "Expected the buffer to be untouched\n");
1263 SetLastError(0xdeadbeef);
1264 memcpy(out
, init_buf
, sizeof(init_buf
));
1265 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
, test
, 0, 0, out
, sizeof(out
)/sizeof(out
[0]) - 1, NULL
);
1266 ok(ret
== 0, "Expected FormatMessageA to return 0, got %u\n", ret
);
1267 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
1268 "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n",
1270 ok(!memcmp(expected_buf
, out
, sizeof(expected_buf
)) ||
1271 broken(!memcmp(broken2_buf
, out
, sizeof(broken2_buf
))), /* W2K3+ */
1272 "Expected the buffer to be untouched\n");
1275 static void test_message_null_buffer(void)
1279 /* Without FORMAT_MESSAGE_ALLOCATE_BUFFER, only the specified buffer size is checked. */
1280 SetLastError(0xdeadbeef);
1281 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, 0, 0, NULL
, 0, NULL
);
1282 error
= GetLastError();
1283 ok(!ret
, "FormatMessageA returned %u\n", ret
);
1284 ok(error
== ERROR_INSUFFICIENT_BUFFER
, "last error %u\n", error
);
1286 SetLastError(0xdeadbeef);
1287 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, 0, 0, NULL
, 1, NULL
);
1288 error
= GetLastError();
1289 ok(!ret
, "FormatMessageA returned %u\n", ret
);
1290 ok(error
== ERROR_INSUFFICIENT_BUFFER
, "last error %u\n", error
);
1292 if (0) /* crashes on Windows */
1294 SetLastError(0xdeadbeef);
1295 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, 0, 0, NULL
, 256, NULL
);
1298 SetLastError(0xdeadbeef);
1299 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_ALLOCATE_BUFFER
, NULL
, 0, 0, NULL
, 0, NULL
);
1300 error
= GetLastError();
1301 ok(!ret
, "FormatMessageA returned %u\n", ret
);
1302 ok(error
== ERROR_NOT_ENOUGH_MEMORY
, "last error %u\n", error
);
1304 SetLastError(0xdeadbeef);
1305 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_ALLOCATE_BUFFER
, NULL
, 0, 0, NULL
, 1, NULL
);
1306 error
= GetLastError();
1307 ok(!ret
, "FormatMessageA returned %u\n", ret
);
1308 ok(error
== ERROR_NOT_ENOUGH_MEMORY
, "last error %u\n", error
);
1310 SetLastError(0xdeadbeef);
1311 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_ALLOCATE_BUFFER
, NULL
, 0, 0, NULL
, 256, NULL
);
1312 error
= GetLastError();
1313 ok(!ret
, "FormatMessageA returned %u\n", ret
);
1314 ok(error
== ERROR_NOT_ENOUGH_MEMORY
, "last error %u\n", error
);
1317 static void test_message_null_buffer_wide(void)
1321 SetLastError(0xdeadbeef);
1322 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, 0, 0, NULL
, 0, NULL
);
1323 error
= GetLastError();
1324 ok(!ret
, "FormatMessageW returned %u\n", ret
);
1325 ok(error
== ERROR_INVALID_PARAMETER
, "last error %u\n", error
);
1327 SetLastError(0xdeadbeef);
1328 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, 0, 0, NULL
, 1, NULL
);
1329 error
= GetLastError();
1330 ok(!ret
, "FormatMessageW returned %u\n", ret
);
1331 ok(error
== ERROR_INVALID_PARAMETER
, "last error %u\n", error
);
1333 SetLastError(0xdeadbeef);
1334 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, 0, 0, NULL
, 256, NULL
);
1335 error
= GetLastError();
1336 ok(!ret
, "FormatMessageW returned %u\n", ret
);
1337 ok(error
== ERROR_INVALID_PARAMETER
, "last error %u\n", error
);
1339 SetLastError(0xdeadbeef);
1340 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_ALLOCATE_BUFFER
, NULL
, 0, 0, NULL
, 0, NULL
);
1341 error
= GetLastError();
1342 ok(!ret
, "FormatMessageW returned %u\n", ret
);
1343 ok(error
== ERROR_INVALID_PARAMETER
, "last error %u\n", error
);
1345 SetLastError(0xdeadbeef);
1346 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_ALLOCATE_BUFFER
, NULL
, 0, 0, NULL
, 1, NULL
);
1347 error
= GetLastError();
1348 ok(!ret
, "FormatMessageW returned %u\n", ret
);
1349 ok(error
== ERROR_INVALID_PARAMETER
, "last error %u\n", error
);
1351 SetLastError(0xdeadbeef);
1352 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_ALLOCATE_BUFFER
, NULL
, 0, 0, NULL
, 256, NULL
);
1353 error
= GetLastError();
1354 ok(!ret
, "FormatMessageW returned %u\n", ret
);
1355 ok(error
== ERROR_INVALID_PARAMETER
, "last error %u\n", error
);
1358 static void test_message_allocate_buffer(void)
1363 /* While MSDN suggests that FormatMessageA allocates a buffer whose size is
1364 * the larger of the output string and the requested buffer size, the tests
1365 * will not try to determine the actual size of the buffer allocated, as
1366 * the return value of LocalSize cannot be trusted for the purpose, and it should
1367 * in any case be safe for FormatMessageA to allocate in the manner that
1370 SetLastError(0xdeadbeef);
1371 buf
= (char *)0xdeadbeef;
1372 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ALLOCATE_BUFFER
,
1373 "", 0, 0, (char *)&buf
, 0, NULL
);
1374 ok(ret
== 0, "Expected FormatMessageA to return 0, got %u\n", ret
);
1375 ok(buf
== NULL
, "Expected output buffer pointer to be NULL\n");
1376 ok(GetLastError() == 0xdeadbeef,
1377 "Expected last error to be untouched, got %u\n", GetLastError());
1379 buf
= (char *)0xdeadbeef;
1380 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ALLOCATE_BUFFER
,
1381 "test", 0, 0, (char *)&buf
, 0, NULL
);
1382 ok(ret
== 4, "Expected FormatMessageA to return 4, got %u\n", ret
);
1383 ok(buf
!= NULL
&& buf
!= (char *)0xdeadbeef,
1384 "Expected output buffer pointer to be valid\n");
1385 if (buf
!= NULL
&& buf
!= (char *)0xdeadbeef)
1387 ok(!strcmp("test", buf
),
1388 "Expected buffer to contain \"test\", got %s\n", buf
);
1392 buf
= (char *)0xdeadbeef;
1393 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ALLOCATE_BUFFER
,
1394 "test", 0, 0, (char *)&buf
, strlen("test"), NULL
);
1395 ok(ret
== 4, "Expected FormatMessageA to return 4, got %u\n", ret
);
1396 ok(buf
!= NULL
&& buf
!= (char *)0xdeadbeef,
1397 "Expected output buffer pointer to be valid\n");
1398 if (buf
!= NULL
&& buf
!= (char *)0xdeadbeef)
1400 ok(!strcmp("test", buf
),
1401 "Expected buffer to contain \"test\", got %s\n", buf
);
1405 buf
= (char *)0xdeadbeef;
1406 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ALLOCATE_BUFFER
,
1407 "test", 0, 0, (char *)&buf
, strlen("test") + 1, NULL
);
1408 ok(ret
== 4, "Expected FormatMessageA to return 4, got %u\n", ret
);
1409 ok(buf
!= NULL
&& buf
!= (char *)0xdeadbeef,
1410 "Expected output buffer pointer to be valid\n");
1411 if (buf
!= NULL
&& buf
!= (char *)0xdeadbeef)
1413 ok(!strcmp("test", buf
),
1414 "Expected buffer to contain \"test\", got %s\n", buf
);
1418 buf
= (char *)0xdeadbeef;
1419 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ALLOCATE_BUFFER
,
1420 "test", 0, 0, (char *)&buf
, strlen("test") + 2, NULL
);
1421 ok(ret
== 4, "Expected FormatMessageA to return 4, got %u\n", ret
);
1422 ok(buf
!= NULL
&& buf
!= (char *)0xdeadbeef,
1423 "Expected output buffer pointer to be valid\n");
1424 if (buf
!= NULL
&& buf
!= (char *)0xdeadbeef)
1426 ok(!strcmp("test", buf
),
1427 "Expected buffer to contain \"test\", got %s\n", buf
);
1431 buf
= (char *)0xdeadbeef;
1432 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ALLOCATE_BUFFER
,
1433 "test", 0, 0, (char *)&buf
, 1024, NULL
);
1434 ok(ret
== 4, "Expected FormatMessageA to return 4, got %u\n", ret
);
1435 ok(buf
!= NULL
&& buf
!= (char *)0xdeadbeef,
1436 "Expected output buffer pointer to be valid\n");
1437 if (buf
!= NULL
&& buf
!= (char *)0xdeadbeef)
1439 ok(!strcmp("test", buf
),
1440 "Expected buffer to contain \"test\", got %s\n", buf
);
1445 static void test_message_allocate_buffer_wide(void)
1447 static const WCHAR empty
[] = {0};
1448 static const WCHAR test
[] = {'t','e','s','t',0};
1453 /* While MSDN suggests that FormatMessageW allocates a buffer whose size is
1454 * the larger of the output string and the requested buffer size, the tests
1455 * will not try to determine the actual size of the buffer allocated, as
1456 * the return value of LocalSize cannot be trusted for the purpose, and it should
1457 * in any case be safe for FormatMessageW to allocate in the manner that
1460 if (0) /* crashes on Windows */
1462 buf
= (WCHAR
*)0xdeadbeef;
1463 FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ALLOCATE_BUFFER
,
1464 NULL
, 0, 0, (WCHAR
*)&buf
, 0, NULL
);
1467 SetLastError(0xdeadbeef);
1468 buf
= (WCHAR
*)0xdeadbeef;
1469 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ALLOCATE_BUFFER
,
1470 empty
, 0, 0, (WCHAR
*)&buf
, 0, NULL
);
1471 ok(ret
== 0, "Expected FormatMessageW to return 0, got %u\n", ret
);
1472 ok(buf
== NULL
, "Expected output buffer pointer to be NULL\n");
1473 ok(GetLastError() == 0xdeadbeef,
1474 "Expected last error to be untouched, got %u\n", GetLastError());
1476 buf
= (WCHAR
*)0xdeadbeef;
1477 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ALLOCATE_BUFFER
,
1478 test
, 0, 0, (WCHAR
*)&buf
, 0, NULL
);
1479 ok(ret
== 4, "Expected FormatMessageA to return 4, got %u\n", ret
);
1480 ok(buf
!= NULL
&& buf
!= (WCHAR
*)0xdeadbeef,
1481 "Expected output buffer pointer to be valid\n");
1482 if (buf
!= NULL
&& buf
!= (WCHAR
*)0xdeadbeef)
1484 ok(!lstrcmpW(test
, buf
),
1485 "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf
));
1489 buf
= (WCHAR
*)0xdeadbeef;
1490 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ALLOCATE_BUFFER
,
1491 test
, 0, 0, (WCHAR
*)&buf
, sizeof(test
)/sizeof(WCHAR
) - 1, NULL
);
1492 ok(ret
== 4, "Expected FormatMessageA to return 4, got %u\n", ret
);
1493 ok(buf
!= NULL
&& buf
!= (WCHAR
*)0xdeadbeef,
1494 "Expected output buffer pointer to be valid\n");
1495 if (buf
!= NULL
&& buf
!= (WCHAR
*)0xdeadbeef)
1497 ok(!lstrcmpW(test
, buf
),
1498 "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf
));
1502 buf
= (WCHAR
*)0xdeadbeef;
1503 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ALLOCATE_BUFFER
,
1504 test
, 0, 0, (WCHAR
*)&buf
, sizeof(test
)/sizeof(WCHAR
), NULL
);
1505 ok(ret
== 4, "Expected FormatMessageA to return 4, got %u\n", ret
);
1506 ok(buf
!= NULL
&& buf
!= (WCHAR
*)0xdeadbeef,
1507 "Expected output buffer pointer to be valid\n");
1508 if (buf
!= NULL
&& buf
!= (WCHAR
*)0xdeadbeef)
1510 ok(!lstrcmpW(test
, buf
),
1511 "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf
));
1515 buf
= (WCHAR
*)0xdeadbeef;
1516 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ALLOCATE_BUFFER
,
1517 test
, 0, 0, (WCHAR
*)&buf
, sizeof(test
)/sizeof(WCHAR
) + 1, NULL
);
1518 ok(ret
== 4, "Expected FormatMessageA to return 4, got %u\n", ret
);
1519 ok(buf
!= NULL
&& buf
!= (WCHAR
*)0xdeadbeef,
1520 "Expected output buffer pointer to be valid\n");
1521 if (buf
!= NULL
&& buf
!= (WCHAR
*)0xdeadbeef)
1523 ok(!lstrcmpW(test
, buf
),
1524 "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf
));
1528 buf
= (WCHAR
*)0xdeadbeef;
1529 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_ALLOCATE_BUFFER
,
1530 test
, 0, 0, (WCHAR
*)&buf
, 1024, NULL
);
1531 ok(ret
== 4, "Expected FormatMessageA to return 4, got %u\n", ret
);
1532 ok(buf
!= NULL
&& buf
!= (WCHAR
*)0xdeadbeef,
1533 "Expected output buffer pointer to be valid\n");
1534 if (buf
!= NULL
&& buf
!= (WCHAR
*)0xdeadbeef)
1536 ok(!lstrcmpW(test
, buf
),
1537 "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf
));
1542 static void test_message_from_hmodule(void)
1546 CHAR out
[0x100] = {0};
1548 h
= GetModuleHandleA("kernel32.dll");
1549 ok(h
!= 0, "GetModuleHandle failed\n");
1551 /*Test existing messageID; as the message strings from wine's kernel32 differ from windows' kernel32 we don't compare
1552 the strings but only test that FormatMessage doesn't return 0*/
1553 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_FROM_HMODULE
, h
, 7/*=ERROR_ARENA_TRASHED*/,
1554 MAKELANGID(LANG_NEUTRAL
, SUBLANG_NEUTRAL
), out
, sizeof(out
)/sizeof(CHAR
), NULL
);
1555 ok(ret
!= 0, "FormatMessageA returned 0\n");
1557 /* Test HRESULT. It's not documented but in practice _com_error::ErrorMessage relies on this. */
1558 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_FROM_HMODULE
, h
, 0x80070005 /* E_ACCESSDENIED */,
1559 MAKELANGID(LANG_NEUTRAL
, SUBLANG_NEUTRAL
), out
, sizeof(out
)/sizeof(CHAR
), NULL
);
1560 ok(ret
!= 0, "FormatMessageA returned 0\n");
1562 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_FROM_HMODULE
, h
, TRUST_E_NOSIGNATURE
,
1563 MAKELANGID(LANG_NEUTRAL
, SUBLANG_NEUTRAL
), out
, sizeof(out
)/sizeof(CHAR
), NULL
);
1564 ok(ret
!= 0, "FormatMessageA returned 0\n");
1566 /* Test a message string with an insertion without passing any variadic arguments. */
1567 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_FROM_HMODULE
, h
, 193 /* ERROR_BAD_EXE_FORMAT */,
1568 MAKELANGID(LANG_NEUTRAL
, SUBLANG_NEUTRAL
), out
, sizeof(out
)/sizeof(CHAR
), NULL
);
1569 ok(ret
== 0, "FormatMessageA returned non-zero\n");
1571 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_FROM_HMODULE
|
1572 FORMAT_MESSAGE_ARGUMENT_ARRAY
, h
, 193 /* ERROR_BAD_EXE_FORMAT */,
1573 MAKELANGID(LANG_NEUTRAL
, SUBLANG_NEUTRAL
), out
, sizeof(out
)/sizeof(CHAR
), NULL
);
1574 ok(ret
== 0, "FormatMessageA returned non-zero\n");
1576 /*Test nonexistent messageID with varying language IDs Note: FormatMessageW behaves the same*/
1577 SetLastError(0xdeadbeef);
1578 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_FROM_HMODULE
, h
, 3044,
1579 MAKELANGID(LANG_NEUTRAL
, SUBLANG_NEUTRAL
), out
, sizeof(out
)/sizeof(CHAR
), NULL
);
1580 error
= GetLastError();
1581 ok(ret
== 0, "FormatMessageA returned %u instead of 0\n", ret
);
1582 ok(error
== ERROR_MR_MID_NOT_FOUND
|| error
== ERROR_MUI_FILE_NOT_FOUND
, "last error %u\n", error
);
1584 SetLastError(0xdeadbeef);
1585 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_FROM_HMODULE
, h
, 3044,
1586 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
), out
, sizeof(out
)/sizeof(CHAR
), NULL
);
1587 error
= GetLastError();
1588 ok(ret
== 0, "FormatMessageA returned %u instead of 0\n", ret
);
1589 ok(error
== ERROR_MR_MID_NOT_FOUND
|| error
== ERROR_MUI_FILE_NOT_LOADED
, "last error %u\n", error
);
1591 SetLastError(0xdeadbeef);
1592 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_FROM_HMODULE
, h
, 3044,
1593 MAKELANGID(LANG_NEUTRAL
, SUBLANG_SYS_DEFAULT
), out
, sizeof(out
)/sizeof(CHAR
), NULL
);
1594 error
= GetLastError();
1595 ok(ret
== 0, "FormatMessageA returned %u instead of 0\n", ret
);
1596 ok(error
== ERROR_MR_MID_NOT_FOUND
|| error
== ERROR_MUI_FILE_NOT_LOADED
, "last error %u\n", error
);
1598 SetLastError(0xdeadbeef);
1599 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_FROM_HMODULE
, h
, 3044,
1600 MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), out
, sizeof(out
)/sizeof(CHAR
), NULL
);
1601 error
= GetLastError();
1602 ok(ret
== 0, "FormatMessageA returned %u instead of 0\n", ret
);
1603 ok(error
== ERROR_RESOURCE_LANG_NOT_FOUND
||
1604 error
== ERROR_MR_MID_NOT_FOUND
||
1605 error
== ERROR_MUI_FILE_NOT_FOUND
||
1606 error
== ERROR_MUI_FILE_NOT_LOADED
,
1607 "last error %u\n", error
);
1609 SetLastError(0xdeadbeef);
1610 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_FROM_HMODULE
, h
, 3044,
1611 MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_UK
), out
, sizeof(out
)/sizeof(CHAR
), NULL
);
1612 error
= GetLastError();
1613 ok(ret
== 0, "FormatMessageA returned %u instead of 0\n", ret
);
1614 ok(error
== ERROR_RESOURCE_LANG_NOT_FOUND
||
1615 error
== ERROR_MR_MID_NOT_FOUND
||
1616 error
== ERROR_MUI_FILE_NOT_FOUND
||
1617 error
== ERROR_MUI_FILE_NOT_LOADED
,
1618 "last error %u\n", error
);
1621 static void test_message_invalid_flags(void)
1623 static const char init_buf
[] = {'x', 'x', 'x', 'x', 'x'};
1629 SetLastError(0xdeadbeef);
1630 memcpy(out
, init_buf
, sizeof(init_buf
));
1631 ret
= FormatMessageA(0, "test", 0, 0, out
, sizeof(out
)/sizeof(CHAR
), NULL
);
1632 ok(ret
== 0, "Expected FormatMessageA to return 0, got %u\n", ret
);
1633 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)),
1634 "Expected the output buffer to be untouched\n");
1635 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1636 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1639 SetLastError(0xdeadbeef);
1640 ptr
= (char *)0xdeadbeef;
1641 ret
= FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER
, "test", 0, 0, (char *)&ptr
, 0, NULL
);
1642 ok(ret
== 0, "Expected FormatMessageA to return 0, got %u\n", ret
);
1643 ok(ptr
== NULL
, "Expected output pointer to be initialized to NULL, got %p\n", ptr
);
1644 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1645 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1648 SetLastError(0xdeadbeef);
1649 memcpy(out
, init_buf
, sizeof(init_buf
));
1650 ret
= FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS
, "test", 0, 0, out
, sizeof(out
)/sizeof(CHAR
), NULL
);
1651 ok(ret
== 0, "Expected FormatMessageA to return 0, got %u\n", ret
);
1652 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)),
1653 "Expected the output buffer to be untouched\n");
1654 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1655 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1658 SetLastError(0xdeadbeef);
1659 memcpy(out
, init_buf
, sizeof(init_buf
));
1660 ret
= FormatMessageA(FORMAT_MESSAGE_ARGUMENT_ARRAY
, "test", 0, 0, out
, sizeof(out
)/sizeof(CHAR
), NULL
);
1661 ok(ret
== 0, "Expected FormatMessageA to return 0, got %u\n", ret
);
1662 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)),
1663 "Expected the output buffer to be untouched\n");
1664 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1665 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1668 SetLastError(0xdeadbeef);
1669 memcpy(out
, init_buf
, sizeof(init_buf
));
1670 ret
= FormatMessageA(FORMAT_MESSAGE_MAX_WIDTH_MASK
, "test", 0, 0, out
, sizeof(out
)/sizeof(CHAR
), NULL
);
1671 ok(ret
== 0, "Expected FormatMessageA to return 0, got %u\n", ret
);
1672 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)),
1673 "Expected the output buffer to be untouched\n");
1674 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1675 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1678 /* Simultaneously setting FORMAT_MESSAGE_FROM_STRING with other source
1679 * flags is apparently permissible, and FORMAT_MESSAGE_FROM_STRING takes
1680 * precedence in this case. */
1682 memcpy(out
, init_buf
, sizeof(init_buf
));
1683 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_FROM_SYSTEM
,
1684 "test", 0, 0, out
, sizeof(out
)/sizeof(CHAR
), NULL
);
1685 ok(ret
== 4, "Expected FormatMessageA to return 4, got %u\n", ret
);
1686 ok(!strcmp("test", out
),
1687 "Expected the output buffer to be untouched\n");
1689 memcpy(out
, init_buf
, sizeof(init_buf
));
1690 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_FROM_HMODULE
,
1691 "test", 0, 0, out
, sizeof(out
)/sizeof(CHAR
), NULL
);
1692 ok(ret
== 4, "Expected FormatMessageA to return 4, got %u\n", ret
);
1693 ok(!strcmp("test", out
),
1694 "Expected the output buffer to be untouched\n");
1696 memcpy(out
, init_buf
, sizeof(init_buf
));
1697 ret
= FormatMessageA(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_FROM_HMODULE
|
1698 FORMAT_MESSAGE_FROM_SYSTEM
, "test", 0, 0, out
,
1699 sizeof(out
)/sizeof(CHAR
), NULL
);
1700 ok(ret
== 4, "Expected FormatMessageA to return 4, got %u\n", ret
);
1701 ok(!strcmp("test", out
),
1702 "Expected the output buffer to be untouched\n");
1705 static void test_message_invalid_flags_wide(void)
1707 static const WCHAR init_buf
[] = {'x', 'x', 'x', 'x', 'x'};
1708 static const WCHAR test
[] = {'t','e','s','t',0};
1714 SetLastError(0xdeadbeef);
1715 memcpy(out
, init_buf
, sizeof(init_buf
));
1716 ret
= FormatMessageW(0, test
, 0, 0, out
, sizeof(out
)/sizeof(WCHAR
), NULL
);
1717 ok(ret
== 0, "Expected FormatMessageW to return 0, got %u\n", ret
);
1718 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)),
1719 "Expected the output buffer to be untouched\n");
1720 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1721 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1724 SetLastError(0xdeadbeef);
1725 ptr
= (WCHAR
*)0xdeadbeef;
1726 ret
= FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER
, test
, 0, 0, (WCHAR
*)&ptr
, 0, NULL
);
1727 ok(ret
== 0, "Expected FormatMessageW to return 0, got %u\n", ret
);
1728 ok(ptr
== NULL
, "Expected output pointer to be initialized to NULL, got %p\n", ptr
);
1729 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1730 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1733 SetLastError(0xdeadbeef);
1734 memcpy(out
, init_buf
, sizeof(init_buf
));
1735 ret
= FormatMessageW(FORMAT_MESSAGE_IGNORE_INSERTS
, test
, 0, 0, out
, sizeof(out
)/sizeof(WCHAR
), NULL
);
1736 ok(ret
== 0, "Expected FormatMessageW to return 0, got %u\n", ret
);
1737 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)),
1738 "Expected the output buffer to be untouched\n");
1739 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1740 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1743 SetLastError(0xdeadbeef);
1744 memcpy(out
, init_buf
, sizeof(init_buf
));
1745 ret
= FormatMessageW(FORMAT_MESSAGE_ARGUMENT_ARRAY
, test
, 0, 0, out
, sizeof(out
)/sizeof(WCHAR
), NULL
);
1746 ok(ret
== 0, "Expected FormatMessageW to return 0, got %u\n", ret
);
1747 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)),
1748 "Expected the output buffer to be untouched\n");
1749 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1750 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1753 SetLastError(0xdeadbeef);
1754 memcpy(out
, init_buf
, sizeof(init_buf
));
1755 ret
= FormatMessageW(FORMAT_MESSAGE_MAX_WIDTH_MASK
, test
, 0, 0, out
, sizeof(out
)/sizeof(WCHAR
), NULL
);
1756 ok(ret
== 0, "Expected FormatMessageW to return 0, got %u\n", ret
);
1757 ok(!memcmp(out
, init_buf
, sizeof(init_buf
)),
1758 "Expected the output buffer to be untouched\n");
1759 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1760 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
1763 /* Simultaneously setting FORMAT_MESSAGE_FROM_STRING with other source
1764 * flags is apparently permissible, and FORMAT_MESSAGE_FROM_STRING takes
1765 * precedence in this case. */
1767 memcpy(out
, init_buf
, sizeof(init_buf
));
1768 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_FROM_SYSTEM
,
1769 test
, 0, 0, out
, sizeof(out
)/sizeof(WCHAR
), NULL
);
1770 ok(ret
== 4, "Expected FormatMessageW to return 4, got %u\n", ret
);
1771 ok(!lstrcmpW(test
, out
),
1772 "Expected the output buffer to be untouched\n");
1774 memcpy(out
, init_buf
, sizeof(init_buf
));
1775 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_FROM_HMODULE
,
1776 test
, 0, 0, out
, sizeof(out
)/sizeof(WCHAR
), NULL
);
1777 ok(ret
== 4, "Expected FormatMessageW to return 4, got %u\n", ret
);
1778 ok(!lstrcmpW(test
, out
),
1779 "Expected the output buffer to be untouched\n");
1781 memcpy(out
, init_buf
, sizeof(init_buf
));
1782 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
| FORMAT_MESSAGE_FROM_HMODULE
|
1783 FORMAT_MESSAGE_FROM_SYSTEM
, test
, 0, 0, out
,
1784 sizeof(out
)/sizeof(WCHAR
), NULL
);
1785 ok(ret
== 4, "Expected FormatMessageW to return 4, got %u\n", ret
);
1786 ok(!lstrcmpW(test
, out
),
1787 "Expected the output buffer to be untouched\n");
1790 static void test_message_from_64bit_number(void)
1792 static const WCHAR I64d
[] = {'%', '1', '!', 'I', '6', '4', 'd', '!', 0};
1793 static const WCHAR I64u
[] = {'%', '1', '!', 'I', '6', '4', 'u', '!', 0};
1794 WCHAR outW
[0x100], expW
[0x100];
1800 const char expected
[32];
1802 } unsigned_tests
[] =
1805 { 1234567890, "1234567890", 10},
1806 { ULL(0xFFFFFFFF,0xFFFFFFFF), "18446744073709551615", 20 },
1807 { ULL(0x7FFFFFFF,0xFFFFFFFF), "9223372036854775807", 19 },
1812 const char expected
[32];
1817 { 1234567890, "1234567890", 10 },
1819 { ULL(0xFFFFFFFF,0xFFFFFFFF), "-1", 2},
1820 { ULL(0x7FFFFFFF,0xFFFFFFFF), "9223372036854775807", 19 },
1821 { -ULL(0x7FFFFFFF,0xFFFFFFFF), "-9223372036854775807", 20},
1825 for (i
= 0; i
< sizeof(unsigned_tests
) / sizeof(unsigned_tests
[0]); i
++)
1827 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, I64u
,
1828 0, 0, outW
, sizeof(outW
) / sizeof(WCHAR
), unsigned_tests
[i
].number
);
1829 MultiByteToWideChar(CP_ACP
, 0, unsigned_tests
[i
].expected
, -1, expW
, sizeof(expW
) / sizeof(WCHAR
));
1831 ok(!lstrcmpW(outW
, expW
),"[%d] failed, expected %s, got %s\n", i
,
1832 unsigned_tests
[i
].expected
, wine_dbgstr_w(outW
));
1833 ok(r
== unsigned_tests
[i
].len
,"[%d] failed: r=%d\n", i
, r
);
1835 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!I64u!",
1836 0, 0, outA
, sizeof(outA
), unsigned_tests
[i
].number
);
1838 ok(!strcmp(outA
, unsigned_tests
[i
].expected
),"[%d] failed, expected %s, got %s\n", i
,
1839 unsigned_tests
[i
].expected
, outA
);
1840 ok(r
== unsigned_tests
[i
].len
,"[%d] failed: r=%d\n", i
, r
);
1844 for (i
= 0; i
< sizeof(signed_tests
) / sizeof(signed_tests
[0]); i
++)
1846 r
= doitW(FORMAT_MESSAGE_FROM_STRING
, I64d
,
1847 0, 0, outW
, sizeof(outW
) / sizeof(WCHAR
), signed_tests
[i
].number
);
1848 MultiByteToWideChar(CP_ACP
, 0, signed_tests
[i
].expected
, -1, expW
, sizeof(expW
) / sizeof(WCHAR
));
1850 ok(!lstrcmpW(outW
, expW
),"[%d] failed, expected %s, got %s\n", i
,
1851 signed_tests
[i
].expected
, wine_dbgstr_w(outW
));
1852 ok(r
== signed_tests
[i
].len
,"[%d] failed: r=%d\n", i
, r
);
1854 r
= doit(FORMAT_MESSAGE_FROM_STRING
, "%1!I64d!",
1855 0, 0, outA
, sizeof(outA
), signed_tests
[i
].number
);
1857 ok(!strcmp(outA
, signed_tests
[i
].expected
),"[%d] failed, expected %s, got %s\n", i
,
1858 signed_tests
[i
].expected
, outA
);
1859 ok(r
== signed_tests
[i
].len
,"[%d] failed: r=%d\n", i
, r
);
1864 START_TEST(format_msg
)
1868 test_message_from_string();
1869 test_message_ignore_inserts();
1870 test_message_wrap();
1871 test_message_insufficient_buffer();
1872 test_message_null_buffer();
1873 test_message_allocate_buffer();
1874 test_message_from_hmodule();
1875 test_message_invalid_flags();
1877 SetLastError(0xdeadbeef);
1878 ret
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
, NULL
, 0, 0, NULL
, 0, NULL
);
1879 if (!ret
&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
1881 win_skip("FormatMessageW is not implemented\n");
1885 test_message_from_string_wide();
1886 test_message_ignore_inserts_wide();
1887 test_message_insufficient_buffer_wide();
1888 test_message_null_buffer_wide();
1889 test_message_allocate_buffer_wide();
1890 test_message_invalid_flags_wide();
1891 test_message_from_64bit_number();