Enhanced reboot pending detection
Rob Mensching committed
Apr 12, 2021 at 20:51 UTC
648133ee7f1206d1208630d5935a4846508fd5b9
2 files changed
+69
-1
src/engine/engine.mc
+6
@@ -1068,3 +1068,9 @@ Language=English
1068
Skipping MSI property '%1!ls!' because condition '%2!ls!' evaluates to %3!hs!.
1069
.
1070
1071
+MessageId=701
1072
+Severity=Warning
1073
+SymbolicName=MSG_PENDING_REBOOT_DETECTED
1074
+Language=English
1075
+A reboot is pending from a prior execution of this bundle: %1!ls!. Apply will be blocked. Continuing...
1076
+.
src/engine/registration.cpp
+63
-1
@@ -97,6 +97,7 @@ static BOOL IsWuRebootPending();
97
static BOOL IsBundleRebootPending(
98
__in BURN_REGISTRATION* pRegistration
99
);
100
+static BOOL IsRegistryRebootPending();
101
102
// function definitions
103
@@ -451,7 +452,7 @@ extern "C" HRESULT RegistrationSetVariables(
452
hr = VariableSetVersion(pVariables, BURN_BUNDLE_VERSION, pRegistration->pVersion, TRUE);
453
ExitOnFailure(hr, "Failed to overwrite the bundle version built-in variable.");
454
454
- hr = VariableSetNumeric(pVariables, BURN_REBOOT_PENDING, IsBundleRebootPending(pRegistration) || IsWuRebootPending(), TRUE);
455
+ hr = VariableSetNumeric(pVariables, BURN_REBOOT_PENDING, IsBundleRebootPending(pRegistration) || IsWuRebootPending() || IsRegistryRebootPending(), TRUE);
456
ExitOnFailure(hr, "Failed to overwrite the bundle reboot-pending built-in variable.");
457
458
LExit:
@@ -505,6 +506,8 @@ extern "C" HRESULT RegistrationDetectResumeType(
506
507
if (IsBundleRebootPending(pRegistration))
508
{
509
+ LogId(REPORT_STANDARD, MSG_PENDING_REBOOT_DETECTED, pRegistration->sczRegistrationKey);
510
+
511
*pResumeType = BOOTSTRAPPER_RESUME_TYPE_REBOOT_PENDING;
512
ExitFunction1(hr = S_OK);
513
}
@@ -1638,3 +1641,62 @@ LExit:
1641
1642
return fBundleRebootPending;
1643
}
1644
+
1645
+static BOOL IsRegistryRebootPending()
1646
+{
1647
+ HRESULT hr = S_OK;
1648
+ DWORD dwValue;
1649
+ HKEY hk = NULL;
1650
+ BOOL fRebootPending = FALSE;
1651
+
1652
+ hr = RegKeyReadNumber(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\ServerManager", L"CurrentRebootAttempts", TRUE, &dwValue);
1653
+ fRebootPending = SUCCEEDED(hr) && 0 < dwValue;
1654
+
1655
+ if (!fRebootPending)
1656
+ {
1657
+ hr = RegKeyReadNumber(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Updates", L"UpdateExeVolatile", TRUE, &dwValue);
1658
+ fRebootPending = SUCCEEDED(hr) && 0 < dwValue;
1659
+
1660
+ if (!fRebootPending)
1661
+ {
1662
+ fRebootPending = RegValueExists(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Component Based Servicing\\RebootPending", NULL, TRUE);
1663
+
1664
+ if (!fRebootPending)
1665
+ {
1666
+ fRebootPending = RegValueExists(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Component Based Servicing\\RebootInProgress", NULL, TRUE);
1667
+
1668
+ if (!fRebootPending)
1669
+ {
1670
+ hr = RegKeyReadNumber(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WindowsUpdate\\Auto Update", L"AUState", TRUE, &dwValue);
1671
+ fRebootPending = SUCCEEDED(hr) && 8 == dwValue;
1672
+
1673
+ if (!fRebootPending)
1674
+ {
1675
+ fRebootPending = RegValueExists(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Session Manager", L"PendingFileRenameOperations", TRUE);
1676
+
1677
+ if (!fRebootPending)
1678
+ {
1679
+ fRebootPending = RegValueExists(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Session Manager", L"PendingFileRenameOperations2", TRUE);
1680
+
1681
+ if (!fRebootPending)
1682
+ {
1683
+ hr = RegOpen(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\FileRenameOperations", KEY_READ | KEY_WOW64_64KEY, &hk);
1684
+ if (SUCCEEDED(hr))
1685
+ {
1686
+ DWORD cSubKeys = 0;
1687
+ DWORD cValues = 0;
1688
+ hr = RegQueryKey(hk, &cSubKeys, &cValues);
1689
+ fRebootPending = SUCCEEDED(hr) && (0 < cSubKeys || 0 < cValues);
1690
+ }
1691
+ }
1692
+ }
1693
+ }
1694
+ }
1695
+ }
1696
+ }
1697
+ }
1698
+
1699
+ ReleaseRegKey(hk);
1700
+
1701
+ return fRebootPending;
1702
+}