@joebigelow / wix-1 / commits / 14cdda3c

Set source of attached containers to WixBundleOriginalSource if set. Use file size when probing local files.

Set source of attached containers to WixBundleOriginalSource if set. Use file size when probing local files. #5586

Sean Hall committed Apr 25, 2021 at 22:44 UTC 14cdda3c489d6b9801f05939044e67b13939b42d
2 files changed +72 -5
src/engine/apply.cpp
+47 -3
@@ -133,6 +133,11 @@ static HRESULT AcquireContainerOrPayload(
133 __in BURN_CACHE_PROGRESS_CONTEXT* pProgress,
134 __out BOOL* pfRetry
135 );
136 +static BOOL IsValidLocalFile(
137 + __in_z LPCWSTR wzFilePath,
138 + __in DWORD64 qwFileSize,
139 + __in BOOL fMinimumFileSize
140 + );
141 static HRESULT LayoutOrCacheContainerOrPayload(
142 __in BURN_CACHE_CONTEXT* pContext,
143 __in_opt BURN_CONTAINER* pContainer,
@@ -1399,6 +1404,25 @@ static HRESULT AcquireContainerOrPayload(
1404 LPWSTR* pwzSourcePath = pContainer ? &pContainer->sczSourcePath : &pPayload->sczSourcePath;
1405 BOOL fFoundLocal = FALSE;
1406 BOOL fPreferExtract = FALSE;
1407 + DWORD64 qwFileSize = 0;
1408 + BOOL fMinimumFileSize = FALSE;
1409 +
1410 + if (pContainer)
1411 + {
1412 + if (pContainer->fAttached)
1413 + {
1414 + fMinimumFileSize = TRUE;
1415 + qwFileSize = pContainer->qwAttachedOffset + pContainer->qwFileSize;
1416 + }
1417 + else if (pContainer->pbHash && pContext->wzLayoutDirectory)
1418 + {
1419 + qwFileSize = pContainer->qwFileSize;
1420 + }
1421 + }
1422 + else if (pPayload->pbHash)
1423 + {
1424 + qwFileSize = pPayload->qwFileSize;
1425 + }
1426
1427 pContext->cSearchPaths = 0;
1428 *pfRetry = FALSE;
@@ -1427,7 +1451,7 @@ static HRESULT AcquireContainerOrPayload(
1451 // When a payload comes from a container, the container has the highest chance of being correct.
1452 // But we want to avoid extracting the container multiple times.
1453 // So only consider the destination path, which means the container was already extracted.
1430 - if (FileExistsEx(pContext->rgSearchPaths[dwDestinationSearchPath], NULL))
1454 + if (IsValidLocalFile(pContext->rgSearchPaths[dwDestinationSearchPath], qwFileSize, fMinimumFileSize))
1455 {
1456 fFoundLocal = TRUE;
1457 dwChosenSearchPath = dwDestinationSearchPath;
@@ -1442,8 +1466,8 @@ static HRESULT AcquireContainerOrPayload(
1466 {
1467 for (DWORD i = 0; i < pContext->cSearchPaths; ++i)
1468 {
1445 - // If the file exists locally, choose it.
1446 - if (FileExistsEx(pContext->rgSearchPaths[i], NULL))
1469 + // If the file exists locally with the correct size, choose it.
1470 + if (IsValidLocalFile(pContext->rgSearchPaths[i], qwFileSize, fMinimumFileSize))
1471 {
1472 dwChosenSearchPath = i;
1473
@@ -1557,6 +1581,26 @@ LExit:
1581 return hr;
1582 }
1583
1584 +static BOOL IsValidLocalFile(
1585 + __in_z LPCWSTR wzFilePath,
1586 + __in DWORD64 qwFileSize,
1587 + __in BOOL fMinimumFileSize
1588 + )
1589 +{
1590 + LONGLONG llFileSize = 0;
1591 +
1592 + if (!qwFileSize)
1593 + {
1594 + return FileExistsEx(wzFilePath, NULL);
1595 + }
1596 + else
1597 + {
1598 + return SUCCEEDED(FileSize(wzFilePath, &llFileSize)) &&
1599 + (static_cast<DWORD64>(llFileSize) == qwFileSize ||
1600 + fMinimumFileSize && static_cast<DWORD64>(llFileSize) > qwFileSize);
1601 + }
1602 +}
1603 +
1604 static HRESULT LayoutOrCacheContainerOrPayload(
1605 __in BURN_CACHE_CONTEXT* pContext,
1606 __in_opt BURN_CONTAINER* pContainer,
src/engine/engine.cpp
+25 -2
@@ -523,7 +523,8 @@ static HRESULT RunNormal(
523 )
524 {
525 HRESULT hr = S_OK;
526 - HANDLE hPipesCreatedEvent = NULL;
526 + LPWSTR sczOriginalSource = NULL;
527 + LPWSTR sczCopiedOriginalSource = NULL;
528 BOOL fContinueExecution = TRUE;
529 BOOL fReloadApp = FALSE;
530 BOOL fSkipCleanup = FALSE;
@@ -558,6 +559,27 @@ static HRESULT RunNormal(
559 hr = CoreQueryRegistration(pEngineState);
560 ExitOnFailure(hr, "Failed to query registration.");
561
562 + // Best effort to set the source of attached containers to BURN_BUNDLE_ORIGINAL_SOURCE.
563 + hr = VariableGetString(&pEngineState->variables, BURN_BUNDLE_ORIGINAL_SOURCE, &sczOriginalSource);
564 + if (SUCCEEDED(hr))
565 + {
566 + for (DWORD i = 0; i < pEngineState->containers.cContainers; ++i)
567 + {
568 + BURN_CONTAINER* pContainer = pEngineState->containers.rgContainers + i;
569 + if (pContainer->fAttached)
570 + {
571 + hr = StrAllocString(&sczCopiedOriginalSource, sczOriginalSource, 0);
572 + if (SUCCEEDED(hr))
573 + {
574 + ReleaseNullStr(pContainer->sczSourcePath);
575 + pContainer->sczSourcePath = sczCopiedOriginalSource;
576 + sczCopiedOriginalSource = NULL;
577 + }
578 + }
579 + }
580 + }
581 + hr = S_OK;
582 +
583 // Set some built-in variables before loading the BA.
584 hr = PlanSetVariables(pEngineState->command.action, &pEngineState->variables);
585 ExitOnFailure(hr, "Failed to set action variables.");
@@ -613,7 +635,8 @@ LExit:
635 ::PostMessageW(pEngineState->command.hwndSplashScreen, WM_CLOSE, 0, 0);
636 }
637
616 - ReleaseHandle(hPipesCreatedEvent);
638 + ReleaseStr(sczOriginalSource);
639 + ReleaseStr(sczCopiedOriginalSource);
640
641 return hr;
642 }