Chromium Code Reviews| Index: content/app/content_main_runner.cc |
| diff --git a/content/app/content_main_runner.cc b/content/app/content_main_runner.cc |
| index 4d76ab1f5170d86e479d12bfb8e9bd007a88ab05..c2a4ab13085ab5667d4ef1bfcca04fbb06ce48c3 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" |
| @@ -55,6 +56,7 @@ |
| #include <atlbase.h> |
| #include <atlapp.h> |
| #include <malloc.h> |
| +#include <string> |
| #elif defined(OS_MACOSX) |
| #include "base/mac/scoped_nsautorelease_pool.h" |
| #include "base/mach_ipc_mac.h" |
| @@ -95,6 +97,79 @@ 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 renderer. 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 EnableThemeSupportForRenderer() { |
| + HWINSTA current_station = ::GetProcessWindowStation(); |
| + static const size_t kStaticBufferLength = 32; |
| + char static_buffer[kStaticBufferLength]; |
| + static_buffer[0] = '\0'; |
|
robertshield
2012/09/06 18:35:56
char static_buffer[kStaticBufferLength] = "";
MAD
2012/09/06 23:57:53
Done.
|
| + const char * current_station_name = static_buffer; |
|
robertshield
2012/09/06 18:35:56
nit: const char* current_station_name = static_buf
MAD
2012/09/06 23:57:53
Done.
|
| + // In case our static buffer isn't big enough, we'll use this dynamic one that |
| + // will be holding on the allocated char buffer long enough. |
| + std::string dynamic_buffer; |
|
robertshield
2012/09/06 18:35:56
Couldn't we simplify this by always using dynamic_
MAD
2012/09/06 23:57:53
Done.
|
| + DWORD needed_length = 0; |
| + if (!::GetUserObjectInformationA(current_station, |
| + UOI_NAME, |
| + static_buffer, |
| + kStaticBufferLength, |
| + &needed_length)) { |
| + DCHECK(needed_length > kStaticBufferLength) << " Windows error: " |
| + << ::GetLastError(); |
| + dynamic_buffer.resize(needed_length); |
| + if (!::GetUserObjectInformationA( |
| + current_station, |
| + UOI_NAME, |
| + const_cast<char*>(dynamic_buffer.c_str()), |
|
rvargas (doing something else)
2012/09/06 23:19:21
WriteInto ?
|
| + needed_length, |
| + &needed_length)) { |
| + NOTREACHED() << "Windows error: " << ::GetLastError(); |
| + } |
| + current_station_name = dynamic_buffer.c_str(); |
| + } |
| + |
| + if (base::strncasecmp(current_station_name, "WinSta0", 7)) { |
| + HWINSTA winsta0 = NULL; |
| + winsta0 = ::OpenWindowStationA("WinSta0", FALSE, GENERIC_READ); |
|
robertshield
2012/09/06 18:35:56
shorten this to HWINSTA winsta0 = ::OpenWindowStat
MAD
2012/09/06 23:57:53
Done.
|
| + 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 (!current_station || !::SetProcessWindowStation(current_station)) { |
|
robertshield
2012/09/06 18:35:56
is it possible to get here if current_station is N
MAD
2012/09/06 23:57:53
Done.
|
| + // We failed to switch back to the secure window station. This might |
| + // confuse the renderer 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 +638,10 @@ static void ReleaseFreeMemoryThunk() { |
| SendTaskPortToParentProcess(); |
| } |
| #elif defined(OS_WIN) |
| + // This must be done early enough since some helper functions like |
| + // IsTouchEnanble, needed to load ressources, may call into the theme dll. |
|
robertshield
2012/09/06 18:35:56
*IsTouchEnabled, *resources
MAD
2012/09/06 23:57:53
Done.
|
| + if (process_type == switches::kRendererProcess) |
| + EnableThemeSupportForRenderer(); |
| #if defined(ENABLE_HIDPI) |
| ui::EnableHighDPISupport(); |
| #endif |