diff options
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 | } |