1 // Copyright 2011 The Chromium Authors
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 <stddef.h>
10
11 #include <memory>
12
13 #include "base/file_version_info.h"
14 #include "base/files/file_path.h"
15 #include "base/path_service.h"
16 #include "base/scoped_native_library.h"
17 #include "base/strings/string_util.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19
20 using base::FilePath;
21
22 namespace {
23
GetTestDataPath()24 FilePath GetTestDataPath() {
25 FilePath path;
26 base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &path);
27 path = path.AppendASCII("base");
28 path = path.AppendASCII("test");
29 path = path.AppendASCII("data");
30 path = path.AppendASCII("file_version_info_unittest");
31 return path;
32 }
33
34 class FileVersionInfoFactory {
35 public:
FileVersionInfoFactory(const FilePath & path)36 explicit FileVersionInfoFactory(const FilePath& path) : path_(path) {}
37 FileVersionInfoFactory(const FileVersionInfoFactory&) = delete;
38 FileVersionInfoFactory& operator=(const FileVersionInfoFactory&) = delete;
39
Create() const40 std::unique_ptr<FileVersionInfo> Create() const {
41 return FileVersionInfo::CreateFileVersionInfo(path_);
42 }
43
44 private:
45 const FilePath path_;
46 };
47
48 class FileVersionInfoForModuleFactory {
49 public:
FileVersionInfoForModuleFactory(const FilePath & path)50 explicit FileVersionInfoForModuleFactory(const FilePath& path)
51 // Load the library with LOAD_LIBRARY_AS_IMAGE_RESOURCE since it shouldn't
52 // be executed.
53 : library_(::LoadLibraryEx(path.value().c_str(),
54 nullptr,
55 LOAD_LIBRARY_AS_IMAGE_RESOURCE)) {
56 EXPECT_TRUE(library_.is_valid());
57 }
58 FileVersionInfoForModuleFactory(const FileVersionInfoForModuleFactory&) =
59 delete;
60 FileVersionInfoForModuleFactory& operator=(
61 const FileVersionInfoForModuleFactory&) = delete;
62
Create() const63 std::unique_ptr<FileVersionInfo> Create() const {
64 return FileVersionInfo::CreateFileVersionInfoForModule(library_.get());
65 }
66
67 private:
68 const base::ScopedNativeLibrary library_;
69 };
70
71 template <typename T>
72 class FileVersionInfoTest : public testing::Test {};
73
74 using FileVersionInfoFactories =
75 ::testing::Types<FileVersionInfoFactory, FileVersionInfoForModuleFactory>;
76
77 } // namespace
78
79 TYPED_TEST_SUITE(FileVersionInfoTest, FileVersionInfoFactories);
80
TYPED_TEST(FileVersionInfoTest,HardCodedProperties)81 TYPED_TEST(FileVersionInfoTest, HardCodedProperties) {
82 const base::FilePath::CharType kDLLName[] =
83 FILE_PATH_LITERAL("FileVersionInfoTest1.dll");
84
85 const wchar_t* const kExpectedValues[15] = {
86 // FileVersionInfoTest.dll
87 L"Goooooogle", // company_name
88 L"Google", // company_short_name
89 L"This is the product name", // product_name
90 L"This is the product short name", // product_short_name
91 L"The Internal Name", // internal_name
92 L"4.3.2.1", // product_version
93 L"Special build property", // special_build
94 L"This is the original filename", // original_filename
95 L"This is my file description", // file_description
96 L"1.2.3.4", // file_version
97 };
98
99 FilePath dll_path = GetTestDataPath();
100 dll_path = dll_path.Append(kDLLName);
101
102 TypeParam factory(dll_path);
103 std::unique_ptr<FileVersionInfo> version_info(factory.Create());
104 ASSERT_TRUE(version_info);
105
106 int j = 0;
107 EXPECT_EQ(kExpectedValues[j++],
108 base::AsWStringView(version_info->company_name()));
109 EXPECT_EQ(kExpectedValues[j++],
110 base::AsWStringView(version_info->company_short_name()));
111 EXPECT_EQ(kExpectedValues[j++],
112 base::AsWStringView(version_info->product_name()));
113 EXPECT_EQ(kExpectedValues[j++],
114 base::AsWStringView(version_info->product_short_name()));
115 EXPECT_EQ(kExpectedValues[j++],
116 base::AsWStringView(version_info->internal_name()));
117 EXPECT_EQ(kExpectedValues[j++],
118 base::AsWStringView(version_info->product_version()));
119 EXPECT_EQ(kExpectedValues[j++],
120 base::AsWStringView(version_info->special_build()));
121 EXPECT_EQ(kExpectedValues[j++],
122 base::AsWStringView(version_info->original_filename()));
123 EXPECT_EQ(kExpectedValues[j++],
124 base::AsWStringView(version_info->file_description()));
125 EXPECT_EQ(kExpectedValues[j++],
126 base::AsWStringView(version_info->file_version()));
127 }
128
TYPED_TEST(FileVersionInfoTest,CustomProperties)129 TYPED_TEST(FileVersionInfoTest, CustomProperties) {
130 FilePath dll_path = GetTestDataPath();
131 dll_path = dll_path.AppendASCII("FileVersionInfoTest1.dll");
132
133 TypeParam factory(dll_path);
134 std::unique_ptr<FileVersionInfo> version_info(factory.Create());
135 ASSERT_TRUE(version_info);
136
137 // Test few existing properties.
138 std::u16string str;
139 FileVersionInfoWin* version_info_win =
140 static_cast<FileVersionInfoWin*>(version_info.get());
141 EXPECT_TRUE(version_info_win->GetValue(u"Custom prop 1", &str));
142 EXPECT_EQ(u"Un", str);
143 EXPECT_EQ(u"Un", version_info_win->GetStringValue(u"Custom prop 1"));
144
145 EXPECT_TRUE(version_info_win->GetValue(u"Custom prop 2", &str));
146 EXPECT_EQ(u"Deux", str);
147 EXPECT_EQ(u"Deux", version_info_win->GetStringValue(u"Custom prop 2"));
148
149 EXPECT_TRUE(version_info_win->GetValue(u"Custom prop 3", &str));
150 EXPECT_EQ(u"1600 Amphitheatre Parkway Mountain View, CA 94043", str);
151 EXPECT_EQ(u"1600 Amphitheatre Parkway Mountain View, CA 94043",
152 version_info_win->GetStringValue(u"Custom prop 3"));
153
154 // Test an non-existing property.
155 EXPECT_FALSE(version_info_win->GetValue(u"Unknown property", &str));
156 EXPECT_EQ(std::u16string(),
157 version_info_win->GetStringValue(u"Unknown property"));
158
159 EXPECT_EQ(base::Version(std::vector<uint32_t>{1, 0, 0, 1}),
160 version_info_win->GetFileVersion());
161 }
162
TYPED_TEST(FileVersionInfoTest,NoVersionInfo)163 TYPED_TEST(FileVersionInfoTest, NoVersionInfo) {
164 FilePath dll_path = GetTestDataPath();
165 dll_path = dll_path.AppendASCII("no_version_info.dll");
166
167 TypeParam factory(dll_path);
168 ASSERT_FALSE(factory.Create());
169 }
170