Chromium Code Reviews| Index: sandbox/win/src/target_services.cc |
| diff --git a/sandbox/win/src/target_services.cc b/sandbox/win/src/target_services.cc |
| index 116f0c929b81ee71ac9d5f7f686593e56a3e78f4..d38acd7a78ad174d535ea439b4978eb0d1ad33ee 100644 |
| --- a/sandbox/win/src/target_services.cc |
| +++ b/sandbox/win/src/target_services.cc |
| @@ -59,6 +59,45 @@ bool CloseOpenHandles(bool* is_csrss_connected) { |
| return true; |
| } |
| +// GetUserDefaultLocaleName is not available on WIN XP. So we'll |
| +// load it on-the-fly. |
| +const wchar_t kKernel32DllName[] = L"kernel32.dll"; |
| +typedef int(WINAPI* GetUserDefaultLocaleNameFunction)(LPWSTR lpLocaleName, |
|
Will Harris
2015/12/03 06:06:40
nit: could use typedef decltype e.g.
typedef decl
liamjm (20p)
2015/12/03 18:18:42
Done.
|
| + int cchLocaleName); |
| + |
| +// Warm up language subsystems before the sandbox is turned on. |
| +// Tested on Win8.1 x64: |
| +// This needs to happen after RevertToSelf() is called, because (at least) in |
| +// the case of GetUserDefaultLCID() it checks the TEB to see if the process is |
| +// impersonating (TEB!IsImpersonating). If it is, the cached locale information |
| +// is not used, nor is it set. Therefore, calls after RevertToSelf() will not |
| +// have warmed-up values to use. |
| +bool WarmupWindowsLocales() { |
| + // NOTE(liamjm): When last checked (Win 8.1 x64) it wasn't necessary to |
| + // warmup all of these functions, but let's not assume that. |
| + ::GetUserDefaultLangID(); |
| + ::GetUserDefaultLCID(); |
| + if (base::win::GetVersion() >= base::win::VERSION_VISTA) { |
| + static GetUserDefaultLocaleNameFunction GetUserDefaultLocaleName_func = |
| + NULL; |
| + if (!GetUserDefaultLocaleName_func) { |
| + HMODULE kernel32_dll = ::GetModuleHandle(kKernel32DllName); |
| + if (!kernel32_dll) { |
| + return false; |
| + } |
| + GetUserDefaultLocaleName_func = |
| + reinterpret_cast<GetUserDefaultLocaleNameFunction>( |
| + GetProcAddress(kernel32_dll, "GetUserDefaultLocaleName")); |
| + if (!GetUserDefaultLocaleName_func) { |
| + return false; |
| + } |
| + } |
| + wchar_t localeName[LOCALE_NAME_MAX_LENGTH] = {0}; |
| + return (0 != GetUserDefaultLocaleName_func( |
| + localeName, LOCALE_NAME_MAX_LENGTH * sizeof(wchar_t))); |
| + } |
| + return true; |
| +} |
| // Used as storage for g_target_services, because other allocation facilities |
| // are not available early. We can't use a regular function static because on |
| @@ -97,6 +136,8 @@ void TargetServicesBase::LowerToken() { |
| ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_FLUSHANDLES); |
| if (ERROR_SUCCESS != ::RegDisablePredefinedCache()) |
| ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_CACHEDISABLE); |
| + if (!WarmupWindowsLocales()) |
| + ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_WARMUP); |
| bool is_csrss_connected = true; |
| if (!CloseOpenHandles(&is_csrss_connected)) |
| ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_CLOSEHANDLES); |