summaryrefslogtreecommitdiffstats
path: root/chrome_frame/simple_resource_loader.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome_frame/simple_resource_loader.cc')
-rw-r--r--chrome_frame/simple_resource_loader.cc136
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, &region);
+ 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);
+}