Chromium Code Reviews| Index: base/win/registry_unittest.cc |
| diff --git a/base/win/registry_unittest.cc b/base/win/registry_unittest.cc |
| index 155402a351fc4593d57f6f8a479c09969d041400..31a59441302659be4daf0690456d24b2450d3635 100644 |
| --- a/base/win/registry_unittest.cc |
| +++ b/base/win/registry_unittest.cc |
| @@ -9,6 +9,7 @@ |
| #include "base/compiler_specific.h" |
| #include "base/stl_util.h" |
| +#include "base/win/windows_version.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| namespace base { |
| @@ -16,27 +17,50 @@ namespace win { |
| namespace { |
| -const wchar_t kRootKey[] = L"Base_Registry_Unittest"; |
| - |
| class RegistryTest : public testing::Test { |
| - public: |
| - RegistryTest() {} |
| - |
| protected: |
| +#if defined(_WIN64) |
| + static const REGSAM kNativeViewMask = KEY_WOW64_64KEY; |
|
grt (UTC plus 2)
2014/05/20 15:28:52
i think you still need definitions of these at nam
Will Harris
2014/05/20 17:03:34
Okay I read the standard and I think I am now comp
grt (UTC plus 2)
2014/05/20 17:46:56
You could keep the initializers up here in the cla
|
| + static const REGSAM kRedirectedViewMask = KEY_WOW64_32KEY; |
| +#else |
| + static const REGSAM kNativeViewMask = KEY_WOW64_32KEY; |
| + static const REGSAM kRedirectedViewMask = KEY_WOW64_64KEY; |
| +#endif // _WIN64 |
| + |
| + RegistryTest() {} |
| virtual void SetUp() OVERRIDE { |
| // Create a temporary key. |
| RegKey key(HKEY_CURRENT_USER, L"", KEY_ALL_ACCESS); |
| key.DeleteKey(kRootKey); |
| ASSERT_NE(ERROR_SUCCESS, key.Open(HKEY_CURRENT_USER, kRootKey, KEY_READ)); |
| ASSERT_EQ(ERROR_SUCCESS, key.Create(HKEY_CURRENT_USER, kRootKey, KEY_READ)); |
| + foo_software_key_ = L"Software\\"; |
| + foo_software_key_ += kRootKey; |
| + foo_software_key_ += L"\\Foo"; |
| + foo_software_wow64_key_ = L"Software\\Wow6432Node\\"; |
| + foo_software_wow64_key_ += kRootKey; |
| + foo_software_wow64_key_ += L"\\Foo"; |
| } |
| virtual void TearDown() OVERRIDE { |
| // Clean up the temporary key. |
| RegKey key(HKEY_CURRENT_USER, L"", KEY_SET_VALUE); |
| ASSERT_EQ(ERROR_SUCCESS, key.DeleteKey(kRootKey)); |
| + ASSERT_NE(ERROR_SUCCESS, key.Open(HKEY_CURRENT_USER, kRootKey, KEY_READ)); |
| } |
| + static bool IsRedirectorPresent() { |
| +#if defined(_WIN64) |
| + return true; |
| +#else |
| + return OSInfo::GetInstance()->wow64_status() == OSInfo::WOW64_ENABLED; |
| +#endif |
| + } |
| + |
| + const wchar_t* const kRootKey = L"Base_Registry_Unittest"; |
| + std::wstring foo_software_key_; |
| + std::wstring foo_software_wow64_key_; |
| + |
| private: |
| DISALLOW_COPY_AND_ASSIGN(RegistryTest); |
| }; |
| @@ -158,6 +182,184 @@ TEST_F(RegistryTest, TruncatedCharTest) { |
| EXPECT_FALSE(iterator.Valid()); |
| } |
| +TEST_F(RegistryTest, RecursiveDelete) { |
| + RegKey key; |
| + // Create kRootKey->Foo |
| + // \->Bar |
| + // \->Foo |
| + // \->Moo |
| + // \->Foo |
| + // and delete kRootKey->Foo |
| + std::wstring foo_key(kRootKey); |
| + foo_key += L"\\Foo"; |
| + ASSERT_EQ(ERROR_SUCCESS, |
| + key.Create(HKEY_CURRENT_USER, foo_key.c_str(), KEY_WRITE)); |
| + ASSERT_EQ(ERROR_SUCCESS, key.CreateKey(L"Bar", KEY_WRITE)); |
| + ASSERT_EQ(ERROR_SUCCESS, |
| + key.Create(HKEY_CURRENT_USER, foo_key.c_str(), KEY_WRITE)); |
| + ASSERT_EQ(ERROR_SUCCESS, key.CreateKey(L"Moo", KEY_WRITE)); |
| + ASSERT_EQ(ERROR_SUCCESS, |
| + key.Create(HKEY_CURRENT_USER, foo_key.c_str(), KEY_WRITE)); |
| + ASSERT_EQ(ERROR_SUCCESS, key.CreateKey(L"Foo", KEY_WRITE)); |
| + foo_key += L"\\Bar"; |
| + ASSERT_EQ(ERROR_SUCCESS, |
| + key.Open(HKEY_CURRENT_USER, foo_key.c_str(), KEY_WRITE)); |
| + foo_key += L"\\Foo"; |
| + ASSERT_EQ(ERROR_SUCCESS, key.CreateKey(L"Foo", KEY_WRITE)); |
| + ASSERT_EQ(ERROR_SUCCESS, |
| + key.Open(HKEY_CURRENT_USER, foo_key.c_str(), KEY_READ)); |
| + |
| + ASSERT_EQ(ERROR_SUCCESS, key.Open(HKEY_CURRENT_USER, kRootKey, KEY_WRITE)); |
| + ASSERT_NE(ERROR_SUCCESS, key.DeleteKey(L"Bar")); |
| + ASSERT_NE(ERROR_SUCCESS, key.DeleteEmptyKey(L"Foo")); |
| + ASSERT_NE(ERROR_SUCCESS, key.DeleteEmptyKey(L"Foo\\Bar")); |
| + ASSERT_EQ(ERROR_SUCCESS, key.DeleteEmptyKey(L"Foo\\Foo")); |
| + ASSERT_EQ(ERROR_SUCCESS, key.DeleteKey(L"Foo")); |
| + ASSERT_NE(ERROR_SUCCESS, key.DeleteKey(L"Foo")); |
| + ASSERT_NE(ERROR_SUCCESS, |
| + key.Open(HKEY_CURRENT_USER, foo_key.c_str(), KEY_READ)); |
| +} |
| + |
| +// This test requires running as an Administrator as it tests redirected |
| +// registry writes to HKLM\Software |
| +// http://msdn.microsoft.com/en-us/library/windows/desktop/aa384253.aspx |
| +TEST_F(RegistryTest, Wow64RedirectedFromNative) { |
| + if (!IsRedirectorPresent()) |
| + return; |
| + |
| + RegKey key; |
| + |
| + // Test redirected key access from non-redirected. |
| + ASSERT_EQ(ERROR_SUCCESS, |
| + key.Create(HKEY_LOCAL_MACHINE, |
| + foo_software_key_.c_str(), |
| + KEY_WRITE | kRedirectedViewMask)); |
| + ASSERT_NE(ERROR_SUCCESS, |
| + key.Open(HKEY_LOCAL_MACHINE, foo_software_key_.c_str(), KEY_READ)); |
| + ASSERT_NE(ERROR_SUCCESS, |
| + key.Open(HKEY_LOCAL_MACHINE, |
| + foo_software_key_.c_str(), |
| + KEY_READ | kNativeViewMask)); |
| + |
| + // Open the non-redirected view of the parent and try to delete the test key. |
| + ASSERT_EQ(ERROR_SUCCESS, |
| + key.Open(HKEY_LOCAL_MACHINE, L"Software", KEY_SET_VALUE)); |
| + ASSERT_NE(ERROR_SUCCESS, key.DeleteKey(kRootKey)); |
| + ASSERT_EQ(ERROR_SUCCESS, |
| + key.Open(HKEY_LOCAL_MACHINE, |
| + L"Software", |
| + KEY_SET_VALUE | kNativeViewMask)); |
| + ASSERT_NE(ERROR_SUCCESS, key.DeleteKey(kRootKey)); |
| + |
| + // Open the redirected view and delete the key created above. |
| + ASSERT_EQ(ERROR_SUCCESS, |
| + key.Open(HKEY_LOCAL_MACHINE, |
| + L"Software", |
| + KEY_SET_VALUE | kRedirectedViewMask)); |
| + ASSERT_EQ(ERROR_SUCCESS, key.DeleteKey(kRootKey)); |
| +} |
| + |
| +TEST_F(RegistryTest, Wow64NativeFromRedirected) { |
| + if (!IsRedirectorPresent()) |
| + return; |
| + RegKey key; |
| + |
| + // Test non-redirected key access from redirected. |
| + ASSERT_EQ(ERROR_SUCCESS, |
| + key.Create(HKEY_LOCAL_MACHINE, |
| + foo_software_key_.c_str(), |
| + KEY_WRITE | kNativeViewMask)); |
| + ASSERT_EQ(ERROR_SUCCESS, |
| + key.Open(HKEY_LOCAL_MACHINE, foo_software_key_.c_str(), KEY_READ)); |
| + ASSERT_NE(ERROR_SUCCESS, |
| + key.Open(HKEY_LOCAL_MACHINE, |
| + foo_software_key_.c_str(), |
| + KEY_READ | kRedirectedViewMask)); |
| + |
| + // Open the redirected view of the parent and try to delete the test key |
| + // from the non-redirected view. |
| + ASSERT_EQ(ERROR_SUCCESS, |
| + key.Open(HKEY_LOCAL_MACHINE, |
| + L"Software", |
| + KEY_SET_VALUE | kRedirectedViewMask)); |
| + ASSERT_NE(ERROR_SUCCESS, key.DeleteKey(kRootKey)); |
| + |
| + ASSERT_EQ(ERROR_SUCCESS, |
| + key.Open(HKEY_LOCAL_MACHINE, |
| + L"Software", |
| + KEY_SET_VALUE | kNativeViewMask)); |
| + ASSERT_EQ(ERROR_SUCCESS, key.DeleteKey(kRootKey)); |
| +} |
| + |
| +TEST_F(RegistryTest, Wow6432NodeFromRedirected) { |
| + if (!IsRedirectorPresent()) |
| + return; |
| + |
| + RegKey key; |
| + // Test access to 32-bit values on 64-bit via the Wow6432Node key. |
| + ASSERT_EQ(ERROR_SUCCESS, |
| + key.Create(HKEY_LOCAL_MACHINE, |
| + foo_software_key_.c_str(), |
| + KEY_WRITE | KEY_WOW64_32KEY)); |
| + ASSERT_EQ(ERROR_SUCCESS, |
| + key.Open(HKEY_LOCAL_MACHINE, |
| + foo_software_wow64_key_.c_str(), |
| + KEY_READ)); |
| + ASSERT_EQ(ERROR_SUCCESS, |
| + key.Open(HKEY_LOCAL_MACHINE, |
| + foo_software_wow64_key_.c_str(), |
| + KEY_READ | KEY_WOW64_64KEY)); |
| + ASSERT_EQ(ERROR_SUCCESS, |
| + key.Open(HKEY_LOCAL_MACHINE, |
| + foo_software_wow64_key_.c_str(), |
| + KEY_READ | KEY_WOW64_32KEY)); |
| + ASSERT_EQ(ERROR_SUCCESS, |
| + key.Open(HKEY_LOCAL_MACHINE, |
| + L"Software", |
| + KEY_SET_VALUE | KEY_WOW64_32KEY)); |
| + ASSERT_EQ(ERROR_SUCCESS, key.DeleteKey(kRootKey)); |
| +} |
| + |
| +TEST_F(RegistryTest, Wow64ConflictingViews) { |
| + RegKey key; |
| + // Test that conflicting WOW64 access flags are always rejected. |
| + ASSERT_EQ(ERROR_SUCCESS, |
| + key.Create(HKEY_LOCAL_MACHINE, |
| + foo_software_key_.c_str(), |
| + KEY_WRITE | KEY_WOW64_32KEY)); |
| + ASSERT_NE(ERROR_SUCCESS, key.CreateKey(L"Foo", KEY_READ | KEY_WOW64_64KEY)); |
| + ASSERT_NE(ERROR_SUCCESS, key.CreateKey(L"Foo", KEY_READ)); |
| + ASSERT_EQ(ERROR_SUCCESS, key.CreateKey(L"Foo", KEY_READ | KEY_WOW64_32KEY)); |
| + ASSERT_EQ(ERROR_SUCCESS, |
| + key.Open(HKEY_LOCAL_MACHINE, |
| + L"Software", |
| + KEY_WRITE | KEY_WOW64_32KEY)); |
| + ASSERT_NE(ERROR_SUCCESS, key.OpenKey(L"Foo", KEY_READ | KEY_WOW64_64KEY)); |
| + ASSERT_NE(ERROR_SUCCESS, key.OpenKey(L"Foo", KEY_READ)); |
| + ASSERT_EQ(ERROR_SUCCESS, key.DeleteKey(kRootKey)); |
| +} |
| + |
| +TEST_F(RegistryTest, OpenSubKey) { |
| + RegKey key; |
| + ASSERT_EQ(ERROR_SUCCESS, |
| + key.Open(HKEY_CURRENT_USER, |
| + kRootKey, |
| + KEY_READ | KEY_CREATE_SUB_KEY)); |
| + |
| + ASSERT_NE(ERROR_SUCCESS, key.OpenKey(L"foo", KEY_READ)); |
| + ASSERT_EQ(ERROR_SUCCESS, key.CreateKey(L"foo", KEY_READ)); |
| + ASSERT_EQ(ERROR_SUCCESS, key.Open(HKEY_CURRENT_USER, kRootKey, KEY_READ)); |
| + ASSERT_EQ(ERROR_SUCCESS, key.OpenKey(L"foo", KEY_READ)); |
| + |
| + std::wstring foo_key(kRootKey); |
| + foo_key += L"\\Foo"; |
| + ASSERT_EQ(ERROR_SUCCESS, |
| + key.Open(HKEY_CURRENT_USER, foo_key.c_str(), KEY_READ)); |
| + |
| + ASSERT_EQ(ERROR_SUCCESS, key.Open(HKEY_CURRENT_USER, kRootKey, KEY_WRITE)); |
| + ASSERT_EQ(ERROR_SUCCESS, key.DeleteKey(L"foo")); |
| +} |
| + |
| } // namespace |
| } // namespace win |