1 // Copyright (c) 2006-2008 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. 4 5 #include "base/file_version_info.h" 6 7 #include <windows.h> 8 9 #include "base/file_path.h" 10 #include "base/logging.h" 11 #include "base/path_service.h" 12 13 // This has to be last. 14 #include <strsafe.h> 15 16 FileVersionInfo::FileVersionInfo(void* data, int language, int code_page) 17 : language_(language), code_page_(code_page) { 18 data_.reset((char*) data); 19 fixed_file_info_ = NULL; 20 UINT size; 21 ::VerQueryValue(data_.get(), L"\\", (LPVOID*)&fixed_file_info_, &size); 22 } 23 24 FileVersionInfo::~FileVersionInfo() { 25 DCHECK(data_.get()); 26 } 27 28 typedef struct { 29 WORD language; 30 WORD code_page; 31 } LanguageAndCodePage; 32 33 // static 34 FileVersionInfo* FileVersionInfo::CreateFileVersionInfoForCurrentModule() { 35 FilePath app_path; 36 if (!PathService::Get(base::FILE_MODULE, &app_path)) 37 return NULL; 38 39 return CreateFileVersionInfo(app_path); 40 } 41 42 // static 43 FileVersionInfo* FileVersionInfo::CreateFileVersionInfo( 44 const FilePath& file_path) { 45 DWORD dummy; 46 const wchar_t* path = file_path.value().c_str(); 47 DWORD length = ::GetFileVersionInfoSize(path, &dummy); 48 if (length == 0) 49 return NULL; 50 51 void* data = calloc(length, 1); 52 if (!data) 53 return NULL; 54 55 if (!::GetFileVersionInfo(path, dummy, length, data)) { 56 free(data); 57 return NULL; 58 } 59 60 LanguageAndCodePage* translate = NULL; 61 uint32 page_count; 62 BOOL query_result = VerQueryValue(data, L"\\VarFileInfo\\Translation", 63 (void**) &translate, &page_count); 64 65 if (query_result && translate) { 66 return new FileVersionInfo(data, translate->language, 67 translate->code_page); 68 69 } else { 70 free(data); 71 return NULL; 72 } 73 } 74 75 FileVersionInfo* FileVersionInfo::CreateFileVersionInfo( 76 const std::wstring& file_path) { 77 FilePath file_path_fp = FilePath::FromWStringHack(file_path); 78 return CreateFileVersionInfo(file_path_fp); 79 } 80 81 std::wstring FileVersionInfo::company_name() { 82 return GetStringValue(L"CompanyName"); 83 } 84 85 std::wstring FileVersionInfo::company_short_name() { 86 return GetStringValue(L"CompanyShortName"); 87 } 88 89 std::wstring FileVersionInfo::internal_name() { 90 return GetStringValue(L"InternalName"); 91 } 92 93 std::wstring FileVersionInfo::product_name() { 94 return GetStringValue(L"ProductName"); 95 } 96 97 std::wstring FileVersionInfo::product_short_name() { 98 return GetStringValue(L"ProductShortName"); 99 } 100 101 std::wstring FileVersionInfo::comments() { 102 return GetStringValue(L"Comments"); 103 } 104 105 std::wstring FileVersionInfo::legal_copyright() { 106 return GetStringValue(L"LegalCopyright"); 107 } 108 109 std::wstring FileVersionInfo::product_version() { 110 return GetStringValue(L"ProductVersion"); 111 } 112 113 std::wstring FileVersionInfo::file_description() { 114 return GetStringValue(L"FileDescription"); 115 } 116 117 std::wstring FileVersionInfo::legal_trademarks() { 118 return GetStringValue(L"LegalTrademarks"); 119 } 120 121 std::wstring FileVersionInfo::private_build() { 122 return GetStringValue(L"PrivateBuild"); 123 } 124 125 std::wstring FileVersionInfo::file_version() { 126 return GetStringValue(L"FileVersion"); 127 } 128 129 std::wstring FileVersionInfo::original_filename() { 130 return GetStringValue(L"OriginalFilename"); 131 } 132 133 std::wstring FileVersionInfo::special_build() { 134 return GetStringValue(L"SpecialBuild"); 135 } 136 137 std::wstring FileVersionInfo::last_change() { 138 return GetStringValue(L"LastChange"); 139 } 140 141 bool FileVersionInfo::is_official_build() { 142 return (GetStringValue(L"Official Build").compare(L"1") == 0); 143 } 144 145 bool FileVersionInfo::GetValue(const wchar_t* name, std::wstring* value_str) { 146 147 WORD lang_codepage[8]; 148 int i = 0; 149 // Use the language and codepage from the DLL. 150 lang_codepage[i++] = language_; 151 lang_codepage[i++] = code_page_; 152 // Use the default language and codepage from the DLL. 153 lang_codepage[i++] = ::GetUserDefaultLangID(); 154 lang_codepage[i++] = code_page_; 155 // Use the language from the DLL and Latin codepage (most common). 156 lang_codepage[i++] = language_; 157 lang_codepage[i++] = 1252; 158 // Use the default language and Latin codepage (most common). 159 lang_codepage[i++] = ::GetUserDefaultLangID(); 160 lang_codepage[i++] = 1252; 161 162 i = 0; 163 while (i < arraysize(lang_codepage)) { 164 wchar_t sub_block[MAX_PATH]; 165 WORD language = lang_codepage[i++]; 166 WORD code_page = lang_codepage[i++]; 167 _snwprintf_s(sub_block, MAX_PATH, MAX_PATH, 168 L"\\StringFileInfo\\%04x%04x\\%ls", language, code_page, name); 169 LPVOID value = NULL; 170 uint32 size; 171 BOOL r = ::VerQueryValue(data_.get(), sub_block, &value, &size); 172 if (r && value) { 173 value_str->assign(static_cast<wchar_t*>(value)); 174 return true; 175 } 176 } 177 return false; 178 } 179 180 std::wstring FileVersionInfo::GetStringValue(const wchar_t* name) { 181 std::wstring str; 182 if (GetValue(name, &str)) 183 return str; 184 else 185 return L""; 186 } 187