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