Home | History | Annotate | Download | only in util
      1 // Copyright (c) 2012 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 
      7 #include "base/files/file_path.h"
      8 #include "base/memory/scoped_ptr.h"
      9 #include "base/strings/string_util.h"
     10 #include "base/win/registry.h"
     11 #include "chrome/installer/util/set_reg_value_work_item.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 namespace {
     18 
     19 const wchar_t kTestRoot[] = L"TempTemp";
     20 const wchar_t kDataStr1[] = L"data_111";
     21 const wchar_t kDataStr2[] = L"data_222";
     22 const wchar_t kNameStr[] = L"name_str";
     23 const wchar_t kNameDword[] = L"name_dword";
     24 
     25 const DWORD dword1 = 0;
     26 const DWORD dword2 = 1;
     27 
     28 class SetRegValueWorkItemTest : public testing::Test {
     29  protected:
     30   virtual void SetUp() {
     31     // Create a temporary key for testing
     32     RegKey key(HKEY_CURRENT_USER, L"", KEY_ALL_ACCESS);
     33     key.DeleteKey(kTestRoot);
     34     ASSERT_NE(ERROR_SUCCESS, key.Open(HKEY_CURRENT_USER, kTestRoot, KEY_READ));
     35     ASSERT_EQ(ERROR_SUCCESS,
     36         key.Create(HKEY_CURRENT_USER, kTestRoot, KEY_READ));
     37   }
     38   virtual void TearDown() {
     39     logging::CloseLogFile();
     40     // Clean up the temporary key
     41     RegKey key(HKEY_CURRENT_USER, L"", KEY_ALL_ACCESS);
     42     ASSERT_EQ(ERROR_SUCCESS, key.DeleteKey(kTestRoot));
     43   }
     44 };
     45 
     46 }  // namespace
     47 
     48 // Write a new value without overwrite flag. The value should be set.
     49 TEST_F(SetRegValueWorkItemTest, WriteNewNonOverwrite) {
     50   RegKey key;
     51 
     52   std::wstring parent_key(kTestRoot);
     53   parent_key.append(&base::FilePath::kSeparators[0], 1);
     54   parent_key.append(L"WriteNewNonOverwrite");
     55   ASSERT_EQ(ERROR_SUCCESS,
     56       key.Create(HKEY_CURRENT_USER, parent_key.c_str(), KEY_READ));
     57 
     58   std::wstring name_str(kNameStr);
     59   std::wstring data_str(kDataStr1);
     60   scoped_ptr<SetRegValueWorkItem> work_item1(
     61       WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, parent_key,
     62                                           name_str, data_str, false));
     63 
     64   std::wstring name_dword(kNameDword);
     65   scoped_ptr<SetRegValueWorkItem> work_item2(
     66       WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, parent_key,
     67                                           name_dword, dword1, false));
     68 
     69   EXPECT_TRUE(work_item1->Do());
     70   EXPECT_TRUE(work_item2->Do());
     71 
     72   std::wstring read_out;
     73   DWORD read_dword;
     74   EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name_str.c_str(), &read_out));
     75   EXPECT_EQ(ERROR_SUCCESS, key.ReadValueDW(name_dword.c_str(), &read_dword));
     76   EXPECT_EQ(read_out, kDataStr1);
     77   EXPECT_EQ(read_dword, dword1);
     78 
     79   work_item1->Rollback();
     80   work_item2->Rollback();
     81 
     82   // Rollback should delete the value.
     83   EXPECT_FALSE(key.HasValue(name_str.c_str()));
     84   EXPECT_FALSE(key.HasValue(name_dword.c_str()));
     85 }
     86 
     87 // Write a new value with overwrite flag. The value should be set.
     88 TEST_F(SetRegValueWorkItemTest, WriteNewOverwrite) {
     89   RegKey key;
     90 
     91   std::wstring parent_key(kTestRoot);
     92   parent_key.append(&base::FilePath::kSeparators[0], 1);
     93   parent_key.append(L"WriteNewOverwrite");
     94   ASSERT_EQ(ERROR_SUCCESS,
     95       key.Create(HKEY_CURRENT_USER, parent_key.c_str(), KEY_READ));
     96 
     97   std::wstring name_str(kNameStr);
     98   std::wstring data_str(kDataStr1);
     99   scoped_ptr<SetRegValueWorkItem> work_item1(
    100       WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, parent_key,
    101                                           name_str, data_str, true));
    102 
    103   std::wstring name_dword(kNameDword);
    104   scoped_ptr<SetRegValueWorkItem> work_item2(
    105       WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, parent_key,
    106                                           name_dword, dword1, true));
    107 
    108   EXPECT_TRUE(work_item1->Do());
    109   EXPECT_TRUE(work_item2->Do());
    110 
    111   std::wstring read_out;
    112   DWORD read_dword;
    113   EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name_str.c_str(), &read_out));
    114   EXPECT_EQ(ERROR_SUCCESS, key.ReadValueDW(name_dword.c_str(), &read_dword));
    115   EXPECT_EQ(read_out, kDataStr1);
    116   EXPECT_EQ(read_dword, dword1);
    117 
    118   work_item1->Rollback();
    119   work_item2->Rollback();
    120 
    121   // Rollback should delete the value.
    122   EXPECT_FALSE(key.HasValue(name_str.c_str()));
    123   EXPECT_FALSE(key.HasValue(name_dword.c_str()));
    124 }
    125 
    126 // Write to an existing value without overwrite flag. There should be
    127 // no change.
    128 TEST_F(SetRegValueWorkItemTest, WriteExistingNonOverwrite) {
    129   RegKey key;
    130 
    131   std::wstring parent_key(kTestRoot);
    132   parent_key.append(&base::FilePath::kSeparators[0], 1);
    133   parent_key.append(L"WriteExistingNonOverwrite");
    134   ASSERT_EQ(ERROR_SUCCESS,
    135       key.Create(HKEY_CURRENT_USER, parent_key.c_str(),
    136                  KEY_READ | KEY_SET_VALUE));
    137 
    138   // First test REG_SZ value.
    139   // Write data to the value we are going to set.
    140   std::wstring name(kNameStr);
    141   ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(name.c_str(), kDataStr1));
    142 
    143   std::wstring data(kDataStr2);
    144   scoped_ptr<SetRegValueWorkItem> work_item(
    145       WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, parent_key,
    146                                           name, data, false));
    147   EXPECT_TRUE(work_item->Do());
    148 
    149   std::wstring read_out;
    150   EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name.c_str(), &read_out));
    151   EXPECT_EQ(0, read_out.compare(kDataStr1));
    152 
    153   work_item->Rollback();
    154   EXPECT_TRUE(key.HasValue(name.c_str()));
    155   EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name.c_str(), &read_out));
    156   EXPECT_EQ(read_out, kDataStr1);
    157 
    158   // Now test REG_DWORD value.
    159   // Write data to the value we are going to set.
    160   name.assign(kNameDword);
    161   ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(name.c_str(), dword1));
    162   work_item.reset(WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER,
    163       parent_key, name, dword2, false));
    164   EXPECT_TRUE(work_item->Do());
    165 
    166   DWORD read_dword;
    167   EXPECT_EQ(ERROR_SUCCESS, key.ReadValueDW(name.c_str(), &read_dword));
    168   EXPECT_EQ(read_dword, dword1);
    169 
    170   work_item->Rollback();
    171   EXPECT_TRUE(key.HasValue(name.c_str()));
    172   EXPECT_EQ(ERROR_SUCCESS, key.ReadValueDW(name.c_str(), &read_dword));
    173   EXPECT_EQ(read_dword, dword1);
    174 }
    175 
    176 // Write to an existing value with overwrite flag. The value should be
    177 // overwritten.
    178 TEST_F(SetRegValueWorkItemTest, WriteExistingOverwrite) {
    179   RegKey key;
    180 
    181   std::wstring parent_key(kTestRoot);
    182   parent_key.append(&base::FilePath::kSeparators[0], 1);
    183   parent_key.append(L"WriteExistingOverwrite");
    184   ASSERT_EQ(ERROR_SUCCESS,
    185       key.Create(HKEY_CURRENT_USER, parent_key.c_str(),
    186                  KEY_READ | KEY_SET_VALUE));
    187 
    188   // First test REG_SZ value.
    189   // Write data to the value we are going to set.
    190   std::wstring name(kNameStr);
    191   ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(name.c_str(), kDataStr1));
    192 
    193   std::wstring name_empty(L"name_empty");
    194   ASSERT_EQ(ERROR_SUCCESS, RegSetValueEx(key.Handle(), name_empty.c_str(), NULL,
    195                                          REG_SZ, NULL, 0));
    196 
    197   std::wstring data(kDataStr2);
    198   scoped_ptr<SetRegValueWorkItem> work_item1(
    199       WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, parent_key,
    200                                           name, data, true));
    201   scoped_ptr<SetRegValueWorkItem> work_item2(
    202       WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, parent_key,
    203                                           name_empty, data, true));
    204 
    205   EXPECT_TRUE(work_item1->Do());
    206   EXPECT_TRUE(work_item2->Do());
    207 
    208   std::wstring read_out;
    209   EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name.c_str(), &read_out));
    210   EXPECT_EQ(0, read_out.compare(kDataStr2));
    211 
    212   EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name_empty.c_str(), &read_out));
    213   EXPECT_EQ(0, read_out.compare(kDataStr2));
    214 
    215   work_item1->Rollback();
    216   work_item2->Rollback();
    217 
    218   EXPECT_TRUE(key.HasValue(name.c_str()));
    219   EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name.c_str(), &read_out));
    220   EXPECT_EQ(read_out, kDataStr1);
    221 
    222   DWORD type = 0;
    223   DWORD size = 0;
    224   EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name_empty.c_str(), NULL, &size,
    225                                          &type));
    226   EXPECT_EQ(REG_SZ, type);
    227   EXPECT_EQ(0, size);
    228 
    229   // Now test REG_DWORD value.
    230   // Write data to the value we are going to set.
    231   name.assign(kNameDword);
    232   ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(name.c_str(), dword1));
    233   scoped_ptr<SetRegValueWorkItem> work_item3(
    234       WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, parent_key, name,
    235                                           dword2, true));
    236   EXPECT_TRUE(work_item3->Do());
    237 
    238   DWORD read_dword;
    239   EXPECT_EQ(ERROR_SUCCESS, key.ReadValueDW(name.c_str(), &read_dword));
    240   EXPECT_EQ(read_dword, dword2);
    241 
    242   work_item3->Rollback();
    243   EXPECT_TRUE(key.HasValue(name.c_str()));
    244   EXPECT_EQ(ERROR_SUCCESS, key.ReadValueDW(name.c_str(), &read_dword));
    245   EXPECT_EQ(read_dword, dword1);
    246 }
    247 
    248 // Write a value to a non-existing key. This should fail.
    249 TEST_F(SetRegValueWorkItemTest, WriteNonExistingKey) {
    250   RegKey key;
    251 
    252   std::wstring parent_key(kTestRoot);
    253   parent_key.append(&base::FilePath::kSeparators[0], 1);
    254   parent_key.append(L"WriteNonExistingKey");
    255 
    256   std::wstring name(L"name");
    257   std::wstring data(kDataStr1);
    258   scoped_ptr<SetRegValueWorkItem> work_item(
    259       WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, parent_key,
    260                                           name, data, false));
    261   EXPECT_FALSE(work_item->Do());
    262 
    263   work_item.reset(WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER,
    264       parent_key, name, dword1, false));
    265   EXPECT_FALSE(work_item->Do());
    266 }
    267