| Index: content/app/content_main_runner.cc
|
| diff --git a/content/app/content_main_runner.cc b/content/app/content_main_runner.cc
|
| index 44421e80ee733ac2c6fc09168db09d56109b20f2..14dbc9e567fab312ac5abbda6cb5d2c40b9aa5ea 100644
|
| --- a/content/app/content_main_runner.cc
|
| +++ b/content/app/content_main_runner.cc
|
| @@ -20,6 +20,7 @@
|
| #include "base/path_service.h"
|
| #include "base/process_util.h"
|
| #include "base/profiler/alternate_timer.h"
|
| +#include "base/string_util.h"
|
| #include "base/stringprintf.h"
|
| #include "base/string_number_conversions.h"
|
| #include "content/browser/browser_main.h"
|
| @@ -95,6 +96,58 @@ extern int ZygoteMain(const MainFunctionParams&,
|
| } // namespace content
|
| #endif
|
|
|
| +namespace {
|
| +#if defined(OS_WIN)
|
| +// In order to have Theme support, we need to connect to the theme service.
|
| +// This needs to be done before we lock down the process. Officially this
|
| +// can be done with OpenThemeData() but it fails unless you pass a valid
|
| +// window at least the first time. Interestingly, the very act of creating a
|
| +// window also sets the connection to the theme service.
|
| +void EnableThemeSupportOnAllWindowStations() {
|
| + HDESK desktop_handle = ::OpenInputDesktop(0, FALSE, READ_CONTROL);
|
| + if (desktop_handle) {
|
| + // This means we are running in an input desktop, which implies WinSta0.
|
| + ::CloseDesktop(desktop_handle);
|
| + return;
|
| + }
|
| +
|
| + HWINSTA current_station = ::GetProcessWindowStation();
|
| + DCHECK(current_station);
|
| +
|
| + HWINSTA winsta0 = ::OpenWindowStationA("WinSta0", FALSE, GENERIC_READ);
|
| + if (!winsta0 || !::SetProcessWindowStation(winsta0)) {
|
| + // Could not set the alternate window station. There is a possibility
|
| + // that the theme wont be correctly initialized.
|
| + NOTREACHED() << "Unable to switch to WinSta0, we: "<< ::GetLastError();
|
| + }
|
| +
|
| + HWND window = ::CreateWindowExW(0, L"Static", L"", WS_POPUP | WS_DISABLED,
|
| + CW_USEDEFAULT, 0, 0, 0, HWND_MESSAGE, NULL,
|
| + ::GetModuleHandleA(NULL), NULL);
|
| + if (!window) {
|
| + DLOG(WARNING) << "failed to enable theme support";
|
| + } else {
|
| + ::DestroyWindow(window);
|
| + window = NULL;
|
| + }
|
| +
|
| + // Revert the window station.
|
| + if (!::SetProcessWindowStation(current_station)) {
|
| + // We failed to switch back to the secure window station. This might
|
| + // confuse the process enough that we should kill it now.
|
| + LOG(FATAL) << "Failed to restore alternate window station";
|
| + }
|
| +
|
| + if (!::CloseWindowStation(winsta0)) {
|
| + // We might be leaking a winsta0 handle. This is a security risk, but
|
| + // since we allow fail over to no desktop protection in low memory
|
| + // condition, this is not a big risk.
|
| + NOTREACHED();
|
| + }
|
| +}
|
| +#endif // defined(OS_WIN)
|
| +} // namespace
|
| +
|
| namespace content {
|
|
|
| base::LazyInstance<ContentBrowserClient>
|
| @@ -563,6 +616,9 @@ static void ReleaseFreeMemoryThunk() {
|
| SendTaskPortToParentProcess();
|
| }
|
| #elif defined(OS_WIN)
|
| + // This must be done early enough since some helper functions like
|
| + // IsTouchEnanbled, needed to load resources, may call into the theme dll.
|
| + EnableThemeSupportOnAllWindowStations();
|
| #if defined(ENABLE_HIDPI)
|
| ui::EnableHighDPISupport();
|
| #endif
|
|
|