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