| 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..254433677a61091e138dbfbfacc107895a9bfd3e 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,
|
| + 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 0;
|
| +}
|
|
|
| // 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);
|
|
|