1 /* 2 * Unit tests for atom functions 3 * 4 * Copyright (c) 2002 Alexandre Julliard 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #include <stdarg.h> 22 #include <stdio.h> 23 24 #include "wine/test.h" 25 #include "windef.h" 26 #include "winbase.h" 27 #include "winerror.h" 28 #include "winuser.h" 29 30 #define DOUBLE(x) (WCHAR)((x<<8)|(x)) 31 32 static const WCHAR foobarW[] = {'f','o','o','b','a','r',0}; 33 static const WCHAR FOOBARW[] = {'F','O','O','B','A','R',0}; 34 static const WCHAR _foobarW[] = {'_','f','o','o','b','a','r',0}; 35 static const WCHAR integfmt[] = {'#','%','d',0}; 36 37 static void do_initA(char* tmp, const char* pattern, int len) 38 { 39 const char* p = pattern; 40 41 while (len--) 42 { 43 *tmp++ = *p++; 44 if (!*p) p = pattern; 45 } 46 *tmp = '\0'; 47 } 48 49 static void do_initW(WCHAR* tmp, const char* pattern, int len) 50 { 51 const char* p = pattern; 52 53 while (len--) 54 { 55 *tmp++ = *p++; 56 if (!*p) p = pattern; 57 } 58 *tmp = '\0'; 59 } 60 61 static BOOL unicode_OS; 62 63 static void test_add_atom(void) 64 { 65 ATOM atom, w_atom; 66 INT_PTR i; 67 68 SetLastError( 0xdeadbeef ); 69 atom = GlobalAddAtomA( "foobar" ); 70 ok( atom >= 0xc000, "bad atom id %x\n", atom ); 71 ok( GetLastError() == 0xdeadbeef, "GlobalAddAtomA set last error\n" ); 72 73 /* Verify that it can be found (or not) appropriately */ 74 ok( GlobalFindAtomA( "foobar" ) == atom, "could not find atom foobar\n" ); 75 ok( GlobalFindAtomA( "FOOBAR" ) == atom, "could not find atom FOOBAR\n" ); 76 ok( !GlobalFindAtomA( "_foobar" ), "found _foobar\n" ); 77 78 /* Add the same atom, specifying string as unicode; should 79 * find the first one, not add a new one */ 80 SetLastError( 0xdeadbeef ); 81 w_atom = GlobalAddAtomW( foobarW ); 82 if (w_atom && GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) 83 unicode_OS = TRUE; 84 else 85 trace("WARNING: Unicode atom APIs are not supported on this platform\n"); 86 87 if (unicode_OS) 88 { 89 ok( w_atom == atom, "Unicode atom does not match ASCII\n" ); 90 ok( GetLastError() == 0xdeadbeef, "GlobalAddAtomW set last error\n" ); 91 } 92 93 /* Verify that it can be found (or not) appropriately via unicode name */ 94 if (unicode_OS) 95 { 96 ok( GlobalFindAtomW( foobarW ) == atom, "could not find atom foobar\n" ); 97 ok( GlobalFindAtomW( FOOBARW ) == atom, "could not find atom FOOBAR\n" ); 98 ok( !GlobalFindAtomW( _foobarW ), "found _foobar\n" ); 99 } 100 101 /* Test integer atoms 102 * (0x0001 .. 0xbfff) should be valid; 103 * (0xc000 .. 0xffff) should be invalid */ 104 105 SetLastError( 0xdeadbeef ); 106 ok( GlobalAddAtomA(0) == 0 && GetLastError() == 0xdeadbeef, "succeeded to add atom 0\n" ); 107 if (unicode_OS) 108 { 109 SetLastError( 0xdeadbeef ); 110 ok( GlobalAddAtomW(0) == 0 && GetLastError() == 0xdeadbeef, "succeeded to add atom 0\n" ); 111 } 112 113 SetLastError( 0xdeadbeef ); 114 for (i = 1; i <= 0xbfff; i++) 115 { 116 SetLastError( 0xdeadbeef ); 117 ok( GlobalAddAtomA((LPCSTR)i) == i && GetLastError() == 0xdeadbeef, 118 "failed to add atom %lx\n", i ); 119 if (unicode_OS) 120 { 121 SetLastError( 0xdeadbeef ); 122 ok( GlobalAddAtomW((LPCWSTR)i) == i && GetLastError() == 0xdeadbeef, 123 "failed to add atom %lx\n", i ); 124 } 125 } 126 127 for (i = 0xc000; i <= 0xffff; i++) 128 { 129 ok( !GlobalAddAtomA((LPCSTR)i), "succeeded adding %lx\n", i ); 130 if (unicode_OS) 131 ok( !GlobalAddAtomW((LPCWSTR)i), "succeeded adding %lx\n", i ); 132 } 133 } 134 135 static void test_get_atom_name(void) 136 { 137 char buf[10]; 138 WCHAR bufW[10]; 139 int i; 140 UINT len; 141 static const WCHAR resultW[] = {'f','o','o','b','a','r',0,'.','.','.'}; 142 char in[257], out[257]; 143 WCHAR inW[257], outW[257]; 144 145 ATOM atom = GlobalAddAtomA( "foobar" ); 146 147 /* Get the name of the atom we added above */ 148 memset( buf, '.', sizeof(buf) ); 149 len = GlobalGetAtomNameA( atom, buf, 10 ); 150 ok( len == strlen("foobar"), "bad length %d\n", len ); 151 ok( !memcmp( buf, "foobar\0...", 10 ), "bad buffer contents\n" ); 152 153 /* Repeat, unicode-style */ 154 if (unicode_OS) 155 { 156 for (i = 0; i < 10; i++) bufW[i] = '.'; 157 SetLastError( 0xdeadbeef ); 158 len = GlobalGetAtomNameW( atom, bufW, 10 ); 159 ok( len && GetLastError() == 0xdeadbeef, "GlobalGetAtomNameW failed\n" ); 160 ok( len == lstrlenW(foobarW), "bad length %d\n", len ); 161 ok( !memcmp( bufW, resultW, 10*sizeof(WCHAR) ), "bad buffer contents\n" ); 162 } 163 164 /* Check error code returns */ 165 memset(buf, '.', 10); 166 ok( !GlobalGetAtomNameA( atom, buf, 0 ), "succeeded\n" ); 167 ok( !memcmp( buf, "..........", 10 ), "should not touch buffer\n" ); 168 169 if (unicode_OS) 170 { 171 static const WCHAR sampleW[] = {'.','.','.','.','.','.','.','.','.','.'}; 172 173 for (i = 0; i < 10; i++) bufW[i] = '.'; 174 ok( !GlobalGetAtomNameW( atom, bufW, 0 ), "succeeded\n" ); 175 ok( !memcmp( bufW, sampleW, sizeof(sampleW) ), "should not touch buffer\n" ); 176 } 177 178 /* Test integer atoms */ 179 for (i = 0; i <= 0xbfff; i++) 180 { 181 memset( buf, 'a', 10 ); 182 len = GlobalGetAtomNameA( (ATOM)i, buf, 10 ); 183 if (i) 184 { 185 char res[20]; 186 ok( (len > 1) && (len < 7), "bad length %d\n", len ); 187 sprintf( res, "#%d", i ); 188 memset( res + strlen(res) + 1, 'a', 10 ); 189 ok( !memcmp( res, buf, 10 ), "bad buffer contents %s\n", buf ); 190 if (len <= 1 || len >= 7) break; /* don't bother testing all of them */ 191 } 192 else 193 ok( !len, "bad length %d\n", len ); 194 195 SetLastError(0xdeadbeef); 196 len = GlobalGetAtomNameA( (ATOM)i, buf, 2); 197 ok(!len, "bad length %d\n", len); 198 ok(GetLastError() == ERROR_MORE_DATA || GetLastError() == ERROR_INVALID_PARAMETER, 199 "wrong error conditions %u for %u\n", GetLastError(), i); 200 } 201 202 memset( buf, '.', sizeof(buf) ); 203 len = GlobalGetAtomNameA( atom, buf, 6 ); 204 ok( len == 0, "bad length %d\n", len ); 205 ok( !memcmp( buf, "fooba\0....", 10 ), "bad buffer contents\n"); 206 if (unicode_OS) 207 { 208 static const WCHAR resW[] = {'f','o','o','b','a','r','.','.','.','.'}; 209 for (len = 0; len < 10; len++) bufW[len] = '.'; 210 SetLastError(0xdeadbeef); 211 len = GlobalGetAtomNameW( atom, bufW, 6 ); 212 ok( len && GetLastError() == 0xdeadbeef, "GlobalGetAtomNameW failed\n" ); 213 ok( len == lstrlenW(foobarW), "bad length %d\n", len ); 214 ok( !memcmp( bufW, resW, 10*sizeof(WCHAR) ), "bad buffer contents\n" ); 215 } 216 217 /* test string limits & overflow */ 218 do_initA(in, "abcdefghij", 255); 219 atom = GlobalAddAtomA(in); 220 ok(atom, "couldn't add atom for %s\n", in); 221 len = GlobalGetAtomNameA(atom, out, sizeof(out)); 222 ok(len == 255, "length mismatch (%u instead of 255)\n", len); 223 for (i = 0; i < 255; i++) 224 { 225 ok(out[i] == "abcdefghij"[i % 10], "wrong string at %i (%c instead of %c)\n", i, out[i], "abcdefghij"[i % 10]); 226 } 227 ok(out[255] == '\0', "wrong end of string\n"); 228 memset(out, '.', sizeof(out)); 229 SetLastError(0xdeadbeef); 230 len = GlobalGetAtomNameA(atom, out, 10); 231 ok(!len, "bad length %d\n", len); 232 ok(GetLastError() == ERROR_MORE_DATA, "wrong error code (%u instead of %u)\n", GetLastError(), ERROR_MORE_DATA); 233 for (i = 0; i < 9; i++) 234 { 235 ok(out[i] == "abcdefghij"[i % 10], "wrong string at %i (%c instead of %c)\n", i, out[i], "abcdefghij"[i % 10]); 236 } 237 ok(out[9] == '\0', "wrong end of string\n"); 238 ok(out[10] == '.', "wrote after end of buf\n"); 239 do_initA(in, "abcdefghij", 256); 240 atom = GlobalAddAtomA(in); 241 ok(!atom, "succeeded\n"); 242 if (unicode_OS) 243 { 244 /* test integral atoms */ 245 for (i = 0; i <= 0xbfff; i++) 246 { 247 memset(outW, 'a', sizeof(outW)); 248 len = GlobalGetAtomNameW( (ATOM)i, outW, 10 ); 249 if (i) 250 { 251 WCHAR res[20]; 252 253 ok( (len > 1) && (len < 7), "bad length %d\n", len ); 254 wsprintfW( res, integfmt, i ); 255 memset( res + lstrlenW(res) + 1, 'a', 10 * sizeof(WCHAR)); 256 ok( !memcmp( res, outW, 10 * sizeof(WCHAR) ), "bad buffer contents for %d\n", i ); 257 if (len <= 1 || len >= 7) break; /* don't bother testing all of them */ 258 } 259 else 260 ok( !len, "bad length %d\n", len ); 261 262 memset(outW, '.', sizeof(outW)); 263 SetLastError(0xdeadbeef); 264 len = GlobalGetAtomNameW( (ATOM)i, outW, 1); 265 if (i) 266 { 267 /* len == 0 with ERROR_MORE_DATA is on NT3.51 */ 268 ok(len == 1 || (len == 0 && GetLastError() == ERROR_MORE_DATA), 269 "0x%04x: got %u with %d (expected '1' or '0' with " 270 "ERROR_MORE_DATA)\n", i, len, GetLastError()); 271 ok(outW[1] == DOUBLE('.'), "buffer overwrite\n"); 272 } 273 else ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "0 badly handled\n"); 274 } 275 276 do_initW(inW, "abcdefghij", 255); 277 atom = GlobalAddAtomW(inW); 278 ok(atom, "couldn't add atom for %s\n", in); 279 len = GlobalGetAtomNameW(atom, outW, sizeof(outW)/sizeof(outW[0])); 280 ok(len == 255, "length mismatch (%u instead of 255)\n", len); 281 for (i = 0; i < 255; i++) 282 { 283 ok(outW[i] == "abcdefghij"[i % 10], "wrong string at %i (%c instead of %c)\n", i, outW[i], "abcdefghij"[i % 10]); 284 } 285 ok(outW[255] == '\0', "wrong end of string\n"); 286 memset(outW, '.', sizeof(outW)); 287 len = GlobalGetAtomNameW(atom, outW, 10); 288 ok(len == 10, "succeeded\n"); 289 for (i = 0; i < 10; i++) 290 { 291 ok(outW[i] == "abcdefghij"[i % 10], "wrong string at %i (%c instead of %c)\n", i, outW[i], "abcdefghij"[i % 10]); 292 } 293 ok(outW[10] == DOUBLE('.'), "wrote after end of buf\n"); 294 do_initW(inW, "abcdefghij", 256); 295 atom = GlobalAddAtomW(inW); 296 ok(!atom, "succeeded\n"); 297 ok(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error code\n"); 298 } 299 } 300 301 static void test_error_handling(void) 302 { 303 char buffer[260]; 304 WCHAR bufferW[260]; 305 int i; 306 307 memset( buffer, 'a', 256 ); 308 buffer[256] = 0; 309 ok( !GlobalAddAtomA(buffer), "add succeeded\n" ); 310 ok( !GlobalFindAtomA(buffer), "find succeeded\n" ); 311 312 if (unicode_OS) 313 { 314 for (i = 0; i < 256; i++) bufferW[i] = 'b'; 315 bufferW[256] = 0; 316 ok( !GlobalAddAtomW(bufferW), "add succeeded\n" ); 317 ok( !GlobalFindAtomW(bufferW), "find succeeded\n" ); 318 } 319 } 320 321 static void test_local_add_atom(void) 322 { 323 ATOM atom, w_atom; 324 INT_PTR i; 325 326 SetLastError( 0xdeadbeef ); 327 atom = AddAtomA( "foobar" ); 328 ok( atom >= 0xc000, "bad atom id %x\n", atom ); 329 ok( GetLastError() == 0xdeadbeef, "AddAtomA set last error\n" ); 330 331 /* Verify that it can be found (or not) appropriately */ 332 ok( FindAtomA( "foobar" ) == atom, "could not find atom foobar\n" ); 333 ok( FindAtomA( "FOOBAR" ) == atom, "could not find atom FOOBAR\n" ); 334 ok( !FindAtomA( "_foobar" ), "found _foobar\n" ); 335 336 /* Add the same atom, specifying string as unicode; should 337 * find the first one, not add a new one */ 338 SetLastError( 0xdeadbeef ); 339 w_atom = AddAtomW( foobarW ); 340 if (w_atom && GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) 341 unicode_OS = TRUE; 342 else 343 trace("WARNING: Unicode atom APIs are not supported on this platform\n"); 344 345 if (unicode_OS) 346 { 347 ok( w_atom == atom, "Unicode atom does not match ASCII\n" ); 348 ok( GetLastError() == 0xdeadbeef, "AddAtomW set last error\n" ); 349 } 350 351 /* Verify that it can be found (or not) appropriately via unicode name */ 352 if (unicode_OS) 353 { 354 ok( FindAtomW( foobarW ) == atom, "could not find atom foobar\n" ); 355 ok( FindAtomW( FOOBARW ) == atom, "could not find atom FOOBAR\n" ); 356 ok( !FindAtomW( _foobarW ), "found _foobar\n" ); 357 } 358 359 /* Test integer atoms 360 * (0x0001 .. 0xbfff) should be valid; 361 * (0xc000 .. 0xffff) should be invalid */ 362 363 SetLastError( 0xdeadbeef ); 364 ok( AddAtomA(0) == 0 && GetLastError() == 0xdeadbeef, "succeeded to add atom 0\n" ); 365 if (unicode_OS) 366 { 367 SetLastError( 0xdeadbeef ); 368 ok( AddAtomW(0) == 0 && GetLastError() == 0xdeadbeef, "succeeded to add atom 0\n" ); 369 } 370 371 SetLastError( 0xdeadbeef ); 372 for (i = 1; i <= 0xbfff; i++) 373 { 374 SetLastError( 0xdeadbeef ); 375 ok( AddAtomA((LPCSTR)i) == i && GetLastError() == 0xdeadbeef, 376 "failed to add atom %lx\n", i ); 377 if (unicode_OS) 378 { 379 SetLastError( 0xdeadbeef ); 380 ok( AddAtomW((LPCWSTR)i) == i && GetLastError() == 0xdeadbeef, 381 "failed to add atom %lx\n", i ); 382 } 383 } 384 385 for (i = 0xc000; i <= 0xffff; i++) 386 { 387 ok( !AddAtomA((LPCSTR)i), "succeeded adding %lx\n", i ); 388 if (unicode_OS) 389 ok( !AddAtomW((LPCWSTR)i), "succeeded adding %lx\n", i ); 390 } 391 } 392 393 static void test_local_get_atom_name(void) 394 { 395 char buf[10], in[257], out[257]; 396 WCHAR bufW[10], inW[257], outW[257]; 397 int i; 398 UINT len; 399 static const WCHAR resultW[] = {'f','o','o','b','a','r',0,'.','.','.'}; 400 401 ATOM atom = AddAtomA( "foobar" ); 402 403 /* Get the name of the atom we added above */ 404 memset( buf, '.', sizeof(buf) ); 405 len = GetAtomNameA( atom, buf, 10 ); 406 ok( len == strlen("foobar"), "bad length %d\n", len ); 407 ok( !memcmp( buf, "foobar\0...", 10 ), "bad buffer contents\n" ); 408 409 /* Repeat, unicode-style */ 410 if (unicode_OS) 411 { 412 for (i = 0; i < 10; i++) bufW[i] = '.'; 413 SetLastError( 0xdeadbeef ); 414 len = GetAtomNameW( atom, bufW, 10 ); 415 ok( len && GetLastError() == 0xdeadbeef, "GetAtomNameW failed\n" ); 416 ok( len == lstrlenW(foobarW), "bad length %d\n", len ); 417 ok( !memcmp( bufW, resultW, 10*sizeof(WCHAR) ), "bad buffer contents\n" ); 418 } 419 420 /* Get the name of the atom we added above */ 421 memset( buf, '.', sizeof(buf) ); 422 len = GetAtomNameA( atom, buf, 6 ); 423 ok( len == 5, "bad length %d\n", len ); 424 ok( !memcmp( buf, "fooba\0....", 10 ), "bad buffer contents\n" ); 425 426 /* Repeat, unicode-style */ 427 if (unicode_OS) 428 { 429 WCHAR resW[] = {'f','o','o','b','a','\0','.','.','.','.'}; 430 for (i = 0; i < 10; i++) bufW[i] = '.'; 431 SetLastError( 0xdeadbeef ); 432 len = GetAtomNameW( atom, bufW, 6 ); 433 ok( len && GetLastError() == 0xdeadbeef, "GlobalGetAtomNameW failed\n" ); 434 ok( len == 5, "bad length %d\n", len ); 435 ok( !memcmp( bufW, resW, 10*sizeof(WCHAR) ), "bad buffer contents\n" ); 436 } 437 438 /* Check error code returns */ 439 memset(buf, '.', 10); 440 ok( !GetAtomNameA( atom, buf, 0 ), "succeeded\n" ); 441 ok( !memcmp( buf, "..........", 10 ), "should not touch buffer\n" ); 442 443 if (unicode_OS) 444 { 445 static const WCHAR sampleW[] = {'.','.','.','.','.','.','.','.','.','.'}; 446 447 for (i = 0; i < 10; i++) bufW[i] = '.'; 448 ok( !GetAtomNameW( atom, bufW, 0 ), "succeeded\n" ); 449 ok( !memcmp( bufW, sampleW, sizeof(sampleW) ), "should not touch buffer\n" ); 450 } 451 452 /* Test integer atoms */ 453 for (i = 0; i <= 0xbfff; i++) 454 { 455 memset( buf, 'a', 10 ); 456 len = GetAtomNameA( (ATOM)i, buf, 10 ); 457 if (i) 458 { 459 char res[20]; 460 ok( (len > 1) && (len < 7), "bad length %d for %s\n", len, buf ); 461 sprintf( res, "#%d", i ); 462 memset( res + strlen(res) + 1, 'a', 10 ); 463 ok( !memcmp( res, buf, 10 ), "bad buffer contents %s\n", buf ); 464 } 465 else 466 ok( !len, "bad length %d\n", len ); 467 468 len = GetAtomNameA( (ATOM)i, buf, 1); 469 ok(!len, "succeed with %u for %u\n", len, i); 470 471 /* ERROR_MORE_DATA is on nt3.51 sp5 */ 472 if (i) 473 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER || 474 GetLastError() == ERROR_MORE_DATA, 475 "wrong error conditions %u for %u\n", GetLastError(), i); 476 else 477 ok(GetLastError() == ERROR_INVALID_PARAMETER || 478 GetLastError() == ERROR_MORE_DATA, 479 "wrong error conditions %u for %u\n", GetLastError(), i); 480 } 481 /* test string limits & overflow */ 482 do_initA(in, "abcdefghij", 255); 483 atom = AddAtomA(in); 484 ok(atom, "couldn't add atom for %s\n", in); 485 len = GetAtomNameA(atom, out, sizeof(out)); 486 ok(len == 255, "length mismatch (%u instead of 255)\n", len); 487 for (i = 0; i < 255; i++) 488 { 489 ok(out[i] == "abcdefghij"[i % 10], "wrong string at %i (%c instead of %c)\n", i, out[i], "abcdefghij"[i % 10]); 490 } 491 ok(out[255] == '\0', "wrong end of string\n"); 492 memset(out, '.', sizeof(out)); 493 len = GetAtomNameA(atom, out, 10); 494 ok(len == 9, "succeeded %d\n", len); 495 for (i = 0; i < 9; i++) 496 { 497 ok(out[i] == "abcdefghij"[i % 10], "wrong string at %i (%c instead of %c)\n", i, out[i], "abcdefghij"[i % 10]); 498 } 499 ok(out[9] == '\0', "wrong end of string\n"); 500 ok(out[10] == '.', "buffer overwrite\n"); 501 do_initA(in, "abcdefghij", 256); 502 atom = AddAtomA(in); 503 ok(!atom, "succeeded\n"); 504 505 /* ERROR_MORE_DATA is on nt3.51 sp5 */ 506 ok(GetLastError() == ERROR_INVALID_PARAMETER || 507 GetLastError() == ERROR_MORE_DATA, 508 "wrong error code (%u)\n", GetLastError()); 509 510 if (unicode_OS) 511 { 512 /* test integral atoms */ 513 for (i = 0; i <= 0xbfff; i++) 514 { 515 memset(outW, 'a', sizeof(outW)); 516 len = GetAtomNameW( (ATOM)i, outW, 10 ); 517 if (i) 518 { 519 WCHAR res[20]; 520 521 ok( (len > 1) && (len < 7), "bad length %d\n", len ); 522 wsprintfW( res, integfmt, i ); 523 memset( res + lstrlenW(res) + 1, 'a', 10 * sizeof(WCHAR)); 524 ok( !memcmp( res, outW, 10 * sizeof(WCHAR) ), "bad buffer contents for %d\n", i ); 525 } 526 else 527 ok( !len, "bad length %d\n", len ); 528 529 len = GetAtomNameW( (ATOM)i, outW, 1); 530 ok(!len, "succeed with %u for %u\n", len, i); 531 532 /* ERROR_MORE_DATA is on nt3.51 sp5 */ 533 ok(GetLastError() == ERROR_MORE_DATA || 534 GetLastError() == (i ? ERROR_INSUFFICIENT_BUFFER : ERROR_INVALID_PARAMETER), 535 "wrong error conditions %u for %u\n", GetLastError(), i); 536 } 537 do_initW(inW, "abcdefghij", 255); 538 atom = AddAtomW(inW); 539 ok(atom, "couldn't add atom for %s\n", in); 540 len = GetAtomNameW(atom, outW, sizeof(outW)/sizeof(outW[0])); 541 ok(len == 255, "length mismatch (%u instead of 255)\n", len); 542 for (i = 0; i < 255; i++) 543 { 544 ok(outW[i] == "abcdefghij"[i % 10], "wrong string at %i (%c instead of %c)\n", i, outW[i], "abcdefghij"[i % 10]); 545 } 546 ok(outW[255] == '\0', "wrong end of string\n"); 547 memset(outW, '.', sizeof(outW)); 548 len = GetAtomNameW(atom, outW, 10); 549 ok(len == 9, "succeeded %d\n", len); 550 for (i = 0; i < 9; i++) 551 { 552 ok(outW[i] == "abcdefghij"[i % 10], "wrong string at %i (%c instead of %c)\n", i, outW[i], "abcdefghij"[i % 10]); 553 } 554 ok(outW[9] == '\0', "wrong end of string\n"); 555 ok(outW[10] == DOUBLE('.'), "buffer overwrite\n"); 556 do_initW(inW, "abcdefghij", 256); 557 atom = AddAtomW(inW); 558 ok(!atom, "succeeded\n"); 559 560 /* ERROR_MORE_DATA is on nt3.51 sp5 */ 561 ok(GetLastError() == ERROR_INVALID_PARAMETER || 562 GetLastError() == ERROR_MORE_DATA, 563 "wrong error code (%u)\n", GetLastError()); 564 } 565 } 566 567 static void test_local_error_handling(void) 568 { 569 char buffer[260]; 570 WCHAR bufferW[260]; 571 int i; 572 573 memset( buffer, 'a', 256 ); 574 buffer[256] = 0; 575 ok( !AddAtomA(buffer), "add succeeded\n" ); 576 ok( !FindAtomA(buffer), "find succeeded\n" ); 577 578 if (unicode_OS) 579 { 580 for (i = 0; i < 256; i++) bufferW[i] = 'b'; 581 bufferW[256] = 0; 582 ok( !AddAtomW(bufferW), "add succeeded\n" ); 583 ok( !FindAtomW(bufferW), "find succeeded\n" ); 584 } 585 } 586 587 START_TEST(atom) 588 { 589 /* Global atom table seems to be available to GUI apps only in 590 Win7, so let's turn this app into a GUI app */ 591 GetDesktopWindow(); 592 593 test_add_atom(); 594 test_get_atom_name(); 595 test_error_handling(); 596 test_local_add_atom(); 597 test_local_get_atom_name(); 598 test_local_error_handling(); 599 } 600