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 "precomp.h" 21 22 #define ULL(a,b) (((ULONG64)(a) << 32) | (b)) 23 24 static DWORD __cdecl doit(DWORD flags, LPCVOID src, DWORD msg_id, DWORD lang_id, 25 LPSTR out, DWORD outsize, ... ) 26 { 27 __ms_va_list list; 28 DWORD r; 29 30 __ms_va_start(list, outsize); 31 r = FormatMessageA(flags, src, msg_id, 32 lang_id, out, outsize, &list); 33 __ms_va_end(list); 34 return r; 35 } 36 37 static DWORD __cdecl doitW(DWORD flags, LPCVOID src, DWORD msg_id, DWORD lang_id, 38 LPWSTR out, DWORD outsize, ... ) 39 { 40 __ms_va_list list; 41 DWORD r; 42 43 __ms_va_start(list, outsize); 44 r = FormatMessageW(flags, src, msg_id, 45 lang_id, out, outsize, &list); 46 __ms_va_end(list); 47 return r; 48 } 49 50 static void test_message_from_string_wide(void) 51 { 52 static const WCHAR test[] = {'t','e','s','t',0}; 53 static const WCHAR empty[] = {0}; 54 static const WCHAR te[] = {'t','e',0}; 55 static const WCHAR st[] = {'s','t',0}; 56 static const WCHAR t[] = {'t',0}; 57 static const WCHAR e[] = {'e',0}; 58 static const WCHAR s[] = {'s',0}; 59 static const WCHAR fmt_null[] = {'%',0}; 60 static const WCHAR fmt_tnull[] = {'t','e','s','t','%',0}; 61 static const WCHAR fmt_1[] = {'%','1',0}; 62 static const WCHAR fmt_12[] = {'%','1','%','2',0}; 63 static const WCHAR fmt_123[] = {'%','1','%','3','%','2','%','1',0}; 64 static const WCHAR fmt_123c[] = {'%','1','!','c','!','%','2','!','c','!','%','3','!','c','!','%','1','!','c','!',0}; 65 static const WCHAR fmt_123lc[] = {'%','1','!','l','c','!','%','2','!','l','c','!','%','3','!','l','c','!','%','1','!','l','c','!',0}; 66 static const WCHAR fmt_123wc[] = {'%','1','!','w','c','!','%','2','!','w','c','!','%','3','!','w','c','!','%','1','!','w','c','!',0}; 67 static const WCHAR fmt_123C[] = {'%','1','!','C','!','%','2','!','C','!','%','3','!','C','!','%','1','!','C','!',0}; 68 static const WCHAR fmt_123d[] = {'%','1','!','d','!','%','2','!','d','!','%','3','!','d','!',0}; 69 static const WCHAR fmt_1s[] = {'%','1','!','s','!',0}; 70 static const WCHAR fmt_s[] = {'%','!','s','!',0}; 71 static const WCHAR fmt_ls[] = {'%','!','l','s','!',0}; 72 static const WCHAR fmt_ws[] = {'%','!','w','s','!',0}; 73 static const WCHAR fmt_S[] = {'%','!','S','!',0}; 74 static const WCHAR fmt_14d[] = {'%','1','!','4','d','!',0}; 75 static const WCHAR fmt_14x[] = {'%','1','!','4','x','!',0}; 76 static const WCHAR fmt_14X[] = {'%','1','!','4','X','!',0}; 77 static const WCHAR fmt_1_4X[] = {'%','1','!','-','4','X','!',0}; 78 static const WCHAR fmt_1_4d[] = {'%','1','!','-','4','d','!',0}; 79 static const WCHAR fmt_2pct[] = {' ','%','%','%','%',' ',0}; 80 static const WCHAR fmt_2dot1d[] = {' ', '%','.','%','.',' ',' ','%','1','!','d','!',0}; 81 static const WCHAR fmt_t0t[] = {'t','e','s','t','%','0','t','e','s','t',0}; 82 static const WCHAR fmt_yah[] = {'y','a','h','%','!','%','0',' ',' ',' ',0}; 83 static const WCHAR fmt_space[] = {'%',' ','%',' ',' ',' ',0}; 84 static const WCHAR fmt_nrt[] = {'%','n','%','r','%','t',0}; 85 static const WCHAR fmt_hi_lf[] = {'h','i','\n',0}; 86 static const WCHAR fmt_hi_crlf[] = {'h','i','\r','\n',0}; 87 static const WCHAR fmt_cr[] = {'\r',0}; 88 static const WCHAR fmt_crcrlf[] = {'\r','\r','\n',0}; 89 static const WCHAR fmt_13s[] = {'%','1','!','3','s','!',0}; 90 static const WCHAR fmt_1os[] = {'%','1','!','*','s','!',0}; 91 static const WCHAR fmt_142u[] = {'%','1','!','4','.','2','u','!',0}; 92 static const WCHAR fmt_1oou[] = {'%','1','!','*','.','*','u','!',0}; 93 static const WCHAR fmt_1oou1oou[] = {'%','1','!','*','.','*','u','!',',','%','1','!','*','.','*','u','!',0}; 94 static const WCHAR fmt_1oou3oou[] = {'%','1','!','*','.','*','u','!',',','%','3','!','*','.','*','u','!',0}; 95 static const WCHAR fmt_1oou4oou[] = {'%','1','!','*','.','*','u','!',',','%','4','!','*','.','*','u','!',0}; 96 97 static const WCHAR s_123d[] = {'1','2','3',0}; 98 static const WCHAR s_14d[] = {' ',' ',' ','1',0}; 99 static const WCHAR s_14x[] = {' ',' ',' ','b',0}; 100 static const WCHAR s_14X[] = {' ',' ',' ','B',0}; 101 static const WCHAR s_1_4X[] = {'B',' ',' ',' ',0}; 102 static const WCHAR s_14d2[] = {' ',' ','1','1',0}; 103 static const WCHAR s_1_4d[] = {'1',' ',' ',' ',0}; 104 static const WCHAR s_1AB[] = {' ','1','A','B',0}; 105 static const WCHAR s_2pct[] = {' ','%','%',' ',0}; 106 static const WCHAR s_2dot147[] = {' ','.','.',' ',' ','4','2','7',0}; 107 static const WCHAR s_yah[] = {'y','a','h','!',0}; 108 static const WCHAR s_space[] = {' ',' ',' ',' ',0}; 109 static const WCHAR s_nrt[] = {'\r','\n','\r','\t',0}; 110 static const WCHAR s_hi_crlf[] = {'h','i','\r','\n',0}; 111 static const WCHAR s_crlf[] = {'\r','\n',0}; 112 static const WCHAR s_crlfcrlf[] = {'\r','\n','\r','\n',0}; 113 static const WCHAR s_hi_sp[] = {'h','i',' ',0}; 114 static const WCHAR s_sp[] = {' ',0}; 115 static const WCHAR s_2sp[] = {' ',' ',0}; 116 static const WCHAR s_spt[] = {' ',' ','t',0}; 117 static const WCHAR s_sp3t[] = {' ',' ',' ','t',0}; 118 static const WCHAR s_sp03[] = {' ',' ','0','3',0}; 119 static const WCHAR s_sp001[] = {' ',' ','0','0','1',0}; 120 static const WCHAR s_sp001002[] = {' ',' ','0','0','1',',',' ','0','0','0','2',0}; 121 static const WCHAR s_sp001sp002[] = {' ',' ','0','0','1',',',' ',' ','0','0','0','2',0}; 122 static const WCHAR s_sp002sp001[] = {' ',' ','0','0','0','2',',',' ',' ','0','0','1',0}; 123 static const WCHAR s_sp002sp003[] = {' ',' ','0','0','0','2',',',' ','0','0','0','0','3',0}; 124 static const WCHAR s_sp001004[] = {' ',' ','0','0','1',',','0','0','0','0','0','4',0}; 125 static const WCHAR s_null[] = {'(','n','u','l','l',')',0}; 126 127 static const WCHAR init_buf[] = {'x', 'x', 'x', 'x', 'x', 'x'}; 128 static const WCHAR broken_buf[] = {'t','e','s','t','x','x'}; 129 130 WCHAR out[0x100] = {0}; 131 DWORD r, error; 132 133 /* the basics */ 134 r = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, test, 0, 135 0, out, sizeof(out)/sizeof(WCHAR), NULL); 136 ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out)); 137 ok(r==4, "failed: r=%d\n", r); 138 139 /* null string, crashes on Windows */ 140 if (0) 141 { 142 SetLastError(0xdeadbeef); 143 memcpy(out, init_buf, sizeof(init_buf)); 144 FormatMessageW(FORMAT_MESSAGE_FROM_STRING, NULL, 0, 145 0, out, sizeof(out)/sizeof(WCHAR), NULL); 146 } 147 148 /* empty string */ 149 SetLastError(0xdeadbeef); 150 memcpy(out, init_buf, sizeof(init_buf)); 151 r = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, empty, 0, 152 0, out, sizeof(out)/sizeof(WCHAR), NULL); 153 error = GetLastError(); 154 ok(!lstrcmpW(empty, out), "failed out=%s\n", wine_dbgstr_w(out)); 155 ok(r==0, "succeeded: r=%d\n", r); 156 ok(error==0xdeadbeef, "last error %u\n", error); 157 158 /* format placeholder with no specifier */ 159 SetLastError(0xdeadbeef); 160 memcpy(out, init_buf, sizeof(init_buf)); 161 r = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, fmt_null, 0, 162 0, out, sizeof(out)/sizeof(WCHAR), NULL); 163 error = GetLastError(); 164 ok(!memcmp(out, init_buf, sizeof(init_buf)), 165 "Expected the buffer to be unchanged\n"); 166 ok(r==0, "succeeded: r=%d\n", r); 167 ok(error==ERROR_INVALID_PARAMETER, "last error %u\n", error); 168 169 /* test string with format placeholder with no specifier */ 170 SetLastError(0xdeadbeef); 171 memcpy(out, init_buf, sizeof(init_buf)); 172 r = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, fmt_tnull, 0, 173 0, out, sizeof(out)/sizeof(WCHAR), 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); 180 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, 185 0, out, sizeof(out)/sizeof(WCHAR), NULL); 186 error = GetLastError(); 187 ok(!memcmp(out, init_buf, sizeof(init_buf)), 188 "Expected the buffer to be unchanged\n"); 189 ok(r==0, "succeeded: r=%d\n", r); 190 ok(error==ERROR_INVALID_PARAMETER, "last error %u\n", error); 191 192 SetLastError(0xdeadbeef); 193 memcpy(out, init_buf, sizeof(init_buf)); 194 r = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, fmt_1, 0, 195 0, out, sizeof(out)/sizeof(WCHAR), NULL); 196 error = GetLastError(); 197 ok(!memcmp(out, init_buf, sizeof(init_buf)), 198 "Expected the buffer to be unchanged\n"); 199 ok(r==0, "succeeded: r=%d\n", r); 200 ok(error==ERROR_INVALID_PARAMETER, "last error %u\n", error); 201 202 /* using the format feature */ 203 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1s, 0, 204 0, out, sizeof(out)/sizeof(WCHAR), test); 205 ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out)); 206 ok(r==4,"failed: r=%d\n", r); 207 208 /* no format */ 209 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1, 0, 210 0, out, sizeof(out)/sizeof(WCHAR), test); 211 ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out)); 212 ok(r==4,"failed: r=%d\n", r); 213 214 /* two pieces */ 215 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_12, 0, 216 0, out, sizeof(out)/sizeof(WCHAR), te, st); 217 ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out)); 218 ok(r==4,"failed: r=%d\n", r); 219 220 /* three pieces */ 221 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_123, 0, 222 0, out, sizeof(out)/sizeof(WCHAR), t, s, e); 223 ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out)); 224 ok(r==4,"failed: r=%d\n", r); 225 226 /* s doesn't seem to work in format strings */ 227 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_s, 0, 228 0, out, sizeof(out)/sizeof(WCHAR), test); 229 ok(!lstrcmpW(&fmt_s[1], out), "failed out=%s\n", wine_dbgstr_w(out)); 230 ok(r==3, "failed: r=%d\n", r); 231 232 /* nor ls */ 233 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_ls, 0, 234 0, out, sizeof(out)/sizeof(WCHAR), test); 235 ok(!lstrcmpW(&fmt_ls[1], out), "failed out=%s\n", wine_dbgstr_w(out)); 236 ok(r==4, "failed: r=%d\n", r); 237 238 /* nor S */ 239 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_S, 0, 240 0, out, sizeof(out)/sizeof(WCHAR), test); 241 ok(!lstrcmpW(&fmt_S[1], out), "failed out=%s\n", wine_dbgstr_w(out)); 242 ok(r==3, "failed: r=%d\n", r); 243 244 /* nor ws */ 245 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_ws, 0, 246 0, out, sizeof(out)/sizeof(WCHAR), test); 247 ok(!lstrcmpW(&fmt_ws[1], out), "failed out=%s\n", wine_dbgstr_w(out)); 248 ok(r==4, "failed: r=%d\n", r); 249 250 /* as characters */ 251 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_123c, 0, 252 0, out, sizeof(out)/sizeof(WCHAR), '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); 255 256 /* lc is unicode */ 257 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_123lc, 0, 258 0, out, sizeof(out)/sizeof(WCHAR), 't', 'e', 's'); 259 ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out)); 260 ok(r==4,"failed: r=%d\n", r); 261 262 /* wc is unicode */ 263 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_123wc, 0, 264 0, out, sizeof(out)/sizeof(WCHAR), 't', 'e', 's'); 265 ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out)); 266 ok(r==4,"failed: r=%d\n", r); 267 268 /* C is unicode */ 269 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_123C, 0, 270 0, out, sizeof(out)/sizeof(WCHAR), 't', 'e', 's'); 271 ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out)); 272 ok(r==4,"failed: r=%d\n", r); 273 274 /* some numbers */ 275 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_123d, 0, 276 0, out, sizeof(out)/sizeof(WCHAR), 1, 2, 3); 277 ok(!lstrcmpW(s_123d, out), "failed out=%s\n", wine_dbgstr_w(out)); 278 ok(r==3,"failed: r=%d\n", r); 279 280 /* a single digit with some spacing */ 281 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_14d, 0, 282 0, out, sizeof(out)/sizeof(WCHAR), 1); 283 ok(!lstrcmpW(s_14d, out), "failed out=%s\n", wine_dbgstr_w(out)); 284 ok(r==4,"failed: r=%d\n", r); 285 286 /* a single digit, left justified */ 287 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1_4d, 0, 288 0, out, sizeof(out)/sizeof(CHAR), 1); 289 ok(!lstrcmpW(s_1_4d, out), "failed out=%s\n", wine_dbgstr_w(out)); 290 ok(r==4,"failed: r=%d\n", r); 291 292 /* two digit decimal number */ 293 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_14d, 0, 294 0, out, sizeof(out)/sizeof(WCHAR), 11); 295 ok(!lstrcmpW(s_14d2, out), "failed out=%s\n", wine_dbgstr_w(out)); 296 ok(r==4,"failed: r=%d\n", r); 297 298 /* a hex number */ 299 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_14x, 0, 300 0, out, sizeof(out)/sizeof(WCHAR), 11); 301 ok(!lstrcmpW(s_14x, out), "failed out=%s\n", wine_dbgstr_w(out)); 302 ok(r==4,"failed: r=%d\n", r); 303 304 /* a hex number, upper case */ 305 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_14X, 0, 306 0, out, sizeof(out)/sizeof(WCHAR), 11); 307 ok(!lstrcmpW(s_14X, out), "failed out=%s\n", wine_dbgstr_w(out)); 308 ok(r==4,"failed: r=%d\n", r); 309 310 /* a hex number, upper case, left justified */ 311 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1_4X, 0, 312 0, out, sizeof(out)/sizeof(WCHAR), 11); 313 ok(!lstrcmpW(s_1_4X, out), "failed out=%s\n", wine_dbgstr_w(out)); 314 ok(r==4,"failed: r=%d\n", r); 315 316 /* a long hex number, upper case */ 317 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_14X, 0, 318 0, out, sizeof(out)/sizeof(WCHAR), 0x1ab); 319 ok(!lstrcmpW(s_1AB, out), "failed out=%s\n", wine_dbgstr_w(out)); 320 ok(r==4,"failed: r=%d\n", r); 321 322 /* two percent... */ 323 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_2pct, 0, 324 0, out, sizeof(out)/sizeof(WCHAR)); 325 ok(!lstrcmpW(s_2pct, out), "failed out=%s\n", wine_dbgstr_w(out)); 326 ok(r==4,"failed: r=%d\n", r); 327 328 /* periods are special cases */ 329 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_2dot1d, 0, 330 0, out, sizeof(out)/sizeof(WCHAR), 0x1ab); 331 ok(!lstrcmpW(s_2dot147, out), "failed out=%s\n", wine_dbgstr_w(out)); 332 ok(r==8,"failed: r=%d\n", r); 333 334 /* %0 ends the line */ 335 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_t0t, 0, 336 0, out, sizeof(out)/sizeof(WCHAR)); 337 ok(!lstrcmpW(test, out), "failed out=%s\n", wine_dbgstr_w(out)); 338 ok(r==4,"failed: r=%d\n", r); 339 340 /* %! prints an exclamation */ 341 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_yah, 0, 342 0, out, sizeof(out)/sizeof(WCHAR)); 343 ok(!lstrcmpW(s_yah, out), "failed out=%s\n", wine_dbgstr_w(out)); 344 ok(r==4,"failed: r=%d\n", r); 345 346 /* %space */ 347 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_space, 0, 348 0, out, sizeof(out)/sizeof(WCHAR)); 349 ok(!lstrcmpW(s_space, out), "failed out=%s\n", wine_dbgstr_w(out)); 350 ok(r==4,"failed: r=%d\n", r); 351 352 /* %n yields \r\n, %r yields \r, %t yields \t */ 353 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_nrt, 0, 354 0, out, sizeof(out)/sizeof(WCHAR)); 355 ok(!lstrcmpW(s_nrt, out), "failed out=%s\n", wine_dbgstr_w(out)); 356 ok(r==4,"failed: r=%d\n", r); 357 358 /* line feed */ 359 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_hi_lf, 0, 360 0, out, sizeof(out)/sizeof(WCHAR)); 361 ok(!lstrcmpW(s_hi_crlf, out), "failed out=%s\n", wine_dbgstr_w(out)); 362 ok(r==4,"failed: r=%d\n", r); 363 364 /* carriage return line feed */ 365 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_hi_crlf, 0, 366 0, out, sizeof(out)/sizeof(WCHAR)); 367 ok(!lstrcmpW(s_hi_crlf, out), "failed out=%s\n", wine_dbgstr_w(out)); 368 ok(r==4,"failed: r=%d\n", r); 369 370 /* carriage return */ 371 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_cr, 0, 372 0, out, sizeof(out)/sizeof(WCHAR)); 373 ok(!lstrcmpW(s_crlf, out), "failed out=%s\n", wine_dbgstr_w(out)); 374 ok(r==2,"failed: r=%d\n", r); 375 376 /* double carriage return line feed */ 377 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_crcrlf, 0, 378 0, out, sizeof(out)/sizeof(WCHAR)); 379 ok(!lstrcmpW(s_crlfcrlf, out), "failed out=%s\n", wine_dbgstr_w(out)); 380 ok(r==4,"failed: r=%d\n", r); 381 382 /* null string as argument */ 383 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1, 0, 384 0, out, sizeof(out)/sizeof(WCHAR), NULL); 385 ok(!lstrcmpW(s_null, out),"failed out=[%s]\n", wine_dbgstr_w(out)); 386 ok(r==6,"failed: r=%d\n",r); 387 388 /* precision and width */ 389 390 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_13s, 391 0, 0, out, sizeof(out)/sizeof(WCHAR), t ); 392 ok(!lstrcmpW(s_spt, out),"failed out=[%s]\n", wine_dbgstr_w(out)); 393 ok(r==3, "failed: r=%d\n",r); 394 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1os, 395 0, 0, out, sizeof(out)/sizeof(WCHAR), 4, t ); 396 ok(!lstrcmpW( s_sp3t, out),"failed out=[%s]\n", wine_dbgstr_w(out)); 397 ok(r==4,"failed: r=%d\n",r); 398 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_142u, 399 0, 0, out, sizeof(out)/sizeof(WCHAR), 3 ); 400 ok(!lstrcmpW( s_sp03, out),"failed out=[%s]\n", wine_dbgstr_w(out)); 401 ok(r==4,"failed: r=%d\n",r); 402 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1oou, 403 0, 0, out, sizeof(out)/sizeof(WCHAR), 5, 3, 1 ); 404 ok(!lstrcmpW( s_sp001, out),"failed out=[%s]\n", wine_dbgstr_w(out)); 405 ok(r==5,"failed: r=%d\n",r); 406 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1oou1oou, 407 0, 0, out, sizeof(out)/sizeof(WCHAR), 5, 3, 1, 4, 2 ); 408 ok(!lstrcmpW( s_sp001002, out),"failed out=[%s]\n", wine_dbgstr_w(out)); 409 ok(r==11,"failed: r=%d\n",r); 410 r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1oou3oou, 411 0, 0, out, sizeof(out)/sizeof(WCHAR), 5, 3, 1, 6, 4, 2 ); 412 ok(!lstrcmpW( s_sp001sp002, out) || 413 broken(!lstrcmpW(s_sp001004, out)), /* NT4/Win2k */ 414 "failed out=[%s]\n", wine_dbgstr_w(out)); 415 ok(r==12,"failed: r=%d\n",r); 416 /* args are not counted the same way with an argument array */ 417 { 418 ULONG_PTR args[] = { 6, 4, 2, 5, 3, 1 }; 419 r = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, fmt_1oou1oou, 420 0, 0, out, sizeof(out)/sizeof(WCHAR), (__ms_va_list *)args ); 421 ok(!lstrcmpW(s_sp002sp003, out),"failed out=[%s]\n", wine_dbgstr_w(out)); 422 ok(r==13,"failed: r=%d\n",r); 423 r = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, fmt_1oou4oou, 424 0, 0, out, sizeof(out)/sizeof(WCHAR), (__ms_va_list *)args ); 425 ok(!lstrcmpW(s_sp002sp001, out),"failed out=[%s]\n", wine_dbgstr_w(out)); 426 ok(r==12,"failed: r=%d\n",r); 427 } 428 429 /* change of pace... test the low byte of dwflags */ 430 431 /* line feed */ 432 r = doitW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, fmt_hi_lf, 0, 433 0, out, sizeof(out)/sizeof(WCHAR)); 434 ok(!lstrcmpW(s_hi_sp, out), "failed out=%s\n", wine_dbgstr_w(out)); 435 ok(r==3,"failed: r=%d\n", r); 436 437 /* carriage return line feed */ 438 r = doitW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, fmt_hi_crlf, 0, 439 0, out, sizeof(out)/sizeof(WCHAR)); 440 ok(!lstrcmpW(s_hi_sp, out), "failed out=%s\n", wine_dbgstr_w(out)); 441 ok(r==3,"failed: r=%d\n", r); 442 443 /* carriage return */ 444 r = doitW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, fmt_cr, 0, 445 0, out, sizeof(out)/sizeof(WCHAR)); 446 ok(!lstrcmpW(s_sp, out), "failed out=%s\n", wine_dbgstr_w(out)); 447 ok(r==1,"failed: r=%d\n", r); 448 449 /* double carriage return line feed */ 450 r = doitW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, fmt_crcrlf, 0, 451 0, out, sizeof(out)/sizeof(WCHAR)); 452 ok(!lstrcmpW(s_2sp, out), "failed out=%s\n", wine_dbgstr_w(out)); 453 ok(r==2,"failed: r=%d\n", r); 454 } 455 456 static void test_message_from_string(void) 457 { 458 CHAR out[0x100] = {0}; 459 DWORD r; 460 static const char init_buf[] = {'x', 'x', 'x', 'x', 'x', 'x'}; 461 static const WCHAR szwTest[] = { 't','e','s','t',0}; 462 463 /* the basics */ 464 r = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, "test", 0, 465 0, out, sizeof(out)/sizeof(CHAR),NULL); 466 ok(!strcmp("test", out),"failed out=[%s]\n",out); 467 ok(r==4,"failed: r=%d\n",r); 468 469 /* null string, crashes on Windows */ 470 if (0) 471 { 472 SetLastError(0xdeadbeef); 473 memcpy(out, init_buf, sizeof(init_buf)); 474 FormatMessageA(FORMAT_MESSAGE_FROM_STRING, NULL, 0, 475 0, out, sizeof(out)/sizeof(CHAR), NULL); 476 } 477 478 /* empty string */ 479 SetLastError(0xdeadbeef); 480 memcpy(out, init_buf, sizeof(init_buf)); 481 r = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, "", 0, 482 0, out, sizeof(out)/sizeof(CHAR), NULL); 483 ok(!memcmp(out, init_buf, sizeof(init_buf)), "Expected the buffer to be untouched\n"); 484 ok(r==0, "succeeded: r=%d\n", r); 485 ok(GetLastError()==0xdeadbeef, 486 "last error %u\n", GetLastError()); 487 488 /* format placeholder with no specifier */ 489 SetLastError(0xdeadbeef); 490 memcpy(out, init_buf, sizeof(init_buf)); 491 r = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, "%", 0, 492 0, out, sizeof(out)/sizeof(CHAR), NULL); 493 ok(!memcmp(out, init_buf, sizeof(init_buf)), 494 "Expected the buffer to be untouched\n"); 495 ok(r==0, "succeeded: r=%d\n", r); 496 ok(GetLastError()==ERROR_INVALID_PARAMETER, 497 "last error %u\n", GetLastError()); 498 499 /* test string with format placeholder with no specifier */ 500 SetLastError(0xdeadbeef); 501 memcpy(out, init_buf, sizeof(init_buf)); 502 r = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, "test%", 0, 503 0, out, sizeof(out)/sizeof(CHAR), NULL); 504 ok(!memcmp(out, init_buf, sizeof(init_buf)), 505 "Expected the buffer to be untouched\n"); 506 ok(r==0, "succeeded: r=%d\n", r); 507 ok(GetLastError()==ERROR_INVALID_PARAMETER, 508 "last error %u\n", GetLastError()); 509 510 /* insertion with no variadic arguments */ 511 SetLastError(0xdeadbeef); 512 memcpy(out, init_buf, sizeof(init_buf)); 513 r = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, "%1", 0, 514 0, out, sizeof(out)/sizeof(CHAR), NULL); 515 ok(!memcmp(out, init_buf, sizeof(init_buf)), "Expected the buffer to be untouched\n"); 516 ok(r==0, "succeeded: r=%d\n", r); 517 ok(GetLastError()==ERROR_INVALID_PARAMETER, "last error %u\n", GetLastError()); 518 519 SetLastError(0xdeadbeef); 520 memcpy(out, init_buf, sizeof(init_buf)); 521 r = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, "%1", 0, 522 0, out, sizeof(out)/sizeof(CHAR), NULL); 523 ok(!memcmp(out, init_buf, sizeof(init_buf)), "Expected the buffer to be untouched\n"); 524 ok(r==0, "succeeded: r=%d\n", r); 525 ok(GetLastError()==ERROR_INVALID_PARAMETER, "last error %u\n", GetLastError()); 526 527 /* using the format feature */ 528 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!s!", 0, 529 0, out, sizeof(out)/sizeof(CHAR), "test"); 530 ok(!strcmp("test", out),"failed out=[%s]\n",out); 531 ok(r==4,"failed: r=%d\n",r); 532 533 /* no format */ 534 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1", 0, 535 0, out, sizeof(out)/sizeof(CHAR), "test"); 536 ok(!strcmp("test", out),"failed out=[%s]\n",out); 537 ok(r==4,"failed: r=%d\n",r); 538 539 /* two pieces */ 540 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1%2", 0, 541 0, out, sizeof(out)/sizeof(CHAR), "te","st"); 542 ok(!strcmp("test", out),"failed out=[%s]\n",out); 543 ok(r==4,"failed: r=%d\n",r); 544 545 /* three pieces */ 546 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1%3%2%1", 0, 547 0, out, sizeof(out)/sizeof(CHAR), "t","s","e"); 548 ok(!strcmp("test", out),"failed out=[%s]\n",out); 549 ok(r==4,"failed: r=%d\n",r); 550 551 /* s doesn't seem to work in format strings */ 552 r = doit(FORMAT_MESSAGE_FROM_STRING, "%!s!", 0, 553 0, out, sizeof(out)/sizeof(CHAR), "test"); 554 ok(!strcmp("!s!", out),"failed out=[%s]\n",out); 555 ok(r==3,"failed: r=%d\n",r); 556 557 /* ls is unicode */ 558 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!ls!", 0, 559 0, out, sizeof(out)/sizeof(CHAR), szwTest); 560 ok(!strcmp("test", out),"failed out=[%s]\n",out); 561 ok(r==4,"failed: r=%d\n",r); 562 563 /* S is unicode */ 564 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!S!", 0, 565 0, out, sizeof(out)/sizeof(CHAR), szwTest); 566 ok(!strcmp("test", out),"failed out=[%s]\n",out); 567 ok(r==4,"failed: r=%d\n",r); 568 569 /* ws is unicode */ 570 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!ws!", 0, 571 0, out, sizeof(out)/sizeof(CHAR), szwTest); 572 ok(!strcmp("test", out),"failed out=[%s]\n",out); 573 ok(r==4,"failed: r=%d\n",r); 574 575 /* as characters */ 576 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!c!%2!c!%3!c!%1!c!", 0, 577 0, out, sizeof(out)/sizeof(CHAR), 't','e','s'); 578 ok(!strcmp("test", out),"failed out=[%s]\n",out); 579 ok(r==4,"failed: r=%d\n",r); 580 581 /* lc is unicode */ 582 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!lc!%2!lc!%3!lc!%1!lc!", 0, 583 0, out, sizeof(out)/sizeof(CHAR), 't','e','s'); 584 ok(!strcmp("test", out),"failed out=[%s]\n",out); 585 ok(r==4,"failed: r=%d\n",r); 586 587 /* wc is unicode */ 588 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!wc!%2!wc!%3!wc!%1!wc!", 0, 589 0, out, sizeof(out)/sizeof(CHAR), 't','e','s'); 590 ok(!strcmp("test", out),"failed out=[%s]\n",out); 591 ok(r==4,"failed: r=%d\n",r); 592 593 /* C is unicode */ 594 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!C!%2!C!%3!C!%1!C!", 0, 595 0, out, sizeof(out)/sizeof(CHAR), 't','e','s'); 596 ok(!strcmp("test", out),"failed out=[%s]\n",out); 597 ok(r==4,"failed: r=%d\n",r); 598 599 /* some numbers */ 600 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!d!%2!d!%3!d!", 0, 601 0, out, sizeof(out)/sizeof(CHAR), 1,2,3); 602 ok(!strcmp("123", out),"failed out=[%s]\n",out); 603 ok(r==3,"failed: r=%d\n",r); 604 605 /* a single digit with some spacing */ 606 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!4d!", 0, 607 0, out, sizeof(out)/sizeof(CHAR), 1); 608 ok(!strcmp(" 1", out),"failed out=[%s]\n",out); 609 ok(r==4,"failed: r=%d\n",r); 610 611 /* a single digit, left justified */ 612 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!-4d!", 0, 613 0, out, sizeof(out)/sizeof(CHAR), 1); 614 ok(!strcmp("1 ", out),"failed out=[%s]\n",out); 615 ok(r==4,"failed: r=%d\n",r); 616 617 /* two digit decimal number */ 618 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!4d!", 0, 619 0, out, sizeof(out)/sizeof(CHAR), 11); 620 ok(!strcmp(" 11", out),"failed out=[%s]\n",out); 621 ok(r==4,"failed: r=%d\n",r); 622 623 /* a hex number */ 624 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!4x!", 0, 625 0, out, sizeof(out)/sizeof(CHAR), 11); 626 ok(!strcmp(" b", out),"failed out=[%s]\n",out); 627 ok(r==4,"failed: r=%d\n",r); 628 629 /* a hex number, upper case */ 630 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!4X!", 0, 631 0, out, sizeof(out)/sizeof(CHAR), 11); 632 ok(!strcmp(" B", out),"failed out=[%s]\n",out); 633 ok(r==4,"failed: r=%d\n",r); 634 635 /* a hex number, upper case, left justified */ 636 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!-4X!", 0, 637 0, out, sizeof(out)/sizeof(CHAR), 11); 638 ok(!strcmp("B ", out),"failed out=[%s]\n",out); 639 ok(r==4,"failed: r=%d\n",r); 640 641 /* a long hex number, upper case */ 642 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!4X!", 0, 643 0, out, sizeof(out)/sizeof(CHAR), 0x1ab); 644 ok(!strcmp(" 1AB", out),"failed out=[%s]\n",out); 645 ok(r==4,"failed: r=%d\n",r); 646 647 /* two percent... */ 648 r = doit(FORMAT_MESSAGE_FROM_STRING, " %%%% ", 0, 649 0, out, sizeof(out)/sizeof(CHAR)); 650 ok(!strcmp(" %% ", out),"failed out=[%s]\n",out); 651 ok(r==4,"failed: r=%d\n",r); 652 653 /* periods are special cases */ 654 r = doit(FORMAT_MESSAGE_FROM_STRING, " %.%. %1!d!", 0, 655 0, out, sizeof(out)/sizeof(CHAR), 0x1ab); 656 ok(!strcmp(" .. 427", out),"failed out=[%s]\n",out); 657 ok(r==7,"failed: r=%d\n",r); 658 659 /* %0 ends the line */ 660 r = doit(FORMAT_MESSAGE_FROM_STRING, "test%0test", 0, 661 0, out, sizeof(out)/sizeof(CHAR)); 662 ok(!strcmp("test", out),"failed out=[%s]\n",out); 663 ok(r==4,"failed: r=%d\n",r); 664 665 /* %! prints an exclamation */ 666 r = doit(FORMAT_MESSAGE_FROM_STRING, "yah%!%0 ", 0, 667 0, out, sizeof(out)/sizeof(CHAR)); 668 ok(!strcmp("yah!", out),"failed out=[%s]\n",out); 669 ok(r==4,"failed: r=%d\n",r); 670 671 /* %space */ 672 r = doit(FORMAT_MESSAGE_FROM_STRING, "% % ", 0, 673 0, out, sizeof(out)/sizeof(CHAR)); 674 ok(!strcmp(" ", out),"failed out=[%s]\n",out); 675 ok(r==4,"failed: r=%d\n",r); 676 677 /* %n yields \r\n, %r yields \r, %t yields \t */ 678 r = doit(FORMAT_MESSAGE_FROM_STRING, "%n%r%t", 0, 679 0, out, sizeof(out)/sizeof(CHAR)); 680 ok(!strcmp("\r\n\r\t", out),"failed out=[%s]\n",out); 681 ok(r==4,"failed: r=%d\n",r); 682 683 /* line feed */ 684 r = doit(FORMAT_MESSAGE_FROM_STRING, "hi\n", 0, 685 0, out, sizeof(out)/sizeof(CHAR)); 686 ok(!strcmp("hi\r\n", out),"failed out=[%s]\n",out); 687 ok(r==4,"failed: r=%d\n",r); 688 689 /* carriage return line feed */ 690 r = doit(FORMAT_MESSAGE_FROM_STRING, "hi\r\n", 0, 691 0, out, sizeof(out)/sizeof(CHAR)); 692 ok(!strcmp("hi\r\n", out),"failed out=[%s]\n",out); 693 ok(r==4,"failed: r=%d\n",r); 694 695 /* carriage return */ 696 r = doit(FORMAT_MESSAGE_FROM_STRING, "\r", 0, 697 0, out, sizeof(out)/sizeof(CHAR)); 698 ok(!strcmp("\r\n", out),"failed out=[%s]\n",out); 699 ok(r==2,"failed: r=%d\n",r); 700 701 /* double carriage return line feed */ 702 r = doit(FORMAT_MESSAGE_FROM_STRING, "\r\r\n", 0, 703 0, out, sizeof(out)/sizeof(CHAR)); 704 ok(!strcmp("\r\n\r\n", out),"failed out=[%s]\n",out); 705 ok(r==4,"failed: r=%d\n",r); 706 707 /* null string as argument */ 708 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1", 0, 709 0, out, sizeof(out)/sizeof(CHAR), NULL); 710 ok(!strcmp("(null)", out),"failed out=[%s]\n",out); 711 ok(r==6,"failed: r=%d\n",r); 712 713 /* precision and width */ 714 715 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!3s!", 716 0, 0, out, sizeof(out), "t" ); 717 ok(!strcmp(" t", out),"failed out=[%s]\n",out); 718 ok(r==3, "failed: r=%d\n",r); 719 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!*s!", 720 0, 0, out, sizeof(out), 4, "t"); 721 if (!strcmp("*s",out)) win_skip( "width/precision not supported\n" ); 722 else 723 { 724 ok(!strcmp( " t", out),"failed out=[%s]\n",out); 725 ok(r==4,"failed: r=%d\n",r); 726 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!4.2u!", 727 0, 0, out, sizeof(out), 3 ); 728 ok(!strcmp( " 03", out),"failed out=[%s]\n",out); 729 ok(r==4,"failed: r=%d\n",r); 730 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!*.*u!", 731 0, 0, out, sizeof(out), 5, 3, 1 ); 732 ok(!strcmp( " 001", out),"failed out=[%s]\n",out); 733 ok(r==5,"failed: r=%d\n",r); 734 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!*.*u!,%1!*.*u!", 735 0, 0, out, sizeof(out), 5, 3, 1, 4, 2 ); 736 ok(!strcmp( " 001, 0002", out),"failed out=[%s]\n",out); 737 ok(r==11,"failed: r=%d\n",r); 738 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!*.*u!,%3!*.*u!", 739 0, 0, out, sizeof(out), 5, 3, 1, 6, 4, 2 ); 740 /* older Win versions marked as broken even though this is arguably the correct behavior */ 741 /* but the new (brain-damaged) behavior is specified on MSDN */ 742 ok(!strcmp( " 001, 0002", out) || 743 broken(!strcmp(" 001,000004", out)), /* NT4/Win2k */ 744 "failed out=[%s]\n",out); 745 ok(r==12,"failed: r=%d\n",r); 746 /* args are not counted the same way with an argument array */ 747 { 748 ULONG_PTR args[] = { 6, 4, 2, 5, 3, 1 }; 749 r = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, 750 "%1!*.*u!,%1!*.*u!", 0, 0, out, sizeof(out), (__ms_va_list *)args ); 751 ok(!strcmp(" 0002, 00003", out),"failed out=[%s]\n",out); 752 ok(r==13,"failed: r=%d\n",r); 753 r = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, 754 "%1!*.*u!,%4!*.*u!", 0, 0, out, sizeof(out), (__ms_va_list *)args ); 755 ok(!strcmp(" 0002, 001", out),"failed out=[%s]\n",out); 756 ok(r==12,"failed: r=%d\n",r); 757 } 758 } 759 760 /* change of pace... test the low byte of dwflags */ 761 762 /* line feed */ 763 r = doit(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, "hi\n", 0, 764 0, out, sizeof(out)/sizeof(CHAR)); 765 ok(!strcmp("hi ", out), "failed out=[%s]\n",out); 766 ok(r==3, "failed: r=%d\n",r); 767 768 /* carriage return line feed */ 769 r = doit(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, "hi\r\n", 0, 770 0, out, sizeof(out)/sizeof(CHAR)); 771 ok(!strcmp("hi ", out),"failed out=[%s]\n",out); 772 ok(r==3,"failed: r=%d\n",r); 773 774 /* carriage return */ 775 r = doit(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, "\r", 0, 776 0, out, sizeof(out)/sizeof(CHAR)); 777 ok(!strcmp(" ", out),"failed out=[%s]\n",out); 778 ok(r==1,"failed: r=%d\n",r); 779 780 /* double carriage return line feed */ 781 r = doit(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, "\r\r\n", 0, 782 0, out, sizeof(out)/sizeof(CHAR)); 783 ok(!strcmp(" ", out),"failed out=[%s]\n",out); 784 ok(r==2,"failed: r=%d\n",r); 785 } 786 787 static void test_message_ignore_inserts(void) 788 { 789 static const char init_buf[] = {'x', 'x', 'x', 'x', 'x'}; 790 791 DWORD ret; 792 CHAR out[256]; 793 794 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, "test", 0, 0, out, 795 sizeof(out)/sizeof(CHAR), NULL); 796 ok(ret == 4, "Expected FormatMessageA to return 4, got %d\n", ret); 797 ok(!strcmp("test", out), "Expected output string \"test\", got %s\n", out); 798 799 /* The %0 escape sequence is handled. */ 800 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, "test%0", 0, 0, out, 801 sizeof(out)/sizeof(CHAR), NULL); 802 ok(ret == 4, "Expected FormatMessageA to return 4, got %d\n", ret); 803 ok(!strcmp("test", out), "Expected output string \"test\", got %s\n", out); 804 805 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, "test%0test", 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 /* While FormatMessageA returns 0 in this case, no last error code is set. */ 811 SetLastError(0xdeadbeef); 812 memcpy(out, init_buf, sizeof(init_buf)); 813 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, "%0test", 0, 0, out, 814 sizeof(out)/sizeof(CHAR), NULL); 815 ok(ret == 0, "Expected FormatMessageA to return 0, got %d\n", ret); 816 ok(!memcmp(out, init_buf, sizeof(init_buf)), "Expected the output buffer to be untouched\n"); 817 ok(GetLastError() == 0xdeadbeef, "Expected GetLastError() to return 0xdeadbeef, got %u\n", GetLastError()); 818 819 /* Insert sequences are ignored. */ 820 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, "test%1%2!*.*s!%99", 0, 0, out, 821 sizeof(out)/sizeof(CHAR), NULL); 822 ok(ret == 17, "Expected FormatMessageA to return 17, got %d\n", ret); 823 ok(!strcmp("test%1%2!*.*s!%99", out), "Expected output string \"test%%1%%2!*.*s!%%99\", got %s\n", out); 824 825 /* Only the "%n", "%r", and "%t" escape sequences are processed. */ 826 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, "%%% %.%!", 0, 0, out, 827 sizeof(out)/sizeof(CHAR), NULL); 828 ok(ret == 8, "Expected FormatMessageA to return 8, got %d\n", ret); 829 ok(!strcmp("%%% %.%!", out), "Expected output string \"%%%%%% %%.%%!\", got %s\n", out); 830 831 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, "%n%r%t", 0, 0, out, 832 sizeof(out)/sizeof(CHAR), NULL); 833 ok(ret == 4, "Expected FormatMessageA to return 4, got %d\n", ret); 834 ok(!strcmp("\r\n\r\t", out), "Expected output string \"\\r\\n\\r\\t\", got %s\n", out); 835 836 /* CRLF characters are processed normally. */ 837 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, "hi\n", 0, 0, out, 838 sizeof(out)/sizeof(CHAR), NULL); 839 ok(ret == 4, "Expected FormatMessageA to return 4, got %d\n", ret); 840 ok(!strcmp("hi\r\n", out), "Expected output string \"hi\\r\\n\", got %s\n", out); 841 842 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, "hi\r\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, "\r", 0, 0, out, 848 sizeof(out)/sizeof(CHAR), NULL); 849 ok(ret == 2, "Expected FormatMessageA to return 2, got %d\n", ret); 850 ok(!strcmp("\r\n", out), "Expected output string \"\\r\\n\", got %s\n", out); 851 852 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, "\r\r\n", 0, 0, out, 853 sizeof(out)/sizeof(CHAR), NULL); 854 ok(ret == 4, "Expected FormatMessageA to return 4, got %d\n", ret); 855 ok(!strcmp("\r\n\r\n", out), "Expected output string \"\\r\\n\\r\\n\", got %s\n", out); 856 857 /* The width parameter is handled the same also. */ 858 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS | 859 FORMAT_MESSAGE_MAX_WIDTH_MASK, "hi\n", 0, 0, out, 860 sizeof(out)/sizeof(CHAR), NULL); 861 ok(!strcmp("hi ", out), "Expected output string \"hi \", got %s\n", out); 862 ok(ret == 3, "Expected FormatMessageA to return 3, got %d\n", ret); 863 864 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS | 865 FORMAT_MESSAGE_MAX_WIDTH_MASK, "hi\r\n", 0, 0, out, 866 sizeof(out)/sizeof(CHAR), NULL); 867 ok(ret == 3, "Expected FormatMessageA to return 3, got %d\n", ret); 868 ok(!strcmp("hi ", out), "Expected output string \"hi \", got %s\n", out); 869 870 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS | 871 FORMAT_MESSAGE_MAX_WIDTH_MASK, "\r", 0, 0, out, 872 sizeof(out)/sizeof(CHAR), NULL); 873 ok(ret == 1, "Expected FormatMessageA to return 1, got %d\n", ret); 874 ok(!strcmp(" ", out), "Expected output string \" \", got %s\n", out); 875 876 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS | 877 FORMAT_MESSAGE_MAX_WIDTH_MASK, "\r\r\n", 0, 0, out, 878 sizeof(out)/sizeof(CHAR), NULL); 879 ok(ret == 2, "Expected FormatMessageA to return 2, got %d\n", ret); 880 ok(!strcmp(" ", out), "Expected output string \" \", got %s\n", out); 881 } 882 883 static void test_message_ignore_inserts_wide(void) 884 { 885 static const WCHAR test[] = {'t','e','s','t',0}; 886 static const WCHAR empty[] = {0}; 887 static const WCHAR fmt_t0[] = {'t','e','s','t','%','0',0}; 888 static const WCHAR fmt_t0t[] = {'t','e','s','t','%','0','t','e','s','t',0}; 889 static const WCHAR fmt_0t[] = {'%','0','t','e','s','t',0}; 890 static const WCHAR fmt_t12oos99[] = {'t','e','s','t','%','1','%','2','!','*','.','*','s','!','%','9','9',0}; 891 static const WCHAR fmt_pctspacedot[] = {'%','%','%',' ','%','.','%','!',0}; 892 static const WCHAR fmt_nrt[] = {'%','n','%','r','%','t',0}; 893 static const WCHAR fmt_hi_lf[] = {'h','i','\n',0}; 894 static const WCHAR fmt_hi_crlf[] = {'h','i','\r','\n',0}; 895 static const WCHAR fmt_cr[] = {'\r',0}; 896 static const WCHAR fmt_crcrlf[] = {'\r','\r','\n',0}; 897 898 static const WCHAR s_nrt[] = {'\r','\n','\r','\t',0}; 899 static const WCHAR s_hi_crlf[] = {'h','i','\r','\n',0}; 900 static const WCHAR s_crlf[] = {'\r','\n',0}; 901 static const WCHAR s_crlfcrlf[] = {'\r','\n','\r','\n',0}; 902 static const WCHAR s_hi_sp[] = {'h','i',' ',0}; 903 static const WCHAR s_sp[] = {' ',0}; 904 static const WCHAR s_2sp[] = {' ',' ',0}; 905 906 DWORD ret; 907 WCHAR out[256]; 908 909 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, test, 0, 0, out, 910 sizeof(out)/sizeof(WCHAR), NULL); 911 ok(ret == 4, "Expected FormatMessageW to return 4, got %d\n", ret); 912 ok(!lstrcmpW(test, out), "Expected output string \"test\", got %s\n", wine_dbgstr_w(out)); 913 914 /* The %0 escape sequence is handled. */ 915 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, fmt_t0, 0, 0, out, 916 sizeof(out)/sizeof(WCHAR), NULL); 917 ok(ret == 4, "Expected FormatMessageW to return 4, got %d\n", ret); 918 ok(!lstrcmpW(test, out), "Expected output string \"test\", got %s\n", wine_dbgstr_w(out)); 919 920 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, fmt_t0t, 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 /* While FormatMessageA returns 0 in this case, no last error code is set. */ 926 SetLastError(0xdeadbeef); 927 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, fmt_0t, 0, 0, out, 928 sizeof(out)/sizeof(WCHAR), NULL); 929 ok(ret == 0, "Expected FormatMessageW to return 0, got %d\n", ret); 930 ok(!lstrcmpW(empty, out), "Expected the output buffer to be the empty string, got %s\n", wine_dbgstr_w(out)); 931 ok(GetLastError() == 0xdeadbeef, "Expected GetLastError() to return 0xdeadbeef, got %u\n", GetLastError()); 932 933 /* Insert sequences are ignored. */ 934 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, fmt_t12oos99, 0, 0, out, 935 sizeof(out)/sizeof(WCHAR), NULL); 936 ok(ret == 17, "Expected FormatMessageW to return 17, got %d\n", ret); 937 ok(!lstrcmpW(fmt_t12oos99, out), "Expected output string \"test%%1%%2!*.*s!%%99\", got %s\n", wine_dbgstr_w(out)); 938 939 /* Only the "%n", "%r", and "%t" escape sequences are processed. */ 940 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, fmt_pctspacedot, 0, 0, out, 941 sizeof(out)/sizeof(WCHAR), NULL); 942 ok(ret == 8, "Expected FormatMessageW to return 8, got %d\n", ret); 943 ok(!lstrcmpW(fmt_pctspacedot, out), "Expected output string \"%%%%%% %%.%%!\", got %s\n", wine_dbgstr_w(out)); 944 945 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, fmt_nrt, 0, 0, out, 946 sizeof(out)/sizeof(WCHAR), NULL); 947 ok(ret == 4, "Expected FormatMessageW to return 4, got %d\n", ret); 948 ok(!lstrcmpW(s_nrt, out), "Expected output string \"\\r\\n\\r\\t\", got %s\n", wine_dbgstr_w(out)); 949 950 /* CRLF characters are processed normally. */ 951 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, fmt_hi_lf, 0, 0, out, 952 sizeof(out)/sizeof(WCHAR), NULL); 953 ok(ret == 4, "Expected FormatMessageW to return 4, got %d\n", ret); 954 ok(!lstrcmpW(s_hi_crlf, out), "Expected output string \"hi\\r\\n\", got %s\n", wine_dbgstr_w(out)); 955 956 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, fmt_hi_crlf, 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_cr, 0, 0, out, 962 sizeof(out)/sizeof(WCHAR), NULL); 963 ok(ret == 2, "Expected FormatMessageW to return 2, got %d\n", ret); 964 ok(!lstrcmpW(s_crlf, out), "Expected output string \"\\r\\n\", got %s\n", wine_dbgstr_w(out)); 965 966 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS, fmt_crcrlf, 0, 0, out, 967 sizeof(out)/sizeof(WCHAR), NULL); 968 ok(ret == 4, "Expected FormatMessageW to return 4, got %d\n", ret); 969 ok(!lstrcmpW(s_crlfcrlf, out), "Expected output string \"\\r\\n\\r\\n\", got %s\n", wine_dbgstr_w(out)); 970 971 /* The width parameter is handled the same also. */ 972 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS | 973 FORMAT_MESSAGE_MAX_WIDTH_MASK, fmt_hi_lf, 0, 0, out, 974 sizeof(out)/sizeof(WCHAR), NULL); 975 ok(ret == 3, "Expected FormatMessageW to return 3, got %d\n", ret); 976 ok(!lstrcmpW(s_hi_sp, out), "Expected output string \"hi \", got %s\n", wine_dbgstr_w(out)); 977 978 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS | 979 FORMAT_MESSAGE_MAX_WIDTH_MASK, fmt_hi_crlf, 0, 0, out, 980 sizeof(out)/sizeof(WCHAR), NULL); 981 ok(ret == 3, "Expected FormatMessageW to return 3, got %d\n", ret); 982 ok(!lstrcmpW(s_hi_sp, out), "Expected output string \"hi \", got %s\n", wine_dbgstr_w(out)); 983 984 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS | 985 FORMAT_MESSAGE_MAX_WIDTH_MASK, fmt_cr, 0, 0, out, 986 sizeof(out)/sizeof(WCHAR), NULL); 987 ok(ret == 1, "Expected FormatMessageW to return 1, got %d\n", ret); 988 ok(!lstrcmpW(s_sp, out), "Expected output string \" \", got %s\n", wine_dbgstr_w(out)); 989 990 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS | 991 FORMAT_MESSAGE_MAX_WIDTH_MASK, fmt_crcrlf, 0, 0, out, 992 sizeof(out)/sizeof(WCHAR), NULL); 993 ok(ret == 2, "Expected FormatMessageW to return 2, got %d\n", ret); 994 ok(!lstrcmpW(s_2sp, out), "Expected output string \" \", got %s\n", wine_dbgstr_w(out)); 995 } 996 997 static void test_message_wrap(void) 998 { 999 DWORD ret; 1000 int i; 1001 CHAR in[300], out[300], ref[300]; 1002 1003 /* No need for wrapping */ 1004 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 20, 1005 "short long line", 0, 0, out, sizeof(out), NULL); 1006 ok(ret == 15, "Expected FormatMessageW to return 15, got %d\n", ret); 1007 ok(!strcmp("short long line", out),"failed out=[%s]\n",out); 1008 1009 /* Wrap the last word */ 1010 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 11, 1011 "short long line", 0, 0, out, sizeof(out), NULL); 1012 ok(ret == 16, "Expected FormatMessageW to return 16, got %d\n", ret); 1013 ok(!strcmp("short long\r\nline", out),"failed out=[%s]\n",out); 1014 1015 /* Wrap the very last word */ 1016 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 20, 1017 "short long long line", 0, 0, out, sizeof(out), NULL); 1018 ok(ret == 21, "Expected FormatMessageW to return 21, got %d\n", ret); 1019 ok(!strcmp("short long long\r\nline", out),"failed out=[%s]\n",out); 1020 1021 /* Strictly less than 10 characters per line! */ 1022 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 10, 1023 "short long line", 0, 0, out, sizeof(out), NULL); 1024 ok(ret == 16, "Expected FormatMessageW to return 16, got %d\n", ret); 1025 ok(!strcmp("short\r\nlong line", out),"failed out=[%s]\n",out); 1026 1027 /* Handling of duplicate spaces */ 1028 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 16, 1029 "short long line", 0, 0, out, sizeof(out), NULL); 1030 ok(ret == 16, "Expected FormatMessageW to return 16, got %d\n", ret); 1031 ok(!strcmp("short long\r\nline", out),"failed out=[%s]\n",out); 1032 1033 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 16, 1034 "short long wordlongerthanaline", 0, 0, out, sizeof(out), NULL); 1035 ok(ret == 33, "Expected FormatMessageW to return 33, got %d\n", ret); 1036 ok(!strcmp("short long\r\nwordlongerthanal\r\nine", out),"failed out=[%s]\n",out); 1037 1038 /* Breaking in the middle of spaces */ 1039 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 12, 1040 "short long line", 0, 0, out, sizeof(out), NULL); 1041 ok(ret == 18, "Expected FormatMessageW to return 18, got %d\n", ret); 1042 ok(!strcmp("short long\r\n line", out),"failed out=[%s]\n",out); 1043 1044 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 12, 1045 "short long wordlongerthanaline", 0, 0, out, sizeof(out), NULL); 1046 ok(ret == 35, "Expected FormatMessageW to return 35, got %d\n", ret); 1047 ok(!strcmp("short long\r\n\r\nwordlongerth\r\nanaline", out),"failed out=[%s]\n",out); 1048 1049 /* Handling of start-of-string spaces */ 1050 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 15, 1051 " short line", 0, 0, out, sizeof(out), NULL); 1052 ok(ret == 13, "Expected FormatMessageW to return 13, got %d\n", ret); 1053 ok(!strcmp(" short line", out),"failed out=[%s]\n",out); 1054 1055 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 11, 1056 " shortlong line", 0, 0, out, sizeof(out), NULL); 1057 ok(ret == 17, "Expected FormatMessageW to return 17, got %d\n", ret); 1058 ok(!strcmp("\r\nshortlong\r\nline", out),"failed out=[%s]\n",out); 1059 1060 /* Handling of start-of-line spaces */ 1061 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 11, 1062 "l1%n shortlong line", 0, 0, out, sizeof(out), NULL); 1063 ok(ret == 21, "Expected FormatMessageW to return 21, got %d\n", ret); 1064 ok(!strcmp("l1\r\n\r\nshortlong\r\nline", out),"failed out=[%s]\n",out); 1065 1066 /* Pure space wrapping */ 1067 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 5, 1068 " ", 0, 0, out, sizeof(out), NULL); 1069 ok(ret == 7, "Expected FormatMessageW to return 7, got %d\n", ret); 1070 ok(!strcmp("\r\n\r\n\r\n ", out),"failed out=[%s]\n",out); 1071 1072 /* Handling of trailing spaces */ 1073 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 5, 1074 "l1 ", 0, 0, out, sizeof(out), NULL); 1075 ok(ret == 10, "Expected FormatMessageW to return 10, got %d\n", ret); 1076 ok(!strcmp("l1\r\n\r\n\r\n ", out),"failed out=[%s]\n",out); 1077 1078 /* Word that just fills the line */ 1079 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 8, 1080 "shortlon", 0, 0, out, sizeof(out), NULL); 1081 ok(ret == 10, "Expected FormatMessageW to return 10, got %d\n", ret); 1082 ok(!strcmp("shortlon\r\n", out),"failed out=[%s]\n",out); 1083 1084 /* Word longer than the line */ 1085 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 8, 1086 "shortlongline", 0, 0, out, sizeof(out), NULL); 1087 ok(ret == 15, "Expected FormatMessageW to return 15, got %d\n", ret); 1088 ok(!strcmp("shortlon\r\ngline", out),"failed out=[%s]\n",out); 1089 1090 /* Wrap the line multiple times */ 1091 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 7, 1092 "short long line", 0, 0, out, sizeof(out), NULL); 1093 ok(ret == 17, "Expected FormatMessageW to return 17, got %d\n", ret); 1094 ok(!strcmp("short\r\nlong\r\nline", out),"failed out=[%s]\n",out); 1095 1096 /* '\n's in the source are ignored */ 1097 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 11, 1098 "short\nlong line", 0, 0, out, sizeof(out), NULL); 1099 ok(ret == 16, "Expected FormatMessageW to return 16, got %d\n", ret); 1100 ok(!strcmp("short long\r\nline", out),"failed out=[%s]\n",out); 1101 1102 /* Wrap even before a '%n' */ 1103 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 8, 1104 "shortlon%n", 0, 0, out, sizeof(out), NULL); 1105 ok(ret == 12, "Expected FormatMessageW to return 12, got %d\n", ret); 1106 ok(!strcmp("shortlon\r\n\r\n", out),"failed out=[%s]\n",out); 1107 1108 /* '%n's count as starting a new line and combine with line wrapping */ 1109 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 10, 1110 "short%nlong line", 0, 0, out, sizeof(out), NULL); 1111 ok(ret == 16, "Expected FormatMessageW to return 16, got %d\n", ret); 1112 ok(!strcmp("short\r\nlong line", out),"failed out=[%s]\n",out); 1113 1114 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 8, 1115 "short%nlong line", 0, 0, out, sizeof(out), NULL); 1116 ok(ret == 17, "Expected FormatMessageW to return 17, got %d\n", ret); 1117 ok(!strcmp("short\r\nlong\r\nline", out),"failed out=[%s]\n",out); 1118 1119 /* '%r's also count as starting a new line and all */ 1120 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 10, 1121 "short%rlong line", 0, 0, out, sizeof(out), NULL); 1122 ok(ret == 15, "Expected FormatMessageW to return 15, got %d\n", ret); 1123 ok(!strcmp("short\rlong line", out),"failed out=[%s]\n",out); 1124 1125 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 8, 1126 "short%rlong line", 0, 0, out, sizeof(out), NULL); 1127 ok(ret == 16, "Expected FormatMessageW to return 16, got %d\n", ret); 1128 ok(!strcmp("short\rlong\r\nline", out),"failed out=[%s]\n",out); 1129 1130 /* IGNORE_INSERTS does not prevent line wrapping or disable '%n' */ 1131 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_IGNORE_INSERTS | 8, 1132 "short%nlong line%1", 0, 0, out, sizeof(out), NULL); 1133 ok(ret == 19, "Expected FormatMessageW to return 19, got %d\n", ret); 1134 ok(!strcmp("short\r\nlong\r\nline%1", out),"failed out=[%s]\n",out); 1135 1136 /* MAX_WIDTH_MASK is the same as specifying an infinite line width */ 1137 strcpy(in, "first line%n"); 1138 strcpy(ref, "first line\r\n"); 1139 for (i=0; i < 26; i++) 1140 { 1141 strcat(in, "123456789 "); 1142 strcat(ref, "123456789 "); 1143 } 1144 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_MAX_WIDTH_MASK, 1145 in, 0, 0, out, sizeof(out), NULL); 1146 ok(ret == 272, "Expected FormatMessageW to return 272, got %d\n", ret); 1147 ok(!strcmp(ref, out),"failed out=[%s]\n",out); 1148 1149 /* Wrapping and non-space characters */ 1150 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 11, 1151 "short long\tline", 0, 0, out, sizeof(out), NULL); 1152 ok(ret == 16, "Expected FormatMessageW to return 16, got %d\n", ret); 1153 ok(!strcmp("short\r\nlong\tline", out),"failed out=[%s]\n",out); 1154 1155 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | 11, 1156 "short long-line", 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-line", 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 1186 static void test_message_insufficient_buffer(void) 1187 { 1188 static const char init_buf[] = {'x', 'x', 'x', 'x', 'x'}; 1189 static const char expected_buf[] = {'x', 'x', 'x', 'x', 'x'}; 1190 DWORD ret; 1191 CHAR out[5]; 1192 1193 SetLastError(0xdeadbeef); 1194 memcpy(out, init_buf, sizeof(init_buf)); 1195 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, "test", 0, 0, out, 0, NULL); 1196 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret); 1197 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 1198 "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n", 1199 GetLastError()); 1200 ok(!memcmp(expected_buf, out, sizeof(expected_buf)), 1201 "Expected the buffer to be untouched\n"); 1202 1203 SetLastError(0xdeadbeef); 1204 memcpy(out, init_buf, sizeof(init_buf)); 1205 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, "test", 0, 0, out, 1, NULL); 1206 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret); 1207 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 1208 "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n", 1209 GetLastError()); 1210 ok(!memcmp(expected_buf, out, sizeof(expected_buf)), 1211 "Expected the buffer to be untouched\n"); 1212 1213 SetLastError(0xdeadbeef); 1214 memcpy(out, init_buf, sizeof(init_buf)); 1215 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, "test", 0, 0, out, sizeof(out)/sizeof(out[0]) - 1, NULL); 1216 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret); 1217 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 1218 "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n", 1219 GetLastError()); 1220 ok(!memcmp(expected_buf, out, sizeof(expected_buf)), 1221 "Expected the buffer to be untouched\n"); 1222 } 1223 1224 static void test_message_insufficient_buffer_wide(void) 1225 { 1226 static const WCHAR test[] = {'t','e','s','t',0}; 1227 static const WCHAR init_buf[] = {'x', 'x', 'x', 'x', 'x'}; 1228 static const WCHAR expected_buf[] = {'x', 'x', 'x', 'x', 'x'}; 1229 static const WCHAR broken_buf[] = {0, 'x', 'x', 'x', 'x'}; 1230 static const WCHAR broken2_buf[] = {'t','e','s',0,'x'}; 1231 1232 DWORD ret; 1233 WCHAR out[5]; 1234 1235 SetLastError(0xdeadbeef); 1236 memcpy(out, init_buf, sizeof(init_buf)); 1237 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, test, 0, 0, out, 0, NULL); 1238 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret); 1239 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 1240 "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n", 1241 GetLastError()); 1242 ok(!memcmp(expected_buf, out, sizeof(expected_buf)), 1243 "Expected the buffer to be untouched\n"); 1244 1245 /* Windows Server 2003 and newer report failure but copy a 1246 * truncated string to the buffer for non-zero buffer sizes. */ 1247 SetLastError(0xdeadbeef); 1248 memcpy(out, init_buf, sizeof(init_buf)); 1249 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, test, 0, 0, out, 1, NULL); 1250 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret); 1251 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 1252 "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n", 1253 GetLastError()); 1254 ok(!memcmp(expected_buf, out, sizeof(expected_buf)) || 1255 broken(!memcmp(broken_buf, out, sizeof(broken_buf))), /* W2K3+ */ 1256 "Expected the buffer to be untouched\n"); 1257 1258 SetLastError(0xdeadbeef); 1259 memcpy(out, init_buf, sizeof(init_buf)); 1260 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, test, 0, 0, out, sizeof(out)/sizeof(out[0]) - 1, NULL); 1261 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret); 1262 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 1263 "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n", 1264 GetLastError()); 1265 ok(!memcmp(expected_buf, out, sizeof(expected_buf)) || 1266 broken(!memcmp(broken2_buf, out, sizeof(broken2_buf))), /* W2K3+ */ 1267 "Expected the buffer to be untouched\n"); 1268 } 1269 1270 static void test_message_null_buffer(void) 1271 { 1272 DWORD ret, error; 1273 1274 /* Without FORMAT_MESSAGE_ALLOCATE_BUFFER, only the specified buffer size is checked. */ 1275 SetLastError(0xdeadbeef); 1276 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, 0, 0, NULL, 0, NULL); 1277 error = GetLastError(); 1278 ok(!ret, "FormatMessageA returned %u\n", ret); 1279 ok(error == ERROR_INSUFFICIENT_BUFFER, "last error %u\n", error); 1280 1281 SetLastError(0xdeadbeef); 1282 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, 0, 0, NULL, 1, NULL); 1283 error = GetLastError(); 1284 ok(!ret, "FormatMessageA returned %u\n", ret); 1285 ok(error == ERROR_INSUFFICIENT_BUFFER, "last error %u\n", error); 1286 1287 if (0) /* crashes on Windows */ 1288 { 1289 SetLastError(0xdeadbeef); 1290 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, 0, 0, NULL, 256, NULL); 1291 } 1292 1293 SetLastError(0xdeadbeef); 1294 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, 0, 0, NULL, 0, NULL); 1295 error = GetLastError(); 1296 ok(!ret, "FormatMessageA returned %u\n", ret); 1297 ok(error == ERROR_NOT_ENOUGH_MEMORY, "last error %u\n", error); 1298 1299 SetLastError(0xdeadbeef); 1300 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, 0, 0, NULL, 1, NULL); 1301 error = GetLastError(); 1302 ok(!ret, "FormatMessageA returned %u\n", ret); 1303 ok(error == ERROR_NOT_ENOUGH_MEMORY, "last error %u\n", error); 1304 1305 SetLastError(0xdeadbeef); 1306 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, 0, 0, NULL, 256, NULL); 1307 error = GetLastError(); 1308 ok(!ret, "FormatMessageA returned %u\n", ret); 1309 ok(error == ERROR_NOT_ENOUGH_MEMORY, "last error %u\n", error); 1310 } 1311 1312 static void test_message_null_buffer_wide(void) 1313 { 1314 DWORD ret, error; 1315 1316 SetLastError(0xdeadbeef); 1317 ret = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, 0, 0, NULL, 0, NULL); 1318 error = GetLastError(); 1319 ok(!ret, "FormatMessageW returned %u\n", ret); 1320 ok(error == ERROR_INVALID_PARAMETER, "last error %u\n", error); 1321 1322 SetLastError(0xdeadbeef); 1323 ret = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, 0, 0, NULL, 1, NULL); 1324 error = GetLastError(); 1325 ok(!ret, "FormatMessageW returned %u\n", ret); 1326 ok(error == ERROR_INVALID_PARAMETER, "last error %u\n", error); 1327 1328 SetLastError(0xdeadbeef); 1329 ret = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, 0, 0, NULL, 256, NULL); 1330 error = GetLastError(); 1331 ok(!ret, "FormatMessageW returned %u\n", ret); 1332 ok(error == ERROR_INVALID_PARAMETER, "last error %u\n", error); 1333 1334 SetLastError(0xdeadbeef); 1335 ret = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, 0, 0, NULL, 0, NULL); 1336 error = GetLastError(); 1337 ok(!ret, "FormatMessageW returned %u\n", ret); 1338 ok(error == ERROR_INVALID_PARAMETER, "last error %u\n", error); 1339 1340 SetLastError(0xdeadbeef); 1341 ret = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, 0, 0, NULL, 1, NULL); 1342 error = GetLastError(); 1343 ok(!ret, "FormatMessageW returned %u\n", ret); 1344 ok(error == ERROR_INVALID_PARAMETER, "last error %u\n", error); 1345 1346 SetLastError(0xdeadbeef); 1347 ret = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, 0, 0, NULL, 256, NULL); 1348 error = GetLastError(); 1349 ok(!ret, "FormatMessageW returned %u\n", ret); 1350 ok(error == ERROR_INVALID_PARAMETER, "last error %u\n", error); 1351 } 1352 1353 static void test_message_allocate_buffer(void) 1354 { 1355 DWORD ret; 1356 char *buf; 1357 1358 /* While MSDN suggests that FormatMessageA allocates a buffer whose size is 1359 * the larger of the output string and the requested buffer size, the tests 1360 * will not try to determine the actual size of the buffer allocated, as 1361 * the return value of LocalSize cannot be trusted for the purpose, and it should 1362 * in any case be safe for FormatMessageA to allocate in the manner that 1363 * MSDN suggests. */ 1364 1365 SetLastError(0xdeadbeef); 1366 buf = (char *)0xdeadbeef; 1367 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER, 1368 "", 0, 0, (char *)&buf, 0, NULL); 1369 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret); 1370 ok(buf == NULL, "Expected output buffer pointer to be NULL\n"); 1371 ok(GetLastError() == 0xdeadbeef, 1372 "Expected last error to be untouched, got %u\n", GetLastError()); 1373 1374 buf = (char *)0xdeadbeef; 1375 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER, 1376 "test", 0, 0, (char *)&buf, 0, NULL); 1377 ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret); 1378 ok(buf != NULL && buf != (char *)0xdeadbeef, 1379 "Expected output buffer pointer to be valid\n"); 1380 if (buf != NULL && buf != (char *)0xdeadbeef) 1381 { 1382 ok(!strcmp("test", buf), 1383 "Expected buffer to contain \"test\", got %s\n", buf); 1384 LocalFree(buf); 1385 } 1386 1387 buf = (char *)0xdeadbeef; 1388 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER, 1389 "test", 0, 0, (char *)&buf, strlen("test"), NULL); 1390 ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret); 1391 ok(buf != NULL && buf != (char *)0xdeadbeef, 1392 "Expected output buffer pointer to be valid\n"); 1393 if (buf != NULL && buf != (char *)0xdeadbeef) 1394 { 1395 ok(!strcmp("test", buf), 1396 "Expected buffer to contain \"test\", got %s\n", buf); 1397 LocalFree(buf); 1398 } 1399 1400 buf = (char *)0xdeadbeef; 1401 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER, 1402 "test", 0, 0, (char *)&buf, strlen("test") + 1, NULL); 1403 ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret); 1404 ok(buf != NULL && buf != (char *)0xdeadbeef, 1405 "Expected output buffer pointer to be valid\n"); 1406 if (buf != NULL && buf != (char *)0xdeadbeef) 1407 { 1408 ok(!strcmp("test", buf), 1409 "Expected buffer to contain \"test\", got %s\n", buf); 1410 LocalFree(buf); 1411 } 1412 1413 buf = (char *)0xdeadbeef; 1414 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER, 1415 "test", 0, 0, (char *)&buf, strlen("test") + 2, NULL); 1416 ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret); 1417 ok(buf != NULL && buf != (char *)0xdeadbeef, 1418 "Expected output buffer pointer to be valid\n"); 1419 if (buf != NULL && buf != (char *)0xdeadbeef) 1420 { 1421 ok(!strcmp("test", buf), 1422 "Expected buffer to contain \"test\", got %s\n", buf); 1423 LocalFree(buf); 1424 } 1425 1426 buf = (char *)0xdeadbeef; 1427 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER, 1428 "test", 0, 0, (char *)&buf, 1024, NULL); 1429 ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret); 1430 ok(buf != NULL && buf != (char *)0xdeadbeef, 1431 "Expected output buffer pointer to be valid\n"); 1432 if (buf != NULL && buf != (char *)0xdeadbeef) 1433 { 1434 ok(!strcmp("test", buf), 1435 "Expected buffer to contain \"test\", got %s\n", buf); 1436 LocalFree(buf); 1437 } 1438 } 1439 1440 static void test_message_allocate_buffer_wide(void) 1441 { 1442 static const WCHAR empty[] = {0}; 1443 static const WCHAR test[] = {'t','e','s','t',0}; 1444 1445 DWORD ret; 1446 WCHAR *buf; 1447 1448 /* While MSDN suggests that FormatMessageW allocates a buffer whose size is 1449 * the larger of the output string and the requested buffer size, the tests 1450 * will not try to determine the actual size of the buffer allocated, as 1451 * the return value of LocalSize cannot be trusted for the purpose, and it should 1452 * in any case be safe for FormatMessageW to allocate in the manner that 1453 * MSDN suggests. */ 1454 1455 if (0) /* crashes on Windows */ 1456 { 1457 buf = (WCHAR *)0xdeadbeef; 1458 FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER, 1459 NULL, 0, 0, (WCHAR *)&buf, 0, NULL); 1460 } 1461 1462 SetLastError(0xdeadbeef); 1463 buf = (WCHAR *)0xdeadbeef; 1464 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER, 1465 empty, 0, 0, (WCHAR *)&buf, 0, NULL); 1466 ok(ret == 0, "Expected FormatMessageW to return 0, got %u\n", ret); 1467 ok(buf == NULL, "Expected output buffer pointer to be NULL\n"); 1468 ok(GetLastError() == 0xdeadbeef, 1469 "Expected last error to be untouched, got %u\n", GetLastError()); 1470 1471 buf = (WCHAR *)0xdeadbeef; 1472 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER, 1473 test, 0, 0, (WCHAR *)&buf, 0, NULL); 1474 ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret); 1475 ok(buf != NULL && buf != (WCHAR *)0xdeadbeef, 1476 "Expected output buffer pointer to be valid\n"); 1477 if (buf != NULL && buf != (WCHAR *)0xdeadbeef) 1478 { 1479 ok(!lstrcmpW(test, buf), 1480 "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf)); 1481 LocalFree(buf); 1482 } 1483 1484 buf = (WCHAR *)0xdeadbeef; 1485 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER, 1486 test, 0, 0, (WCHAR *)&buf, sizeof(test)/sizeof(WCHAR) - 1, NULL); 1487 ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret); 1488 ok(buf != NULL && buf != (WCHAR *)0xdeadbeef, 1489 "Expected output buffer pointer to be valid\n"); 1490 if (buf != NULL && buf != (WCHAR *)0xdeadbeef) 1491 { 1492 ok(!lstrcmpW(test, buf), 1493 "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf)); 1494 LocalFree(buf); 1495 } 1496 1497 buf = (WCHAR *)0xdeadbeef; 1498 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER, 1499 test, 0, 0, (WCHAR *)&buf, sizeof(test)/sizeof(WCHAR), NULL); 1500 ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret); 1501 ok(buf != NULL && buf != (WCHAR *)0xdeadbeef, 1502 "Expected output buffer pointer to be valid\n"); 1503 if (buf != NULL && buf != (WCHAR *)0xdeadbeef) 1504 { 1505 ok(!lstrcmpW(test, buf), 1506 "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf)); 1507 LocalFree(buf); 1508 } 1509 1510 buf = (WCHAR *)0xdeadbeef; 1511 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER, 1512 test, 0, 0, (WCHAR *)&buf, sizeof(test)/sizeof(WCHAR) + 1, NULL); 1513 ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret); 1514 ok(buf != NULL && buf != (WCHAR *)0xdeadbeef, 1515 "Expected output buffer pointer to be valid\n"); 1516 if (buf != NULL && buf != (WCHAR *)0xdeadbeef) 1517 { 1518 ok(!lstrcmpW(test, buf), 1519 "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf)); 1520 LocalFree(buf); 1521 } 1522 1523 buf = (WCHAR *)0xdeadbeef; 1524 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER, 1525 test, 0, 0, (WCHAR *)&buf, 1024, NULL); 1526 ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret); 1527 ok(buf != NULL && buf != (WCHAR *)0xdeadbeef, 1528 "Expected output buffer pointer to be valid\n"); 1529 if (buf != NULL && buf != (WCHAR *)0xdeadbeef) 1530 { 1531 ok(!lstrcmpW(test, buf), 1532 "Expected buffer to contain \"test\", got %s\n", wine_dbgstr_w(buf)); 1533 LocalFree(buf); 1534 } 1535 } 1536 1537 static void test_message_from_hmodule(void) 1538 { 1539 DWORD ret, error; 1540 HMODULE h; 1541 CHAR out[0x100] = {0}; 1542 1543 h = GetModuleHandleA("kernel32.dll"); 1544 ok(h != 0, "GetModuleHandle failed\n"); 1545 1546 /*Test existing messageID; as the message strings from wine's kernel32 differ from windows' kernel32 we don't compare 1547 the strings but only test that FormatMessage doesn't return 0*/ 1548 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 7/*=ERROR_ARENA_TRASHED*/, 1549 MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), out, sizeof(out)/sizeof(CHAR), NULL); 1550 ok(ret != 0, "FormatMessageA returned 0\n"); 1551 1552 /* Test HRESULT. It's not documented but in practice _com_error::ErrorMessage relies on this. */ 1553 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 0x80070005 /* E_ACCESSDENIED */, 1554 MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), out, sizeof(out)/sizeof(CHAR), NULL); 1555 ok(ret != 0, "FormatMessageA returned 0\n"); 1556 1557 /* Test a message string with an insertion without passing any variadic arguments. */ 1558 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 193 /* ERROR_BAD_EXE_FORMAT */, 1559 MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), out, sizeof(out)/sizeof(CHAR), NULL); 1560 ok(ret == 0, "FormatMessageA returned non-zero\n"); 1561 1562 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE | 1563 FORMAT_MESSAGE_ARGUMENT_ARRAY, h, 193 /* ERROR_BAD_EXE_FORMAT */, 1564 MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), out, sizeof(out)/sizeof(CHAR), NULL); 1565 ok(ret == 0, "FormatMessageA returned non-zero\n"); 1566 1567 /*Test nonexistent messageID with varying language IDs Note: FormatMessageW behaves the same*/ 1568 SetLastError(0xdeadbeef); 1569 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 3044, 1570 MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), out, sizeof(out)/sizeof(CHAR), NULL); 1571 error = GetLastError(); 1572 ok(ret == 0, "FormatMessageA returned %u instead of 0\n", ret); 1573 ok(error == ERROR_MR_MID_NOT_FOUND || error == ERROR_MUI_FILE_NOT_FOUND, "last error %u\n", error); 1574 1575 SetLastError(0xdeadbeef); 1576 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 3044, 1577 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), out, sizeof(out)/sizeof(CHAR), NULL); 1578 error = GetLastError(); 1579 ok(ret == 0, "FormatMessageA returned %u instead of 0\n", ret); 1580 ok(error == ERROR_MR_MID_NOT_FOUND || error == ERROR_MUI_FILE_NOT_LOADED, "last error %u\n", error); 1581 1582 SetLastError(0xdeadbeef); 1583 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 3044, 1584 MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT), out, sizeof(out)/sizeof(CHAR), NULL); 1585 error = GetLastError(); 1586 ok(ret == 0, "FormatMessageA returned %u instead of 0\n", ret); 1587 ok(error == ERROR_MR_MID_NOT_FOUND || error == ERROR_MUI_FILE_NOT_LOADED, "last error %u\n", error); 1588 1589 SetLastError(0xdeadbeef); 1590 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 3044, 1591 MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), out, sizeof(out)/sizeof(CHAR), NULL); 1592 error = GetLastError(); 1593 ok(ret == 0, "FormatMessageA returned %u instead of 0\n", ret); 1594 ok(error == ERROR_RESOURCE_LANG_NOT_FOUND || 1595 error == ERROR_MR_MID_NOT_FOUND || 1596 error == ERROR_MUI_FILE_NOT_FOUND || 1597 error == ERROR_MUI_FILE_NOT_LOADED, 1598 "last error %u\n", error); 1599 1600 SetLastError(0xdeadbeef); 1601 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 3044, 1602 MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_UK), out, sizeof(out)/sizeof(CHAR), NULL); 1603 error = GetLastError(); 1604 ok(ret == 0, "FormatMessageA returned %u instead of 0\n", ret); 1605 ok(error == ERROR_RESOURCE_LANG_NOT_FOUND || 1606 error == ERROR_MR_MID_NOT_FOUND || 1607 error == ERROR_MUI_FILE_NOT_FOUND || 1608 error == ERROR_MUI_FILE_NOT_LOADED, 1609 "last error %u\n", error); 1610 } 1611 1612 static void test_message_invalid_flags(void) 1613 { 1614 static const char init_buf[] = {'x', 'x', 'x', 'x', 'x'}; 1615 1616 DWORD ret; 1617 CHAR out[5]; 1618 char *ptr; 1619 1620 SetLastError(0xdeadbeef); 1621 memcpy(out, init_buf, sizeof(init_buf)); 1622 ret = FormatMessageA(0, "test", 0, 0, out, sizeof(out)/sizeof(CHAR), NULL); 1623 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret); 1624 ok(!memcmp(out, init_buf, sizeof(init_buf)), 1625 "Expected the output buffer to be untouched\n"); 1626 ok(GetLastError() == ERROR_INVALID_PARAMETER, 1627 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", 1628 GetLastError()); 1629 1630 SetLastError(0xdeadbeef); 1631 ptr = (char *)0xdeadbeef; 1632 ret = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER, "test", 0, 0, (char *)&ptr, 0, NULL); 1633 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret); 1634 ok(ptr == NULL, "Expected output pointer to be initialized to NULL, got %p\n", ptr); 1635 ok(GetLastError() == ERROR_INVALID_PARAMETER, 1636 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", 1637 GetLastError()); 1638 1639 SetLastError(0xdeadbeef); 1640 memcpy(out, init_buf, sizeof(init_buf)); 1641 ret = FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS, "test", 0, 0, out, sizeof(out)/sizeof(CHAR), NULL); 1642 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret); 1643 ok(!memcmp(out, init_buf, sizeof(init_buf)), 1644 "Expected the output buffer to be untouched\n"); 1645 ok(GetLastError() == ERROR_INVALID_PARAMETER, 1646 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", 1647 GetLastError()); 1648 1649 SetLastError(0xdeadbeef); 1650 memcpy(out, init_buf, sizeof(init_buf)); 1651 ret = FormatMessageA(FORMAT_MESSAGE_ARGUMENT_ARRAY, "test", 0, 0, out, sizeof(out)/sizeof(CHAR), NULL); 1652 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret); 1653 ok(!memcmp(out, init_buf, sizeof(init_buf)), 1654 "Expected the output buffer to be untouched\n"); 1655 ok(GetLastError() == ERROR_INVALID_PARAMETER, 1656 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", 1657 GetLastError()); 1658 1659 SetLastError(0xdeadbeef); 1660 memcpy(out, init_buf, sizeof(init_buf)); 1661 ret = FormatMessageA(FORMAT_MESSAGE_MAX_WIDTH_MASK, "test", 0, 0, out, sizeof(out)/sizeof(CHAR), NULL); 1662 ok(ret == 0, "Expected FormatMessageA to return 0, got %u\n", ret); 1663 ok(!memcmp(out, init_buf, sizeof(init_buf)), 1664 "Expected the output buffer to be untouched\n"); 1665 ok(GetLastError() == ERROR_INVALID_PARAMETER, 1666 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", 1667 GetLastError()); 1668 1669 /* Simultaneously setting FORMAT_MESSAGE_FROM_STRING with other source 1670 * flags is apparently permissible, and FORMAT_MESSAGE_FROM_STRING takes 1671 * precedence in this case. */ 1672 1673 memcpy(out, init_buf, sizeof(init_buf)); 1674 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_FROM_SYSTEM, 1675 "test", 0, 0, out, sizeof(out)/sizeof(CHAR), NULL); 1676 ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret); 1677 ok(!strcmp("test", out), 1678 "Expected the output buffer to be untouched\n"); 1679 1680 memcpy(out, init_buf, sizeof(init_buf)); 1681 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_FROM_HMODULE, 1682 "test", 0, 0, out, sizeof(out)/sizeof(CHAR), NULL); 1683 ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret); 1684 ok(!strcmp("test", out), 1685 "Expected the output buffer to be untouched\n"); 1686 1687 memcpy(out, init_buf, sizeof(init_buf)); 1688 ret = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_FROM_HMODULE | 1689 FORMAT_MESSAGE_FROM_SYSTEM, "test", 0, 0, out, 1690 sizeof(out)/sizeof(CHAR), NULL); 1691 ok(ret == 4, "Expected FormatMessageA to return 4, got %u\n", ret); 1692 ok(!strcmp("test", out), 1693 "Expected the output buffer to be untouched\n"); 1694 } 1695 1696 static void test_message_invalid_flags_wide(void) 1697 { 1698 static const WCHAR init_buf[] = {'x', 'x', 'x', 'x', 'x'}; 1699 static const WCHAR test[] = {'t','e','s','t',0}; 1700 1701 DWORD ret; 1702 WCHAR out[5]; 1703 WCHAR *ptr; 1704 1705 SetLastError(0xdeadbeef); 1706 memcpy(out, init_buf, sizeof(init_buf)); 1707 ret = FormatMessageW(0, test, 0, 0, out, sizeof(out)/sizeof(WCHAR), NULL); 1708 ok(ret == 0, "Expected FormatMessageW to return 0, got %u\n", ret); 1709 ok(!memcmp(out, init_buf, sizeof(init_buf)), 1710 "Expected the output buffer to be untouched\n"); 1711 ok(GetLastError() == ERROR_INVALID_PARAMETER, 1712 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", 1713 GetLastError()); 1714 1715 SetLastError(0xdeadbeef); 1716 ptr = (WCHAR *)0xdeadbeef; 1717 ret = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER, test, 0, 0, (WCHAR *)&ptr, 0, NULL); 1718 ok(ret == 0, "Expected FormatMessageW to return 0, got %u\n", ret); 1719 ok(ptr == NULL, "Expected output pointer to be initialized to NULL, got %p\n", ptr); 1720 ok(GetLastError() == ERROR_INVALID_PARAMETER, 1721 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", 1722 GetLastError()); 1723 1724 SetLastError(0xdeadbeef); 1725 memcpy(out, init_buf, sizeof(init_buf)); 1726 ret = FormatMessageW(FORMAT_MESSAGE_IGNORE_INSERTS, test, 0, 0, out, sizeof(out)/sizeof(WCHAR), NULL); 1727 ok(ret == 0, "Expected FormatMessageW to return 0, got %u\n", ret); 1728 ok(!memcmp(out, init_buf, sizeof(init_buf)), 1729 "Expected the output buffer to be untouched\n"); 1730 ok(GetLastError() == ERROR_INVALID_PARAMETER, 1731 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", 1732 GetLastError()); 1733 1734 SetLastError(0xdeadbeef); 1735 memcpy(out, init_buf, sizeof(init_buf)); 1736 ret = FormatMessageW(FORMAT_MESSAGE_ARGUMENT_ARRAY, test, 0, 0, out, sizeof(out)/sizeof(WCHAR), NULL); 1737 ok(ret == 0, "Expected FormatMessageW to return 0, got %u\n", ret); 1738 ok(!memcmp(out, init_buf, sizeof(init_buf)), 1739 "Expected the output buffer to be untouched\n"); 1740 ok(GetLastError() == ERROR_INVALID_PARAMETER, 1741 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", 1742 GetLastError()); 1743 1744 SetLastError(0xdeadbeef); 1745 memcpy(out, init_buf, sizeof(init_buf)); 1746 ret = FormatMessageW(FORMAT_MESSAGE_MAX_WIDTH_MASK, test, 0, 0, out, sizeof(out)/sizeof(WCHAR), NULL); 1747 ok(ret == 0, "Expected FormatMessageW to return 0, got %u\n", ret); 1748 ok(!memcmp(out, init_buf, sizeof(init_buf)), 1749 "Expected the output buffer to be untouched\n"); 1750 ok(GetLastError() == ERROR_INVALID_PARAMETER, 1751 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", 1752 GetLastError()); 1753 1754 /* Simultaneously setting FORMAT_MESSAGE_FROM_STRING with other source 1755 * flags is apparently permissible, and FORMAT_MESSAGE_FROM_STRING takes 1756 * precedence in this case. */ 1757 1758 memcpy(out, init_buf, sizeof(init_buf)); 1759 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_FROM_SYSTEM, 1760 test, 0, 0, out, sizeof(out)/sizeof(WCHAR), NULL); 1761 ok(ret == 4, "Expected FormatMessageW to return 4, got %u\n", ret); 1762 ok(!lstrcmpW(test, out), 1763 "Expected the output buffer to be untouched\n"); 1764 1765 memcpy(out, init_buf, sizeof(init_buf)); 1766 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_FROM_HMODULE, 1767 test, 0, 0, out, sizeof(out)/sizeof(WCHAR), NULL); 1768 ok(ret == 4, "Expected FormatMessageW to return 4, got %u\n", ret); 1769 ok(!lstrcmpW(test, out), 1770 "Expected the output buffer to be untouched\n"); 1771 1772 memcpy(out, init_buf, sizeof(init_buf)); 1773 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_FROM_HMODULE | 1774 FORMAT_MESSAGE_FROM_SYSTEM, test, 0, 0, out, 1775 sizeof(out)/sizeof(WCHAR), NULL); 1776 ok(ret == 4, "Expected FormatMessageW to return 4, got %u\n", ret); 1777 ok(!lstrcmpW(test, out), 1778 "Expected the output buffer to be untouched\n"); 1779 } 1780 1781 static void test_message_from_64bit_number(void) 1782 { 1783 static const WCHAR I64d[] = {'%', '1', '!', 'I', '6', '4', 'd', '!', 0}; 1784 static const WCHAR I64u[] = {'%', '1', '!', 'I', '6', '4', 'u', '!', 0}; 1785 WCHAR outW[0x100], expW[0x100]; 1786 char outA[0x100]; 1787 DWORD r; 1788 static const struct 1789 { 1790 UINT64 number; 1791 const char expected[32]; 1792 int len; 1793 } unsigned_tests[] = 1794 { 1795 { 0, "0", 1 }, 1796 { 1234567890, "1234567890", 10}, 1797 { ULL(0xFFFFFFFF,0xFFFFFFFF), "18446744073709551615", 20 }, 1798 { ULL(0x7FFFFFFF,0xFFFFFFFF), "9223372036854775807", 19 }, 1799 }; 1800 static const struct 1801 { 1802 INT64 number; 1803 const char expected[32]; 1804 int len; 1805 } signed_tests[] = 1806 { 1807 { 0, "0" , 1}, 1808 { 1234567890, "1234567890", 10 }, 1809 { -1, "-1", 2}, 1810 { ULL(0xFFFFFFFF,0xFFFFFFFF), "-1", 2}, 1811 { ULL(0x7FFFFFFF,0xFFFFFFFF), "9223372036854775807", 19 }, 1812 { -ULL(0x7FFFFFFF,0xFFFFFFFF), "-9223372036854775807", 20}, 1813 }; 1814 int i; 1815 1816 for (i = 0; i < sizeof(unsigned_tests) / sizeof(unsigned_tests[0]); i++) 1817 { 1818 r = doitW(FORMAT_MESSAGE_FROM_STRING, I64u, 1819 0, 0, outW, sizeof(outW) / sizeof(WCHAR), unsigned_tests[i].number); 1820 MultiByteToWideChar(CP_ACP, 0, unsigned_tests[i].expected, -1, expW, sizeof(expW) / sizeof(WCHAR)); 1821 todo_wine { 1822 ok(!lstrcmpW(outW, expW),"[%d] failed, expected %s, got %s\n", i, 1823 unsigned_tests[i].expected, wine_dbgstr_w(outW)); 1824 ok(r == unsigned_tests[i].len,"[%d] failed: r=%d\n", i, r); 1825 } 1826 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!I64u!", 1827 0, 0, outA, sizeof(outA), unsigned_tests[i].number); 1828 todo_wine { 1829 ok(!strcmp(outA, unsigned_tests[i].expected),"[%d] failed, expected %s, got %s\n", i, 1830 unsigned_tests[i].expected, outA); 1831 ok(r == unsigned_tests[i].len,"[%d] failed: r=%d\n", i, r); 1832 } 1833 } 1834 1835 for (i = 0; i < sizeof(signed_tests) / sizeof(signed_tests[0]); i++) 1836 { 1837 r = doitW(FORMAT_MESSAGE_FROM_STRING, I64d, 1838 0, 0, outW, sizeof(outW) / sizeof(WCHAR), signed_tests[i].number); 1839 MultiByteToWideChar(CP_ACP, 0, signed_tests[i].expected, -1, expW, sizeof(expW) / sizeof(WCHAR)); 1840 todo_wine { 1841 ok(!lstrcmpW(outW, expW),"[%d] failed, expected %s, got %s\n", i, 1842 signed_tests[i].expected, wine_dbgstr_w(outW)); 1843 ok(r == signed_tests[i].len,"[%d] failed: r=%d\n", i, r); 1844 } 1845 r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!I64d!", 1846 0, 0, outA, sizeof(outA), signed_tests[i].number); 1847 todo_wine { 1848 ok(!strcmp(outA, signed_tests[i].expected),"[%d] failed, expected %s, got %s\n", i, 1849 signed_tests[i].expected, outA); 1850 ok(r == signed_tests[i].len,"[%d] failed: r=%d\n", i, r); 1851 } 1852 } 1853 } 1854 1855 START_TEST(format_msg) 1856 { 1857 DWORD ret; 1858 1859 test_message_from_string(); 1860 test_message_ignore_inserts(); 1861 test_message_wrap(); 1862 test_message_insufficient_buffer(); 1863 test_message_null_buffer(); 1864 test_message_allocate_buffer(); 1865 test_message_from_hmodule(); 1866 test_message_invalid_flags(); 1867 1868 SetLastError(0xdeadbeef); 1869 ret = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, NULL, 0, 0, NULL, 0, NULL); 1870 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) 1871 { 1872 win_skip("FormatMessageW is not implemented\n"); 1873 return; 1874 } 1875 1876 test_message_from_string_wide(); 1877 test_message_ignore_inserts_wide(); 1878 test_message_insufficient_buffer_wide(); 1879 test_message_null_buffer_wide(); 1880 test_message_allocate_buffer_wide(); 1881 test_message_invalid_flags_wide(); 1882 test_message_from_64bit_number(); 1883 } 1884