diff options
Diffstat (limited to 'chrome_frame/simple_resource_loader.cc')
-rw-r--r-- | chrome_frame/simple_resource_loader.cc | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/chrome_frame/simple_resource_loader.cc b/chrome_frame/simple_resource_loader.cc new file mode 100644 index 0000000..2eb2167 --- /dev/null +++ b/chrome_frame/simple_resource_loader.cc @@ -0,0 +1,136 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome_frame/simple_resource_loader.h" + +#include <atlbase.h> +#include <string> + +#include "base/base_paths.h" +#include "base/file_path.h" +#include "base/file_util.h" +#include "base/path_service.h" +#include "base/i18n/rtl.h" +#include "base/string_util.h" +#include "base/win_util.h" + +const wchar_t kLocalesDirName[] = L"Locales"; + +HINSTANCE SimpleResourceLoader::locale_dll_handle_; + +SimpleResourceLoader::SimpleResourceLoader() { + // Find and load the resource DLL. + std::wstring locale = GetSystemLocale(); + std::wstring locale_dll_path; + + if (GetLocaleFilePath(locale, &locale_dll_path)) { + DCHECK(locale_dll_handle_ == NULL) << "Locale DLL is already loaded!"; + locale_dll_handle_ = LoadLocaleDll(locale_dll_path); + DCHECK(locale_dll_handle_ != NULL) << "Failed to load locale dll!"; + } +} + + +std::wstring SimpleResourceLoader::GetSystemLocale() { + std::string language, region; + base::i18n::GetLanguageAndRegionFromOS(&language, ®ion); + std::string ret; + if (!language.empty()) + ret.append(language); + if (!region.empty()) { + ret.append("-"); + ret.append(region); + } + return ASCIIToWide(ret); +} + +bool SimpleResourceLoader::GetLocaleFilePath(const std::wstring& locale, + std::wstring* file_path) { + DCHECK(file_path); + + FilePath module_path; + PathService::Get(base::DIR_MODULE, &module_path); + FilePath locales_path = module_path.Append(kLocalesDirName); + + // We may be residing in the "locales" directory's parent, or we might be + // in a sibling directory. Move up one and look for Locales again in the + // latter case. + if (!file_util::DirectoryExists(locales_path)) { + locales_path = module_path.DirName(); + locales_path = locales_path.Append(kLocalesDirName); + } + + bool found_dll = false; + if (file_util::DirectoryExists(locales_path)) { + std::wstring dll_name(locale); + dll_name += L".dll"; + + // First look for the named locale DLL. + FilePath look_path(locales_path.Append(dll_name)); + if (file_util::PathExists(look_path)) { + *file_path = look_path.value(); + found_dll = true; + } else { + + // If we didn't find it, try defaulting to en-US.dll. + dll_name = L"en-US.dll"; + look_path = locales_path.Append(dll_name); + if (file_util::PathExists(look_path)) { + *file_path = look_path.value(); + found_dll = true; + } + } + } else { + NOTREACHED() << "Could not locate locales DLL directory."; + } + + return found_dll; +} + +HINSTANCE SimpleResourceLoader::LoadLocaleDll(const std::wstring& dll_path) { + DWORD load_flags = 0; + if (win_util::GetWinVersion() >= win_util::WINVERSION_VISTA) { + load_flags = LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE | + LOAD_LIBRARY_AS_IMAGE_RESOURCE; + } else { + load_flags = DONT_RESOLVE_DLL_REFERENCES; + } + + // The dll should only have resources, not executable code. + HINSTANCE locale_dll_handle = LoadLibraryEx(dll_path.c_str(), NULL, + load_flags); + DCHECK(locale_dll_handle != NULL) << "unable to load generated resources: " + << GetLastError(); + + return locale_dll_handle; +} + +std::wstring SimpleResourceLoader::GetLocalizedResource(int message_id) { + if (!locale_dll_handle_) { + LOG(WARNING) << "locale resources are not loaded"; + return std::wstring(); + } + + DCHECK(IS_INTRESOURCE(message_id)); + + const ATLSTRINGRESOURCEIMAGE* image = AtlGetStringResourceImage( + locale_dll_handle_, message_id); + if (!image) { + // Fall back on the current module (shouldn't be any strings here except + // in unittests). + image = AtlGetStringResourceImage(_AtlBaseModule.GetModuleInstance(), + message_id); + if (!image) { + NOTREACHED() << "unable to find resource: " << message_id; + return std::wstring(); + } + } + return std::wstring(image->achString, image->nLength); +} + +// static +std::wstring SimpleResourceLoader::Get(int message_id) { + SimpleResourceLoader* loader = SimpleResourceLoader::instance(); + return loader->GetLocalizedResource(message_id); +} |