1 /* Unit test suite for FormatMessageA/W 2 * 3 * Copyright 2002 Mike McCormack for CodeWeavers 4 * 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. 9 * 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. 14 * 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 18 */ 19 20 #include <stdarg.h> 21 22 #include "wine/test.h" 23 #include "windef.h" 24 #include "winbase.h" 25 #include "winnls.h" 26 27 #define ULL(a,b) (((ULONG64)(a) << 32) | (b)) 28 29 static DWORD WINAPIV doit(DWORD flags, LPCVOID src, DWORD msg_id, DWORD lang_id, 30 LPSTR out, DWORD outsize, ... ) 31 { 32 __ms_va_list list; 33 DWORD r; 34 35 __ms_va_start(list, outsize); 36 r = FormatMessageA(flags, src, msg_id, 37 lang_id, out, outsize, &list); 38 __ms_va_end(list); 39 return r; 40 } 41 42 static DWORD WINAPIV doitW(DWORD flags, LPCVOID src, DWORD msg_id, DWORD lang_id, 43 LPWSTR out, DWORD outsize, ... ) 44 { 45 __ms_va_list list; 46 DWORD r; 47 48 __ms_va_start(list, outsize); 49 r = FormatMessageW(flags, src, msg_id, 50 lang_id, out, outsize, &list); 51 __ms_va_end(list); 52 return r; 53 } 54 55 static void test_message_from_string_wide(void) 56 { 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}; 101 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}; 131 132 static const WCHAR init_buf[] = {'x', 'x', 'x', 'x', 'x', 'x'}; 133 static const WCHAR broken_buf[] = {'t','e','s','t','x','x'}; 134 135 WCHAR out[0x100] = {0}; 136 DWORD r, error; 137 138 /* the basics */ 139 r = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, test, 0, 140 0, out, sizeof(out)/sizeof(WCHAR), NULL); 141 ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out)); 142 ok(r==4, "failed: r=%d\n", r); 143 144 /* null string, crashes on Windows */ 145 if (0) 146 { 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); 151 } 152 153 /* empty string */ 154 SetLastError(0xdeadbeef); 155 memcpy(out, init_buf, sizeof(init_buf)); 156 r = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, empty, 0, 157 0, out, sizeof(out)/sizeof(WCHAR), NULL); 158 error = GetLastError(); 159 ok(!lstrcmpW(empty, out), "failed out=%s\n", wine_dbgstr_w(out)); 160 ok(r==0, "succeeded: r=%d\n", r); 161 ok(error==0xdeadbeef, "last error %u\n", error); 162 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); 173 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); 185 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); 196 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); 206 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); 212 213 /* no format */ 214 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1, 0, 215 0, out, sizeof(out)/sizeof(WCHAR), test); 216 ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out)); 217 ok(r==4,"failed: r=%d\n", r); 218 219 /* two pieces */ 220 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_12, 0, 221 0, out, sizeof(out)/sizeof(WCHAR), te, st); 222 ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out)); 223 ok(r==4,"failed: r=%d\n", r); 224 225 /* three pieces */ 226 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_123, 0, 227 0, out, sizeof(out)/sizeof(WCHAR), t, s, e); 228 ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out)); 229 ok(r==4,"failed: r=%d\n", r); 230 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); 236 237 /* nor ls */ 238 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_ls, 0, 239 0, out, sizeof(out)/sizeof(WCHAR), test); 240 ok(!lstrcmpW(&fmt_ls[1], out), "failed out=%s\n", wine_dbgstr_w(out)); 241 ok(r==4, "failed: r=%d\n", r); 242 243 /* nor S */ 244 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_S, 0, 245 0, out, sizeof(out)/sizeof(WCHAR), test); 246 ok(!lstrcmpW(&fmt_S[1], out), "failed out=%s\n", wine_dbgstr_w(out)); 247 ok(r==3, "failed: r=%d\n", r); 248 249 /* nor ws */ 250 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_ws, 0, 251 0, out, sizeof(out)/sizeof(WCHAR), test); 252 ok(!lstrcmpW(&fmt_ws[1], out), "failed out=%s\n", wine_dbgstr_w(out)); 253 ok(r==4, "failed: r=%d\n", r); 254 255 /* as characters */ 256 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_123c, 0, 257 0, out, sizeof(out)/sizeof(WCHAR), 't', 'e', 's'); 258 ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out)); 259 ok(r==4,"failed: r=%d\n", r); 260 261 /* lc is unicode */ 262 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_123lc, 0, 263 0, out, sizeof(out)/sizeof(WCHAR), 't', 'e', 's'); 264 ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out)); 265 ok(r==4,"failed: r=%d\n", r); 266 267 /* wc is unicode */ 268 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_123wc, 0, 269 0, out, sizeof(out)/sizeof(WCHAR), 't', 'e', 's'); 270 ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out)); 271 ok(r==4,"failed: r=%d\n", r); 272 273 /* C is unicode */ 274 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_123C, 0, 275 0, out, sizeof(out)/sizeof(WCHAR), 't', 'e', 's'); 276 ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out)); 277 ok(r==4,"failed: r=%d\n", r); 278 279 /* some numbers */ 280 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_123d, 0, 281 0, out, sizeof(out)/sizeof(WCHAR), 1, 2, 3); 282 ok(!lstrcmpW(s_123d, out), "failed out=%s\n", wine_dbgstr_w(out)); 283 ok(r==3,"failed: r=%d\n", r); 284 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); 290 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); 296 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); 302 303 /* a hex number */ 304 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_14x, 0, 305 0, out, sizeof(out)/sizeof(WCHAR), 11); 306 ok(!lstrcmpW(s_14x, out), "failed out=%s\n", wine_dbgstr_w(out)); 307 ok(r==4,"failed: r=%d\n", r); 308 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); 314 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); 320 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); 326 327 /* two percent... */ 328 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_2pct, 0, 329 0, out, sizeof(out)/sizeof(WCHAR)); 330 ok(!lstrcmpW(s_2pct, out), "failed out=%s\n", wine_dbgstr_w(out)); 331 ok(r==4,"failed: r=%d\n", r); 332 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); 338 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); 344 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); 350 351 /* %space */ 352 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_space, 0, 353 0, out, sizeof(out)/sizeof(WCHAR)); 354 ok(!lstrcmpW(s_space, out), "failed out=%s\n", wine_dbgstr_w(out)); 355 ok(r==4,"failed: r=%d\n", r); 356 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); 362 363 /* line feed */ 364 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_hi_lf, 0, 365 0, out, sizeof(out)/sizeof(WCHAR)); 366 ok(!lstrcmpW(s_hi_crlf, out), "failed out=%s\n", wine_dbgstr_w(out)); 367 ok(r==4,"failed: r=%d\n", r); 368 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); 374 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); 380 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); 386 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); 392 393 /* precision and width */ 394 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 */ 422 { 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); 432 } 433 434 /* change of pace... test the low byte of dwflags */ 435 436 /* line feed */ 437 r = doitW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, fmt_hi_lf, 0, 438 0, out, sizeof(out)/sizeof(WCHAR)); 439 ok(!lstrcmpW(s_hi_sp, out), "failed out=%s\n", wine_dbgstr_w(out)); 440 ok(r==3,"failed: r=%d\n", r); 441 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); 447 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); 453 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); 459 } 460 461 static void test_message_from_string(void) 462 { 463 CHAR out[0x100] = {0}; 464 DWORD r; 465 static const char init_buf[] = {'x', 'x', 'x', 'x', 'x', 'x'}; 466 static const WCHAR szwTest[] = { 't','e','s','t',0}; 467 468 /* the basics */ 469 r = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, "test", 0, 470 0, out, sizeof(out)/sizeof(CHAR),NULL); 471 ok(!strcmp("test", out),"failed out=[%s]\n",out); 472 ok(r==4,"failed: r=%d\n",r); 473 474 /* null string, crashes on Windows */ 475 if (0) 476 { 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); 481 } 482 483 /* empty string */ 484 SetLastError(0xdeadbeef); 485 memcpy(out, init_buf, sizeof(init_buf)); 486 r = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, "", 0, 487 0, out, sizeof(out)/sizeof(CHAR), NULL); 488 ok(!memcmp(out, init_buf, sizeof(init_buf)), "Expected the buffer to be untouched\n"); 489 ok(r==0, "succeeded: r=%d\n", r); 490 ok(GetLastError()==0xdeadbeef, 491 "last error %u\n", GetLastError()); 492 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()); 503 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()); 514 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()); 523 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()); 531 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); 537 538 /* no format */ 539 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1", 0, 540 0, out, sizeof(out)/sizeof(CHAR), "test"); 541 ok(!strcmp("test", out),"failed out=[%s]\n",out); 542 ok(r==4,"failed: r=%d\n",r); 543 544 /* two pieces */ 545 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1%2", 0, 546 0, out, sizeof(out)/sizeof(CHAR), "te","st"); 547 ok(!strcmp("test", out),"failed out=[%s]\n",out); 548 ok(r==4,"failed: r=%d\n",r); 549 550 /* three pieces */ 551 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1%3%2%1", 0, 552 0, out, sizeof(out)/sizeof(CHAR), "t","s","e"); 553 ok(!strcmp("test", out),"failed out=[%s]\n",out); 554 ok(r==4,"failed: r=%d\n",r); 555 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); 561 562 /* ls is unicode */ 563 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!ls!", 0, 564 0, out, sizeof(out)/sizeof(CHAR), szwTest); 565 ok(!strcmp("test", out),"failed out=[%s]\n",out); 566 ok(r==4,"failed: r=%d\n",r); 567 568 /* S is unicode */ 569 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!S!", 0, 570 0, out, sizeof(out)/sizeof(CHAR), szwTest); 571 ok(!strcmp("test", out),"failed out=[%s]\n",out); 572 ok(r==4,"failed: r=%d\n",r); 573 574 /* ws is unicode */ 575 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!ws!", 0, 576 0, out, sizeof(out)/sizeof(CHAR), szwTest); 577 ok(!strcmp("test", out),"failed out=[%s]\n",out); 578 ok(r==4,"failed: r=%d\n",r); 579 580 /* as characters */ 581 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!c!%2!c!%3!c!%1!c!", 0, 582 0, out, sizeof(out)/sizeof(CHAR), 't','e','s'); 583 ok(!strcmp("test", out),"failed out=[%s]\n",out); 584 ok(r==4,"failed: r=%d\n",r); 585 586 /* lc is unicode */ 587 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!lc!%2!lc!%3!lc!%1!lc!", 0, 588 0, out, sizeof(out)/sizeof(CHAR), 't','e','s'); 589 ok(!strcmp("test", out),"failed out=[%s]\n",out); 590 ok(r==4,"failed: r=%d\n",r); 591 592 /* wc is unicode */ 593 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!wc!%2!wc!%3!wc!%1!wc!", 0, 594 0, out, sizeof(out)/sizeof(CHAR), 't','e','s'); 595 ok(!strcmp("test", out),"failed out=[%s]\n",out); 596 ok(r==4,"failed: r=%d\n",r); 597 598 /* C is unicode */ 599 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!C!%2!C!%3!C!%1!C!", 0, 600 0, out, sizeof(out)/sizeof(CHAR), 't','e','s'); 601 ok(!strcmp("test", out),"failed out=[%s]\n",out); 602 ok(r==4,"failed: r=%d\n",r); 603 604 /* some numbers */ 605 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!d!%2!d!%3!d!", 0, 606 0, out, sizeof(out)/sizeof(CHAR), 1,2,3); 607 ok(!strcmp("123", out),"failed out=[%s]\n",out); 608 ok(r==3,"failed: r=%d\n",r); 609 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); 615 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); 621 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); 627 628 /* a hex number */ 629 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!4x!", 0, 630 0, out, sizeof(out)/sizeof(CHAR), 11); 631 ok(!strcmp(" b", out),"failed out=[%s]\n",out); 632 ok(r==4,"failed: r=%d\n",r); 633 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); 639 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); 645 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); 651 652 /* two percent... */ 653 r = doit(FORMAT_MESSAGE_FROM_STRING, " %%%% ", 0, 654 0, out, sizeof(out)/sizeof(CHAR)); 655 ok(!strcmp(" %% ", out),"failed out=[%s]\n",out); 656 ok(r==4,"failed: r=%d\n",r); 657 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); 663 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); 669 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); 675 676 /* %space */ 677 r = doit(FORMAT_MESSAGE_FROM_STRING, "% % ", 0, 678 0, out, sizeof(out)/sizeof(CHAR)); 679 ok(!strcmp(" ", out),"failed out=[%s]\n",out); 680 ok(r==4,"failed: r=%d\n",r); 681 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); 687 688 /* line feed */ 689 r = doit(FORMAT_MESSAGE_FROM_STRING, "hi\n", 0, 690 0, out, sizeof(out)/sizeof(CHAR)); 691 ok(!strcmp("hi\r\n", out),"failed out=[%s]\n",out); 692 ok(r==4,"failed: r=%d\n",r); 693 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); 699 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); 705 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); 711 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); 717 718 /* precision and width */ 719 720 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!3s!", 721 0, 0, out, sizeof(out), "t" ); 722 ok(!strcmp(" t", out),"failed out=[%s]\n",out); 723 ok(r==3, "failed: r=%d\n",r); 724 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!*s!", 725 0, 0, out, sizeof(out), 4, "t"); 726 if (!strcmp("*s",out)) win_skip( "width/precision not supported\n" ); 727 else 728 { 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 */ 752 { 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); 762 } 763 } 764 765 /* change of pace... test the low byte of dwflags */ 766 767 /* line feed */ 768 r = doit(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, "hi\n", 0, 769 0, out, sizeof(out)/sizeof(CHAR)); 770 ok(!strcmp("hi ", out), "failed out=[%s]\n",out); 771 ok(r==3, "failed: r=%d\n",r); 772 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); 778 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); 784 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); 790 } 791 792 static void test_message_ignore_inserts(void) 793 { 794 static const char init_buf[] = {'x', 'x', 'x', 'x', 'x'}; 795 796 DWORD ret; 797 CHAR out[256]; 798 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); 803 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); 809 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); 814 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()); 823 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); 829 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); 835 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); 840 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); 846 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); 851 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); 856 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); 861 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); 868 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); 874 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); 880 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); 886 } 887 888 static void test_message_ignore_inserts_wide(void) 889 { 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}; 902 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}; 910 911 DWORD ret; 912 WCHAR out[256]; 913 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)); 918 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)); 924 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)); 929 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()); 937 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)); 943 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)); 949 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)); 954 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)); 960 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)); 965 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)); 970 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)); 975 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)); 982 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)); 988 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)); 994 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)); 1000 } 1001 1002 static void test_message_wrap(void) 1003 { 1004 DWORD ret; 1005 int i; 1006 CHAR in[300], out[300], ref[300]; 1007 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); 1013 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); 1019 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); 1025 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); 1031 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); 1037 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); 1042 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); 1048 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); 1053 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); 1059 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); 1064 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); 1070 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); 1076 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); 1082 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); 1088 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); 1094 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); 1100 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); 1106 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); 1112 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); 1118 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); 1123 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); 1129 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); 1134 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); 1140 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++) 1145 { 1146 strcat(in, "123456789 "); 1147 strcat(ref, "123456789 "); 1148 } 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); 1153 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); 1159 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); 1164 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); 1169 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); 1174 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); 1179 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); 1184 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); 1189 } 1190 1191 static void test_message_insufficient_buffer(void) 1192 { 1193 static const char init_buf[] = {'x', 'x', 'x', 'x', 'x'}; 1194 static const char expected_buf[] = {'x', 'x', 'x', 'x', 'x'}; 1195 DWORD ret; 1196 CHAR out[5]; 1197 1198 SetLastError(0xdeadbeef); 1199 memcpy(out, init_buf, sizeof(init_buf)); 1200 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, "test", 0, 0, out, 0, NULL); 1201 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret); 1202 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 1203 "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n", 1204 GetLastError()); 1205 ok(!memcmp(expected_buf, out, sizeof(expected_buf)), 1206 "Expected the buffer to be untouched\n"); 1207 1208 SetLastError(0xdeadbeef); 1209 memcpy(out, init_buf, sizeof(init_buf)); 1210 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, "test", 0, 0, out, 1, NULL); 1211 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret); 1212 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 1213 "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n", 1214 GetLastError()); 1215 ok(!memcmp(expected_buf, out, sizeof(expected_buf)), 1216 "Expected the buffer to be untouched\n"); 1217 1218 SetLastError(0xdeadbeef); 1219 memcpy(out, init_buf, sizeof(init_buf)); 1220 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, "test", 0, 0, out, sizeof(out)/sizeof(out[0]) - 1, NULL); 1221 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret); 1222 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 1223 "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n", 1224 GetLastError()); 1225 ok(!memcmp(expected_buf, out, sizeof(expected_buf)), 1226 "Expected the buffer to be untouched\n"); 1227 } 1228 1229 static void test_message_insufficient_buffer_wide(void) 1230 { 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'}; 1236 1237 DWORD ret; 1238 WCHAR out[5]; 1239 1240 SetLastError(0xdeadbeef); 1241 memcpy(out, init_buf, sizeof(init_buf)); 1242 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, test, 0, 0, out, 0, NULL); 1243 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret); 1244 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 1245 "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n", 1246 GetLastError()); 1247 ok(!memcmp(expected_buf, out, sizeof(expected_buf)), 1248 "Expected the buffer to be untouched\n"); 1249 1250 /* Windows Server 2003 and newer report failure but copy a 1251 * truncated string to the buffer for non-zero buffer sizes. */ 1252 SetLastError(0xdeadbeef); 1253 memcpy(out, init_buf, sizeof(init_buf)); 1254 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, test, 0, 0, out, 1, NULL); 1255 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret); 1256 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 1257 "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n", 1258 GetLastError()); 1259 ok(!memcmp(expected_buf, out, sizeof(expected_buf)) || 1260 broken(!memcmp(broken_buf, out, sizeof(broken_buf))), /* W2K3+ */ 1261 "Expected the buffer to be untouched\n"); 1262 1263 SetLastError(0xdeadbeef); 1264 memcpy(out, init_buf, sizeof(init_buf)); 1265 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, test, 0, 0, out, sizeof(out)/sizeof(out[0]) - 1, NULL); 1266 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret); 1267 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 1268 "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n", 1269 GetLastError()); 1270 ok(!memcmp(expected_buf, out, sizeof(expected_buf)) || 1271 broken(!memcmp(broken2_buf, out, sizeof(broken2_buf))), /* W2K3+ */ 1272 "Expected the buffer to be untouched\n"); 1273 } 1274 1275 static void test_message_null_buffer(void) 1276 { 1277 DWORD ret, error; 1278 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); 1285 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); 1291 1292 if (0) /* crashes on Windows */ 1293 { 1294 SetLastError(0xdeadbeef); 1295 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, 0, 0, NULL, 256, NULL); 1296 } 1297 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); 1303 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); 1309 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); 1315 } 1316 1317 static void test_message_null_buffer_wide(void) 1318 { 1319 DWORD ret, error; 1320 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); 1326 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); 1332 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); 1338 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); 1344 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); 1350 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); 1356 } 1357 1358 static void test_message_allocate_buffer(void) 1359 { 1360 DWORD ret; 1361 char *buf; 1362 1363 /* While MSDN suggests that FormatMessageA allocates a buffer whose size is 1364 * the larger of the output string and the requested buffer size, the tests 1365 * will not try to determine the actual size of the buffer allocated, as 1366 * the return value of LocalSize cannot be trusted for the purpose, and it should 1367 * in any case be safe for FormatMessageA to allocate in the manner that 1368 * MSDN suggests. */ 1369 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()); 1378 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) 1386 { 1387 ok(!strcmp("test", buf), 1388 "Expected buffer to contain \"test\", got %s\n", buf); 1389 LocalFree(buf); 1390 } 1391 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) 1399 { 1400 ok(!strcmp("test", buf), 1401 "Expected buffer to contain \"test\", got %s\n", buf); 1402 LocalFree(buf); 1403 } 1404 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) 1412 { 1413 ok(!strcmp("test", buf), 1414 "Expected buffer to contain \"test\", got %s\n", buf); 1415 LocalFree(buf); 1416 } 1417 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) 1425 { 1426 ok(!strcmp("test", buf), 1427 "Expected buffer to contain \"test\", got %s\n", buf); 1428 LocalFree(buf); 1429 } 1430 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) 1438 { 1439 ok(!strcmp("test", buf), 1440 "Expected buffer to contain \"test\", got %s\n", buf); 1441 LocalFree(buf); 1442 } 1443 } 1444 1445 static void test_message_allocate_buffer_wide(void) 1446 { 1447 static const WCHAR empty[] = {0}; 1448 static const WCHAR test[] = {'t','e','s','t',0}; 1449 1450 DWORD ret; 1451 WCHAR *buf; 1452 1453 /* While MSDN suggests that FormatMessageW allocates a buffer whose size is 1454 * the larger of the output string and the requested buffer size, the tests 1455 * will not try to determine the actual size of the buffer allocated, as 1456 * the return value of LocalSize cannot be trusted for the purpose, and it should 1457 * in any case be safe for FormatMessageW to allocate in the manner that 1458 * MSDN suggests. */ 1459 1460 if (0) /* crashes on Windows */ 1461 { 1462 buf = (WCHAR *)0xdeadbeef; 1463 FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER, 1464 NULL, 0, 0, (WCHAR *)&buf, 0, NULL); 1465 } 1466 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()); 1475 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) 1483 { 1484 ok(!lstrcmpW(test, buf), 1485 "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf)); 1486 LocalFree(buf); 1487 } 1488 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) 1496 { 1497 ok(!lstrcmpW(test, buf), 1498 "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf)); 1499 LocalFree(buf); 1500 } 1501 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) 1509 { 1510 ok(!lstrcmpW(test, buf), 1511 "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf)); 1512 LocalFree(buf); 1513 } 1514 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) 1522 { 1523 ok(!lstrcmpW(test, buf), 1524 "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf)); 1525 LocalFree(buf); 1526 } 1527 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) 1535 { 1536 ok(!lstrcmpW(test, buf), 1537 "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf)); 1538 LocalFree(buf); 1539 } 1540 } 1541 1542 static void test_message_from_hmodule(void) 1543 { 1544 DWORD ret, error; 1545 HMODULE h; 1546 CHAR out[0x100] = {0}; 1547 1548 h = GetModuleHandleA("kernel32.dll"); 1549 ok(h != 0, "GetModuleHandle failed\n"); 1550 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"); 1556 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"); 1561 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"); 1565 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"); 1570 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"); 1575 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); 1583 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); 1590 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); 1597 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); 1608 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); 1619 } 1620 1621 static void test_message_invalid_flags(void) 1622 { 1623 static const char init_buf[] = {'x', 'x', 'x', 'x', 'x'}; 1624 1625 DWORD ret; 1626 CHAR out[5]; 1627 char *ptr; 1628 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", 1637 GetLastError()); 1638 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", 1646 GetLastError()); 1647 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", 1656 GetLastError()); 1657 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", 1666 GetLastError()); 1667 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", 1676 GetLastError()); 1677 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. */ 1681 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"); 1688 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"); 1695 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"); 1703 } 1704 1705 static void test_message_invalid_flags_wide(void) 1706 { 1707 static const WCHAR init_buf[] = {'x', 'x', 'x', 'x', 'x'}; 1708 static const WCHAR test[] = {'t','e','s','t',0}; 1709 1710 DWORD ret; 1711 WCHAR out[5]; 1712 WCHAR *ptr; 1713 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", 1722 GetLastError()); 1723 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", 1731 GetLastError()); 1732 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", 1741 GetLastError()); 1742 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", 1751 GetLastError()); 1752 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", 1761 GetLastError()); 1762 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. */ 1766 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"); 1773 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"); 1780 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"); 1788 } 1789 1790 static void test_message_from_64bit_number(void) 1791 { 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]; 1795 char outA[0x100]; 1796 DWORD r; 1797 static const struct 1798 { 1799 UINT64 number; 1800 const char expected[32]; 1801 int len; 1802 } unsigned_tests[] = 1803 { 1804 { 0, "0", 1 }, 1805 { 1234567890, "1234567890", 10}, 1806 { ULL(0xFFFFFFFF,0xFFFFFFFF), "18446744073709551615", 20 }, 1807 { ULL(0x7FFFFFFF,0xFFFFFFFF), "9223372036854775807", 19 }, 1808 }; 1809 static const struct 1810 { 1811 INT64 number; 1812 const char expected[32]; 1813 int len; 1814 } signed_tests[] = 1815 { 1816 { 0, "0" , 1}, 1817 { 1234567890, "1234567890", 10 }, 1818 { -1, "-1", 2}, 1819 { ULL(0xFFFFFFFF,0xFFFFFFFF), "-1", 2}, 1820 { ULL(0x7FFFFFFF,0xFFFFFFFF), "9223372036854775807", 19 }, 1821 { -ULL(0x7FFFFFFF,0xFFFFFFFF), "-9223372036854775807", 20}, 1822 }; 1823 int i; 1824 1825 for (i = 0; i < sizeof(unsigned_tests) / sizeof(unsigned_tests[0]); i++) 1826 { 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)); 1830 todo_wine { 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); 1834 } 1835 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!I64u!", 1836 0, 0, outA, sizeof(outA), unsigned_tests[i].number); 1837 todo_wine { 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); 1841 } 1842 } 1843 1844 for (i = 0; i < sizeof(signed_tests) / sizeof(signed_tests[0]); i++) 1845 { 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)); 1849 todo_wine { 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); 1853 } 1854 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!I64d!", 1855 0, 0, outA, sizeof(outA), signed_tests[i].number); 1856 todo_wine { 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); 1860 } 1861 } 1862 } 1863 1864 START_TEST(format_msg) 1865 { 1866 DWORD ret; 1867 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(); 1876 1877 SetLastError(0xdeadbeef); 1878 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, NULL, 0, 0, NULL, 0, NULL); 1879 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) 1880 { 1881 win_skip("FormatMessageW is not implemented\n"); 1882 return; 1883 } 1884 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(); 1892 } 1893