aboutsummaryrefslogtreecommitdiff
path: root/src/burn/engine
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/burn/engine/approvedexe.cpp105
-rw-r--r--src/burn/engine/approvedexe.h4
-rw-r--r--src/burn/engine/bundlepackageengine.cpp4
-rw-r--r--src/burn/engine/cache.cpp6
-rw-r--r--src/burn/engine/core.h2
-rw-r--r--src/burn/engine/elevation.cpp2
-rw-r--r--src/burn/engine/exeengine.cpp29
-rw-r--r--src/burn/engine/registration.cpp14
8 files changed, 141 insertions, 25 deletions
diff --git a/src/burn/engine/approvedexe.cpp b/src/burn/engine/approvedexe.cpp
index 28b26d6d..383ee7fa 100644
--- a/src/burn/engine/approvedexe.cpp
+++ b/src/burn/engine/approvedexe.cpp
@@ -3,6 +3,13 @@
3#include "precomp.h" 3#include "precomp.h"
4 4
5 5
6// internal function declarations
7
8static HRESULT IsRunDll32(
9 __in BURN_VARIABLES* pVariables,
10 __in LPCWSTR wzExecutablePath
11 );
12
6// function definitions 13// function definitions
7 14
8extern "C" HRESULT ApprovedExesParseFromXml( 15extern "C" HRESULT ApprovedExesParseFromXml(
@@ -221,12 +228,15 @@ LExit:
221extern "C" HRESULT ApprovedExesVerifySecureLocation( 228extern "C" HRESULT ApprovedExesVerifySecureLocation(
222 __in BURN_CACHE* pCache, 229 __in BURN_CACHE* pCache,
223 __in BURN_VARIABLES* pVariables, 230 __in BURN_VARIABLES* pVariables,
224 __in LPCWSTR wzExecutablePath 231 __in LPCWSTR wzExecutablePath,
232 __in int argc,
233 __in LPCWSTR* argv
225 ) 234 )
226{ 235{
227 HRESULT hr = S_OK; 236 HRESULT hr = S_OK;
228 LPWSTR scz = NULL; 237 LPWSTR scz = NULL;
229 LPWSTR sczSecondary = NULL; 238 LPWSTR sczSecondary = NULL;
239 LPWSTR sczRunDll32Param = NULL;
230 240
231 const LPCWSTR vrgSecureFolderVariables[] = { 241 const LPCWSTR vrgSecureFolderVariables[] = {
232 L"ProgramFiles64Folder", 242 L"ProgramFiles64Folder",
@@ -273,11 +283,104 @@ extern "C" HRESULT ApprovedExesVerifySecureLocation(
273 ExitFunction(); 283 ExitFunction();
274 } 284 }
275 285
286 // Test if executable is rundll32.exe, and it's target is in a secure location
287 // Example for CUDA UninstallString: "C:\WINDOWS\SysWOW64\RunDll32.EXE" "C:\Program Files\NVIDIA Corporation\Installer2\InstallerCore\NVI2.DLL",UninstallPackage CUDAToolkit_12.8
288 if (argc && argv && argv[0] && *argv[0])
289 {
290 hr = IsRunDll32(pVariables, wzExecutablePath);
291 ExitOnFailure(hr, "Failed to test whether executable is rundll32");
292
293 if (hr == S_OK)
294 {
295 LPCWSTR szComma = wcschr(argv[0], L',');
296 if (szComma && *szComma)
297 {
298 hr = StrAllocString(&sczRunDll32Param, argv[0], szComma - argv[0]);
299 ExitOnFailure(hr, "Failed to allocate string");
300 }
301 else
302 {
303 hr = StrAllocString(&sczRunDll32Param, argv[0], 0);
304 ExitOnFailure(hr, "Failed to allocate string");
305 }
306
307 hr = ApprovedExesVerifySecureLocation(pCache, pVariables, sczRunDll32Param, 0, NULL);
308 ExitOnFailure(hr, "Failed to test whether rundll32's parameter, '%ls', is in a secure location", sczRunDll32Param);
309 if (hr == S_OK)
310 {
311 ExitFunction();
312 }
313 }
314 }
315
276 hr = S_FALSE; 316 hr = S_FALSE;
277 317
278LExit: 318LExit:
279 ReleaseStr(scz); 319 ReleaseStr(scz);
280 ReleaseStr(sczSecondary); 320 ReleaseStr(sczSecondary);
321 ReleaseStr(sczRunDll32Param);
322
323 return hr;
324}
325
326static HRESULT IsRunDll32(
327 __in BURN_VARIABLES* pVariables,
328 __in LPCWSTR wzExecutablePath
329 )
330{
331 HRESULT hr = S_OK;
332 LPWSTR sczFolder = NULL;
333 LPWSTR sczFullPath = NULL;
334 BOOL fEqual = FALSE;
335
336 hr = VariableGetString(pVariables, L"SystemFolder", &sczFolder);
337 ExitOnFailure(hr, "Failed to get the variable: SystemFolder");
338
339 hr = PathConcat(sczFolder, L"rundll32.exe", &sczFullPath);
340 ExitOnFailure(hr, "Failed to combine paths");
341
342 hr = PathCompareCanonicalized(wzExecutablePath, sczFullPath, &fEqual);
343 ExitOnFailure(hr, "Failed to compare paths");
344 if (fEqual)
345 {
346 hr = S_OK;
347 ExitFunction();
348 }
349
350 hr = VariableGetString(pVariables, L"System64Folder", &sczFolder);
351 ExitOnFailure(hr, "Failed to get the variable: System64Folder");
352
353 hr = PathConcat(sczFolder, L"rundll32.exe", &sczFullPath);
354 ExitOnFailure(hr, "Failed to combine paths");
355
356 hr = PathCompareCanonicalized(wzExecutablePath, sczFullPath, &fEqual);
357 ExitOnFailure(hr, "Failed to compare paths");
358 if (fEqual)
359 {
360 hr = S_OK;
361 ExitFunction();
362 }
363
364 // Sysnative
365 hr = PathSystemWindowsSubdirectory(L"SysNative\\", &sczFolder);
366 ExitOnFailure(hr, "Failed to append SysNative directory.");
367
368 hr = PathConcat(sczFolder, L"rundll32.exe", &sczFullPath);
369 ExitOnFailure(hr, "Failed to combine paths");
370
371 hr = PathCompareCanonicalized(wzExecutablePath, sczFullPath, &fEqual);
372 ExitOnFailure(hr, "Failed to compare paths");
373 if (fEqual)
374 {
375 hr = S_OK;
376 ExitFunction();
377 }
378
379 hr = S_FALSE;
380
381LExit:
382 ReleaseStr(sczFolder);
383 ReleaseStr(sczFullPath);
281 384
282 return hr; 385 return hr;
283} 386}
diff --git a/src/burn/engine/approvedexe.h b/src/burn/engine/approvedexe.h
index 7a68c174..0f441485 100644
--- a/src/burn/engine/approvedexe.h
+++ b/src/burn/engine/approvedexe.h
@@ -58,7 +58,9 @@ HRESULT ApprovedExesLaunch(
58HRESULT ApprovedExesVerifySecureLocation( 58HRESULT ApprovedExesVerifySecureLocation(
59 __in BURN_CACHE* pCache, 59 __in BURN_CACHE* pCache,
60 __in BURN_VARIABLES* pVariables, 60 __in BURN_VARIABLES* pVariables,
61 __in LPCWSTR wzExecutablePath 61 __in LPCWSTR wzExecutablePath,
62 __in int argc,
63 __in LPCWSTR* argv
62 ); 64 );
63 65
64 66
diff --git a/src/burn/engine/bundlepackageengine.cpp b/src/burn/engine/bundlepackageengine.cpp
index 612da389..db433918 100644
--- a/src/burn/engine/bundlepackageengine.cpp
+++ b/src/burn/engine/bundlepackageengine.cpp
@@ -817,7 +817,7 @@ static HRESULT ExecuteBundle(
817 817
818 if (pPackage->fPerMachine) 818 if (pPackage->fPerMachine)
819 { 819 {
820 hr = ApprovedExesVerifySecureLocation(pCache, pVariables, sczExecutablePath); 820 hr = ApprovedExesVerifySecureLocation(pCache, pVariables, sczExecutablePath, argcArp - 1, (argcArp > 1) ? const_cast<LPCWSTR*>(argvArp + 1) : NULL);
821 ExitOnFailure(hr, "Failed to verify the QuietUninstallString executable path is in a secure location: %ls", sczExecutablePath); 821 ExitOnFailure(hr, "Failed to verify the QuietUninstallString executable path is in a secure location: %ls", sczExecutablePath);
822 if (S_FALSE == hr) 822 if (S_FALSE == hr)
823 { 823 {
@@ -940,7 +940,7 @@ static HRESULT ExecuteBundle(
940 940
941 if (wzRelationTypeCommandLine) 941 if (wzRelationTypeCommandLine)
942 { 942 {
943 hr = StrAllocConcatFormatted(&sczBaseCommand, L" -%ls", wzRelationTypeCommandLine); 943 hr = StrAllocConcatFormatted(&sczBaseCommand, L" -quiet -%ls", wzRelationTypeCommandLine);
944 ExitOnFailure(hr, "Failed to append relation type argument."); 944 ExitOnFailure(hr, "Failed to append relation type argument.");
945 } 945 }
946 946
diff --git a/src/burn/engine/cache.cpp b/src/burn/engine/cache.cpp
index 16db4a81..e432df69 100644
--- a/src/burn/engine/cache.cpp
+++ b/src/burn/engine/cache.cpp
@@ -260,6 +260,9 @@ extern "C" HRESULT CacheInitializeSources(
260 hr = PathForCurrentProcess(&sczCurrentPath, NULL); 260 hr = PathForCurrentProcess(&sczCurrentPath, NULL);
261 ExitOnFailure(hr, "Failed to get current process path."); 261 ExitOnFailure(hr, "Failed to get current process path.");
262 262
263 hr = VariableSetString(pVariables, BURN_BUNDLE_SOURCE_PROCESS_PATH, sczCurrentPath, FALSE, FALSE);
264 ExitOnFailure(hr, "Failed to set %ls variable.", BURN_BUNDLE_SOURCE_PROCESS_PATH);
265
263 // Determine if we are running from the package cache or not. 266 // Determine if we are running from the package cache or not.
264 hr = CacheGetCompletedPath(pCache, pRegistration->fPerMachine, pRegistration->sczCode, &sczCompletedFolder); 267 hr = CacheGetCompletedPath(pCache, pRegistration->fPerMachine, pRegistration->sczCode, &sczCompletedFolder);
265 ExitOnFailure(hr, "Failed to get completed path for bundle."); 268 ExitOnFailure(hr, "Failed to get completed path for bundle.");
@@ -275,6 +278,9 @@ extern "C" HRESULT CacheInitializeSources(
275 hr = PathGetDirectory(sczCurrentPath, &pCache->sczSourceProcessFolder); 278 hr = PathGetDirectory(sczCurrentPath, &pCache->sczSourceProcessFolder);
276 ExitOnFailure(hr, "Failed to initialize cache source folder."); 279 ExitOnFailure(hr, "Failed to initialize cache source folder.");
277 280
281 hr = VariableSetString(pVariables, BURN_BUNDLE_SOURCE_PROCESS_FOLDER, pCache->sczSourceProcessFolder, FALSE, FALSE);
282 ExitOnFailure(hr, "Failed to set %ls variable.", BURN_BUNDLE_SOURCE_PROCESS_FOLDER);
283
278 // If we're not running from the cache, ensure the original source is set. 284 // If we're not running from the cache, ensure the original source is set.
279 if (!pCache->fRunningFromCache) 285 if (!pCache->fRunningFromCache)
280 { 286 {
diff --git a/src/burn/engine/core.h b/src/burn/engine/core.h
index c5d0a370..cf615e35 100644
--- a/src/burn/engine/core.h
+++ b/src/burn/engine/core.h
@@ -46,6 +46,8 @@ const LPCWSTR BURN_BUNDLE_FORCED_RESTART_PACKAGE = L"WixBundleForcedRestartPacka
46const LPCWSTR BURN_BUNDLE_INSTALLED = L"WixBundleInstalled"; 46const LPCWSTR BURN_BUNDLE_INSTALLED = L"WixBundleInstalled";
47const LPCWSTR BURN_BUNDLE_ELEVATED = L"WixBundleElevated"; 47const LPCWSTR BURN_BUNDLE_ELEVATED = L"WixBundleElevated";
48const LPCWSTR BURN_BUNDLE_PROVIDER_KEY = L"WixBundleProviderKey"; 48const LPCWSTR BURN_BUNDLE_PROVIDER_KEY = L"WixBundleProviderKey";
49const LPCWSTR BURN_BUNDLE_SOURCE_PROCESS_PATH = L"WixBundleSourceProcessPath";
50const LPCWSTR BURN_BUNDLE_SOURCE_PROCESS_FOLDER = L"WixBundleSourceProcessFolder";
49const LPCWSTR BURN_BUNDLE_TAG = L"WixBundleTag"; 51const LPCWSTR BURN_BUNDLE_TAG = L"WixBundleTag";
50const LPCWSTR BURN_BUNDLE_UILEVEL = L"WixBundleUILevel"; 52const LPCWSTR BURN_BUNDLE_UILEVEL = L"WixBundleUILevel";
51const LPCWSTR BURN_BUNDLE_VERSION = L"WixBundleVersion"; 53const LPCWSTR BURN_BUNDLE_VERSION = L"WixBundleVersion";
diff --git a/src/burn/engine/elevation.cpp b/src/burn/engine/elevation.cpp
index 90e9db01..f208efc9 100644
--- a/src/burn/engine/elevation.cpp
+++ b/src/burn/engine/elevation.cpp
@@ -3876,7 +3876,7 @@ static HRESULT OnLaunchApprovedExe(
3876 hr = RegReadString(hKey, pApprovedExe->sczValueName, &pLaunchApprovedExe->sczExecutablePath); 3876 hr = RegReadString(hKey, pApprovedExe->sczValueName, &pLaunchApprovedExe->sczExecutablePath);
3877 ExitOnFailure(hr, "Failed to read the value for the approved exe path."); 3877 ExitOnFailure(hr, "Failed to read the value for the approved exe path.");
3878 3878
3879 hr = ApprovedExesVerifySecureLocation(pCache, pVariables, pLaunchApprovedExe->sczExecutablePath); 3879 hr = ApprovedExesVerifySecureLocation(pCache, pVariables, pLaunchApprovedExe->sczExecutablePath, 0, NULL);
3880 ExitOnFailure(hr, "Failed to verify the executable path is in a secure location: %ls", pLaunchApprovedExe->sczExecutablePath); 3880 ExitOnFailure(hr, "Failed to verify the executable path is in a secure location: %ls", pLaunchApprovedExe->sczExecutablePath);
3881 if (S_FALSE == hr) 3881 if (S_FALSE == hr)
3882 { 3882 {
diff --git a/src/burn/engine/exeengine.cpp b/src/burn/engine/exeengine.cpp
index 85168943..3a2816dd 100644
--- a/src/burn/engine/exeengine.cpp
+++ b/src/burn/engine/exeengine.cpp
@@ -489,29 +489,30 @@ extern "C" HRESULT ExeEngineExecutePackage(
489 } 489 }
490 else if (BURN_EXE_DETECTION_TYPE_ARP == pPackage->Exe.detectionType && BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pExecuteAction->exePackage.action) 490 else if (BURN_EXE_DETECTION_TYPE_ARP == pPackage->Exe.detectionType && BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pExecuteAction->exePackage.action)
491 { 491 {
492 ExitOnNull(sczArpUninstallString, hr, E_INVALIDARG, "%hs is null.", pPackage->Exe.fArpUseUninstallString ? "UninstallString" : "QuietUninstallString"); 492 LPCWSTR szRegName = pPackage->Exe.fArpUseUninstallString ? L"UninstallString" : L"QuietUninstallString";
493 ExitOnNull(sczArpUninstallString, hr, E_INVALIDARG, "%ls is null.", szRegName);
493 494
494 hr = AppParseCommandLine(sczArpUninstallString, &argcArp, &argvArp); 495 hr = AppParseCommandLine(sczArpUninstallString, &argcArp, &argvArp);
495 ExitOnFailure(hr, "Failed to parse QuietUninstallString: %ls.", sczArpUninstallString); 496 ExitOnFailure(hr, "Failed to parse %ls: %ls.", szRegName, sczArpUninstallString);
496 497
497 ExitOnNull(argcArp, hr, E_INVALIDARG, "QuietUninstallString must contain an executable path."); 498 ExitOnNull(argcArp, hr, E_INVALIDARG, "%ls must contain an executable path.", szRegName);
498 499
499 hr = StrAllocString(&sczExecutablePath, argvArp[0], 0); 500 hr = StrAllocString(&sczExecutablePath, argvArp[0], 0);
500 ExitOnFailure(hr, "Failed to copy executable path."); 501 ExitOnFailure(hr, "Failed to copy executable path.");
501 502
502 if (pPackage->fPerMachine) 503 if (pPackage->fPerMachine)
503 { 504 {
504 hr = ApprovedExesVerifySecureLocation(pCache, pVariables, sczExecutablePath); 505 hr = ApprovedExesVerifySecureLocation(pCache, pVariables, sczExecutablePath, argcArp - 1, (argcArp > 1) ? const_cast<LPCWSTR*>(argvArp + 1) : NULL);
505 ExitOnFailure(hr, "Failed to verify the QuietUninstallString executable path is in a secure location: %ls", sczExecutablePath); 506 ExitOnFailure(hr, "Failed to verify the %ls executable path is in a secure location: %ls", szRegName, sczExecutablePath);
506 if (S_FALSE == hr) 507 if (S_FALSE == hr)
507 { 508 {
508 LogStringLine(REPORT_STANDARD, "The QuietUninstallString executable path is not in a secure location: %ls", sczExecutablePath); 509 LogStringLine(REPORT_STANDARD, "The %ls executable path is not in a secure location: %ls", szRegName, sczExecutablePath);
509 ExitFunction1(hr = HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED)); 510 ExitFunction1(hr = HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED));
510 } 511 }
511 } 512 }
512 513
513 hr = PathGetDirectory(sczExecutablePath, &sczCachedDirectory); 514 hr = PathGetDirectory(sczExecutablePath, &sczCachedDirectory);
514 ExitOnFailure(hr, "Failed to get parent directory for QuietUninstallString executable path: %ls", sczExecutablePath); 515 ExitOnFailure(hr, "Failed to get parent directory for %ls executable path: %ls", szRegName, sczExecutablePath);
515 } 516 }
516 else 517 else
517 { 518 {
@@ -587,13 +588,15 @@ extern "C" HRESULT ExeEngineExecutePackage(
587 } 588 }
588 589
589 // build base command 590 // build base command
590 hr = StrAllocFormatted(&sczBaseCommand, L"\"%ls\"", sczExecutablePath); 591 if (sczArpUninstallString && *sczArpUninstallString)
591 ExitOnFailure(hr, "Failed to allocate base command."); 592 {
592 593 hr = StrAllocString(&sczBaseCommand, sczArpUninstallString, 0);
593 for (int i = 1; i < argcArp; ++i) 594 ExitOnFailure(hr, "Failed to allocate base command.");
595 }
596 else
594 { 597 {
595 hr = AppAppendCommandLineArgument(&sczBaseCommand, argvArp[i]); 598 hr = StrAllocFormatted(&sczBaseCommand, L"\"%ls\"", sczExecutablePath);
596 ExitOnFailure(hr, "Failed to append argument from ARP."); 599 ExitOnFailure(hr, "Failed to allocate base command.");
597 } 600 }
598 601
599 if (pPackage->Exe.fBundle) 602 if (pPackage->Exe.fBundle)
diff --git a/src/burn/engine/registration.cpp b/src/burn/engine/registration.cpp
index 85c006f7..966fc849 100644
--- a/src/burn/engine/registration.cpp
+++ b/src/burn/engine/registration.cpp
@@ -808,13 +808,6 @@ extern "C" HRESULT RegistrationSessionBegin(
808 ExitOnFailure(hr, "Failed to write software tags."); 808 ExitOnFailure(hr, "Failed to write software tags.");
809 } 809 }
810 810
811 // Update registration.
812 if (pRegistration->update.fRegisterUpdate)
813 {
814 hr = WriteUpdateRegistration(pRegistration, pVariables);
815 ExitOnFailure(hr, "Failed to write update registration.");
816 }
817
818 // Only set install date and initial estimated size here for the first time. 811 // Only set install date and initial estimated size here for the first time.
819 // Estimated size will always get updated at the end of the session. 812 // Estimated size will always get updated at the end of the session.
820 if (fCreated) 813 if (fCreated)
@@ -904,6 +897,13 @@ extern "C" HRESULT RegistrationSessionEnd(
904 897
905 hr = UpdateEstimatedSize(hkRegistration, qwEstimatedSize); 898 hr = UpdateEstimatedSize(hkRegistration, qwEstimatedSize);
906 ExitOnFailure(hr, "Failed to update estimated size."); 899 ExitOnFailure(hr, "Failed to update estimated size.");
900
901 // Update registration.
902 if (pRegistration->update.fRegisterUpdate)
903 {
904 hr = WriteUpdateRegistration(pRegistration, pVariables);
905 ExitOnFailure(hr, "Failed to write update registration.");
906 }
907 } 907 }
908 908
909 // Update resume mode. 909 // Update resume mode.