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