1 /* 2 * PROJECT: ReactOS API tests 3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) 4 * PURPOSE: Test for advpack.dll DelNode function 5 * COPYRIGHT: Copyright 2023 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com> 6 */ 7 #include <apitest.h> 8 9 #include <windef.h> 10 #include <stdio.h> 11 12 /* Flags for DelNode */ 13 #define ADN_DEL_IF_EMPTY 0x00000001 14 #define ADN_DONT_DEL_SUBDIRS 0x00000002 15 #define ADN_DONT_DEL_DIR 0x00000004 16 #define ADN_DEL_UNC_PATHS 0x00000008 17 18 /* DelNodeA and DelNodeW in advpack.dll */ 19 typedef HRESULT (WINAPI *DELNODEA)(LPCSTR, DWORD); 20 typedef HRESULT (WINAPI *DELNODEW)(LPCWSTR, DWORD); 21 22 static HINSTANCE s_hAdvPack = NULL; 23 static DELNODEA s_pDelNodeA = NULL; 24 static DELNODEW s_pDelNodeW = NULL; 25 26 typedef struct 27 { 28 const char *item; 29 BOOL is_dir; 30 } NODEA; 31 32 static const NODEA s_nodesA[] = 33 { 34 { "dir1", TRUE }, /* 0 */ 35 { "dir1\\dir2", TRUE }, /* 1 */ 36 { "dir1\\dir2\\file1", FALSE }, /* 2 */ 37 }; 38 39 typedef struct 40 { 41 const WCHAR *item; 42 BOOL is_dir; 43 } NODEW; 44 45 static const NODEW s_nodesW[] = 46 { 47 { L"dir1", TRUE }, /* 0 */ 48 { L"dir1\\dir2", TRUE }, /* 1 */ 49 { L"dir1\\dir2\\file1", FALSE }, /* 2 */ 50 }; 51 52 typedef enum 53 { 54 EAT_CREATE, 55 EAT_DELETE, 56 EAT_CHECK_EXIST, 57 EAT_CHECK_NON_EXIST, 58 EAT_CALL 59 } ENTRY_ACTION_TYPE; 60 61 typedef struct 62 { 63 INT lineno; 64 INT node; 65 ENTRY_ACTION_TYPE action_type; 66 DWORD flags; 67 HRESULT ret; 68 } ENTRY; 69 70 /* TODO: ADN_DEL_UNC_PATHS */ 71 #define FLAGS0 0 72 #define FLAGS1 ADN_DEL_IF_EMPTY 73 #define FLAGS2 ADN_DONT_DEL_DIR 74 #define FLAGS3 ADN_DONT_DEL_SUBDIRS 75 #define FLAGS4 (ADN_DONT_DEL_DIR | ADN_DONT_DEL_SUBDIRS) 76 #define FLAGS5 (ADN_DEL_IF_EMPTY | ADN_DONT_DEL_DIR) 77 #define FLAGS6 (ADN_DEL_IF_EMPTY | ADN_DONT_DEL_SUBDIRS) 78 #define FLAGS7 (ADN_DEL_IF_EMPTY | ADN_DONT_DEL_DIR | ADN_DONT_DEL_SUBDIRS) 79 #define FLAGS8 0xFFFFFFFF 80 81 /* The test entries */ 82 static const ENTRY s_entries[] = 83 { 84 { __LINE__, 0, EAT_CREATE }, 85 { __LINE__, 1, EAT_CREATE }, 86 { __LINE__, 1, EAT_DELETE }, 87 { __LINE__, 0, EAT_DELETE }, 88 89 { __LINE__, 0, EAT_CREATE }, 90 { __LINE__, 1, EAT_CREATE }, 91 { __LINE__, 0, EAT_CALL, FLAGS0, S_OK }, 92 { __LINE__, 0, EAT_CHECK_NON_EXIST }, 93 94 { __LINE__, 0, EAT_CREATE }, 95 { __LINE__, 1, EAT_CREATE }, 96 { __LINE__, 0, EAT_CALL, FLAGS1, E_FAIL }, 97 { __LINE__, 0, EAT_CHECK_EXIST }, 98 99 { __LINE__, 0, EAT_CREATE }, 100 { __LINE__, 1, EAT_CREATE }, 101 { __LINE__, 0, EAT_CALL, FLAGS2, S_OK }, 102 { __LINE__, 0, EAT_CHECK_EXIST }, 103 104 { __LINE__, 0, EAT_CREATE }, 105 { __LINE__, 1, EAT_CREATE }, 106 { __LINE__, 0, EAT_CALL, FLAGS3, S_OK }, 107 { __LINE__, 0, EAT_CHECK_EXIST }, 108 109 { __LINE__, 0, EAT_CREATE }, 110 { __LINE__, 1, EAT_CREATE }, 111 { __LINE__, 0, EAT_CALL, FLAGS4, S_OK }, 112 { __LINE__, 0, EAT_CHECK_EXIST }, 113 114 { __LINE__, 0, EAT_CREATE }, 115 { __LINE__, 1, EAT_CREATE }, 116 { __LINE__, 0, EAT_CALL, FLAGS5, E_FAIL }, 117 { __LINE__, 0, EAT_CHECK_EXIST }, 118 119 { __LINE__, 0, EAT_CREATE }, 120 { __LINE__, 1, EAT_CREATE }, 121 { __LINE__, 0, EAT_CALL, FLAGS6, E_FAIL }, 122 { __LINE__, 0, EAT_CHECK_EXIST }, 123 124 { __LINE__, 0, EAT_CREATE }, 125 { __LINE__, 1, EAT_CREATE }, 126 { __LINE__, 0, EAT_CALL, FLAGS7, E_FAIL }, 127 { __LINE__, 0, EAT_CHECK_EXIST }, 128 129 { __LINE__, 0, EAT_CREATE }, 130 { __LINE__, 1, EAT_CREATE }, 131 { __LINE__, 0, EAT_CALL, FLAGS8, E_FAIL }, 132 { __LINE__, 0, EAT_CHECK_EXIST }, 133 134 { __LINE__, 0, EAT_CREATE }, 135 { __LINE__, 1, EAT_CREATE }, 136 { __LINE__, 2, EAT_CREATE }, 137 { __LINE__, 0, EAT_CALL, FLAGS0, S_OK }, 138 { __LINE__, 0, EAT_CHECK_NON_EXIST }, 139 140 { __LINE__, 0, EAT_CREATE }, 141 { __LINE__, 1, EAT_CREATE }, 142 { __LINE__, 2, EAT_CREATE }, 143 { __LINE__, 0, EAT_CALL, FLAGS1, E_FAIL }, 144 { __LINE__, 0, EAT_CHECK_EXIST }, 145 { __LINE__, 1, EAT_CHECK_EXIST }, 146 { __LINE__, 2, EAT_CHECK_EXIST }, 147 148 { __LINE__, 0, EAT_CREATE }, 149 { __LINE__, 1, EAT_CREATE }, 150 { __LINE__, 2, EAT_CREATE }, 151 { __LINE__, 0, EAT_CALL, FLAGS2, S_OK }, 152 { __LINE__, 0, EAT_CHECK_EXIST }, 153 { __LINE__, 1, EAT_CHECK_NON_EXIST }, 154 { __LINE__, 2, EAT_CHECK_NON_EXIST }, 155 156 { __LINE__, 0, EAT_CREATE }, 157 { __LINE__, 1, EAT_CREATE }, 158 { __LINE__, 2, EAT_CREATE }, 159 { __LINE__, 0, EAT_CALL, FLAGS3, S_OK }, 160 { __LINE__, 0, EAT_CHECK_EXIST }, 161 { __LINE__, 1, EAT_CHECK_EXIST }, 162 { __LINE__, 2, EAT_CHECK_EXIST }, 163 164 { __LINE__, 0, EAT_CREATE }, 165 { __LINE__, 1, EAT_CREATE }, 166 { __LINE__, 2, EAT_CREATE }, 167 { __LINE__, 0, EAT_CALL, FLAGS4, S_OK }, 168 { __LINE__, 0, EAT_CHECK_EXIST }, 169 { __LINE__, 1, EAT_CHECK_EXIST }, 170 { __LINE__, 2, EAT_CHECK_EXIST }, 171 172 { __LINE__, 0, EAT_CREATE }, 173 { __LINE__, 1, EAT_CREATE }, 174 { __LINE__, 2, EAT_CREATE }, 175 { __LINE__, 0, EAT_CALL, FLAGS5, E_FAIL }, 176 { __LINE__, 0, EAT_CHECK_EXIST }, 177 { __LINE__, 1, EAT_CHECK_EXIST }, 178 { __LINE__, 2, EAT_CHECK_EXIST }, 179 180 { __LINE__, 0, EAT_CREATE }, 181 { __LINE__, 1, EAT_CREATE }, 182 { __LINE__, 2, EAT_CREATE }, 183 { __LINE__, 0, EAT_CALL, FLAGS6, E_FAIL }, 184 { __LINE__, 0, EAT_CHECK_EXIST }, 185 { __LINE__, 1, EAT_CHECK_EXIST }, 186 { __LINE__, 2, EAT_CHECK_EXIST }, 187 188 { __LINE__, 0, EAT_CREATE }, 189 { __LINE__, 1, EAT_CREATE }, 190 { __LINE__, 2, EAT_CREATE }, 191 { __LINE__, 0, EAT_CALL, FLAGS7, E_FAIL }, 192 { __LINE__, 0, EAT_CHECK_EXIST }, 193 { __LINE__, 1, EAT_CHECK_EXIST }, 194 { __LINE__, 2, EAT_CHECK_EXIST }, 195 196 { __LINE__, 0, EAT_CREATE }, 197 { __LINE__, 1, EAT_CREATE }, 198 { __LINE__, 2, EAT_CREATE }, 199 { __LINE__, 0, EAT_CALL, FLAGS8, E_FAIL }, 200 { __LINE__, 0, EAT_CHECK_EXIST }, 201 { __LINE__, 1, EAT_CHECK_EXIST }, 202 { __LINE__, 2, EAT_CHECK_EXIST }, 203 204 { __LINE__, 1, EAT_CREATE }, 205 { __LINE__, 2, EAT_CREATE }, 206 { __LINE__, 1, EAT_CALL, FLAGS0, S_OK }, 207 { __LINE__, 1, EAT_CHECK_NON_EXIST }, 208 209 { __LINE__, 1, EAT_CREATE }, 210 { __LINE__, 2, EAT_CREATE }, 211 { __LINE__, 1, EAT_CALL, FLAGS1, E_FAIL }, 212 { __LINE__, 1, EAT_CHECK_EXIST }, 213 { __LINE__, 2, EAT_CHECK_EXIST }, 214 215 { __LINE__, 1, EAT_CREATE }, 216 { __LINE__, 2, EAT_CREATE }, 217 { __LINE__, 1, EAT_CALL, FLAGS2, S_OK }, 218 { __LINE__, 1, EAT_CHECK_EXIST }, 219 { __LINE__, 2, EAT_CHECK_NON_EXIST }, 220 221 { __LINE__, 1, EAT_CREATE }, 222 { __LINE__, 2, EAT_CREATE }, 223 { __LINE__, 1, EAT_CALL, FLAGS3, S_OK }, 224 { __LINE__, 1, EAT_CHECK_NON_EXIST }, 225 226 { __LINE__, 1, EAT_CREATE }, 227 { __LINE__, 2, EAT_CREATE }, 228 { __LINE__, 1, EAT_CALL, FLAGS4, S_OK }, 229 { __LINE__, 1, EAT_CHECK_EXIST }, 230 { __LINE__, 2, EAT_CHECK_NON_EXIST }, 231 232 { __LINE__, 1, EAT_CREATE }, 233 { __LINE__, 2, EAT_CREATE }, 234 { __LINE__, 1, EAT_CALL, FLAGS5, E_FAIL }, 235 { __LINE__, 1, EAT_CHECK_EXIST }, 236 { __LINE__, 2, EAT_CHECK_EXIST }, 237 238 { __LINE__, 1, EAT_CREATE }, 239 { __LINE__, 2, EAT_CREATE }, 240 { __LINE__, 1, EAT_CALL, FLAGS6, E_FAIL }, 241 { __LINE__, 1, EAT_CHECK_EXIST }, 242 { __LINE__, 2, EAT_CHECK_EXIST }, 243 244 { __LINE__, 1, EAT_CREATE }, 245 { __LINE__, 2, EAT_CREATE }, 246 { __LINE__, 1, EAT_CALL, FLAGS7, E_FAIL }, 247 { __LINE__, 1, EAT_CHECK_EXIST }, 248 { __LINE__, 2, EAT_CHECK_EXIST }, 249 250 { __LINE__, 1, EAT_CREATE }, 251 { __LINE__, 2, EAT_CREATE }, 252 { __LINE__, 1, EAT_CALL, FLAGS8, E_FAIL }, 253 { __LINE__, 1, EAT_CHECK_EXIST }, 254 { __LINE__, 2, EAT_CHECK_EXIST }, 255 256 { __LINE__, 2, EAT_DELETE }, 257 258 { __LINE__, 1, EAT_CREATE }, 259 { __LINE__, 1, EAT_CALL, FLAGS0, S_OK }, 260 { __LINE__, 1, EAT_CHECK_NON_EXIST }, 261 262 { __LINE__, 1, EAT_CREATE }, 263 { __LINE__, 1, EAT_CALL, FLAGS1, S_OK }, 264 { __LINE__, 1, EAT_CHECK_NON_EXIST }, 265 266 { __LINE__, 1, EAT_CREATE }, 267 { __LINE__, 1, EAT_CALL, FLAGS2, S_OK }, 268 { __LINE__, 1, EAT_CHECK_EXIST }, 269 270 { __LINE__, 1, EAT_CREATE }, 271 { __LINE__, 1, EAT_CALL, FLAGS3, S_OK }, 272 { __LINE__, 1, EAT_CHECK_NON_EXIST }, 273 274 { __LINE__, 1, EAT_CREATE }, 275 { __LINE__, 1, EAT_CALL, FLAGS4, S_OK }, 276 { __LINE__, 1, EAT_CHECK_EXIST }, 277 278 { __LINE__, 1, EAT_CREATE }, 279 { __LINE__, 1, EAT_CALL, FLAGS5, S_OK }, 280 { __LINE__, 1, EAT_CHECK_NON_EXIST }, 281 282 { __LINE__, 1, EAT_CREATE }, 283 { __LINE__, 1, EAT_CALL, FLAGS6, S_OK }, 284 { __LINE__, 1, EAT_CHECK_NON_EXIST }, 285 286 { __LINE__, 1, EAT_CREATE }, 287 { __LINE__, 1, EAT_CALL, FLAGS7, S_OK }, 288 { __LINE__, 1, EAT_CHECK_NON_EXIST }, 289 290 { __LINE__, 1, EAT_CREATE }, 291 { __LINE__, 1, EAT_CALL, FLAGS8, S_OK }, 292 { __LINE__, 1, EAT_CHECK_NON_EXIST }, 293 294 { __LINE__, 1, EAT_CREATE }, 295 296 { __LINE__, 2, EAT_CREATE }, 297 { __LINE__, 2, EAT_CALL, FLAGS0, S_OK }, 298 { __LINE__, 2, EAT_CHECK_NON_EXIST }, 299 300 { __LINE__, 2, EAT_CREATE }, 301 { __LINE__, 2, EAT_CALL, FLAGS1, S_OK }, 302 { __LINE__, 2, EAT_CHECK_NON_EXIST }, 303 304 { __LINE__, 2, EAT_CREATE }, 305 { __LINE__, 2, EAT_CALL, FLAGS2, S_OK }, 306 { __LINE__, 2, EAT_CHECK_NON_EXIST }, 307 308 { __LINE__, 2, EAT_CREATE }, 309 { __LINE__, 2, EAT_CALL, FLAGS3, S_OK }, 310 { __LINE__, 2, EAT_CHECK_NON_EXIST }, 311 312 { __LINE__, 2, EAT_CREATE }, 313 { __LINE__, 2, EAT_CALL, FLAGS4, S_OK }, 314 { __LINE__, 2, EAT_CHECK_NON_EXIST }, 315 316 { __LINE__, 2, EAT_CREATE }, 317 { __LINE__, 2, EAT_CALL, FLAGS5, S_OK }, 318 { __LINE__, 2, EAT_CHECK_NON_EXIST }, 319 320 { __LINE__, 2, EAT_CREATE }, 321 { __LINE__, 2, EAT_CALL, FLAGS6, S_OK }, 322 { __LINE__, 2, EAT_CHECK_NON_EXIST }, 323 324 { __LINE__, 2, EAT_CREATE }, 325 { __LINE__, 2, EAT_CALL, FLAGS7, S_OK }, 326 { __LINE__, 2, EAT_CHECK_NON_EXIST }, 327 328 { __LINE__, 2, EAT_CREATE }, 329 { __LINE__, 2, EAT_CALL, FLAGS8, S_OK }, 330 { __LINE__, 2, EAT_CHECK_NON_EXIST }, 331 332 { __LINE__, 2, EAT_DELETE }, 333 { __LINE__, 1, EAT_DELETE }, 334 { __LINE__, 0, EAT_DELETE }, 335 336 { __LINE__, 2, EAT_CALL, FLAGS0, E_FAIL }, 337 { __LINE__, 2, EAT_CALL, FLAGS1, E_FAIL }, 338 { __LINE__, 2, EAT_CALL, FLAGS2, E_FAIL }, 339 { __LINE__, 2, EAT_CALL, FLAGS3, E_FAIL }, 340 { __LINE__, 2, EAT_CALL, FLAGS4, E_FAIL }, 341 { __LINE__, 2, EAT_CALL, FLAGS5, E_FAIL }, 342 { __LINE__, 2, EAT_CALL, FLAGS6, E_FAIL }, 343 { __LINE__, 2, EAT_CALL, FLAGS7, E_FAIL }, 344 { __LINE__, 2, EAT_CALL, FLAGS8, E_FAIL }, 345 346 { __LINE__, 1, EAT_CALL, FLAGS0, E_FAIL }, 347 { __LINE__, 1, EAT_CALL, FLAGS1, E_FAIL }, 348 { __LINE__, 1, EAT_CALL, FLAGS2, E_FAIL }, 349 { __LINE__, 1, EAT_CALL, FLAGS3, E_FAIL }, 350 { __LINE__, 1, EAT_CALL, FLAGS4, E_FAIL }, 351 { __LINE__, 1, EAT_CALL, FLAGS5, E_FAIL }, 352 { __LINE__, 1, EAT_CALL, FLAGS6, E_FAIL }, 353 { __LINE__, 1, EAT_CALL, FLAGS7, E_FAIL }, 354 { __LINE__, 1, EAT_CALL, FLAGS8, E_FAIL }, 355 }; 356 357 static char s_cur_dir_A[MAX_PATH] = ""; 358 static WCHAR s_cur_dir_W[MAX_PATH] = L""; 359 360 static char *GetPathA(const char *item) 361 { 362 static char s_path[MAX_PATH]; 363 lstrcpyA(s_path, s_cur_dir_A); 364 lstrcatA(s_path, "\\"); 365 lstrcatA(s_path, item); 366 return s_path; 367 } 368 369 static WCHAR *GetPathW(const WCHAR *item) 370 { 371 static WCHAR s_path[MAX_PATH]; 372 lstrcpyW(s_path, s_cur_dir_W); 373 lstrcatW(s_path, L"\\"); 374 lstrcatW(s_path, item); 375 return s_path; 376 } 377 378 static void cleanupA(void) 379 { 380 size_t i, k; 381 for (k = 0; k < 4; ++k) 382 { 383 for (i = 0; i < _countof(s_nodesA); ++i) 384 { 385 const NODEA *node = &s_nodesA[i]; 386 char *path = GetPathA(node->item); 387 388 DeleteFileA(path); 389 RemoveDirectoryA(path); 390 } 391 } 392 } 393 394 static void Test_DelNodeA(void) 395 { 396 DWORD attr; 397 size_t i; 398 399 if (!GetCurrentDirectoryA(_countof(s_cur_dir_A), s_cur_dir_A)) 400 { 401 skip("GetCurrentDirectoryA failed\n"); 402 return; 403 } 404 405 cleanupA(); 406 407 for (i = 0; i < _countof(s_entries); ++i) 408 { 409 const ENTRY *entry = &s_entries[i]; 410 INT lineno = entry->lineno; 411 const NODEA *node = &s_nodesA[entry->node]; 412 char *path = GetPathA(node->item); 413 INT ret; 414 415 switch (entry->action_type) 416 { 417 case EAT_CREATE: 418 if (node->is_dir) 419 { 420 CreateDirectoryA(path, NULL); 421 422 attr = GetFileAttributesA(path); 423 ok(attr != INVALID_FILE_ATTRIBUTES, "Line %d: path:%s, attr:0x%08lX\n", lineno, path, attr); 424 ok((attr & FILE_ATTRIBUTE_DIRECTORY), "Line %d: path:%s, attr:0x%08lX\n", lineno, path, attr); 425 } 426 else 427 { 428 fclose(fopen(path, "w")); 429 430 attr = GetFileAttributesA(path); 431 ok(attr != INVALID_FILE_ATTRIBUTES, "Line %d: attr was 0x%08lX\n", lineno, attr); 432 ok(!(attr & FILE_ATTRIBUTE_DIRECTORY), "Line %d: attr was 0x%08lX\n", lineno, attr); 433 } 434 break; 435 case EAT_DELETE: 436 if (node->is_dir) 437 { 438 RemoveDirectoryA(path); 439 } 440 else 441 { 442 DeleteFileA(path); 443 } 444 attr = GetFileAttributesA(path); 445 ok(attr == INVALID_FILE_ATTRIBUTES, "Line %d: cannot delete\n", lineno); 446 break; 447 case EAT_CHECK_EXIST: 448 attr = GetFileAttributesA(path); 449 ok(attr != INVALID_FILE_ATTRIBUTES, "Line %d: attr was 0x%08lX\n", lineno, attr); 450 break; 451 case EAT_CHECK_NON_EXIST: 452 attr = GetFileAttributesA(path); 453 ok(attr == INVALID_FILE_ATTRIBUTES, "Line %d: attr was 0x%08lX\n", lineno, attr); 454 break; 455 case EAT_CALL: 456 ret = (*s_pDelNodeA)(path, entry->flags); 457 ok(ret == entry->ret, "Line %d: ret:%d, path:%s, flags:0x%08lX\n", 458 lineno, ret, path, entry->flags); 459 break; 460 } 461 } 462 463 cleanupA(); 464 } 465 466 static void cleanupW(void) 467 { 468 size_t i, k; 469 for (k = 0; k < 4; ++k) 470 { 471 for (i = 0; i < _countof(s_nodesW); ++i) 472 { 473 const NODEW *node = &s_nodesW[i]; 474 WCHAR *path = GetPathW(node->item); 475 476 DeleteFileW(path); 477 RemoveDirectoryW(path); 478 } 479 } 480 } 481 482 static void Test_DelNodeW(void) 483 { 484 DWORD attr; 485 size_t i; 486 487 if (!GetCurrentDirectoryW(_countof(s_cur_dir_W), s_cur_dir_W)) 488 { 489 skip("GetCurrentDirectoryA failed\n"); 490 return; 491 } 492 493 cleanupW(); 494 495 for (i = 0; i < _countof(s_entries); ++i) 496 { 497 const ENTRY *entry = &s_entries[i]; 498 INT lineno = entry->lineno; 499 const NODEW *node = &s_nodesW[entry->node]; 500 WCHAR *path = GetPathW(node->item); 501 INT ret; 502 503 switch (entry->action_type) 504 { 505 case EAT_CREATE: 506 if (node->is_dir) 507 { 508 CreateDirectoryW(path, NULL); 509 510 attr = GetFileAttributesW(path); 511 ok(attr != INVALID_FILE_ATTRIBUTES, "Line %d: path:%S, attr:0x%08lX\n", lineno, path, attr); 512 ok((attr & FILE_ATTRIBUTE_DIRECTORY), "Line %d: path:%S, attr:0x%08lX\n", lineno, path, attr); 513 } 514 else 515 { 516 fclose(_wfopen(path, L"w")); 517 518 attr = GetFileAttributesW(path); 519 ok(attr != INVALID_FILE_ATTRIBUTES, "Line %d: attr was 0x%08lX\n", lineno, attr); 520 ok(!(attr & FILE_ATTRIBUTE_DIRECTORY), "Line %d: attr was 0x%08lX\n", lineno, attr); 521 } 522 break; 523 case EAT_DELETE: 524 if (node->is_dir) 525 { 526 RemoveDirectoryW(path); 527 } 528 else 529 { 530 DeleteFileW(path); 531 } 532 attr = GetFileAttributesW(path); 533 ok(attr == INVALID_FILE_ATTRIBUTES, "Line %d: cannot delete\n", lineno); 534 break; 535 case EAT_CHECK_EXIST: 536 attr = GetFileAttributesW(path); 537 ok(attr != INVALID_FILE_ATTRIBUTES, "Line %d: attr was 0x%08lX\n", lineno, attr); 538 break; 539 case EAT_CHECK_NON_EXIST: 540 attr = GetFileAttributesW(path); 541 ok(attr == INVALID_FILE_ATTRIBUTES, "Line %d: attr was 0x%08lX\n", lineno, attr); 542 break; 543 case EAT_CALL: 544 ret = (*s_pDelNodeW)(path, entry->flags); 545 ok(ret == entry->ret, "Line %d: ret:%d, path:%S, flags:0x%08lX\n", 546 lineno, ret, path, entry->flags); 547 break; 548 } 549 } 550 551 cleanupW(); 552 } 553 554 START_TEST(DelNode) 555 { 556 s_hAdvPack = LoadLibraryA("advpack.dll"); 557 if (s_hAdvPack == NULL) 558 { 559 skip("unable to load advpack.dll\n"); 560 return; 561 } 562 563 /* DelNodeA */ 564 s_pDelNodeA = (DELNODEA)GetProcAddress(s_hAdvPack, "DelNodeA"); 565 if (s_pDelNodeA) 566 { 567 Test_DelNodeA(); 568 } 569 else 570 { 571 skip("DelNodeA not found in advpack.dll\n"); 572 } 573 574 /* DelNodeW */ 575 s_pDelNodeW = (DELNODEW)GetProcAddress(s_hAdvPack, "DelNodeW"); 576 if (s_pDelNodeW) 577 { 578 Test_DelNodeW(); 579 } 580 else 581 { 582 skip("DelNodeW not found in advpack.dll\n"); 583 } 584 585 FreeLibrary(s_hAdvPack); 586 s_hAdvPack = NULL; 587 } 588