diff options
Diffstat (limited to 'src/burn/engine')
-rw-r--r-- | src/burn/engine/cache.cpp | 127 | ||||
-rw-r--r-- | src/burn/engine/cache.h | 7 | ||||
-rw-r--r-- | src/burn/engine/engine.cpp | 7 | ||||
-rw-r--r-- | src/burn/engine/engine.mc | 16 |
4 files changed, 101 insertions, 56 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 | } |
diff --git a/src/burn/engine/cache.h b/src/burn/engine/cache.h index 8b038b99..9c698b4b 100644 --- a/src/burn/engine/cache.h +++ b/src/burn/engine/cache.h | |||
@@ -35,11 +35,18 @@ typedef struct _BURN_CACHE | |||
35 | LPWSTR sczDefaultMachinePackageCache; | 35 | LPWSTR sczDefaultMachinePackageCache; |
36 | LPWSTR sczCurrentMachinePackageCache; | 36 | LPWSTR sczCurrentMachinePackageCache; |
37 | 37 | ||
38 | WCHAR wzGuid[GUID_STRING_LENGTH + 1]; | ||
39 | LPWSTR* rgsczPotentialBaseWorkingFolders; | ||
40 | DWORD cPotentialBaseWorkingFolders; | ||
41 | |||
38 | // Only valid after CacheInitializeSources | 42 | // Only valid after CacheInitializeSources |
39 | BOOL fInitializedCacheSources; | 43 | BOOL fInitializedCacheSources; |
40 | BOOL fRunningFromCache; | 44 | BOOL fRunningFromCache; |
41 | LPWSTR sczSourceProcessFolder; | 45 | LPWSTR sczSourceProcessFolder; |
42 | LPWSTR sczAcquisitionFolder; | 46 | LPWSTR sczAcquisitionFolder; |
47 | |||
48 | // Only valid after CacheEnsureBaseWorkingFolder | ||
49 | BOOL fInitializedBaseWorkingFolder; | ||
43 | LPWSTR sczBaseWorkingFolder; | 50 | LPWSTR sczBaseWorkingFolder; |
44 | } BURN_CACHE; | 51 | } BURN_CACHE; |
45 | 52 | ||
diff --git a/src/burn/engine/engine.cpp b/src/burn/engine/engine.cpp index a408ed4a..aca43438 100644 --- a/src/burn/engine/engine.cpp +++ b/src/burn/engine/engine.cpp | |||
@@ -97,6 +97,7 @@ extern "C" HRESULT EngineRun( | |||
97 | LPWSTR sczExePath = NULL; | 97 | LPWSTR sczExePath = NULL; |
98 | BOOL fRunUntrusted = FALSE; | 98 | BOOL fRunUntrusted = FALSE; |
99 | BOOL fRunNormal = FALSE; | 99 | BOOL fRunNormal = FALSE; |
100 | BOOL fRunRunOnce = FALSE; | ||
100 | BOOL fRestart = FALSE; | 101 | BOOL fRestart = FALSE; |
101 | 102 | ||
102 | BURN_ENGINE_STATE engineState = { }; | 103 | BURN_ENGINE_STATE engineState = { }; |
@@ -221,6 +222,8 @@ extern "C" HRESULT EngineRun( | |||
221 | break; | 222 | break; |
222 | 223 | ||
223 | case BURN_MODE_RUNONCE: | 224 | case BURN_MODE_RUNONCE: |
225 | fRunRunOnce = TRUE; | ||
226 | |||
224 | hr = RunRunOnce(&engineState, nCmdShow); | 227 | hr = RunRunOnce(&engineState, nCmdShow); |
225 | ExitOnFailure(hr, "Failed to run RunOnce mode."); | 228 | ExitOnFailure(hr, "Failed to run RunOnce mode."); |
226 | break; | 229 | break; |
@@ -303,6 +306,10 @@ LExit: | |||
303 | { | 306 | { |
304 | LogId(REPORT_STANDARD, MSG_EXITING_CLEAN_ROOM, FAILED(hr) ? (int)hr : *pdwExitCode); | 307 | LogId(REPORT_STANDARD, MSG_EXITING_CLEAN_ROOM, FAILED(hr) ? (int)hr : *pdwExitCode); |
305 | } | 308 | } |
309 | else if (fRunRunOnce) | ||
310 | { | ||
311 | LogId(REPORT_STANDARD, MSG_EXITING_RUN_ONCE, FAILED(hr) ? (int)hr : *pdwExitCode); | ||
312 | } | ||
306 | 313 | ||
307 | if (fLogInitialized) | 314 | if (fLogInitialized) |
308 | { | 315 | { |
diff --git a/src/burn/engine/engine.mc b/src/burn/engine/engine.mc index 32473252..9a08fa3f 100644 --- a/src/burn/engine/engine.mc +++ b/src/burn/engine/engine.mc | |||
@@ -149,6 +149,20 @@ Language=English | |||
149 | Exit code: 0x%1!x! | 149 | Exit code: 0x%1!x! |
150 | . | 150 | . |
151 | 151 | ||
152 | MessageId=18 | ||
153 | Severity=Success | ||
154 | SymbolicName=MSG_EXITING_RUN_ONCE | ||
155 | Language=English | ||
156 | Exit code: 0x%1!x! | ||
157 | . | ||
158 | |||
159 | MessageId=19 | ||
160 | Severity=Warning | ||
161 | SymbolicName=MSG_INVALID_BASE_WORKING_FOLDER | ||
162 | Language=English | ||
163 | Failed to use folder as base working folder: %2!ls!, encountered error: %1!ls!. | ||
164 | . | ||
165 | |||
152 | MessageId=51 | 166 | MessageId=51 |
153 | Severity=Error | 167 | Severity=Error |
154 | SymbolicName=MSG_FAILED_PARSE_CONDITION | 168 | SymbolicName=MSG_FAILED_PARSE_CONDITION |
@@ -811,7 +825,7 @@ MessageId=346 | |||
811 | Severity=Warning | 825 | Severity=Warning |
812 | SymbolicName=MSG_CACHE_RETRYING_PACKAGE | 826 | SymbolicName=MSG_CACHE_RETRYING_PACKAGE |
813 | Language=English | 827 | Language=English |
814 | Application requested retry of caching package: %1!ls!, encountered error: 0x%2!x!. Retrying... | 828 | Application requested retry of caching package: %2!ls!, encountered error: %1!ls!. Retrying... |
815 | . | 829 | . |
816 | 830 | ||
817 | MessageId=347 | 831 | MessageId=347 |