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 "app/resource_bundle.h"
9 #include "app/app_paths.h"
10 #include "app/l10n_util.h"
11 #include "base/data_pack.h"
12 #include "base/debug_util.h"
13 #include "base/debug/stack_trace.h"
14 #include "base/file_util.h"
15 #include "base/lock.h"
16 #include "base/logging.h"
17 #include "base/path_service.h"
18 #include "base/resource_util.h"
19 #include "base/stl_util-inl.h"
20 #include "base/string_piece.h"
21 #include "base/win/windows_version.h"
27 // Returns the flags that should be passed to LoadLibraryEx.
28 DWORD
GetDataDllLoadFlags() {
29 if (base::win::GetVersion() >= base::win::VERSION_VISTA
)
30 return LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE
| LOAD_LIBRARY_AS_IMAGE_RESOURCE
;
32 return DONT_RESOLVE_DLL_REFERENCES
;
35 } // end anonymous namespace
37 ResourceBundle::~ResourceBundle() {
39 UnloadLocaleResources();
40 STLDeleteContainerPointers(data_packs_
.begin(),
42 resources_data_
= NULL
;
45 void ResourceBundle::UnloadLocaleResources() {
46 if (locale_resources_data_
) {
47 BOOL rv
= FreeLibrary(locale_resources_data_
);
49 locale_resources_data_
= NULL
;
53 void ResourceBundle::LoadCommonResources() {
54 // As a convenience, set resources_data_ to the current resource module.
55 DCHECK(NULL
== resources_data_
) << "common resources already loaded";
56 resources_data_
= _AtlBaseModule
.GetResourceInstance();
59 std::string
ResourceBundle::LoadLocaleResources(
60 const std::string
& pref_locale
) {
61 DCHECK(NULL
== locale_resources_data_
) << "locale dll already loaded";
62 const std::string app_locale
= l10n_util::GetApplicationLocale(pref_locale
);
63 const FilePath
& locale_path
= GetLocaleFilePath(app_locale
);
64 if (locale_path
.value().empty()) {
65 // It's possible that there are no locale dlls found, in which case we just
71 // The dll should only have resources, not executable code.
72 locale_resources_data_
= LoadLibraryEx(locale_path
.value().c_str(), NULL
,
73 GetDataDllLoadFlags());
74 DCHECK(locale_resources_data_
!= NULL
) <<
75 "unable to load generated resources";
80 FilePath
ResourceBundle::GetLocaleFilePath(const std::string
& app_locale
) {
82 PathService::Get(app::DIR_LOCALES
, &locale_path
);
84 if (app_locale
.empty())
87 return locale_path
.AppendASCII(app_locale
+ ".dll");
91 RefCountedStaticMemory
* ResourceBundle::LoadResourceBytes(
92 DataHandle module
, int resource_id
) {
95 if (base::GetDataResourceFromModule(module
, resource_id
, &data_ptr
,
97 return new RefCountedStaticMemory(
98 reinterpret_cast<const unsigned char*>(data_ptr
), data_size
);
104 HICON
ResourceBundle::LoadThemeIcon(int icon_id
) {
105 return ::LoadIcon(resources_data_
, MAKEINTRESOURCE(icon_id
));
108 base::StringPiece
ResourceBundle::GetRawDataResource(int resource_id
) const {
111 if (base::GetDataResourceFromModule(_AtlBaseModule
.GetModuleInstance(),
115 return base::StringPiece(static_cast<const char*>(data_ptr
), data_size
);
116 } else if (locale_resources_data_
&&
117 base::GetDataResourceFromModule(locale_resources_data_
,
121 return base::StringPiece(static_cast<const char*>(data_ptr
), data_size
);
124 base::StringPiece data
;
125 for (size_t i
= 0; i
< data_packs_
.size(); ++i
) {
126 if (data_packs_
[i
]->GetStringPiece(resource_id
, &data
))
130 return base::StringPiece();
133 // Loads and returns a cursor from the current module.
134 HCURSOR
ResourceBundle::LoadCursor(int cursor_id
) {
135 return ::LoadCursor(_AtlBaseModule
.GetModuleInstance(),
136 MAKEINTRESOURCE(cursor_id
));
139 string16
ResourceBundle::GetLocalizedString(int message_id
) {
140 // If for some reason we were unable to load a resource dll, return an empty
141 // string (better than crashing).
142 if (!locale_resources_data_
) {
143 base::debug::StackTrace().PrintBacktrace(); // See http://crbug.com/21925.
144 LOG(WARNING
) << "locale resources are not loaded";
148 DCHECK(IS_INTRESOURCE(message_id
));
150 // Get a reference directly to the string resource.
151 HINSTANCE hinstance
= locale_resources_data_
;
152 const ATLSTRINGRESOURCEIMAGE
* image
= AtlGetStringResourceImage(hinstance
,
155 // Fall back on the current module (shouldn't be any strings here except
157 image
= AtlGetStringResourceImage(_AtlBaseModule
.GetModuleInstance(),
160 // See http://crbug.com/21925.
161 base::debug::StackTrace().PrintBacktrace();
162 NOTREACHED() << "unable to find resource: " << message_id
;
163 return std::wstring();
166 // Copy into a string16 and return.
167 return string16(image
->achString
, image
->nLength
);