@@ -29,6 +29,7 @@ const LPCWSTR REGISTRY_BUNDLE_UNINSTALL_STRING = L"UninstallString";
2929const LPCWSTR REGISTRY_BUNDLE_RESUME_COMMAND_LINE = L" BundleResumeCommandLine" ;
3030const LPCWSTR REGISTRY_BUNDLE_VERSION_MAJOR = L" VersionMajor" ;
3131const LPCWSTR REGISTRY_BUNDLE_VERSION_MINOR = L" VersionMinor" ;
32+ const LPCWSTR REGISTRY_BUNDLE_SCOPE = L" BundleScope" ;
3233const LPCWSTR SWIDTAG_FOLDER = L" swidtag" ;
3334const LPCWSTR REGISTRY_BUNDLE_VARIABLE_KEY = L" variables" ;
3435
@@ -303,6 +304,10 @@ extern "C" HRESULT RegistrationParseFromXml(
303304 pRegistration->hkRoot = reinterpret_cast <HKEY>(0ull );
304305 }
305306
307+ // build uninstall registry key path
308+ hr = StrAllocFormatted (&pRegistration->sczRegistrationKey , L" %ls\\ %ls" , BURN_REGISTRATION_REGISTRY_UNINSTALL_KEY, pRegistration->sczCode );
309+ ExitOnFailure (hr, " Failed to build uninstall registry key path." );
310+
306311LExit:
307312 ReleaseObject (pixnRegistrationNode);
308313 ReleaseObject (pixnArpNode);
@@ -458,6 +463,9 @@ extern "C" HRESULT RegistrationSetDynamicVariables(
458463 hr = VariableSetNumeric (pVariables, BURN_BUNDLE_INSTALLED, llInstalled, TRUE );
459464 ExitOnFailure (hr, " Failed to set the bundle installed built-in variable." );
460465
466+ hr = VariableSetNumeric (pVariables, BURN_BUNDLE_DETECTED_SCOPE, pRegistration->detectedScope , TRUE );
467+ ExitOnFailure (hr, " Failed to set the bundle detected scope built-in variable." );
468+
461469 hr = VariableSetNumeric (pVariables, VARIABLE_REBOOTPENDING, IsWuRebootPending () || IsRegistryRebootPending (), TRUE );
462470 ExitOnFailure (hr, " Failed to overwrite the bundle reboot-pending built-in variable." );
463471
@@ -479,16 +487,20 @@ extern "C" HRESULT RegistrationDetectInstalled(
479487 {
480488 // For PUOM/PMOU bundles, check per-machine then fall back to per-user.
481489 hr = DetectInstalled (pRegistration, HKEY_LOCAL_MACHINE);
482- ExitOnFailure (hr, " Failed to detect HKEY_LOCAL_MACHINE bundle registration install state." );
483490
484- if (BOOTSTRAPPER_REGISTRATION_TYPE_NONE == pRegistration-> detectedRegistrationType )
491+ if (FAILED (hr) )
485492 {
486493 hr = DetectInstalled (pRegistration, HKEY_CURRENT_USER);
487- ExitOnFailure (hr, " Failed to detect HKEY_CURRENT_USER bundle registration install state." );
488494 }
489495 }
490496
491- LExit:
497+ // LExit:
498+ // Not finding the key or value is okay.
499+ if (E_FILENOTFOUND == hr || E_PATHNOTFOUND == hr)
500+ {
501+ hr = S_OK;
502+ }
503+
492504 return hr;
493505}
494506
@@ -654,6 +666,9 @@ extern "C" HRESULT RegistrationSessionBegin(
654666 hr = RegWriteStringFormatted (hkRegistration, REGISTRY_BUNDLE_DISPLAY_ICON, L" %s,0" , pRegistration->sczCacheExecutablePath );
655667 ExitOnFailure (hr, " Failed to write %ls value." , REGISTRY_BUNDLE_DISPLAY_ICON);
656668
669+ hr = RegWriteNumber (hkRegistration, REGISTRY_BUNDLE_SCOPE, pRegistration->fPerMachine ? BOOTSTRAPPER_SCOPE_PER_MACHINE : BOOTSTRAPPER_SCOPE_PER_USER);
670+ ExitOnFailure (hr, " Failed to write %ls value." , REGISTRY_BUNDLE_SCOPE);
671+
657672 // update display name
658673 hr = UpdateBundleNameRegistration (pRegistration, pVariables, hkRegistration, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS == registrationType);
659674 ExitOnFailure (hr, " Failed to update name and publisher." );
@@ -1054,10 +1069,6 @@ extern "C" HRESULT RegistrationSetPaths(
10541069 // save registration key root
10551070 pRegistration->hkRoot = pRegistration->fPerMachine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
10561071
1057- // build uninstall registry key path
1058- hr = StrAllocFormatted (&pRegistration->sczRegistrationKey , L" %ls\\ %ls" , BURN_REGISTRATION_REGISTRY_UNINSTALL_KEY, pRegistration->sczCode );
1059- ExitOnFailure (hr, " Failed to build uninstall registry key path." );
1060-
10611072 // build cache directory
10621073 hr = CacheGetCompletedPath (pCache, pRegistration->fPerMachine , pRegistration->sczCode , &sczCacheDirectory);
10631074 ExitOnFailure (hr, " Failed to build cache directory." );
@@ -1754,25 +1765,28 @@ static HRESULT DetectInstalled(
17541765 HRESULT hr = S_OK;
17551766 HKEY hkRegistration = NULL ;
17561767 DWORD dwInstalled = 0 ;
1768+ DWORD dwScope = 0 ;
17571769
17581770 pRegistration->fCached = pRegistration->sczCacheExecutablePath && FileExistsEx (pRegistration->sczCacheExecutablePath , NULL );
17591771 pRegistration->detectedRegistrationType = BOOTSTRAPPER_REGISTRATION_TYPE_NONE;
1772+ pRegistration->detectedScope = BOOTSTRAPPER_SCOPE_DEFAULT;
17601773
17611774 // open registration key
17621775 hr = RegOpen (hkRoot, pRegistration->sczRegistrationKey , KEY_QUERY_VALUE, &hkRegistration);
17631776 if (SUCCEEDED (hr))
17641777 {
17651778 hr = RegReadNumber (hkRegistration, REGISTRY_BUNDLE_INSTALLED, &dwInstalled);
1779+ ExitOnFailure (hr, " Failed to read registration %ls@%ls." , pRegistration->sczRegistrationKey , REGISTRY_BUNDLE_INSTALLED);
17661780
17671781 pRegistration->detectedRegistrationType = (1 == dwInstalled) ? BOOTSTRAPPER_REGISTRATION_TYPE_FULL : BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS;
1768- }
17691782
1770- // Not finding the key or value is okay.
1771- if (E_FILENOTFOUND == hr || E_PATHNOTFOUND == hr)
1772- {
1773- hr = S_OK ;
1783+ hr = RegReadNumber (hkRegistration, REGISTRY_BUNDLE_SCOPE, &dwScope);
1784+ ExitOnFailure (hr, " Failed to read registration %ls@%ls. " , pRegistration-> sczRegistrationKey , REGISTRY_BUNDLE_SCOPE);
1785+
1786+ pRegistration-> detectedScope = static_cast <BOOTSTRAPPER_SCOPE>(dwScope) ;
17741787 }
17751788
1789+ LExit:
17761790 ReleaseRegKey (hkRegistration);
17771791
17781792 return hr;
0 commit comments