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