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