Windows Update Control Panel Restorer - #5052
Conversation
|
Thanks for the pull request! This repository uses a two-stage review: an AI review that you run yourself, followed by a human review. To get started, comment See the pull request review process for the full details. |
|
/ai-review |
Submission reviewNote: This review was done by Claude. Due to the amount of submissions, doing a fully manual review for each pull request is no longer feasible. Thank you for understanding. Remember: The AI reviewer can be wrong - it may misread code, flag correct code as broken, or suggest changes that make things worse. Treat its findings as suggestions to verify, not instructions to follow blindly. You're responsible for the code you submit, so if a finding doesn't hold up, say so instead of changing working code to satisfy it. Please address the following issues. The items in the collapsed sections are optional, so it's your call whether to address them. There are a couple of blocking issues here — one architectural (the runtime download), one that looks like unfinished work — plus a few concrete stability bugs. 1. The mod downloads and executes a DLL from a Microsoft server at runtime — this breaks Windhawk's self-contained rule. 2. The submission looks unfinished — there's a "HELP NEEDED" block addressed to the reviewer, and the advertised task-links feature is actually disabled. 3. The Ctrl+P hotkey is a system-wide hotkey and will hijack Print in every application. 4. The hotkey window class is registered but never unregistered — it crashes on the next mod load. 5. The private Optional improvements
Minor polish — none of this affects users, so it's your call.
Functionality notes
Non-critical observations about the feature behavior itself.
Next steps:
See the review process for details. |
|
/ai-review |
Submission reviewNote: This review was done by Claude. Due to the amount of submissions, doing a fully manual review for each pull request is no longer feasible. Thank you for understanding. Remember: The AI reviewer can be wrong - it may misread code, flag correct code as broken, or suggest changes that make things worse. Treat its findings as suggestions to verify, not instructions to follow blindly. You're responsible for the code you submit, so if a finding doesn't hold up, say so instead of changing working code to satisfy it. Please address the following issues. The items in the collapsed sections are optional, so it's your call whether to address them. Thanks for the update — the hotkey, the unregistered window class and the unfinished nav-pane placeholder from the previous round are all resolved, and the sidebar is now implemented. The runtime download is still the blocking issue, and the new code introduced a few more problems. 1. The mod still downloads and executes a DLL from a Microsoft server at runtime. There's no small fix; the mod needs an architecture that never fetches a remote file. The rest of the machinery (in-memory CPL registration, embedded MUI table, DirectUI XML patching) doesn't depend on the download — what does is the 2. Page rendering does blocking service + COM work on the Control Panel UI thread.
3. Debug leftovers are shipped and active. 4. The if (type == IMAGE_ICON && IS_INTRESOURCE(name) &&
instance == GetModuleHandleW(L"shell32.dll")) {(and pick IDs that shell32 genuinely doesn't define, or better, use a distinctive range). 5. The 6. 7. Leaks that accumulate across enable/disable cycles.
8. 9. 10. The README has no screenshot. This mod recreates a visible Control Panel page with two selectable skins and a colored status banner — a screenshot (or two, one per skin) makes a big difference in the mod catalog. Only Optional improvements
Minor polish — none of this affects users, so it's your call.
Functionality notes
Non-critical observations and ideas about the feature behavior itself.
Next steps:
See the review process for details. |
|
/ai-review |
Submission reviewNote: This review was done by Claude. Due to the amount of submissions, doing a fully manual review for each pull request is no longer feasible. Thank you for understanding. Remember: The AI reviewer can be wrong - it may misread code, flag correct code as broken, or suggest changes that make things worse. Treat its findings as suggestions to verify, not instructions to follow blindly. You're responsible for the code you submit, so if a finding doesn't hold up, say so instead of changing working code to satisfy it. Please address the following issues. The items in the collapsed sections are optional, so it's your call whether to address them. The blocking architectural issue from the previous two rounds is unchanged, and the new background-worker layer added since the last review brought its own problems (unload hang, races on shared caches, a registry-tracking regression). 1. The mod still downloads and executes a DLL from a Microsoft server at runtime. There is no small fix; the mod needs an architecture that never fetches a remote file. What actually depends on the payload is the Two things that follow from the same design and need an answer regardless:
2. The README is unfinished and has no screenshots. Lines 65-68 ship a note to yourself rather than content: This mod is entirely visual, so please add a real screenshot per skin (and remove the placeholder). Your merged win7-legacy-applet-restorer does this correctly. 3.
So toggling the mod off while it is starting up freezes Windhawk. Please make the wait bounded: close the WinINet handles from 4. Page rendering can still block the Control Panel UI thread for seconds. The caching added this round doesn't cover the cold path. The render path should never do either. Return an empty string / "up to date"-neutral state when the value isn't cached yet, and let the next page render pick it up: static std::wstring LastInstallTimeText() {
std::lock_guard<std::mutex> lock(g_statusMutex);
return g_lastInstallComputed ? g_cachedLastInstall : std::wstring();
}5. Shared caches are read/written from several Explorer threads with no synchronization. Each Explorer/Control Panel window runs on its own thread, so two windows rendering the page (or two icon requests) genuinely race:
A 6. void Track(HKEY hKey, const std::wstring& path) {
if (!hKey || IsSpecialRoot(hKey)) return;
if (!ContainsRelevantKeywordInsensitive(path)) return; // <-- missing here
...
}Two related regressions against that same mod, both inside code that runs on foreign shell threads:
7. The 8. Optional improvements
Minor polish — none of this affects users, so it's your call.
Functionality notes
Non-critical observations and ideas about the feature behavior itself.
Next steps:
See the review process for details. |
|
The embedded MUI strings are necessary for UI localization as they are text translations, not executable code. The DLL itself is downloaded directly from Microsoft's official symbol server (msdl.microsoft.com) and verified by SHA-256. This approach is identical to the already-approved Windhawk mods like "Win10 taskbar on Win11 24H2." The mod does NOT redistribute the DLL but it uses it as a runtime dependency. |
Updated README and settings for Windows Update Control Panel Restorer mod. Removed debug option and improved comments.
|
/ai-review |
Submission reviewNote: This review was done by Claude. Due to the amount of submissions, doing a fully manual review for each pull request is no longer feasible. Thank you for understanding. Remember: The AI reviewer can be wrong - it may misread code, flag correct code as broken, or suggest changes that make things worse. Treat its findings as suggestions to verify, not instructions to follow blindly. You're responsible for the code you submit, so if a finding doesn't hold up, say so instead of changing working code to satisfy it. Please address the following issues. The items in the collapsed sections are optional, so it's your call whether to address them. First, a correction to the earlier rounds of this review: the runtime download from the Microsoft Symbol Server is no longer being treated as blocking. Your Performance Information and Tools Restorer was merged on 2026-08-10 with the same pinned-SHA-256 symbol-server payload design, so that architecture has been accepted for this family of mods and it would be inconsistent to keep blocking on it here. The remaining findings below are about this mod's own code. Note also that the fixed RVAs into the payload ( 1. "Check for updates" can freeze an Explorer UI thread, and can stall mod unload for minutes.
2. Two Control Panel windows can open two "Change settings" dialogs, and the second one paints with a deleted GDI brush.
Fix: make the "already open" check and the registration one atomic step under 3. The payload is verified and then loaded as two separate steps, leaving a TOCTOU window in front of fixed-RVA hooking. Fix: hold the file open across verify-and-load. Open it once with 4. Two resource accumulations that are never reclaimed.
If you conclude there's genuinely no safe way to reclaim either of these inside this design, say so in the PR and it can be recorded as a known limitation instead — but it shouldn't stay silent. Optional improvements
Minor polish — none of this affects users, so it's your call.
Functionality notes
Non-critical observations and ideas about the feature behavior itself.
Next steps:
See the review process for details. |
Refactor settings dialog state management to use a struct instead of static globals. This change allows for multiple instances of the dialog to maintain their own state without conflicts.
|
/ai-review |
Submission reviewNote: This review was done by Claude. Due to the amount of submissions, doing a fully manual review for each pull request is no longer feasible. Thank you for understanding. Remember: The AI reviewer can be wrong - it may misread code, flag correct code as broken, or suggest changes that make things worse. Treat its findings as suggestions to verify, not instructions to follow blindly. You're responsible for the code you submit, so if a finding doesn't hold up, say so instead of changing working code to satisfy it. Please address the following issues. The items in the collapsed sections are optional, so it's your call whether to address them. This is a very ambitious mod (10.5k lines, a downloaded payload, a registry virtualization layer, private DirectUI/ABI patching, and four hand-built dialogs) running inside 1. Payload verification is TOCTOU: the file is verified by path, then loaded by path.
You already solved this in your own Performance Information and Tools Restorer, which pins the file handle across the verify→load window and then proves the loaded module maps the same file object:
Please port that pattern here (verify through the pinned handle, confirm after Related: 2. Unload can hang for minutes, and the Explorer UI thread can freeze, joining the WUA search thread.
Use the asynchronous API so the search is actually cancellable:
3. The Explorer UI thread is blocked for up to 3 seconds inside the COM activation hooks.
Since the item is deliberately registered before the payload is ready, it would be better to fail the activation immediately and show the fallback, or to make the shell re-navigate once 4. The
static thread_local IPropertyBag* wucltuxWroteToBag = nullptr;
if (wucltuxWroteToBag == bag) { // never true - the hook wrote to its own copy
bag->Release();
return S_FALSE;
}never fires. The comment ("On builds where wucltux DOES publish its own list for this bag (Windows 11) … publishing a second list afterwards would only allocate and leak") describes exactly what now happens: on those builds Hoist the marker to a single file-scope While you're there: both 5. if (g_wuSettingsDlgPending) return nullptr; // another thread is creating one
g_wuSettingsDlgPending = true;
return nullptr;Both paths return 6. static HANDLE WINAPI LoadImageWHookForLegacyWarningIcon(HINSTANCE instance, ...) {
if (instance != GetModuleHandleW(L"shell32.dll")) return LoadImageWOriginalFor...(...);
7.
Two related notes on that cache: it's capped at 8. The DirectUI hooks do full work for every DirectUI document in the shell.
Both hooks receive the resource module. The WU page's XML always comes from the pinned payload, so an early 9. Private DirectUI internals are probed on unrelated windows.
void* root = reinterpret_cast<void*>(GetWindowLongPtrW(hwnd, 0));
ATOM atom = pStrToID(L"auOptionSelectorCombobox");
return root && atom && pFindDescendent(root, atom);That takes whatever is in the window's first extra-bytes slot and passes it to 10. A 200 ms polling timer with a hardcoded ID is installed on a window the mod doesn't own.
Separately, the timer keeps firing every 200 ms for as long as the settings page is open, and each tick calls 11. Modules and files are leaked on every load/unload cycle.
Individually these are small, but they accumulate across the enable/disable/settings-change cycles that mod development and updates involve, and none of them is reclaimed until Explorer restarts. It would be good to at least free the payload and the current 12. The custom dialogs have no DPI scaling.
Scale the pixel constants by 13.
14. The classic settings dialog silently discards the user's selection. The combobox is deliberately left enabled ("so it feels interactive") while 15. Downloading Windhawk's guidance is that a mod must be self-contained and must not depend on, download, or contact external servers. This mod requires a ~one-time network fetch before the page can render at all, and the pinned I'm flagging it rather than blocking on it, because your Performance Information and Tools Restorer does the same thing and was merged — so there's precedent and this is ultimately the maintainer's call. Worth being explicit about it in the PR description so it gets decided deliberately rather than by inheritance. Two things that make the situation here worse than in that mod, and are worth mentioning either way: the hooking depends on hardcoded RVAs into the pinned build ( Optional improvements
Minor polish — none of this affects users, so it's your call.
Functionality notes
Non-critical observations and ideas about the feature behavior itself.
Next steps:
See the review process for details. |
Updated the Windows Update Control Panel Restorer to improve the handling of the native combobox and payload verification process.
|
/ai-review |
|
This pull request has already had 3 AI reviews in the last 24 hours, which is the limit, so no review was posted this time. Comment |
|
/ai-review |
Submission reviewNote: This review was done by Claude. Due to the amount of submissions, doing a fully manual review for each pull request is no longer feasible. Thank you for understanding. Remember: The AI reviewer can be wrong - it may misread code, flag correct code as broken, or suggest changes that make things worse. Treat its findings as suggestions to verify, not instructions to follow blindly. You're responsible for the code you submit, so if a finding doesn't hold up, say so instead of changing working code to satisfy it. Please address the following issues. The items in the collapsed sections are optional, so it's your call whether to address them. The overall structure follows the pattern you already established in performance-info-tools-restorer.wh.cpp, and the payload handling in particular is careful (pin-then-verify-then-load with 1. The update-search thread is detached at unload, which will crash explorer.exe.
} else {
Wh_Log(L"...online update search still running at unload; detaching instead of blocking Explorer");
g_wuSearchThread->detach();
}Windhawk unloads the mod with a single The comment acknowledges this and points at the right fix - please do it rather than deferring: use the asynchronous Background on the unloadability contract and the worker-thread case specifically: https://github.com/ramensoftware/windhawk/wiki/Global-objects-and-process-shutdown (see #1-worker-thread-stdthread). The 2. The payload-notice thread has the same escape hatch.
if (WaitForSingleObject(thread, kFinalWaitMs) == WAIT_TIMEOUT) {
Wh_Log(L"...payload-notice thread did not exit in time; giving up rather than blocking unload");
}
The wait here is safe to make unconditional: the notice runs on its own dedicated thread that holds no locks, and 3. The mod's own dialogs have no DPI scaling. There is no // WuFaqDlgProc
const int bodyTop = 62; ... const int btnW = 68; const int btnH = 23;
CreateWindowExW(WS_EX_CLIENTEDGE, L"RichEdit20W", ..., 14, bodyTop, cw - 28, bodyHeight, ...);
// WuCheckDlgProc
CreateWindowExW(0, L"STATIC", ..., 16, 44, w - 32, 18, ...);
CreateWindowExW(0, L"msctls_progress32", ..., 16, 64, w - 32, 14, ...);
// WuPaintDialogHeader / WuCreateHeaderFont
RECT header = { client.left, client.top, client.right, headerHeight }; // 40 or 56
DrawIconEx(hdc, 16, y, icon, iconSize, iconSize, ...);
return CreateFontW(-16, 0, 0, 0, FW_SEMIBOLD, ...);The dialog shells are built from Scale every hard-coded pixel value through the window's DPI, e.g.: const UINT dpi = GetDpiForWindow(hwnd);
const auto S = [dpi](int px) { return MulDiv(px, dpi, 96); };
... CreateWindowExW(0, L"STATIC", ..., S(16), S(44), w - S(32), S(18), ...);and use Optional improvements
Minor polish - none of this affects users, so it's your call.
Functionality notes
Non-critical observations and ideas about the feature behavior itself.
Next steps:
See the review process for details. |
|
/ai-review |
|
This pull request has already had 3 AI reviews in the last 24 hours, which is the limit, so no review was posted this time. Comment |
This is a Windhawk mod that restores the classic Windows 7/8.1 Windows Update Control Panel interface on Windows 10 and 11 systems by downloading the Windows 8.1 file from the Microsoft servers to make it work properly. The mod recreates the familiar colored status banner with real-time update information (up to date, updates available, pending restart) using the modern WUA (Windows Update Agent) backend. It includes multi-language support, classic task links, and friendly error messages when the Windows Update service is unavailable. To make the mod better, please point out any possible improvements for accuracy and functionality to make it more robust and functional.To make the mod better, please point out any possible improvements for accuracy and functionality to make it more robust and functional.
Changelog
If this pull request updates an existing mod, describe the changes below:
Mod authorship
If this pull request introduces a new mod, please complete the section below.
This mod was created by:
Please select the options that best apply. Your selection does not affect the acceptance criteria, but it helps reviewers understand the context of the code and provide relevant feedback.