diff options
| author | Sean Hall <r.sean.hall@gmail.com> | 2022-06-03 17:48:57 -0500 |
|---|---|---|
| committer | Sean Hall <r.sean.hall@gmail.com> | 2022-06-07 19:44:36 -0500 |
| commit | 648f370f7966b2738c1446601057d888bbd2c70f (patch) | |
| tree | 9022566b1016f94127dfb7e84c9b4dfa057993cd /src/burn/engine/cache.cpp | |
| parent | 6b0f2d978504da82070523eb6adb0b59f9812e93 (diff) | |
| download | wix-648f370f7966b2738c1446601057d888bbd2c70f.tar.gz wix-648f370f7966b2738c1446601057d888bbd2c70f.tar.bz2 wix-648f370f7966b2738c1446601057d888bbd2c70f.zip | |
Make PathGetSystemPath return an array of paths ordered by preference.
Diffstat (limited to 'src/burn/engine/cache.cpp')
| -rw-r--r-- | src/burn/engine/cache.cpp | 127 |
1 files changed, 72 insertions, 55 deletions
diff --git a/src/burn/engine/cache.cpp b/src/burn/engine/cache.cpp index b311a195..7fca8cc7 100644 --- a/src/burn/engine/cache.cpp +++ b/src/burn/engine/cache.cpp | |||
| @@ -14,10 +14,10 @@ static HRESULT CacheVerifyPayloadSignature( | |||
| 14 | __in_z LPCWSTR wzUnverifiedPayloadPath, | 14 | __in_z LPCWSTR wzUnverifiedPayloadPath, |
| 15 | __in HANDLE hFile | 15 | __in HANDLE hFile |
| 16 | ); | 16 | ); |
| 17 | static HRESULT CalculateBaseWorkingFolder( | 17 | static HRESULT CalculatePotentialBaseWorkingFolders( |
| 18 | __in BURN_CACHE* pCache, | ||
| 18 | __in BURN_ENGINE_COMMAND* pInternalCommand, | 19 | __in BURN_ENGINE_COMMAND* pInternalCommand, |
| 19 | __in LPCWSTR wzAcquisitionFolder, | 20 | __in LPCWSTR wzAcquisitionFolder |
| 20 | __inout_z LPWSTR* psczBaseWorkingFolder | ||
| 21 | ); | 21 | ); |
| 22 | static HRESULT CalculateWorkingFolders( | 22 | static HRESULT CalculateWorkingFolders( |
| 23 | __in BURN_CACHE* pCache, | 23 | __in BURN_CACHE* pCache, |
| @@ -321,8 +321,8 @@ extern "C" HRESULT CacheEnsureAcquisitionFolder( | |||
| 321 | hr = DirEnsureExists(pCache->sczAcquisitionFolder, NULL); | 321 | hr = DirEnsureExists(pCache->sczAcquisitionFolder, NULL); |
| 322 | ExitOnFailure(hr, "Failed create acquisition folder."); | 322 | ExitOnFailure(hr, "Failed create acquisition folder."); |
| 323 | 323 | ||
| 324 | // Best effort to ensure our working folder is not encrypted. | 324 | // Best effort to ensure our acquisition folder is not encrypted. |
| 325 | ::DecryptFileW(pCache->sczBaseWorkingFolder, 0); | 325 | ::DecryptFileW(pCache->sczAcquisitionFolder, 0); |
| 326 | 326 | ||
| 327 | LExit: | 327 | LExit: |
| 328 | return hr; | 328 | return hr; |
| @@ -336,9 +336,30 @@ extern "C" HRESULT CacheEnsureBaseWorkingFolder( | |||
| 336 | Assert(pCache->fInitializedCache); | 336 | Assert(pCache->fInitializedCache); |
| 337 | 337 | ||
| 338 | HRESULT hr = S_OK; | 338 | HRESULT hr = S_OK; |
| 339 | LPWSTR sczPotential = NULL; | ||
| 340 | |||
| 341 | if (!pCache->fInitializedBaseWorkingFolder) | ||
| 342 | { | ||
| 343 | for (DWORD i = 0; i < pCache->cPotentialBaseWorkingFolders; ++i) | ||
| 344 | { | ||
| 345 | hr = PathConcatRelativeToBase(pCache->rgsczPotentialBaseWorkingFolders[i], pCache->wzGuid, &sczPotential); | ||
| 346 | ExitOnFailure(hr, "Failed to append random guid on to potential path for working folder."); | ||
| 347 | |||
| 348 | hr = DirEnsureExists(sczPotential, NULL); | ||
| 349 | if (SUCCEEDED(hr)) | ||
| 350 | { | ||
| 351 | pCache->sczBaseWorkingFolder = sczPotential; | ||
| 352 | sczPotential = NULL; | ||
| 353 | break; | ||
| 354 | } | ||
| 355 | |||
| 356 | LogErrorId(hr, MSG_INVALID_BASE_WORKING_FOLDER, sczPotential, NULL, NULL); | ||
| 357 | } | ||
| 339 | 358 | ||
| 340 | hr = DirEnsureExists(pCache->sczBaseWorkingFolder, NULL); | 359 | ExitOnNull(pCache->sczBaseWorkingFolder, hr, E_INVALIDSTATE, "No usable base working folder found."); |
| 341 | ExitOnFailure(hr, "Failed create working folder."); | 360 | |
| 361 | pCache->fInitializedBaseWorkingFolder = TRUE; | ||
| 362 | } | ||
| 342 | 363 | ||
| 343 | // Best effort to ensure our working folder is not encrypted. | 364 | // Best effort to ensure our working folder is not encrypted. |
| 344 | ::DecryptFileW(pCache->sczBaseWorkingFolder, 0); | 365 | ::DecryptFileW(pCache->sczBaseWorkingFolder, 0); |
| @@ -350,6 +371,8 @@ extern "C" HRESULT CacheEnsureBaseWorkingFolder( | |||
| 350 | } | 371 | } |
| 351 | 372 | ||
| 352 | LExit: | 373 | LExit: |
| 374 | ReleaseStr(sczPotential); | ||
| 375 | |||
| 353 | return hr; | 376 | return hr; |
| 354 | } | 377 | } |
| 355 | 378 | ||
| @@ -360,6 +383,7 @@ extern "C" HRESULT CacheCalculateBundleWorkingPath( | |||
| 360 | ) | 383 | ) |
| 361 | { | 384 | { |
| 362 | Assert(pCache->fInitializedCache); | 385 | Assert(pCache->fInitializedCache); |
| 386 | Assert(pCache->fInitializedBaseWorkingFolder); | ||
| 363 | 387 | ||
| 364 | HRESULT hr = S_OK; | 388 | HRESULT hr = S_OK; |
| 365 | 389 | ||
| @@ -1180,7 +1204,7 @@ extern "C" HRESULT CacheRemoveBaseWorkingFolder( | |||
| 1180 | { | 1204 | { |
| 1181 | HRESULT hr = S_OK; | 1205 | HRESULT hr = S_OK; |
| 1182 | 1206 | ||
| 1183 | if (pCache->fInitializedCacheSources) | 1207 | if (pCache->fInitializedBaseWorkingFolder) |
| 1184 | { | 1208 | { |
| 1185 | // Try to clean out everything in the working folder. | 1209 | // Try to clean out everything in the working folder. |
| 1186 | hr = DirEnsureDeleteEx(pCache->sczBaseWorkingFolder, DIR_DELETE_FILES | DIR_DELETE_RECURSE | DIR_DELETE_SCHEDULE); | 1210 | hr = DirEnsureDeleteEx(pCache->sczBaseWorkingFolder, DIR_DELETE_FILES | DIR_DELETE_RECURSE | DIR_DELETE_SCHEDULE); |
| @@ -1343,70 +1367,78 @@ extern "C" void CacheUninitialize( | |||
| 1343 | __in BURN_CACHE* pCache | 1367 | __in BURN_CACHE* pCache |
| 1344 | ) | 1368 | ) |
| 1345 | { | 1369 | { |
| 1346 | ReleaseNullStr(pCache->sczCurrentMachinePackageCache); | 1370 | ReleaseStrArray(pCache->rgsczPotentialBaseWorkingFolders, pCache->cPotentialBaseWorkingFolders); |
| 1347 | ReleaseNullStr(pCache->sczDefaultMachinePackageCache); | 1371 | ReleaseStr(pCache->sczCurrentMachinePackageCache); |
| 1348 | ReleaseNullStr(pCache->sczDefaultUserPackageCache); | 1372 | ReleaseStr(pCache->sczDefaultMachinePackageCache); |
| 1349 | ReleaseNullStr(pCache->sczBaseWorkingFolder); | 1373 | ReleaseStr(pCache->sczDefaultUserPackageCache); |
| 1350 | ReleaseNullStr(pCache->sczAcquisitionFolder); | 1374 | ReleaseStr(pCache->sczBaseWorkingFolder); |
| 1351 | ReleaseNullStr(pCache->sczSourceProcessFolder); | 1375 | ReleaseStr(pCache->sczAcquisitionFolder); |
| 1352 | 1376 | ReleaseStr(pCache->sczSourceProcessFolder); | |
| 1353 | pCache->fRunningFromCache = FALSE; | 1377 | |
| 1354 | pCache->fInitializedCache = FALSE; | 1378 | memset(pCache, 0, sizeof(BURN_CACHE)); |
| 1355 | pCache->fInitializedCacheSources = FALSE; | ||
| 1356 | pCache->fPerMachineCacheRootVerified = FALSE; | ||
| 1357 | pCache->fOriginalPerMachineCacheRootVerified = FALSE; | ||
| 1358 | pCache->fUnverifiedCacheFolderCreated = FALSE; | ||
| 1359 | pCache->fCustomMachinePackageCache = FALSE; | ||
| 1360 | } | 1379 | } |
| 1361 | 1380 | ||
| 1362 | // Internal functions. | 1381 | // Internal functions. |
| 1363 | 1382 | ||
| 1364 | static HRESULT CalculateBaseWorkingFolder( | 1383 | static HRESULT CalculatePotentialBaseWorkingFolders( |
| 1384 | __in BURN_CACHE* pCache, | ||
| 1365 | __in BURN_ENGINE_COMMAND* pInternalCommand, | 1385 | __in BURN_ENGINE_COMMAND* pInternalCommand, |
| 1366 | __in LPCWSTR wzAcquisitionFolder, | 1386 | __in LPCWSTR wzAcquisitionFolder |
| 1367 | __inout_z LPWSTR* psczBaseWorkingFolder | ||
| 1368 | ) | 1387 | ) |
| 1369 | { | 1388 | { |
| 1389 | Assert(!pCache->rgsczPotentialBaseWorkingFolders && !pCache->cPotentialBaseWorkingFolders); | ||
| 1370 | HRESULT hr = S_OK; | 1390 | HRESULT hr = S_OK; |
| 1391 | LPWSTR sczTemp = NULL; | ||
| 1371 | 1392 | ||
| 1372 | ReleaseNullStr(*psczBaseWorkingFolder); | 1393 | hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&pCache->rgsczPotentialBaseWorkingFolders), 6, sizeof(LPWSTR), 6); |
| 1394 | ExitOnFailure(hr, "Failed to initialize array."); | ||
| 1373 | 1395 | ||
| 1374 | // The value from the command line takes precedence. | 1396 | // The value from the command line takes precedence. |
| 1375 | if (pInternalCommand->sczEngineWorkingDirectory) | 1397 | if (pInternalCommand->sczEngineWorkingDirectory) |
| 1376 | { | 1398 | { |
| 1377 | hr = PathExpand(psczBaseWorkingFolder, pInternalCommand->sczEngineWorkingDirectory, PATH_EXPAND_FULLPATH); | 1399 | hr = PathExpand(&sczTemp, pInternalCommand->sczEngineWorkingDirectory, PATH_EXPAND_FULLPATH); |
| 1378 | ExitOnFailure(hr, "Failed to expand engine working directory from command-line: '%ls'", pInternalCommand->sczEngineWorkingDirectory); | 1400 | ExitOnFailure(hr, "Failed to expand engine working directory from command-line: '%ls'", pInternalCommand->sczEngineWorkingDirectory); |
| 1379 | 1401 | ||
| 1380 | ExitFunction(); | 1402 | pCache->rgsczPotentialBaseWorkingFolders[pCache->cPotentialBaseWorkingFolders] = sczTemp; |
| 1403 | sczTemp = NULL; | ||
| 1404 | ++pCache->cPotentialBaseWorkingFolders; | ||
| 1381 | } | 1405 | } |
| 1382 | 1406 | ||
| 1383 | // The base working folder can be specified through policy, | 1407 | // The base working folder can be specified through policy, |
| 1384 | // but only use it if elevated because it should be secured against non-admin users. | 1408 | // but only use it if elevated because it should be secured against non-admin users. |
| 1385 | if (pInternalCommand->fInitiallyElevated) | 1409 | if (pInternalCommand->fInitiallyElevated) |
| 1386 | { | 1410 | { |
| 1387 | hr = PolcReadString(POLICY_BURN_REGISTRY_PATH, L"EngineWorkingDirectory", NULL, psczBaseWorkingFolder); | 1411 | hr = PolcReadString(POLICY_BURN_REGISTRY_PATH, L"EngineWorkingDirectory", NULL, &sczTemp); |
| 1388 | ExitOnFailure(hr, "Failed to read EngineWorkingDirectory policy directory."); | 1412 | ExitOnFailure(hr, "Failed to read EngineWorkingDirectory policy directory."); |
| 1389 | 1413 | ||
| 1390 | if (*psczBaseWorkingFolder) | 1414 | if (sczTemp) |
| 1391 | { | 1415 | { |
| 1392 | // PolcReadString is supposed to automatically expand REG_EXPAND_SZ values. | 1416 | // PolcReadString is supposed to automatically expand REG_EXPAND_SZ values. |
| 1393 | ExitFunction(); | 1417 | pCache->rgsczPotentialBaseWorkingFolders[pCache->cPotentialBaseWorkingFolders] = sczTemp; |
| 1418 | sczTemp = NULL; | ||
| 1419 | ++pCache->cPotentialBaseWorkingFolders; | ||
| 1394 | } | 1420 | } |
| 1395 | } | 1421 | } |
| 1396 | 1422 | ||
| 1397 | // Default to the acquisition folder, but need to use system temp path for security reasons if running elevated. | 1423 | // Default to the acquisition folder, but need to use system temp path for security reasons if running elevated. |
| 1398 | if (pInternalCommand->fInitiallyElevated) | 1424 | if (pInternalCommand->fInitiallyElevated) |
| 1399 | { | 1425 | { |
| 1400 | hr = PathGetSystemTempPath(psczBaseWorkingFolder); | 1426 | hr = PathGetSystemTempPaths(&pCache->rgsczPotentialBaseWorkingFolders, &pCache->cPotentialBaseWorkingFolders); |
| 1401 | ExitOnFailure(hr, "Failed to get system temp folder path for base working folder."); | 1427 | ExitOnFailure(hr, "Failed to get system temp folder paths for base working folder."); |
| 1402 | } | 1428 | } |
| 1403 | else | 1429 | else |
| 1404 | { | 1430 | { |
| 1405 | hr = StrAllocString(psczBaseWorkingFolder, wzAcquisitionFolder, 0); | 1431 | hr = StrAllocString(&sczTemp, wzAcquisitionFolder, 0); |
| 1406 | ExitOnFailure(hr, "Failed to copy acquisition folder path for base working folder."); | 1432 | ExitOnFailure(hr, "Failed to copy acquisition folder path for base working folder."); |
| 1433 | |||
| 1434 | pCache->rgsczPotentialBaseWorkingFolders[pCache->cPotentialBaseWorkingFolders] = sczTemp; | ||
| 1435 | sczTemp = NULL; | ||
| 1436 | ++pCache->cPotentialBaseWorkingFolders; | ||
| 1407 | } | 1437 | } |
| 1408 | 1438 | ||
| 1409 | LExit: | 1439 | LExit: |
| 1440 | ReleaseStr(sczTemp); | ||
| 1441 | |||
| 1410 | return hr; | 1442 | return hr; |
| 1411 | } | 1443 | } |
| 1412 | 1444 | ||
| @@ -1416,11 +1448,7 @@ static HRESULT CalculateWorkingFolders( | |||
| 1416 | ) | 1448 | ) |
| 1417 | { | 1449 | { |
| 1418 | HRESULT hr = S_OK; | 1450 | HRESULT hr = S_OK; |
| 1419 | RPC_STATUS rs = RPC_S_OK; | ||
| 1420 | LPWSTR sczBaseAcquisitionPath = NULL; | 1451 | LPWSTR sczBaseAcquisitionPath = NULL; |
| 1421 | LPWSTR sczTempPath = NULL; | ||
| 1422 | UUID guid = {}; | ||
| 1423 | WCHAR wzGuid[39]; | ||
| 1424 | 1452 | ||
| 1425 | hr = PathGetTempPath(&sczBaseAcquisitionPath); | 1453 | hr = PathGetTempPath(&sczBaseAcquisitionPath); |
| 1426 | ExitOnFailure(hr, "Failed to get temp folder path for acquisition folder base."); | 1454 | ExitOnFailure(hr, "Failed to get temp folder path for acquisition folder base."); |
| @@ -1428,31 +1456,20 @@ static HRESULT CalculateWorkingFolders( | |||
| 1428 | hr = PathBackslashTerminate(&sczBaseAcquisitionPath); | 1456 | hr = PathBackslashTerminate(&sczBaseAcquisitionPath); |
| 1429 | ExitOnFailure(hr, "Failed to backslashify base engine working directory."); | 1457 | ExitOnFailure(hr, "Failed to backslashify base engine working directory."); |
| 1430 | 1458 | ||
| 1431 | hr = CalculateBaseWorkingFolder(pInternalCommand, sczBaseAcquisitionPath, &sczTempPath); | 1459 | hr = CalculatePotentialBaseWorkingFolders(pCache, pInternalCommand, sczBaseAcquisitionPath); |
| 1432 | ExitOnFailure(hr, "Failed to get base engine working directory."); | 1460 | ExitOnFailure(hr, "Failed to get potential base engine working directories."); |
| 1433 | |||
| 1434 | hr = PathBackslashTerminate(&sczTempPath); | ||
| 1435 | ExitOnFailure(hr, "Failed to backslashify base engine working directory."); | ||
| 1436 | 1461 | ||
| 1437 | rs = ::UuidCreate(&guid); | 1462 | hr = GuidFixedCreate(pCache->wzGuid); |
| 1438 | hr = HRESULT_FROM_RPC(rs); | ||
| 1439 | ExitOnFailure(hr, "Failed to create working folder guid."); | 1463 | ExitOnFailure(hr, "Failed to create working folder guid."); |
| 1440 | 1464 | ||
| 1441 | if (!::StringFromGUID2(guid, wzGuid, countof(wzGuid))) | 1465 | pCache->wzGuid[GUID_STRING_LENGTH - 1] = L'\\'; |
| 1442 | { | 1466 | pCache->wzGuid[GUID_STRING_LENGTH] = L'\0'; |
| 1443 | hr = E_OUTOFMEMORY; | ||
| 1444 | ExitOnRootFailure(hr, "Failed to convert working folder guid into string."); | ||
| 1445 | } | ||
| 1446 | 1467 | ||
| 1447 | hr = StrAllocFormatted(&pCache->sczAcquisitionFolder, L"%ls%ls\\", sczBaseAcquisitionPath, wzGuid); | 1468 | hr = PathConcatRelativeToBase(sczBaseAcquisitionPath, pCache->wzGuid, &pCache->sczAcquisitionFolder); |
| 1448 | ExitOnFailure(hr, "Failed to append random guid on to temp path for acquisition folder."); | 1469 | ExitOnFailure(hr, "Failed to append random guid on to temp path for acquisition folder."); |
| 1449 | 1470 | ||
| 1450 | hr = StrAllocFormatted(&pCache->sczBaseWorkingFolder, L"%ls%ls\\", sczTempPath, wzGuid); | ||
| 1451 | ExitOnFailure(hr, "Failed to append random guid on to temp path for working folder."); | ||
| 1452 | |||
| 1453 | LExit: | 1471 | LExit: |
| 1454 | ReleaseStr(sczBaseAcquisitionPath); | 1472 | ReleaseStr(sczBaseAcquisitionPath); |
| 1455 | ReleaseStr(sczTempPath); | ||
| 1456 | 1473 | ||
| 1457 | return hr; | 1474 | return hr; |
| 1458 | } | 1475 | } |
