Reactos

[SETUPAPI] Sync setupapi/queue.c to Wine 4.8 (#5233)

Sync setupapi/queue.c to Wine 4.8 to improve cab extraction.
This fixes 'fixme:(dll/win32/setupapi/queue.c:418) awful hack: extracting cabinet'

authored by

Doug Lyons and committed by
GitHub
5c8ec78b a0d747fa

+55 -103
+54 -102
dll/win32/setupapi/queue.c
··· 361 361 return PARSER_get_dest_dir( &context ); 362 362 } 363 363 364 + struct extract_cab_ctx 365 + { 366 + const WCHAR *src; 367 + const WCHAR *dst; 368 + }; 364 369 365 - #ifndef __REACTOS__ 366 - static void (WINAPI *pExtractFiles)( LPSTR, LPSTR, DWORD, DWORD, DWORD, DWORD ); 367 - #else 368 - static void (WINAPI *pExtractFiles)( LPSTR, LPSTR, DWORD, LPSTR, LPVOID, DWORD ); 369 - #endif 370 + static UINT WINAPI extract_cab_cb( void *arg, UINT message, UINT_PTR param1, UINT_PTR param2 ) 371 + { 372 + struct extract_cab_ctx *ctx = arg; 373 + 374 + switch (message) 375 + { 376 + case SPFILENOTIFY_FILEINCABINET: 377 + { 378 + FILE_IN_CABINET_INFO_W *info = (FILE_IN_CABINET_INFO_W *)param1; 379 + const WCHAR *filename; 380 + 381 + if ((filename = strrchrW( info->NameInCabinet, '\\' ))) 382 + filename++; 383 + else 384 + filename = info->NameInCabinet; 385 + 386 + if (lstrcmpiW( filename, ctx->src )) 387 + return FILEOP_SKIP; 388 + 389 + strcpyW( info->FullTargetName, ctx->dst ); 390 + return FILEOP_DOIT; 391 + } 392 + case SPFILENOTIFY_FILEEXTRACTED: 393 + { 394 + const FILEPATHS_W *paths = (const FILEPATHS_W *)param1; 395 + return paths->Win32Error; 396 + } 397 + case SPFILENOTIFY_NEEDNEWCABINET: 398 + { 399 + const CABINET_INFO_W *info = (const CABINET_INFO_W *)param1; 400 + strcpyW( (WCHAR *)param2, info->CabinetPath ); 401 + return ERROR_SUCCESS; 402 + } 403 + case SPFILENOTIFY_CABINETINFO: 404 + return 0; 405 + default: 406 + FIXME("Unexpected message %#x.\n", message); 407 + return 0; 408 + } 409 + } 370 410 371 411 /*********************************************************************** 372 412 * extract_cabinet_file ··· 379 419 #ifndef __REACTOS__ 380 420 static const WCHAR extW[] = {'.','c','a','b',0}; 381 421 #endif 382 - static HMODULE advpack; 383 - 384 - char *cab_path, *cab_file; 385 - int len = strlenW( cabinet ); 422 + static const WCHAR backslashW[] = {'\\',0}; 423 + WCHAR path[MAX_PATH]; 424 + struct extract_cab_ctx ctx = {src, dst}; 386 425 387 426 #ifdef __REACTOS__ 388 427 TRACE("extract_cabinet_file(cab = '%s' ; root = '%s' ; src = '%s' ; dst = '%s')\n", 389 428 debugstr_w(cabinet), debugstr_w(root), debugstr_w(src), debugstr_w(dst)); 390 429 #else 430 + int len = strlenW( cabinet ); 391 431 /* make sure the cabinet file has a .cab extension */ 392 432 if (len <= 4 || strcmpiW( cabinet + len - 4, extW )) return FALSE; 393 433 #endif 394 - if (!pExtractFiles) 395 - { 396 - if (!advpack && !(advpack = LoadLibraryA( "advpack.dll" ))) 397 - { 398 - ERR( "could not load advpack.dll\n" ); 399 - return FALSE; 400 - } 401 - if (!(pExtractFiles = (void *)GetProcAddress( advpack, "ExtractFiles" ))) 402 - { 403 - ERR( "could not find ExtractFiles in advpack.dll\n" ); 404 - return FALSE; 405 - } 406 - } 407 - 408 - if (!(cab_path = strdupWtoA( root ))) return FALSE; 409 - len = WideCharToMultiByte( CP_ACP, 0, cabinet, -1, NULL, 0, NULL, NULL ); 410 - if (!(cab_file = HeapAlloc( GetProcessHeap(), 0, strlen(cab_path) + len + 1 ))) 411 - { 412 - HeapFree( GetProcessHeap(), 0, cab_path ); 413 - return FALSE; 414 - } 415 - strcpy( cab_file, cab_path ); 416 - if (cab_file[0] && cab_file[strlen(cab_file)-1] != '\\') strcat( cab_file, "\\" ); 417 - WideCharToMultiByte( CP_ACP, 0, cabinet, -1, cab_file + strlen(cab_file), len, NULL, NULL ); 418 - FIXME( "awful hack: extracting cabinet %s\n", debugstr_a(cab_file) ); 419 - 420 - #ifdef __REACTOS__ 421 - { 422 - BOOL Success; 423 - char *src_file; 424 - const WCHAR *src_fileW; 425 - WCHAR TempPath[MAX_PATH]; 434 + strcpyW(path, root); 435 + strcatW(path, backslashW); 436 + strcatW(path, cabinet); 426 437 427 - /* Retrieve the temporary path */ 428 - if (!GetTempPathW(ARRAYSIZE(TempPath), TempPath)) 429 - { 430 - ERR("GetTempPathW error\n"); 431 - HeapFree( GetProcessHeap(), 0, cab_file ); 432 - return FALSE; 433 - } 434 - 435 - /* Build the real path to where the file will be extracted */ 436 - HeapFree( GetProcessHeap(), 0, cab_path ); 437 - if (!(cab_path = strdupWtoA( TempPath ))) 438 - { 439 - HeapFree( GetProcessHeap(), 0, cab_file ); 440 - return FALSE; 441 - } 442 - 443 - /* Build the file list */ 444 - src_fileW = strrchrW(src, '\\'); // Find where the filename starts. 445 - if (src_fileW) ++src_fileW; 446 - else src_fileW = src; 447 - /* Convert to ANSI */ 448 - if (!(src_file = strdupWtoA( src_fileW ))) 449 - { 450 - HeapFree( GetProcessHeap(), 0, cab_file ); 451 - HeapFree( GetProcessHeap(), 0, cab_path ); 452 - return FALSE; 453 - } 454 - 455 - /* Prepare for the move operation */ 456 - /* Build the full path to the extracted file, that will be renamed */ 457 - if (!(src = HeapAlloc( GetProcessHeap(), 0, (strlenW(TempPath) + 1 + strlenW(src_fileW) + 1) * sizeof(WCHAR) ))) 458 - { 459 - HeapFree( GetProcessHeap(), 0, src_file ); 460 - HeapFree( GetProcessHeap(), 0, cab_file ); 461 - HeapFree( GetProcessHeap(), 0, cab_path ); 462 - return FALSE; 463 - } 464 - concat_W( (WCHAR*)src, NULL, TempPath, src_fileW ); 465 - 466 - TRACE("pExtractFiles(cab_file = '%s' ; cab_path = '%s', src_file = '%s')\n", 467 - debugstr_a(cab_file), debugstr_a(cab_path), debugstr_a(src_file)); 468 - 469 - /* Extract to temporary folder */ 470 - pExtractFiles( cab_file, cab_path, 0, src_file, NULL, 0 ); 471 - HeapFree( GetProcessHeap(), 0, src_file ); 472 - HeapFree( GetProcessHeap(), 0, cab_file ); 473 - HeapFree( GetProcessHeap(), 0, cab_path ); 474 - 475 - /* Move to destination, overwriting the original file if needed */ 476 - TRACE("Renaming src = '%s' to dst = '%s')\n", debugstr_w(src), debugstr_w(dst)); 477 - Success = MoveFileExW( src, dst , MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED ); 478 - HeapFree( GetProcessHeap(), 0, (WCHAR*)src ); 479 - return Success; 480 - } 481 - #else 482 - pExtractFiles( cab_file, cab_path, 0, 0, 0, 0 ); 483 - HeapFree( GetProcessHeap(), 0, cab_file ); 484 - HeapFree( GetProcessHeap(), 0, cab_path ); 485 - return CopyFileW( src, dst, FALSE /*FIXME*/ ); 486 - #endif 438 + return SetupIterateCabinetW( path, 0, extract_cab_cb, &ctx ); 487 439 } 488 440 489 441 ··· 1493 1445 if (op->src_tag) 1494 1446 { 1495 1447 if (extract_cabinet_file( op->src_tag, op->src_root, 1496 - paths.Source, paths.Target )) break; 1448 + op->src_file, paths.Target )) break; 1497 1449 } 1498 1450 paths.Win32Error = GetLastError(); 1499 1451 op_result = handler( context, SPFILENOTIFY_COPYERROR,
+1 -1
media/doc/WINESYNC.txt
··· 363 363 364 364 setupapi - 365 365 dll/win32/setupapi/dialog.c # Synced to WineStaging-1.9.15 366 - dll/win32/setupapi/query.c # Partially synced to WineStaging-1.9.4 366 + dll/win32/setupapi/query.c # Partially synced to Wine-4.8 367 367 dll/win32/setupapi/setupcab.c # Synced to WineStaging-1.9.4 368 368 369 369 win32k -