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 |