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: 23 RegistryTest() {} 24 25 protected: 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 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 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 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 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