| 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 |