aboutsummaryrefslogtreecommitdiff
path: root/src/burn/engine
diff options
context:
space:
mode:
Diffstat (limited to 'src/burn/engine')
-rw-r--r--src/burn/engine/cache.cpp127
-rw-r--r--src/burn/engine/cache.h7
-rw-r--r--src/burn/engine/engine.cpp7
-rw-r--r--src/burn/engine/engine.mc16
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 );
17static HRESULT CalculateBaseWorkingFolder( 17static 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 );
22static HRESULT CalculateWorkingFolders( 22static 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
327LExit: 327LExit:
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
352LExit: 373LExit:
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
1364static HRESULT CalculateBaseWorkingFolder( 1383static 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
1409LExit: 1439LExit:
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
1453LExit: 1471LExit:
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
149Exit code: 0x%1!x! 149Exit code: 0x%1!x!
150. 150.
151 151
152MessageId=18
153Severity=Success
154SymbolicName=MSG_EXITING_RUN_ONCE
155Language=English
156Exit code: 0x%1!x!
157.
158
159MessageId=19
160Severity=Warning
161SymbolicName=MSG_INVALID_BASE_WORKING_FOLDER
162Language=English
163Failed to use folder as base working folder: %2!ls!, encountered error: %1!ls!.
164.
165
152MessageId=51 166MessageId=51
153Severity=Error 167Severity=Error
154SymbolicName=MSG_FAILED_PARSE_CONDITION 168SymbolicName=MSG_FAILED_PARSE_CONDITION
@@ -811,7 +825,7 @@ MessageId=346
811Severity=Warning 825Severity=Warning
812SymbolicName=MSG_CACHE_RETRYING_PACKAGE 826SymbolicName=MSG_CACHE_RETRYING_PACKAGE
813Language=English 827Language=English
814Application requested retry of caching package: %1!ls!, encountered error: 0x%2!x!. Retrying... 828Application requested retry of caching package: %2!ls!, encountered error: %1!ls!. Retrying...
815. 829.
816 830
817MessageId=347 831MessageId=347