1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome_frame/simple_resource_loader.h"
10 #include "base/base_paths.h"
11 #include "base/file_path.h"
12 #include "base/file_util.h"
13 #include "base/path_service.h"
14 #include "base/i18n/rtl.h"
15 #include "base/string_util.h"
16 #include "base/utf_string_conversions.h"
17 #include "base/win_util.h"
19 const wchar_t kLocalesDirName
[] = L
"Locales";
21 HINSTANCE
SimpleResourceLoader::locale_dll_handle_
;
23 SimpleResourceLoader::SimpleResourceLoader() {
24 // Find and load the resource DLL.
25 std::wstring locale
= GetSystemLocale();
26 std::wstring locale_dll_path
;
28 if (GetLocaleFilePath(locale
, &locale_dll_path
)) {
29 DCHECK(locale_dll_handle_
== NULL
) << "Locale DLL is already loaded!";
30 locale_dll_handle_
= LoadLocaleDll(locale_dll_path
);
31 DCHECK(locale_dll_handle_
!= NULL
) << "Failed to load locale dll!";
36 std::wstring
SimpleResourceLoader::GetSystemLocale() {
37 std::string language
, region
;
38 base::i18n::GetLanguageAndRegionFromOS(&language
, ®ion
);
40 if (!language
.empty())
42 if (!region
.empty()) {
46 return ASCIIToWide(ret
);
49 bool SimpleResourceLoader::GetLocaleFilePath(const std::wstring
& locale
,
50 std::wstring
* file_path
) {
54 PathService::Get(base::DIR_MODULE
, &module_path
);
55 FilePath locales_path
= module_path
.Append(kLocalesDirName
);
57 // We may be residing in the "locales" directory's parent, or we might be
58 // in a sibling directory. Move up one and look for Locales again in the
60 if (!file_util::DirectoryExists(locales_path
)) {
61 locales_path
= module_path
.DirName();
62 locales_path
= locales_path
.Append(kLocalesDirName
);
65 bool found_dll
= false;
66 if (file_util::DirectoryExists(locales_path
)) {
67 std::wstring
dll_name(locale
);
70 // First look for the named locale DLL.
71 FilePath
look_path(locales_path
.Append(dll_name
));
72 if (file_util::PathExists(look_path
)) {
73 *file_path
= look_path
.value();
77 // If we didn't find it, try defaulting to en-US.dll.
78 dll_name
= L
"en-US.dll";
79 look_path
= locales_path
.Append(dll_name
);
80 if (file_util::PathExists(look_path
)) {
81 *file_path
= look_path
.value();
86 NOTREACHED() << "Could not locate locales DLL directory.";
92 HINSTANCE
SimpleResourceLoader::LoadLocaleDll(const std::wstring
& dll_path
) {
94 if (win_util::GetWinVersion() >= win_util::WINVERSION_VISTA
) {
95 load_flags
= LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE
|
96 LOAD_LIBRARY_AS_IMAGE_RESOURCE
;
98 load_flags
= DONT_RESOLVE_DLL_REFERENCES
;
101 // The dll should only have resources, not executable code.
102 HINSTANCE locale_dll_handle
= LoadLibraryEx(dll_path
.c_str(), NULL
,
104 DCHECK(locale_dll_handle
!= NULL
) << "unable to load generated resources: "
107 return locale_dll_handle
;
110 std::wstring
SimpleResourceLoader::GetLocalizedResource(int message_id
) {
111 if (!locale_dll_handle_
) {
112 LOG(WARNING
) << "locale resources are not loaded";
113 return std::wstring();
116 DCHECK(IS_INTRESOURCE(message_id
));
118 const ATLSTRINGRESOURCEIMAGE
* image
= AtlGetStringResourceImage(
119 locale_dll_handle_
, message_id
);
121 // Fall back on the current module (shouldn't be any strings here except
123 image
= AtlGetStringResourceImage(_AtlBaseModule
.GetModuleInstance(),
126 NOTREACHED() << "unable to find resource: " << message_id
;
127 return std::wstring();
130 return std::wstring(image
->achString
, image
->nLength
);
134 std::wstring
SimpleResourceLoader::Get(int message_id
) {
135 SimpleResourceLoader
* loader
= SimpleResourceLoader::instance();
136 return loader
->GetLocalizedResource(message_id
);
139 HINSTANCE
SimpleResourceLoader::GetResourceModuleHandle() {
140 return locale_dll_handle_
;