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
}