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,
     62                                           parent_key,
     63                                           WorkItem::kWow64Default,
     64                                           name_str,
     65                                           data_str,
     66                                           false));
     67 
     68   std::wstring name_dword(kNameDword);
     69   scoped_ptr<SetRegValueWorkItem> work_item2(
     70       WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER,
     71                                           parent_key,
     72                                           WorkItem::kWow64Default,
     73                                           name_dword,
     74                                           dword1,
     75                                           false));
     76 
     77   EXPECT_TRUE(work_item1->Do());
     78   EXPECT_TRUE(work_item2->Do());
     79 
     80   std::wstring read_out;
     81   DWORD read_dword;
     82   EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name_str.c_str(), &read_out));
     83   EXPECT_EQ(ERROR_SUCCESS, key.ReadValueDW(name_dword.c_str(), &read_dword));
     84   EXPECT_EQ(read_out, kDataStr1);
     85   EXPECT_EQ(read_dword, dword1);
     86 
     87   work_item1->Rollback();
     88   work_item2->Rollback();
     89 
     90   // Rollback should delete the value.
     91   EXPECT_FALSE(key.HasValue(name_str.c_str()));
     92   EXPECT_FALSE(key.HasValue(name_dword.c_str()));
     93 }
     94 
     95 // Write a new value with overwrite flag. The value should be set.
     96 TEST_F(SetRegValueWorkItemTest, WriteNewOverwrite) {
     97   RegKey key;
     98 
     99   std::wstring parent_key(kTestRoot);
    100   parent_key.append(&base::FilePath::kSeparators[0], 1);
    101   parent_key.append(L"WriteNewOverwrite");
    102   ASSERT_EQ(ERROR_SUCCESS,
    103       key.Create(HKEY_CURRENT_USER, parent_key.c_str(), KEY_READ));
    104 
    105   std::wstring name_str(kNameStr);
    106   std::wstring data_str(kDataStr1);
    107   scoped_ptr<SetRegValueWorkItem> work_item1(
    108       WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER,
    109                                           parent_key,
    110                                           WorkItem::kWow64Default,
    111                                           name_str,
    112                                           data_str,
    113                                           true));
    114 
    115   std::wstring name_dword(kNameDword);
    116   scoped_ptr<SetRegValueWorkItem> work_item2(
    117       WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER,
    118                                           parent_key,
    119                                           WorkItem::kWow64Default,
    120                                           name_dword,
    121                                           dword1,
    122                                           true));
    123 
    124   EXPECT_TRUE(work_item1->Do());
    125   EXPECT_TRUE(work_item2->Do());
    126 
    127   std::wstring read_out;
    128   DWORD read_dword;
    129   EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name_str.c_str(), &read_out));
    130   EXPECT_EQ(ERROR_SUCCESS, key.ReadValueDW(name_dword.c_str(), &read_dword));
    131   EXPECT_EQ(read_out, kDataStr1);
    132   EXPECT_EQ(read_dword, dword1);
    133 
    134   work_item1->Rollback();
    135   work_item2->Rollback();
    136 
    137   // Rollback should delete the value.
    138   EXPECT_FALSE(key.HasValue(name_str.c_str()));
    139   EXPECT_FALSE(key.HasValue(name_dword.c_str()));
    140 }
    141 
    142 // Write to an existing value without overwrite flag. There should be
    143 // no change.
    144 TEST_F(SetRegValueWorkItemTest, WriteExistingNonOverwrite) {
    145   RegKey key;
    146 
    147   std::wstring parent_key(kTestRoot);
    148   parent_key.append(&base::FilePath::kSeparators[0], 1);
    149   parent_key.append(L"WriteExistingNonOverwrite");
    150   ASSERT_EQ(ERROR_SUCCESS,
    151       key.Create(HKEY_CURRENT_USER, parent_key.c_str(),
    152                  KEY_READ | KEY_SET_VALUE));
    153 
    154   // First test REG_SZ value.
    155   // Write data to the value we are going to set.
    156   std::wstring name(kNameStr);
    157   ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(name.c_str(), kDataStr1));
    158 
    159   std::wstring data(kDataStr2);
    160   scoped_ptr<SetRegValueWorkItem> work_item(
    161       WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER,
    162                                           parent_key,
    163                                           WorkItem::kWow64Default,
    164                                           name,
    165                                           data,
    166                                           false));
    167   EXPECT_TRUE(work_item->Do());
    168 
    169   std::wstring read_out;
    170   EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name.c_str(), &read_out));
    171   EXPECT_EQ(0, read_out.compare(kDataStr1));
    172 
    173   work_item->Rollback();
    174   EXPECT_TRUE(key.HasValue(name.c_str()));
    175   EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name.c_str(), &read_out));
    176   EXPECT_EQ(read_out, kDataStr1);
    177 
    178   // Now test REG_DWORD value.
    179   // Write data to the value we are going to set.
    180   name.assign(kNameDword);
    181   ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(name.c_str(), dword1));
    182   work_item.reset(WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER,
    183                                                       parent_key,
    184                                                       WorkItem::kWow64Default,
    185                                                       name,
    186                                                       dword2,
    187                                                       false));
    188   EXPECT_TRUE(work_item->Do());
    189 
    190   DWORD read_dword;
    191   EXPECT_EQ(ERROR_SUCCESS, key.ReadValueDW(name.c_str(), &read_dword));
    192   EXPECT_EQ(read_dword, dword1);
    193 
    194   work_item->Rollback();
    195   EXPECT_TRUE(key.HasValue(name.c_str()));
    196   EXPECT_EQ(ERROR_SUCCESS, key.ReadValueDW(name.c_str(), &read_dword));
    197   EXPECT_EQ(read_dword, dword1);
    198 }
    199 
    200 // Write to an existing value with overwrite flag. The value should be
    201 // overwritten.
    202 TEST_F(SetRegValueWorkItemTest, WriteExistingOverwrite) {
    203   RegKey key;
    204 
    205   std::wstring parent_key(kTestRoot);
    206   parent_key.append(&base::FilePath::kSeparators[0], 1);
    207   parent_key.append(L"WriteExistingOverwrite");
    208   ASSERT_EQ(ERROR_SUCCESS,
    209       key.Create(HKEY_CURRENT_USER, parent_key.c_str(),
    210                  KEY_READ | KEY_SET_VALUE));
    211 
    212   // First test REG_SZ value.
    213   // Write data to the value we are going to set.
    214   std::wstring name(kNameStr);
    215   ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(name.c_str(), kDataStr1));
    216 
    217   std::wstring name_empty(L"name_empty");
    218   ASSERT_EQ(ERROR_SUCCESS, RegSetValueEx(key.Handle(), name_empty.c_str(), NULL,
    219                                          REG_SZ, NULL, 0));
    220 
    221   std::wstring data(kDataStr2);
    222   scoped_ptr<SetRegValueWorkItem> work_item1(
    223       WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER,
    224                                           parent_key,
    225                                           WorkItem::kWow64Default,
    226                                           name,
    227                                           data,
    228                                           true));
    229   scoped_ptr<SetRegValueWorkItem> work_item2(
    230       WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER,
    231                                           parent_key,
    232                                           WorkItem::kWow64Default,
    233                                           name_empty,
    234                                           data,
    235                                           true));
    236 
    237   EXPECT_TRUE(work_item1->Do());
    238   EXPECT_TRUE(work_item2->Do());
    239 
    240   std::wstring read_out;
    241   EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name.c_str(), &read_out));
    242   EXPECT_EQ(0, read_out.compare(kDataStr2));
    243 
    244   EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name_empty.c_str(), &read_out));
    245   EXPECT_EQ(0, read_out.compare(kDataStr2));
    246 
    247   work_item1->Rollback();
    248   work_item2->Rollback();
    249 
    250   EXPECT_TRUE(key.HasValue(name.c_str()));
    251   EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name.c_str(), &read_out));
    252   EXPECT_EQ(read_out, kDataStr1);
    253 
    254   DWORD type = 0;
    255   DWORD size = 0;
    256   EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name_empty.c_str(), NULL, &size,
    257                                          &type));
    258   EXPECT_EQ(REG_SZ, type);
    259   EXPECT_EQ(0, size);
    260 
    261   // Now test REG_DWORD value.
    262   // Write data to the value we are going to set.
    263   name.assign(kNameDword);
    264   ASSERT_EQ(ERROR_SUCCESS, key.WriteValue(name.c_str(), dword1));
    265   scoped_ptr<SetRegValueWorkItem> work_item3(
    266       WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER,
    267                                           parent_key,
    268                                           WorkItem::kWow64Default,
    269                                           name,
    270                                           dword2,
    271                                           true));
    272   EXPECT_TRUE(work_item3->Do());
    273 
    274   DWORD read_dword;
    275   EXPECT_EQ(ERROR_SUCCESS, key.ReadValueDW(name.c_str(), &read_dword));
    276   EXPECT_EQ(read_dword, dword2);
    277 
    278   work_item3->Rollback();
    279   EXPECT_TRUE(key.HasValue(name.c_str()));
    280   EXPECT_EQ(ERROR_SUCCESS, key.ReadValueDW(name.c_str(), &read_dword));
    281   EXPECT_EQ(read_dword, dword1);
    282 }
    283 
    284 // Write a value to a non-existing key. This should fail.
    285 TEST_F(SetRegValueWorkItemTest, WriteNonExistingKey) {
    286   RegKey key;
    287 
    288   std::wstring parent_key(kTestRoot);
    289   parent_key.append(&base::FilePath::kSeparators[0], 1);
    290   parent_key.append(L"WriteNonExistingKey");
    291 
    292   std::wstring name(L"name");
    293   std::wstring data(kDataStr1);
    294   scoped_ptr<SetRegValueWorkItem> work_item(
    295       WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER,
    296                                           parent_key,
    297                                           WorkItem::kWow64Default,
    298                                           name,
    299                                           data,
    300                                           false));
    301   EXPECT_FALSE(work_item->Do());
    302 
    303   work_item.reset(WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER,
    304                                                       parent_key,
    305                                                       WorkItem::kWow64Default,
    306                                                       name,
    307                                                       dword1,
    308                                                       false));
    309   EXPECT_FALSE(work_item->Do());
    310 }
    311