OLD | NEW |
| (Empty) |
1 // Copyright 2007-2010 Google Inc. | |
2 // | |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
4 // you may not use this file except in compliance with the License. | |
5 // You may obtain a copy of the License at | |
6 // | |
7 // http://www.apache.org/licenses/LICENSE-2.0 | |
8 // | |
9 // Unless required by applicable law or agreed to in writing, software | |
10 // distributed under the License is distributed on an "AS IS" BASIS, | |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 // See the License for the specific language governing permissions and | |
13 // limitations under the License. | |
14 // ======================================================================== | |
15 | |
16 #include "omaha/goopdate/resource_manager.h" | |
17 #include <windows.h> | |
18 #include <map> | |
19 #include <vector> | |
20 #include "omaha/base/constants.h" | |
21 #include "omaha/base/commontypes.h" | |
22 #include "omaha/base/debug.h" | |
23 #include "omaha/base/error.h" | |
24 #include "omaha/base/file.h" | |
25 #include "omaha/base/file_ver.h" | |
26 #include "omaha/base/logging.h" | |
27 #include "omaha/base/path.h" | |
28 #include "omaha/base/utils.h" | |
29 #include "omaha/common/goopdate_utils.h" | |
30 #include "omaha/common/lang.h" | |
31 | |
32 namespace omaha { | |
33 | |
34 ResourceManager* ResourceManager::instance_ = NULL; | |
35 | |
36 HRESULT ResourceManager::CreateForDefaultLanguage(bool is_machine, | |
37 const CString& resource_dir) { | |
38 return Create(is_machine, | |
39 resource_dir, | |
40 lang::GetDefaultLanguage(is_machine)); | |
41 } | |
42 | |
43 HRESULT ResourceManager::Create( | |
44 bool is_machine, const CString& resource_dir, const CString& lang) { | |
45 CString language = lang; | |
46 if (language.IsEmpty() || !lang::IsLanguageSupported(language)) { | |
47 language = lang::GetDefaultLanguage(is_machine); | |
48 } | |
49 | |
50 if (!instance_) { | |
51 instance_ = new ResourceManager(is_machine, resource_dir); | |
52 return instance_->SetDefaultResourceByLanguage(language); | |
53 } | |
54 return S_OK; | |
55 } | |
56 | |
57 void ResourceManager::Delete() { | |
58 ResourceManager* instance = NULL; | |
59 instance = omaha::interlocked_exchange_pointer(&instance_, instance); | |
60 | |
61 delete instance; | |
62 } | |
63 | |
64 ResourceManager& ResourceManager::Instance() { | |
65 ASSERT1(instance_); | |
66 return *instance_; | |
67 } | |
68 | |
69 ResourceManager::ResourceManager(bool is_machine, const CString& resource_dir) | |
70 : is_machine_(is_machine), | |
71 resource_dir_(resource_dir), | |
72 saved_atl_resource_(NULL) { | |
73 } | |
74 | |
75 ResourceManager::~ResourceManager() { | |
76 if (saved_atl_resource_) { | |
77 _AtlBaseModule.SetResourceInstance(saved_atl_resource_); | |
78 } | |
79 } | |
80 | |
81 HRESULT ResourceManager::SetDefaultResourceByLanguage(const CString& language) { | |
82 ResourceDllInfo dll_info; | |
83 HRESULT hr = GetResourceDllInfo(language, &dll_info); | |
84 if (FAILED(hr)) { | |
85 return hr; | |
86 } | |
87 | |
88 // All CString.LoadString and CreateDialog calls should use the resource of | |
89 // the default language. | |
90 saved_atl_resource_ = _AtlBaseModule.SetResourceInstance(dll_info.dll_handle); | |
91 | |
92 return hr; | |
93 } | |
94 | |
95 HRESULT ResourceManager::GetResourceDll(const CString& language, | |
96 HINSTANCE* dll_handle) { | |
97 ASSERT1(dll_handle); | |
98 | |
99 ResourceDllInfo dll_info; | |
100 HRESULT hr = GetResourceDllInfo(language, &dll_info); | |
101 if (FAILED(hr)) { | |
102 return hr; | |
103 } | |
104 *dll_handle = dll_info.dll_handle; | |
105 return S_OK; | |
106 } | |
107 | |
108 HRESULT ResourceManager::GetResourceDllInfo(const CString& language, | |
109 ResourceDllInfo* dll_info) { | |
110 ASSERT1(dll_info); | |
111 __mutexScope(lock_); | |
112 | |
113 ASSERT1(lang::IsLanguageSupported(language)); | |
114 | |
115 LanguageToResourceMap::const_iterator it = resource_map_.find(language); | |
116 if (it != resource_map_.end()) { | |
117 *dll_info = it->second; | |
118 return S_OK; | |
119 } | |
120 return LoadResourceDll(language, dll_info); | |
121 } | |
122 | |
123 // Assumes that the language has not been loaded previously. | |
124 HRESULT ResourceManager::LoadResourceDll(const CString& language, | |
125 ResourceDllInfo* dll_info) { | |
126 ASSERT1(dll_info); | |
127 ASSERT1(lang::IsLanguageSupported(language)); | |
128 dll_info->dll_handle = NULL; | |
129 | |
130 __mutexScope(lock_); | |
131 | |
132 ASSERT1(resource_map_.find(language) == resource_map_.end()); | |
133 | |
134 // First try to load the resource dll for the language parameter. | |
135 HRESULT hr = LoadLibraryAsDataFile(GetResourceDllName(language), dll_info); | |
136 if (FAILED(hr)) { | |
137 CORE_LOG(LE, (_T("[Resource dll load failed.][0x%08x]"), hr)); | |
138 return hr; | |
139 } | |
140 | |
141 FileVer file_ver; | |
142 VERIFY1(file_ver.Open(dll_info->file_path)); | |
143 dll_info->language = file_ver.QueryValue(kLanguageVersionName); | |
144 CORE_LOG(L1, (_T("[Loaded resource dll %s]"), dll_info->file_path)); | |
145 | |
146 resource_map_.insert(std::make_pair(language, *dll_info)); | |
147 return S_OK; | |
148 } | |
149 | |
150 HRESULT ResourceManager::LoadLibraryAsDataFile( | |
151 const CString& filename, | |
152 ResourceDllInfo* dll_info) const { | |
153 ASSERT1(!filename.IsEmpty()); | |
154 ASSERT1(dll_info); | |
155 ASSERT1(!resource_dir_.IsEmpty()); | |
156 | |
157 dll_info->file_path = ConcatenatePath(resource_dir_, filename); | |
158 if (dll_info->file_path.IsEmpty()) { | |
159 ASSERT1(false); | |
160 return GOOPDATE_E_RESOURCE_DLL_PATH_EMPTY; | |
161 } | |
162 dll_info->dll_handle = ::LoadLibraryEx(dll_info->file_path, | |
163 NULL, | |
164 LOAD_LIBRARY_AS_DATAFILE); | |
165 if (!dll_info->dll_handle) { | |
166 HRESULT hr = HRESULTFromLastError(); | |
167 CORE_LOG(L2, (_T("[Could not load resource dll %s.]"), | |
168 dll_info->file_path)); | |
169 return hr; | |
170 } | |
171 | |
172 return S_OK; | |
173 } | |
174 | |
175 CString ResourceManager::GetResourceDllName(const CString& language) { | |
176 ASSERT1(!language.IsEmpty()); | |
177 | |
178 CString filename; | |
179 filename.Format(kOmahaResourceDllNameFormat, | |
180 lang::GetWrittenLanguage(language)); | |
181 return filename; | |
182 } | |
183 | |
184 void ResourceManager::GetSupportedLanguageDllNames( | |
185 std::vector<CString>* filenames) { | |
186 std::vector<CString> codes; | |
187 lang::GetSupportedLanguages(&codes); | |
188 | |
189 for (size_t i = 0; i < codes.size(); ++i) { | |
190 if (lang::DoesSupportedLanguageUseDifferentId(codes[i])) { | |
191 // There is not a separate DLL for this language. | |
192 continue; | |
193 } | |
194 filenames->push_back(GetResourceDllName(codes[i])); | |
195 } | |
196 } | |
197 | |
198 } // namespace omaha | |
OLD | NEW |