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/win/registry.h"
6
7 #include <cstring>
8 #include <vector>
9
10 #include "base/compiler_specific.h"
11 #include "base/stl_util.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 namespace base {
15 namespace win {
16
17 namespace {
18
19 const wchar_t kRootKey[] = L"Base_Registry_Unittest";
20
21 class RegistryTest : public testing::Test {
22 public:
RegistryTest()23 RegistryTest() {}
24
25 protected:
SetUp()26 virtual void SetUp() OVERRIDE {
27 // Create a temporary key.
28 RegKey key(HKEY_CURRENT_USER, L"", KEY_ALL_ACCESS);
29 key.DeleteKey(kRootKey);
30 ASSERT_NE(ERROR_SUCCESS, key.Open(HKEY_CURRENT_USER, kRootKey, KEY_READ));
31 ASSERT_EQ(ERROR_SUCCESS, key.Create(HKEY_CURRENT_USER, kRootKey, KEY_READ));
32 }
33
TearDown()34 virtual void TearDown() OVERRIDE {
35 // Clean up the temporary key.
36 RegKey key(HKEY_CURRENT_USER, L"", KEY_SET_VALUE);
37 ASSERT_EQ(ERROR_SUCCESS, key.DeleteKey(kRootKey));
38 }
39
40 private:
41 DISALLOW_COPY_AND_ASSIGN(RegistryTest);
42 };
43
TEST_F(RegistryTest,ValueTest)44 TEST_F(RegistryTest, ValueTest) {
45 RegKey key;
46
47 std::wstring foo_key(kRootKey);
48 foo_key += L"\\Foo";
49 ASSERT_EQ(ERROR_SUCCESS, key.Create(HKEY_CURRENT_USER, foo_key.c_str(),
50 KEY_READ));
51
52 {
53 ASSERT_EQ(ERROR_SUCCESS, key.Open(HKEY_CURRENT_USER, foo_key.c_str(),
54 KEY_READ | KEY_SET_VALUE));
55 ASSERT_TRUE(key.Valid());
56
57 const wchar_t kStringValueName[] = L"StringValue";
58 const wchar_t kDWORDValueName[] = L"DWORDValue";
59 const wchar_t kInt64ValueName[] = L"Int64Value";
60 const wchar_t kStringData[] = L"string data";
61 const DWORD kDWORDData = 0xdeadbabe;
62 const int64 kInt64Data = 0xdeadbabedeadbabeLL;
63
64 // Test value creation
65 ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(kStringValueName, kStringData));
66 ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(kDWORDValueName, kDWORDData));
67 ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(kInt64ValueName, &kInt64Data,
68 sizeof(kInt64Data), REG_QWORD));
69 EXPECT_EQ(3U, key.GetValueCount());
70 EXPECT_TRUE(key.HasValue(kStringValueName));
71 EXPECT_TRUE(key.HasValue(kDWORDValueName));
72 EXPECT_TRUE(key.HasValue(kInt64ValueName));
73
74 // Test Read
75 std::wstring string_value;
76 DWORD dword_value = 0;
77 int64 int64_value = 0;
78 ASSERT_EQ(ERROR_SUCCESS, key.ReadValue(kStringValueName, &string_value));
79 ASSERT_EQ(ERROR_SUCCESS, key.ReadValueDW(kDWORDValueName, &dword_value));
80 ASSERT_EQ(ERROR_SUCCESS, key.ReadInt64(kInt64ValueName, &int64_value));
81 EXPECT_STREQ(kStringData, string_value.c_str());
82 EXPECT_EQ(kDWORDData, dword_value);
83 EXPECT_EQ(kInt64Data, int64_value);
84
85 // Make sure out args are not touched if ReadValue fails
86 const wchar_t* kNonExistent = L"NonExistent";
87 ASSERT_NE(ERROR_SUCCESS, key.ReadValue(kNonExistent, &string_value));
88 ASSERT_NE(ERROR_SUCCESS, key.ReadValueDW(kNonExistent, &dword_value));
89 ASSERT_NE(ERROR_SUCCESS, key.ReadInt64(kNonExistent, &int64_value));
90 EXPECT_STREQ(kStringData, string_value.c_str());
91 EXPECT_EQ(kDWORDData, dword_value);
92 EXPECT_EQ(kInt64Data, int64_value);
93
94 // Test delete
95 ASSERT_EQ(ERROR_SUCCESS, key.DeleteValue(kStringValueName));
96 ASSERT_EQ(ERROR_SUCCESS, key.DeleteValue(kDWORDValueName));
97 ASSERT_EQ(ERROR_SUCCESS, key.DeleteValue(kInt64ValueName));
98 EXPECT_EQ(0U, key.GetValueCount());
99 EXPECT_FALSE(key.HasValue(kStringValueName));
100 EXPECT_FALSE(key.HasValue(kDWORDValueName));
101 EXPECT_FALSE(key.HasValue(kInt64ValueName));
102 }
103 }
104
TEST_F(RegistryTest,BigValueIteratorTest)105 TEST_F(RegistryTest, BigValueIteratorTest) {
106 RegKey key;
107 std::wstring foo_key(kRootKey);
108 foo_key += L"\\Foo";
109 ASSERT_EQ(ERROR_SUCCESS, key.Create(HKEY_CURRENT_USER, foo_key.c_str(),
110 KEY_READ));
111 ASSERT_EQ(ERROR_SUCCESS, key.Open(HKEY_CURRENT_USER, foo_key.c_str(),
112 KEY_READ | KEY_SET_VALUE));
113 ASSERT_TRUE(key.Valid());
114
115 // Create a test value that is larger than MAX_PATH.
116 std::wstring data(MAX_PATH * 2, L'a');
117
118 ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(data.c_str(), data.c_str()));
119
120 RegistryValueIterator iterator(HKEY_CURRENT_USER, foo_key.c_str());
121 ASSERT_TRUE(iterator.Valid());
122 EXPECT_STREQ(data.c_str(), iterator.Name());
123 EXPECT_STREQ(data.c_str(), iterator.Value());
124 // ValueSize() is in bytes, including NUL.
125 EXPECT_EQ((MAX_PATH * 2 + 1) * sizeof(wchar_t), iterator.ValueSize());
126 ++iterator;
127 EXPECT_FALSE(iterator.Valid());
128 }
129
TEST_F(RegistryTest,TruncatedCharTest)130 TEST_F(RegistryTest, TruncatedCharTest) {
131 RegKey key;
132 std::wstring foo_key(kRootKey);
133 foo_key += L"\\Foo";
134 ASSERT_EQ(ERROR_SUCCESS, key.Create(HKEY_CURRENT_USER, foo_key.c_str(),
135 KEY_READ));
136 ASSERT_EQ(ERROR_SUCCESS, key.Open(HKEY_CURRENT_USER, foo_key.c_str(),
137 KEY_READ | KEY_SET_VALUE));
138 ASSERT_TRUE(key.Valid());
139
140 const wchar_t kName[] = L"name";
141 // kData size is not a multiple of sizeof(wchar_t).
142 const uint8 kData[] = { 1, 2, 3, 4, 5 };
143 EXPECT_EQ(5, arraysize(kData));
144 ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(kName, kData,
145 arraysize(kData), REG_BINARY));
146
147 RegistryValueIterator iterator(HKEY_CURRENT_USER, foo_key.c_str());
148 ASSERT_TRUE(iterator.Valid());
149 EXPECT_STREQ(kName, iterator.Name());
150 // ValueSize() is in bytes.
151 ASSERT_EQ(arraysize(kData), iterator.ValueSize());
152 // Value() is NUL terminated.
153 int end = (iterator.ValueSize() + sizeof(wchar_t) - 1) / sizeof(wchar_t);
154 EXPECT_NE(L'\0', iterator.Value()[end-1]);
155 EXPECT_EQ(L'\0', iterator.Value()[end]);
156 EXPECT_EQ(0, std::memcmp(kData, iterator.Value(), arraysize(kData)));
157 ++iterator;
158 EXPECT_FALSE(iterator.Valid());
159 }
160
161 } // namespace
162
163 } // namespace win
164 } // namespace base
165