diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2021-04-16 10:38:06 -0500 |
---|---|---|
committer | Sean Hall <r.sean.hall@gmail.com> | 2021-04-19 23:12:55 -0500 |
commit | 31539e7a5baf0f75f3cd0e4764c003bb6a8310ce (patch) | |
tree | 76b64317abc34bb1ba0f05c92aba49eb8815f1c4 | |
parent | 12a5bf684009c743a9de56f48681466a2cfdda02 (diff) | |
download | wix-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.cpp | 61 |
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 | ); |
126 | static HRESULT PreparePayloadDestinationPath( | ||
127 | __in_z LPCWSTR wzDestinationPath | ||
128 | ); | ||
126 | static HRESULT CopyPayload( | 129 | static 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 | ||
1427 | static HRESULT CopyPayload( | 1433 | static 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 | ||
1453 | LExit: | ||
1454 | if (E_FILENOTFOUND == hr || E_PATHNOTFOUND == hr) | ||
1455 | { | ||
1456 | hr = S_OK; | ||
1457 | } | ||
1458 | |||
1459 | return hr; | ||
1460 | } | ||
1461 | |||
1462 | static 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 |