Home | History | Annotate | Download | only in util
      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 <windows.h>
      6 #include <atlsecurity.h>  // NOLINT
      7 #include "base/logging.h"
      8 #include "base/memory/scoped_ptr.h"
      9 #include "base/win/registry.h"
     10 #include "chrome/installer/util/delete_reg_key_work_item.h"
     11 #include "chrome/installer/util/registry_test_data.h"
     12 #include "chrome/installer/util/work_item.h"
     13 #include "testing/gtest/include/gtest/gtest.h"
     14 
     15 using base::win::RegKey;
     16 
     17 class DeleteRegKeyWorkItemTest : public testing::Test {
     18  protected:
     19   static void TearDownTestCase() {
     20     logging::CloseLogFile();
     21   }
     22 
     23   virtual void SetUp() {
     24     ASSERT_TRUE(test_data_.Initialize(HKEY_CURRENT_USER, L"SOFTWARE\\TmpTmp"));
     25   }
     26 
     27   RegistryTestData test_data_;
     28 };
     29 
     30 // Test that deleting a key that doesn't exist succeeds, and that rollback does
     31 // nothing.
     32 TEST_F(DeleteRegKeyWorkItemTest, TestNoKey) {
     33   const std::wstring key_paths[] = {
     34     std::wstring(test_data_.base_path() + L"\\NoKeyHere"),
     35     std::wstring(test_data_.base_path() + L"\\NoKeyHere\\OrHere")
     36   };
     37   RegKey key;
     38   for (size_t i = 0; i < arraysize(key_paths); ++i) {
     39     const std::wstring& key_path = key_paths[i];
     40     scoped_ptr<DeleteRegKeyWorkItem> item(
     41         WorkItem::CreateDeleteRegKeyWorkItem(test_data_.root_key(), key_path));
     42     EXPECT_TRUE(item->Do());
     43     EXPECT_NE(ERROR_SUCCESS, key.Open(test_data_.root_key(), key_path.c_str(),
     44                                       KEY_READ));
     45     item->Rollback();
     46     item.reset();
     47     EXPECT_NE(ERROR_SUCCESS, key.Open(test_data_.root_key(), key_path.c_str(),
     48                                       KEY_READ));
     49   }
     50 }
     51 
     52 // Test that deleting an empty key succeeds, and that rollback brings it back.
     53 TEST_F(DeleteRegKeyWorkItemTest, TestEmptyKey) {
     54   RegKey key;
     55   const std::wstring& key_path = test_data_.empty_key_path();
     56   scoped_ptr<DeleteRegKeyWorkItem> item(
     57       WorkItem::CreateDeleteRegKeyWorkItem(test_data_.root_key(), key_path));
     58   EXPECT_TRUE(item->Do());
     59   EXPECT_NE(ERROR_SUCCESS, key.Open(test_data_.root_key(), key_path.c_str(),
     60                                     KEY_READ));
     61   item->Rollback();
     62   item.reset();
     63   EXPECT_EQ(ERROR_SUCCESS, key.Open(test_data_.root_key(), key_path.c_str(),
     64                                     KEY_READ));
     65 }
     66 
     67 // Test that deleting a key with subkeys and values succeeds, and that rollback
     68 // brings them all back.
     69 TEST_F(DeleteRegKeyWorkItemTest, TestNonEmptyKey) {
     70   RegKey key;
     71   const std::wstring& key_path = test_data_.non_empty_key_path();
     72   scoped_ptr<DeleteRegKeyWorkItem> item(
     73       WorkItem::CreateDeleteRegKeyWorkItem(test_data_.root_key(), key_path));
     74   EXPECT_TRUE(item->Do());
     75   EXPECT_NE(ERROR_SUCCESS, key.Open(test_data_.root_key(), key_path.c_str(),
     76                                     KEY_READ));
     77   item->Rollback();
     78   item.reset();
     79   test_data_.ExpectMatchesNonEmptyKey(test_data_.root_key(), key_path.c_str());
     80 }
     81 
     82 // Test that deleting a key with subkeys we can't delete fails, and that
     83 // everything is there after rollback.
     84 // Showing as flaky on windows.
     85 // http://crbug.com/74654
     86 TEST_F(DeleteRegKeyWorkItemTest, DISABLED_TestUndeletableKey) {
     87   RegKey key;
     88   std::wstring key_name(test_data_.base_path() + L"\\UndeletableKey");
     89   EXPECT_EQ(ERROR_SUCCESS, key.Create(test_data_.root_key(), key_name.c_str(),
     90                                       KEY_WRITE));
     91   EXPECT_EQ(ERROR_SUCCESS, key.WriteValue(NULL, key_name.c_str()));
     92   DWORD dw_value = 1;
     93   RegKey subkey;
     94   RegKey subkey2;
     95   EXPECT_EQ(ERROR_SUCCESS, subkey.Create(key.Handle(), L"Subkey",
     96                                          KEY_WRITE | WRITE_DAC));
     97   EXPECT_EQ(ERROR_SUCCESS, subkey.WriteValue(L"SomeValue", 1U));
     98   EXPECT_EQ(ERROR_SUCCESS, subkey2.Create(subkey.Handle(), L"Subkey2",
     99                                           KEY_WRITE | WRITE_DAC));
    100   EXPECT_EQ(ERROR_SUCCESS, subkey2.WriteValue(L"", 2U));
    101   CSecurityDesc sec_desc;
    102   sec_desc.FromString(L"D:PAI(A;OICI;KR;;;BU)");  // builtin users read
    103   EXPECT_EQ(ERROR_SUCCESS,
    104             RegSetKeySecurity(subkey.Handle(), DACL_SECURITY_INFORMATION,
    105                               const_cast<SECURITY_DESCRIPTOR*>(
    106                                   sec_desc.GetPSECURITY_DESCRIPTOR())));
    107   sec_desc.FromString(L"D:PAI(A;OICI;KA;;;BU)");  // builtin users all access
    108   EXPECT_EQ(ERROR_SUCCESS,
    109             RegSetKeySecurity(subkey2.Handle(), DACL_SECURITY_INFORMATION,
    110                               const_cast<SECURITY_DESCRIPTOR*>(
    111                                   sec_desc.GetPSECURITY_DESCRIPTOR())));
    112   subkey2.Close();
    113   subkey.Close();
    114   key.Close();
    115   scoped_ptr<DeleteRegKeyWorkItem> item(
    116       WorkItem::CreateDeleteRegKeyWorkItem(test_data_.root_key(), key_name));
    117   EXPECT_FALSE(item->Do());
    118   EXPECT_EQ(ERROR_SUCCESS, key.Open(test_data_.root_key(), key_name.c_str(),
    119                                     KEY_QUERY_VALUE));
    120   item->Rollback();
    121   item.reset();
    122   EXPECT_EQ(ERROR_SUCCESS, key.Open(test_data_.root_key(), key_name.c_str(),
    123                                     KEY_QUERY_VALUE));
    124   std::wstring str_value;
    125   EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(NULL, &str_value));
    126   EXPECT_EQ(key_name, str_value);
    127   EXPECT_EQ(ERROR_SUCCESS, key.OpenKey(L"Subkey", KEY_READ | WRITE_DAC));
    128   dw_value = 0;
    129   EXPECT_EQ(ERROR_SUCCESS, key.ReadValueDW(L"SomeValue", &dw_value));
    130   EXPECT_EQ(1U, dw_value);
    131   // Give users all access to the subkey so it can be deleted.
    132   EXPECT_EQ(ERROR_SUCCESS,
    133       RegSetKeySecurity(key.Handle(), DACL_SECURITY_INFORMATION,
    134                         const_cast<SECURITY_DESCRIPTOR*>(
    135                             sec_desc.GetPSECURITY_DESCRIPTOR())));
    136   EXPECT_EQ(ERROR_SUCCESS, key.OpenKey(L"Subkey2", KEY_QUERY_VALUE));
    137   EXPECT_EQ(ERROR_SUCCESS, key.ReadValueDW(L"", &dw_value));
    138   EXPECT_EQ(2U, dw_value);
    139 }
    140