aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2021-04-16 10:38:06 -0500
committerSean Hall <r.sean.hall@gmail.com>2021-04-19 23:12:55 -0500
commit31539e7a5baf0f75f3cd0e4764c003bb6a8310ce (patch)
tree76b64317abc34bb1ba0f05c92aba49eb8815f1c4
parent12a5bf684009c743a9de56f48681466a2cfdda02 (diff)
downloadwix-31539e7a5baf0f75f3cd0e4764c003bb6a8310ce.tar.gz
wix-31539e7a5baf0f75f3cd0e4764c003bb6a8310ce.tar.bz2
wix-31539e7a5baf0f75f3cd0e4764c003bb6a8310ce.zip
Make sure payload unverified path is not read-only during acquisition.
-rw-r--r--src/engine/apply.cpp61
1 files changed, 37 insertions, 24 deletions
diff --git a/src/engine/apply.cpp b/src/engine/apply.cpp
index f3821769..a2ec023e 100644
--- a/src/engine/apply.cpp
+++ b/src/engine/apply.cpp
@@ -123,6 +123,9 @@ static HRESULT LayoutOrCacheContainerOrPayload(
123 __in DWORD cTryAgainAttempts, 123 __in DWORD cTryAgainAttempts,
124 __out BOOL* pfRetry 124 __out BOOL* pfRetry
125 ); 125 );
126static HRESULT PreparePayloadDestinationPath(
127 __in_z LPCWSTR wzDestinationPath
128 );
126static HRESULT CopyPayload( 129static HRESULT CopyPayload(
127 __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress, 130 __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress,
128 __in HANDLE hSourceFile, 131 __in HANDLE hSourceFile,
@@ -1044,6 +1047,9 @@ static HRESULT ExtractContainer(
1044 BURN_PAYLOAD* pExtract = pContext->pPayloads->rgPayloads + iExtract; 1047 BURN_PAYLOAD* pExtract = pContext->pPayloads->rgPayloads + iExtract;
1045 if (pExtract->sczUnverifiedPath && CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, sczExtractPayloadId, -1, pExtract->sczSourcePath, -1)) 1048 if (pExtract->sczUnverifiedPath && CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, sczExtractPayloadId, -1, pExtract->sczSourcePath, -1))
1046 { 1049 {
1050 hr = PreparePayloadDestinationPath(pExtract->sczUnverifiedPath);
1051 ExitOnFailure(hr, "Failed to prepare payload destination path: %ls", pExtract->sczUnverifiedPath);
1052
1047 // TODO: Send progress when extracting stream to file. 1053 // TODO: Send progress when extracting stream to file.
1048 hr = ContainerStreamToFile(&context, pExtract->sczUnverifiedPath); 1054 hr = ContainerStreamToFile(&context, pExtract->sczUnverifiedPath);
1049 ExitOnFailure(hr, "Failed to extract payload: %ls from container: %ls", sczExtractPayloadId, pContainer->sczId); 1055 ExitOnFailure(hr, "Failed to extract payload: %ls from container: %ls", sczExtractPayloadId, pContainer->sczId);
@@ -1424,22 +1430,12 @@ LExit:
1424 return hr; 1430 return hr;
1425} 1431}
1426 1432
1427static HRESULT CopyPayload( 1433static HRESULT PreparePayloadDestinationPath(
1428 __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress,
1429 __in HANDLE hSourceFile,
1430 __in_z LPCWSTR wzSourcePath,
1431 __in_z LPCWSTR wzDestinationPath 1434 __in_z LPCWSTR wzDestinationPath
1432 ) 1435 )
1433{ 1436{
1434 HRESULT hr = S_OK; 1437 HRESULT hr = S_OK;
1435 DWORD dwFileAttributes = 0; 1438 DWORD dwFileAttributes = 0;
1436 LPCWSTR wzPackageOrContainerId = pProgress->pContainer ? pProgress->pContainer->sczId : pProgress->pPackage ? pProgress->pPackage->sczId : L"";
1437 LPCWSTR wzPayloadId = pProgress->pPayload ? pProgress->pPayload->sczKey : L"";
1438 HANDLE hDestinationFile = INVALID_HANDLE_VALUE;
1439 HANDLE hSourceOpenedFile = INVALID_HANDLE_VALUE;
1440
1441 DWORD dwLogId = pProgress->pContainer ? (pProgress->pPayload ? MSG_ACQUIRE_CONTAINER_PAYLOAD : MSG_ACQUIRE_CONTAINER) : pProgress->pPackage ? MSG_ACQUIRE_PACKAGE_PAYLOAD : MSG_ACQUIRE_BUNDLE_PAYLOAD;
1442 LogId(REPORT_STANDARD, dwLogId, wzPackageOrContainerId, wzPayloadId, "copy", wzSourcePath);
1443 1439
1444 // If the destination file already exists, clear the readonly bit to avoid E_ACCESSDENIED. 1440 // If the destination file already exists, clear the readonly bit to avoid E_ACCESSDENIED.
1445 if (FileExistsEx(wzDestinationPath, &dwFileAttributes)) 1441 if (FileExistsEx(wzDestinationPath, &dwFileAttributes))
@@ -1454,6 +1450,34 @@ static HRESULT CopyPayload(
1454 } 1450 }
1455 } 1451 }
1456 1452
1453LExit:
1454 if (E_FILENOTFOUND == hr || E_PATHNOTFOUND == hr)
1455 {
1456 hr = S_OK;
1457 }
1458
1459 return hr;
1460}
1461
1462static HRESULT CopyPayload(
1463 __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress,
1464 __in HANDLE hSourceFile,
1465 __in_z LPCWSTR wzSourcePath,
1466 __in_z LPCWSTR wzDestinationPath
1467 )
1468{
1469 HRESULT hr = S_OK;
1470 LPCWSTR wzPackageOrContainerId = pProgress->pContainer ? pProgress->pContainer->sczId : pProgress->pPackage ? pProgress->pPackage->sczId : L"";
1471 LPCWSTR wzPayloadId = pProgress->pPayload ? pProgress->pPayload->sczKey : L"";
1472 HANDLE hDestinationFile = INVALID_HANDLE_VALUE;
1473 HANDLE hSourceOpenedFile = INVALID_HANDLE_VALUE;
1474
1475 DWORD dwLogId = pProgress->pContainer ? (pProgress->pPayload ? MSG_ACQUIRE_CONTAINER_PAYLOAD : MSG_ACQUIRE_CONTAINER) : pProgress->pPackage ? MSG_ACQUIRE_PACKAGE_PAYLOAD : MSG_ACQUIRE_BUNDLE_PAYLOAD;
1476 LogId(REPORT_STANDARD, dwLogId, wzPackageOrContainerId, wzPayloadId, "copy", wzSourcePath);
1477
1478 hr = PreparePayloadDestinationPath(wzDestinationPath);
1479 ExitOnFailure(hr, "Failed to prepare payload destination path: %ls", wzDestinationPath);
1480
1457 if (INVALID_HANDLE_VALUE == hSourceFile) 1481 if (INVALID_HANDLE_VALUE == hSourceFile)
1458 { 1482 {
1459 hSourceOpenedFile = ::CreateFileW(wzSourcePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); 1483 hSourceOpenedFile = ::CreateFileW(wzSourcePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
@@ -1503,7 +1527,6 @@ static HRESULT DownloadPayload(
1503 ) 1527 )
1504{ 1528{
1505 HRESULT hr = S_OK; 1529 HRESULT hr = S_OK;
1506 DWORD dwFileAttributes = 0;
1507 LPCWSTR wzPackageOrContainerId = pProgress->pContainer ? pProgress->pContainer->sczId : pProgress->pPackage ? pProgress->pPackage->sczId : L""; 1530 LPCWSTR wzPackageOrContainerId = pProgress->pContainer ? pProgress->pContainer->sczId : pProgress->pPackage ? pProgress->pPackage->sczId : L"";
1508 LPCWSTR wzPayloadId = pProgress->pPayload ? pProgress->pPayload->sczKey : L""; 1531 LPCWSTR wzPayloadId = pProgress->pPayload ? pProgress->pPayload->sczKey : L"";
1509 DOWNLOAD_SOURCE* pDownloadSource = pProgress->pContainer ? &pProgress->pContainer->downloadSource : &pProgress->pPayload->downloadSource; 1532 DOWNLOAD_SOURCE* pDownloadSource = pProgress->pContainer ? &pProgress->pContainer->downloadSource : &pProgress->pPayload->downloadSource;
@@ -1515,18 +1538,8 @@ static HRESULT DownloadPayload(
1515 DWORD dwLogId = pProgress->pContainer ? (pProgress->pPayload ? MSG_ACQUIRE_CONTAINER_PAYLOAD : MSG_ACQUIRE_CONTAINER) : pProgress->pPackage ? MSG_ACQUIRE_PACKAGE_PAYLOAD : MSG_ACQUIRE_BUNDLE_PAYLOAD; 1538 DWORD dwLogId = pProgress->pContainer ? (pProgress->pPayload ? MSG_ACQUIRE_CONTAINER_PAYLOAD : MSG_ACQUIRE_CONTAINER) : pProgress->pPackage ? MSG_ACQUIRE_PACKAGE_PAYLOAD : MSG_ACQUIRE_BUNDLE_PAYLOAD;
1516 LogId(REPORT_STANDARD, dwLogId, wzPackageOrContainerId, wzPayloadId, "download", pDownloadSource->sczUrl); 1539 LogId(REPORT_STANDARD, dwLogId, wzPackageOrContainerId, wzPayloadId, "download", pDownloadSource->sczUrl);
1517 1540
1518 // If the destination file already exists, clear the readonly bit to avoid E_ACCESSDENIED. 1541 hr = PreparePayloadDestinationPath(wzDestinationPath);
1519 if (FileExistsEx(wzDestinationPath, &dwFileAttributes)) 1542 ExitOnFailure(hr, "Failed to prepare payload destination path: %ls", wzDestinationPath);
1520 {
1521 if (FILE_ATTRIBUTE_READONLY & dwFileAttributes)
1522 {
1523 dwFileAttributes &= ~FILE_ATTRIBUTE_READONLY;
1524 if (!::SetFileAttributes(wzDestinationPath, dwFileAttributes))
1525 {
1526 ExitWithLastError(hr, "Failed to clear readonly bit on payload destination path: %ls", wzDestinationPath);
1527 }
1528 }
1529 }
1530 1543
1531 cacheCallback.pfnProgress = CacheProgressRoutine; 1544 cacheCallback.pfnProgress = CacheProgressRoutine;
1532 cacheCallback.pfnCancel = NULL; // TODO: set this 1545 cacheCallback.pfnCancel = NULL; // TODO: set this