Pivotlink: Browser Router V1.1 - #5000
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. The bypass feature itself is a reasonable idea, but the machinery added to implement it (a 50 ms polling thread plus a shared section in every process on the system) is a large system-wide cost, and the part that is supposed to justify that cost — cross-process state for sandboxed apps — looks like it doesn't actually work. Details below. 1. A 50 ms polling thread is started in every process on the machine. The mod is
On a typical session that's a few hundred extra threads and several thousand wakeups per second doing nothing, plus added latency on every process launch. It also forces a win32k/GUI-thread conversion in processes that would otherwise never touch user32. Constant polling of this kind is one of the most frequently rejected patterns in this repo. The polling is also unconditional: it runs even when Suggested fix, in order of preference:
2. The Two independent problems:
The net effect is that in sandboxed apps the mod silently falls back to the plain 3. WaitForSingleObject(g_hPollerThread, 2000);
CloseHandle(g_hPollerThread);If the wait times out, There is no deadlock risk here — the thread only waits on the stop event with a 50 ms timeout and takes WaitForSingleObject(g_hPollerThread, INFINITE);4. The 2-second grace window causes silent false bypasses in everyday use.
Suggestions: apply the shared-state fallback only where the direct key read genuinely can't work rather than everywhere, shorten the window a lot (a few hundred ms is enough to bridge press→ 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. |
Changes addressing review feedbackMain issues (all addressed)1. Polling thread removed from every process → single poller in explorer.exe only. 2. Shared memory namespace clarification. 3. 4. 2-second grace window reduced to 500ms. Optional improvements (all addressed)
Functionality notes (acknowledged)
/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. Most of the findings below are in the new bypass machinery, but the first two are pre-existing in the routing path and matter more because the mod injects everywhere ( 1. The URL is appended to the browser's command line unquoted — command-line injection. In sei.lpFile = targetBrowser.c_str();
sei.lpParameters = cleanUrl.c_str();
therefore becomes an extra Chromium switch; Quoting is sufficient (a single quoted argument starting with if (cleanUrl.find_first_of(L"\" \t\r\n") != std::wstring::npos) {
return false; // let the shell handle it
}
std::wstring params = L"\"" + cleanUrl + L"\"";
sei.lpParameters = params.c_str();The 2. std::wstring targetPath = GetBrowserFullPath(targetBrowser);
if (targetPath.empty()) return false; // fall through to the shell
sei.lpFile = targetPath.c_str();This also makes the two routing paths behave consistently. See the note in Functionality notes about letting the settings accept a full path, which covers browsers that have no 3. The two WindhawkUtils::SetFunctionHook(CreateProcessW, CreateProcessW_Hook, &CreateProcessW_Original);
...
Wh_SetFunctionHook(pKB, (void*)CreateProcessW_Hook, (void**)&CreateProcessW_Original);Both hooks write their trampoline into the same CreateProcessW_t CreateProcessW_kernel32_Original;
CreateProcessW_t CreateProcessW_kernelbase_Original;Alternatively, hook only the kernelbase copy — that's the established pattern in the repo, e.g. block-windows-startmenu-and-hosts.wh.cpp#L215-L226 hooks 4. The bypass shared memory probably doesn't reach the sandboxed apps it was added for. The stated motivation is MSIX/UWP apps (WhatsApp, Store), but:
Before investing further in this, it's worth checking whether routing works in an AppContainer at all: 5. The bypass setup/teardown isn't wired into 6. The is rewritten to if (_wcsicmp(targetExe.c_str(), targetBrowser.c_str()) == 0) goto passthrough;Preserving the caller's remaining switches when routing between browsers of the same family would be a further improvement, but the no-op case above is the one that actively breaks working launches. 7. The poller thread runs at 20 Hz in explorer.exe for the life of the session. 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. |
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.