@joebigelow / wix-1 / commits / 648133ee

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 +}