diff options
Diffstat (limited to 'src/engine/apply.cpp')
-rw-r--r-- | src/engine/apply.cpp | 50 |
1 files changed, 47 insertions, 3 deletions
diff --git a/src/engine/apply.cpp b/src/engine/apply.cpp index 74f57f6a..58d41b28 100644 --- a/src/engine/apply.cpp +++ b/src/engine/apply.cpp | |||
@@ -133,6 +133,11 @@ static HRESULT AcquireContainerOrPayload( | |||
133 | __in BURN_CACHE_PROGRESS_CONTEXT* pProgress, | 133 | __in BURN_CACHE_PROGRESS_CONTEXT* pProgress, |
134 | __out BOOL* pfRetry | 134 | __out BOOL* pfRetry |
135 | ); | 135 | ); |
136 | static BOOL IsValidLocalFile( | ||
137 | __in_z LPCWSTR wzFilePath, | ||
138 | __in DWORD64 qwFileSize, | ||
139 | __in BOOL fMinimumFileSize | ||
140 | ); | ||
136 | static HRESULT LayoutOrCacheContainerOrPayload( | 141 | static HRESULT LayoutOrCacheContainerOrPayload( |
137 | __in BURN_CACHE_CONTEXT* pContext, | 142 | __in BURN_CACHE_CONTEXT* pContext, |
138 | __in_opt BURN_CONTAINER* pContainer, | 143 | __in_opt BURN_CONTAINER* pContainer, |
@@ -1399,6 +1404,25 @@ static HRESULT AcquireContainerOrPayload( | |||
1399 | LPWSTR* pwzSourcePath = pContainer ? &pContainer->sczSourcePath : &pPayload->sczSourcePath; | 1404 | LPWSTR* pwzSourcePath = pContainer ? &pContainer->sczSourcePath : &pPayload->sczSourcePath; |
1400 | BOOL fFoundLocal = FALSE; | 1405 | BOOL fFoundLocal = FALSE; |
1401 | BOOL fPreferExtract = 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 | } | ||
1402 | 1426 | ||
1403 | pContext->cSearchPaths = 0; | 1427 | pContext->cSearchPaths = 0; |
1404 | *pfRetry = FALSE; | 1428 | *pfRetry = FALSE; |
@@ -1427,7 +1451,7 @@ static HRESULT AcquireContainerOrPayload( | |||
1427 | // When a payload comes from a container, the container has the highest chance of being correct. | 1451 | // When a payload comes from a container, the container has the highest chance of being correct. |
1428 | // But we want to avoid extracting the container multiple times. | 1452 | // But we want to avoid extracting the container multiple times. |
1429 | // So only consider the destination path, which means the container was already extracted. | 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)) |
1431 | { | 1455 | { |
1432 | fFoundLocal = TRUE; | 1456 | fFoundLocal = TRUE; |
1433 | dwChosenSearchPath = dwDestinationSearchPath; | 1457 | dwChosenSearchPath = dwDestinationSearchPath; |
@@ -1442,8 +1466,8 @@ static HRESULT AcquireContainerOrPayload( | |||
1442 | { | 1466 | { |
1443 | for (DWORD i = 0; i < pContext->cSearchPaths; ++i) | 1467 | for (DWORD i = 0; i < pContext->cSearchPaths; ++i) |
1444 | { | 1468 | { |
1445 | // If the file exists locally, choose it. | 1469 | // If the file exists locally with the correct size, choose it. |
1446 | if (FileExistsEx(pContext->rgSearchPaths[i], NULL)) | 1470 | if (IsValidLocalFile(pContext->rgSearchPaths[i], qwFileSize, fMinimumFileSize)) |
1447 | { | 1471 | { |
1448 | dwChosenSearchPath = i; | 1472 | dwChosenSearchPath = i; |
1449 | 1473 | ||
@@ -1557,6 +1581,26 @@ LExit: | |||
1557 | return hr; | 1581 | return hr; |
1558 | } | 1582 | } |
1559 | 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 | |||
1560 | static HRESULT LayoutOrCacheContainerOrPayload( | 1604 | static HRESULT LayoutOrCacheContainerOrPayload( |
1561 | __in BURN_CACHE_CONTEXT* pContext, | 1605 | __in BURN_CACHE_CONTEXT* pContext, |
1562 | __in_opt BURN_CONTAINER* pContainer, | 1606 | __in_opt BURN_CONTAINER* pContainer, |