Compare commits

...
1 Commits
@@ -192,7 +192,7 @@ class Windows {
GetPrivacyWindowBand get_band_ = nullptr; GetPrivacyWindowBand get_band_ = nullptr;
}; };
DWORD WINAPI Run(void*) { DWORD Run() {
wchar_t bootstrap[256]{}; wchar_t bootstrap[256]{};
if (!GetEnvironmentVariableW(kPrivacyBandBootstrap, bootstrap, 256)) if (!GetEnvironmentVariableW(kPrivacyBandBootstrap, bootstrap, 256))
return ERROR_INVALID_PARAMETER; return ERROR_INVALID_PARAMETER;
@@ -239,8 +239,8 @@ DWORD WINAPI Run(void*) {
auto last_check = GetTickCount64(); auto last_check = GetTickCount64();
HANDLE watched[] = {parent, stop}; HANDLE watched[] = {parent, stop};
// Once enabled, retain surviving covers on a validation/layout fault. // Once enabled, retain surviving covers on a validation/layout fault.
// The parent pauses the session after reading the latched error. Only // The parent releases privacy after reading the latched error. Only an
// an explicit stop or parent death tears the remaining windows down. // explicit stop or parent death tears the remaining windows down.
while (initialized) { while (initialized) {
const DWORD wait = MsgWaitForMultipleObjectsEx( const DWORD wait = MsgWaitForMultipleObjectsEx(
2, watched, 100, QS_ALLINPUT, MWMO_INPUTAVAILABLE); 2, watched, 100, QS_ALLINPUT, MWMO_INPUTAVAILABLE);
@@ -273,21 +273,26 @@ DWORD WINAPI Run(void*) {
} }
UnmapViewOfFile(shared); UnmapViewOfFile(shared);
for (HANDLE handle : handles) CloseHandle(handle); for (HANDLE handle : handles) CloseHandle(handle);
// This module runs only in the dedicated process created for this session.
// Exit outside DllMain/loader lock, after HWND destruction on their UI
// thread.
ExitProcess(exit_code);
return exit_code; return exit_code;
} }
void CALLBACK RunBeforeBrokerEntryPoint(ULONG_PTR) {
// The LoadLibraryW startup APC has returned, so the loader lock is no longer
// held. Own the primary thread until privacy stops, including startup errors.
// Never return into RuntimeBroker's COM server startup: an elevated launch
// can fail there with CO_E_WRONG_SERVER_IDENTITY and kill healthy covers.
ExitProcess(Run());
}
} // namespace } // namespace
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID) { BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID) {
if (reason == DLL_PROCESS_ATTACH) { if (reason == DLL_PROCESS_ATTACH) {
module = instance; module = instance;
// Keep thread notifications enabled: this module uses the static CRT. // Loaded by the startup APC on our dedicated, suspended broker's primary
HANDLE thread = CreateThread(nullptr, 0, Run, nullptr, 0, nullptr); // thread. Queue the window loop after that APC instead of starting a worker
if (!thread) return FALSE; // alongside RuntimeBroker's own entry point. Do not run it under loader lock.
CloseHandle(thread); if (!QueueUserAPC(RunBeforeBrokerEntryPoint, GetCurrentThread(), 0))
return FALSE;
} }
return TRUE; return TRUE;
} }