blob: 6528ca3dfbb1237e4679dc4347270373360bac70 [file] [log] [blame]
[email protected]f481221192011-04-07 22:15:341// Copyright (c) 2011 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commitd7cae122008-07-26 21:49:384
[email protected]bcff05a2010-04-14 01:46:435#include "base/file_version_info_win.h"
initial.commitd7cae122008-07-26 21:49:386
[email protected]f5393332009-06-03 15:01:297#include <windows.h>
8
9#include "base/file_path.h"
[email protected]bcff05a2010-04-14 01:46:4310#include "base/file_version_info.h"
initial.commitd7cae122008-07-26 21:49:3811#include "base/logging.h"
12#include "base/path_service.h"
[email protected]34b99632011-01-01 01:01:0613#include "base/threading/thread_restrictions.h"
initial.commitd7cae122008-07-26 21:49:3814
[email protected]bcff05a2010-04-14 01:46:4315FileVersionInfoWin::FileVersionInfoWin(void* data, int language, int code_page)
initial.commitd7cae122008-07-26 21:49:3816 : language_(language), code_page_(code_page) {
[email protected]45446a52010-11-04 17:41:0017 base::ThreadRestrictions::AssertIOAllowed();
initial.commitd7cae122008-07-26 21:49:3818 data_.reset((char*) data);
19 fixed_file_info_ = NULL;
20 UINT size;
21 ::VerQueryValue(data_.get(), L"\\", (LPVOID*)&fixed_file_info_, &size);
22}
23
[email protected]bcff05a2010-04-14 01:46:4324FileVersionInfoWin::~FileVersionInfoWin() {
initial.commitd7cae122008-07-26 21:49:3825 DCHECK(data_.get());
26}
27
28typedef struct {
29 WORD language;
30 WORD code_page;
31} LanguageAndCodePage;
32
33// static
[email protected]70910be2011-04-22 23:55:4534FileVersionInfo* FileVersionInfo::CreateFileVersionInfoForModule(
35 HMODULE module) {
36 // Note that the use of MAX_PATH is basically in line with what we do for
37 // all registered paths (PathProviderWin).
38 wchar_t system_buffer[MAX_PATH];
39 system_buffer[0] = 0;
40 if (!GetModuleFileName(module, system_buffer, MAX_PATH))
initial.commitd7cae122008-07-26 21:49:3841 return NULL;
42
[email protected]70910be2011-04-22 23:55:4543 FilePath app_path(system_buffer);
initial.commitd7cae122008-07-26 21:49:3844 return CreateFileVersionInfo(app_path);
45}
46
47// static
48FileVersionInfo* FileVersionInfo::CreateFileVersionInfo(
[email protected]09562232008-12-23 16:57:3649 const FilePath& file_path) {
[email protected]45446a52010-11-04 17:41:0050 base::ThreadRestrictions::AssertIOAllowed();
51
initial.commitd7cae122008-07-26 21:49:3852 DWORD dummy;
[email protected]09562232008-12-23 16:57:3653 const wchar_t* path = file_path.value().c_str();
initial.commitd7cae122008-07-26 21:49:3854 DWORD length = ::GetFileVersionInfoSize(path, &dummy);
55 if (length == 0)
56 return NULL;
57
58 void* data = calloc(length, 1);
59 if (!data)
60 return NULL;
61
62 if (!::GetFileVersionInfo(path, dummy, length, data)) {
63 free(data);
64 return NULL;
65 }
66
67 LanguageAndCodePage* translate = NULL;
68 uint32 page_count;
69 BOOL query_result = VerQueryValue(data, L"\\VarFileInfo\\Translation",
70 (void**) &translate, &page_count);
71
72 if (query_result && translate) {
[email protected]bcff05a2010-04-14 01:46:4373 return new FileVersionInfoWin(data, translate->language,
74 translate->code_page);
initial.commitd7cae122008-07-26 21:49:3875
76 } else {
77 free(data);
78 return NULL;
79 }
80}
81
[email protected]4f260d02010-12-23 18:35:4282string16 FileVersionInfoWin::company_name() {
initial.commitd7cae122008-07-26 21:49:3883 return GetStringValue(L"CompanyName");
84}
85
[email protected]4f260d02010-12-23 18:35:4286string16 FileVersionInfoWin::company_short_name() {
initial.commitd7cae122008-07-26 21:49:3887 return GetStringValue(L"CompanyShortName");
88}
89
[email protected]4f260d02010-12-23 18:35:4290string16 FileVersionInfoWin::internal_name() {
initial.commitd7cae122008-07-26 21:49:3891 return GetStringValue(L"InternalName");
92}
93
[email protected]4f260d02010-12-23 18:35:4294string16 FileVersionInfoWin::product_name() {
initial.commitd7cae122008-07-26 21:49:3895 return GetStringValue(L"ProductName");
96}
97
[email protected]4f260d02010-12-23 18:35:4298string16 FileVersionInfoWin::product_short_name() {
initial.commitd7cae122008-07-26 21:49:3899 return GetStringValue(L"ProductShortName");
100}
101
[email protected]4f260d02010-12-23 18:35:42102string16 FileVersionInfoWin::comments() {
initial.commitd7cae122008-07-26 21:49:38103 return GetStringValue(L"Comments");
104}
105
[email protected]4f260d02010-12-23 18:35:42106string16 FileVersionInfoWin::legal_copyright() {
initial.commitd7cae122008-07-26 21:49:38107 return GetStringValue(L"LegalCopyright");
108}
109
[email protected]4f260d02010-12-23 18:35:42110string16 FileVersionInfoWin::product_version() {
initial.commitd7cae122008-07-26 21:49:38111 return GetStringValue(L"ProductVersion");
112}
113
[email protected]4f260d02010-12-23 18:35:42114string16 FileVersionInfoWin::file_description() {
initial.commitd7cae122008-07-26 21:49:38115 return GetStringValue(L"FileDescription");
116}
117
[email protected]4f260d02010-12-23 18:35:42118string16 FileVersionInfoWin::legal_trademarks() {
initial.commitd7cae122008-07-26 21:49:38119 return GetStringValue(L"LegalTrademarks");
120}
121
[email protected]4f260d02010-12-23 18:35:42122string16 FileVersionInfoWin::private_build() {
initial.commitd7cae122008-07-26 21:49:38123 return GetStringValue(L"PrivateBuild");
124}
125
[email protected]4f260d02010-12-23 18:35:42126string16 FileVersionInfoWin::file_version() {
initial.commitd7cae122008-07-26 21:49:38127 return GetStringValue(L"FileVersion");
128}
129
[email protected]4f260d02010-12-23 18:35:42130string16 FileVersionInfoWin::original_filename() {
initial.commitd7cae122008-07-26 21:49:38131 return GetStringValue(L"OriginalFilename");
132}
133
[email protected]4f260d02010-12-23 18:35:42134string16 FileVersionInfoWin::special_build() {
initial.commitd7cae122008-07-26 21:49:38135 return GetStringValue(L"SpecialBuild");
136}
137
[email protected]4f260d02010-12-23 18:35:42138string16 FileVersionInfoWin::last_change() {
initial.commitd7cae122008-07-26 21:49:38139 return GetStringValue(L"LastChange");
140}
141
[email protected]bcff05a2010-04-14 01:46:43142bool FileVersionInfoWin::is_official_build() {
initial.commitd7cae122008-07-26 21:49:38143 return (GetStringValue(L"Official Build").compare(L"1") == 0);
144}
145
[email protected]bcff05a2010-04-14 01:46:43146bool FileVersionInfoWin::GetValue(const wchar_t* name,
147 std::wstring* value_str) {
initial.commitd7cae122008-07-26 21:49:38148 WORD lang_codepage[8];
149 int i = 0;
150 // Use the language and codepage from the DLL.
151 lang_codepage[i++] = language_;
152 lang_codepage[i++] = code_page_;
153 // Use the default language and codepage from the DLL.
154 lang_codepage[i++] = ::GetUserDefaultLangID();
155 lang_codepage[i++] = code_page_;
156 // Use the language from the DLL and Latin codepage (most common).
157 lang_codepage[i++] = language_;
158 lang_codepage[i++] = 1252;
159 // Use the default language and Latin codepage (most common).
160 lang_codepage[i++] = ::GetUserDefaultLangID();
161 lang_codepage[i++] = 1252;
162
163 i = 0;
164 while (i < arraysize(lang_codepage)) {
165 wchar_t sub_block[MAX_PATH];
166 WORD language = lang_codepage[i++];
167 WORD code_page = lang_codepage[i++];
168 _snwprintf_s(sub_block, MAX_PATH, MAX_PATH,
[email protected]51154742008-08-14 00:41:45169 L"\\StringFileInfo\\%04x%04x\\%ls", language, code_page, name);
initial.commitd7cae122008-07-26 21:49:38170 LPVOID value = NULL;
171 uint32 size;
172 BOOL r = ::VerQueryValue(data_.get(), sub_block, &value, &size);
173 if (r && value) {
174 value_str->assign(static_cast<wchar_t*>(value));
175 return true;
176 }
177 }
178 return false;
179}
180
[email protected]bcff05a2010-04-14 01:46:43181std::wstring FileVersionInfoWin::GetStringValue(const wchar_t* name) {
initial.commitd7cae122008-07-26 21:49:38182 std::wstring str;
183 if (GetValue(name, &str))
184 return str;
185 else
186 return L"";
187}