/*
 * libjingle
 * Copyright 2003-2008, Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

// Unittest for registry access API

#include "talk/base/gunit.h"
#include "talk/base/common.h"
#include "talk/base/win32regkey.h"

namespace talk_base {

#ifndef EXPECT_SUCCEEDED
#define EXPECT_SUCCEEDED(x)  EXPECT_TRUE(SUCCEEDED(x))
#endif

#ifndef EXPECT_FAILED
#define EXPECT_FAILED(x)  EXPECT_TRUE(FAILED(x))
#endif

#define kBaseKey           L"Software\\Google\\__TEST"
#define kSubkeyName        L"subkey_test"

const wchar_t kRkey1[] = kBaseKey;
const wchar_t kRkey1SubkeyName[] = kSubkeyName;
const wchar_t kRkey1Subkey[] = kBaseKey L"\\" kSubkeyName;
const wchar_t kFullRkey1[] = L"HKCU\\" kBaseKey;
const wchar_t kFullRkey1Subkey[] = L"HKCU\\" kBaseKey L"\\" kSubkeyName;

const wchar_t kValNameInt[] = L"Int32 Value";
const DWORD kIntVal = 20;
const DWORD kIntVal2 = 30;

const wchar_t kValNameInt64[] = L"Int64 Value";
const DWORD64 kIntVal64 = 119600064000000000uI64;

const wchar_t kValNameFloat[] = L"Float Value";
const float kFloatVal = 12.3456789f;

const wchar_t kValNameDouble[] = L"Double Value";
const double kDoubleVal = 98.7654321;

const wchar_t kValNameStr[] = L"Str Value";
const wchar_t kStrVal[] = L"Some string data 1";
const wchar_t kStrVal2[] = L"Some string data 2";

const wchar_t kValNameBinary[] = L"Binary Value";
const char kBinaryVal[] = "Some binary data abcdefghi 1";
const char kBinaryVal2[] = "Some binary data abcdefghi 2";

const wchar_t kValNameMultiStr[] = L"MultiStr Value";
const wchar_t kMultiSZ[] = L"abc\0def\0P12345\0";
const wchar_t kEmptyMultiSZ[] = L"";
const wchar_t kInvalidMultiSZ[] = {L'6', L'7', L'8'};

// friend function of RegKey
void RegKeyHelperFunctionsTest() {
  // Try out some dud values
  std::wstring temp_key = L"";
  EXPECT_TRUE(RegKey::GetRootKeyInfo(&temp_key) == NULL);
  EXPECT_STREQ(temp_key.c_str(), L"");

  temp_key = L"a";
  EXPECT_TRUE(RegKey::GetRootKeyInfo(&temp_key) == NULL);
  EXPECT_STREQ(temp_key.c_str(), L"");

  // The basics
  temp_key = L"HKLM\\a";
  EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_LOCAL_MACHINE);
  EXPECT_STREQ(temp_key.c_str(), L"a");

  temp_key = L"HKEY_LOCAL_MACHINE\\a";
  EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_LOCAL_MACHINE);
  EXPECT_STREQ(temp_key.c_str(), L"a");

  temp_key = L"HKCU\\a";
  EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_CURRENT_USER);
  EXPECT_STREQ(temp_key.c_str(), L"a");

  temp_key = L"HKEY_CURRENT_USER\\a";
  EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_CURRENT_USER);
  EXPECT_STREQ(temp_key.c_str(), L"a");

  temp_key = L"HKU\\a";
  EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_USERS);
  EXPECT_STREQ(temp_key.c_str(), L"a");

  temp_key = L"HKEY_USERS\\a";
  EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_USERS);
  EXPECT_STREQ(temp_key.c_str(), L"a");

  temp_key = L"HKCR\\a";
  EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_CLASSES_ROOT);
  EXPECT_STREQ(temp_key.c_str(), L"a");

  temp_key = L"HKEY_CLASSES_ROOT\\a";
  EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_CLASSES_ROOT);
  EXPECT_STREQ(temp_key.c_str(), L"a");

  // Make sure it is case insensitive
  temp_key = L"hkcr\\a";
  EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_CLASSES_ROOT);
  EXPECT_STREQ(temp_key.c_str(), L"a");

  temp_key = L"hkey_CLASSES_ROOT\\a";
  EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_CLASSES_ROOT);
  EXPECT_STREQ(temp_key.c_str(), L"a");

  //
  // Test RegKey::GetParentKeyInfo
  //

  // dud cases
  temp_key = L"";
  EXPECT_STREQ(RegKey::GetParentKeyInfo(&temp_key).c_str(), L"");
  EXPECT_STREQ(temp_key.c_str(), L"");

  temp_key = L"a";
  EXPECT_STREQ(RegKey::GetParentKeyInfo(&temp_key).c_str(), L"");
  EXPECT_STREQ(temp_key.c_str(), L"a");

  temp_key = L"a\\b";
  EXPECT_STREQ(RegKey::GetParentKeyInfo(&temp_key).c_str(), L"a");
  EXPECT_STREQ(temp_key.c_str(), L"b");

  temp_key = L"\\b";
  EXPECT_STREQ(RegKey::GetParentKeyInfo(&temp_key).c_str(), L"");
  EXPECT_STREQ(temp_key.c_str(), L"b");

  // Some regular cases
  temp_key = L"HKEY_CLASSES_ROOT\\moon";
  EXPECT_STREQ(RegKey::GetParentKeyInfo(&temp_key).c_str(),
               L"HKEY_CLASSES_ROOT");
  EXPECT_STREQ(temp_key.c_str(), L"moon");

  temp_key = L"HKEY_CLASSES_ROOT\\moon\\doggy";
  EXPECT_STREQ(RegKey::GetParentKeyInfo(&temp_key).c_str(),
               L"HKEY_CLASSES_ROOT\\moon");
  EXPECT_STREQ(temp_key.c_str(), L"doggy");

  //
  // Test MultiSZBytesToStringArray
  //

  std::vector<std::wstring> result;
  EXPECT_SUCCEEDED(RegKey::MultiSZBytesToStringArray(
      reinterpret_cast<const uint8*>(kMultiSZ), sizeof(kMultiSZ), &result));
  EXPECT_EQ(result.size(), 3);
  EXPECT_STREQ(result[0].c_str(), L"abc");
  EXPECT_STREQ(result[1].c_str(), L"def");
  EXPECT_STREQ(result[2].c_str(), L"P12345");

  EXPECT_SUCCEEDED(RegKey::MultiSZBytesToStringArray(
      reinterpret_cast<const uint8*>(kEmptyMultiSZ),
      sizeof(kEmptyMultiSZ), &result));
  EXPECT_EQ(result.size(), 0);
  EXPECT_FALSE(SUCCEEDED(RegKey::MultiSZBytesToStringArray(
      reinterpret_cast<const uint8*>(kInvalidMultiSZ),
      sizeof(kInvalidMultiSZ), &result)));
}

TEST(RegKeyTest, RegKeyHelperFunctionsTest) {
  RegKeyHelperFunctionsTest();
}

TEST(RegKeyTest, RegKeyNonStaticFunctionsTest) {
  DWORD int_val = 0;
  DWORD64 int64_val = 0;
  wchar_t* str_val = NULL;
  uint8* binary_val = NULL;
  DWORD uint8_count = 0;

  // Just in case...
  // make sure the no test key residue is left from previous aborted runs
  RegKey::DeleteKey(kFullRkey1);

  // initial state
  RegKey r_key;
  EXPECT_TRUE(r_key.key() == NULL);

  // create a reg key
  EXPECT_SUCCEEDED(r_key.Create(HKEY_CURRENT_USER, kRkey1));

  // do the create twice - it should return the already created one
  EXPECT_SUCCEEDED(r_key.Create(HKEY_CURRENT_USER, kRkey1));

  // now do an open - should work just fine
  EXPECT_SUCCEEDED(r_key.Open(HKEY_CURRENT_USER, kRkey1));

  // get an in-existent value
  EXPECT_EQ(r_key.GetValue(kValNameInt, &int_val),
            HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));

  // set and get some values

  // set an INT 32
  EXPECT_SUCCEEDED(r_key.SetValue(kValNameInt, kIntVal));

  // check that the value exists
  EXPECT_TRUE(r_key.HasValue(kValNameInt));

  // read it back
  EXPECT_SUCCEEDED(r_key.GetValue(kValNameInt, &int_val));
  EXPECT_EQ(int_val, kIntVal);

  // set it again!
  EXPECT_SUCCEEDED(r_key.SetValue(kValNameInt, kIntVal2));

  // read it again
  EXPECT_SUCCEEDED(r_key.GetValue(kValNameInt, &int_val));
  EXPECT_EQ(int_val, kIntVal2);

  // delete the value
  EXPECT_SUCCEEDED(r_key.DeleteValue(kValNameInt));

  // check that the value is gone
  EXPECT_FALSE(r_key.HasValue(kValNameInt));

  // set an INT 64
  EXPECT_SUCCEEDED(r_key.SetValue(kValNameInt64, kIntVal64));

  // check that the value exists
  EXPECT_TRUE(r_key.HasValue(kValNameInt64));

  // read it back
  EXPECT_SUCCEEDED(r_key.GetValue(kValNameInt64, &int64_val));
  EXPECT_EQ(int64_val, kIntVal64);

  // delete the value
  EXPECT_SUCCEEDED(r_key.DeleteValue(kValNameInt64));

  // check that the value is gone
  EXPECT_FALSE(r_key.HasValue(kValNameInt64));

  // set a string
  EXPECT_SUCCEEDED(r_key.SetValue(kValNameStr, kStrVal));

  // check that the value exists
  EXPECT_TRUE(r_key.HasValue(kValNameStr));

  // read it back
  EXPECT_SUCCEEDED(r_key.GetValue(kValNameStr, &str_val));
  EXPECT_TRUE(lstrcmp(str_val, kStrVal) == 0);
  delete[] str_val;

  // set it again
  EXPECT_SUCCEEDED(r_key.SetValue(kValNameStr, kStrVal2));

  // read it again
  EXPECT_SUCCEEDED(r_key.GetValue(kValNameStr, &str_val));
  EXPECT_TRUE(lstrcmp(str_val, kStrVal2) == 0);
  delete[] str_val;

  // delete the value
  EXPECT_SUCCEEDED(r_key.DeleteValue(kValNameStr));

  // check that the value is gone
  EXPECT_FALSE(r_key.HasValue(kValNameInt));

  // set a binary value
  EXPECT_SUCCEEDED(r_key.SetValue(kValNameBinary,
      reinterpret_cast<const uint8*>(kBinaryVal), sizeof(kBinaryVal) - 1));

  // check that the value exists
  EXPECT_TRUE(r_key.HasValue(kValNameBinary));

  // read it back
  EXPECT_SUCCEEDED(r_key.GetValue(kValNameBinary, &binary_val, &uint8_count));
  EXPECT_TRUE(memcmp(binary_val, kBinaryVal, sizeof(kBinaryVal) - 1) == 0);
  delete[] binary_val;

  // set it again
  EXPECT_SUCCEEDED(r_key.SetValue(kValNameBinary,
      reinterpret_cast<const uint8*>(kBinaryVal2), sizeof(kBinaryVal) - 1));

  // read it again
  EXPECT_SUCCEEDED(r_key.GetValue(kValNameBinary, &binary_val, &uint8_count));
  EXPECT_TRUE(memcmp(binary_val, kBinaryVal2, sizeof(kBinaryVal2) - 1) == 0);
  delete[] binary_val;

  // delete the value
  EXPECT_SUCCEEDED(r_key.DeleteValue(kValNameBinary));

  // check that the value is gone
  EXPECT_FALSE(r_key.HasValue(kValNameBinary));

  // set some values and check the total count

  // set an INT 32
  EXPECT_SUCCEEDED(r_key.SetValue(kValNameInt, kIntVal));

  // set an INT 64
  EXPECT_SUCCEEDED(r_key.SetValue(kValNameInt64, kIntVal64));

  // set a string
  EXPECT_SUCCEEDED(r_key.SetValue(kValNameStr, kStrVal));

  // set a binary value
  EXPECT_SUCCEEDED(r_key.SetValue(kValNameBinary,
      reinterpret_cast<const uint8*>(kBinaryVal), sizeof(kBinaryVal) - 1));

  // get the value count
  uint32 value_count = r_key.GetValueCount();
  EXPECT_EQ(value_count, 4);

  // check the value names
  std::wstring value_name;
  DWORD type = 0;

  EXPECT_SUCCEEDED(r_key.GetValueNameAt(0, &value_name, &type));
  EXPECT_STREQ(value_name.c_str(), kValNameInt);
  EXPECT_EQ(type, REG_DWORD);

  EXPECT_SUCCEEDED(r_key.GetValueNameAt(1, &value_name, &type));
  EXPECT_STREQ(value_name.c_str(), kValNameInt64);
  EXPECT_EQ(type, REG_QWORD);

  EXPECT_SUCCEEDED(r_key.GetValueNameAt(2, &value_name, &type));
  EXPECT_STREQ(value_name.c_str(), kValNameStr);
  EXPECT_EQ(type, REG_SZ);

  EXPECT_SUCCEEDED(r_key.GetValueNameAt(3, &value_name, &type));
  EXPECT_STREQ(value_name.c_str(), kValNameBinary);
  EXPECT_EQ(type, REG_BINARY);

  // check that there are no more values
  EXPECT_FAILED(r_key.GetValueNameAt(4, &value_name, &type));

  uint32 subkey_count = r_key.GetSubkeyCount();
  EXPECT_EQ(subkey_count, 0);

  // now create a subkey and make sure we can get the name
  RegKey temp_key;
  EXPECT_SUCCEEDED(temp_key.Create(HKEY_CURRENT_USER, kRkey1Subkey));

  // check the subkey exists
  EXPECT_TRUE(r_key.HasSubkey(kRkey1SubkeyName));

  // check the name
  EXPECT_EQ(r_key.GetSubkeyCount(), 1);

  std::wstring subkey_name;
  EXPECT_SUCCEEDED(r_key.GetSubkeyNameAt(0, &subkey_name));
  EXPECT_STREQ(subkey_name.c_str(), kRkey1SubkeyName);

  // delete the key
  EXPECT_SUCCEEDED(r_key.DeleteSubKey(kRkey1));

  // close this key
  EXPECT_SUCCEEDED(r_key.Close());

  // whack the whole key
  EXPECT_SUCCEEDED(RegKey::DeleteKey(kFullRkey1));
}

TEST(RegKeyTest, RegKeyStaticFunctionsTest) {
  DWORD int_val = 0;
  DWORD64 int64_val = 0;
  float float_val = 0;
  double double_val = 0;
  wchar_t* str_val = NULL;
  std::wstring wstr_val;
  uint8* binary_val = NULL;
  DWORD uint8_count = 0;

  // Just in case...
  // make sure the no test key residue is left from previous aborted runs
  RegKey::DeleteKey(kFullRkey1);

  // get an in-existent value from an un-existent key
  EXPECT_EQ(RegKey::GetValue(kFullRkey1, kValNameInt, &int_val),
            HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));

  // set int32
  EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1, kValNameInt, kIntVal));

  // check that the value exists
  EXPECT_TRUE(RegKey::HasValue(kFullRkey1, kValNameInt));

  // get an in-existent value from an existent key
  EXPECT_EQ(RegKey::GetValue(kFullRkey1, L"bogus", &int_val),
            HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));

  // read it back
  EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameInt, &int_val));
  EXPECT_EQ(int_val, kIntVal);

  // delete the value
  EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1, kValNameInt));

  // check that the value is gone
  EXPECT_FALSE(RegKey::HasValue(kFullRkey1, kValNameInt));

  // set int64
  EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1, kValNameInt64, kIntVal64));

  // check that the value exists
  EXPECT_TRUE(RegKey::HasValue(kFullRkey1, kValNameInt64));

  // read it back
  EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameInt64, &int64_val));
  EXPECT_EQ(int64_val, kIntVal64);

  // delete the value
  EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1, kValNameInt64));

  // check that the value is gone
  EXPECT_FALSE(RegKey::HasValue(kFullRkey1, kValNameInt64));

  // set float
  EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1, kValNameFloat, kFloatVal));

  // check that the value exists
  EXPECT_TRUE(RegKey::HasValue(kFullRkey1, kValNameFloat));

  // read it back
  EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameFloat, &float_val));
  EXPECT_EQ(float_val, kFloatVal);

  // delete the value
  EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1, kValNameFloat));

  // check that the value is gone
  EXPECT_FALSE(RegKey::HasValue(kFullRkey1, kValNameFloat));
  EXPECT_FAILED(RegKey::GetValue(kFullRkey1, kValNameFloat, &float_val));

  // set double
  EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1, kValNameDouble, kDoubleVal));

  // check that the value exists
  EXPECT_TRUE(RegKey::HasValue(kFullRkey1, kValNameDouble));

  // read it back
  EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameDouble, &double_val));
  EXPECT_EQ(double_val, kDoubleVal);

  // delete the value
  EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1, kValNameDouble));

  // check that the value is gone
  EXPECT_FALSE(RegKey::HasValue(kFullRkey1, kValNameDouble));
  EXPECT_FAILED(RegKey::GetValue(kFullRkey1, kValNameDouble, &double_val));

  // set string
  EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1, kValNameStr, kStrVal));

  // check that the value exists
  EXPECT_TRUE(RegKey::HasValue(kFullRkey1, kValNameStr));

  // read it back
  EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameStr, &str_val));
  EXPECT_TRUE(lstrcmp(str_val, kStrVal) == 0);
  delete[] str_val;

  // read it back in std::wstring
  EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameStr, &wstr_val));
  EXPECT_STREQ(wstr_val.c_str(), kStrVal);

  // get an in-existent value from an existent key
  EXPECT_EQ(RegKey::GetValue(kFullRkey1, L"bogus", &str_val),
            HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));

  // delete the value
  EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1, kValNameStr));

  // check that the value is gone
  EXPECT_FALSE(RegKey::HasValue(kFullRkey1, kValNameStr));

  // set binary
  EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1, kValNameBinary,
      reinterpret_cast<const uint8*>(kBinaryVal), sizeof(kBinaryVal)-1));

  // check that the value exists
  EXPECT_TRUE(RegKey::HasValue(kFullRkey1, kValNameBinary));

  // read it back
  EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameBinary,
      &binary_val, &uint8_count));
  EXPECT_TRUE(memcmp(binary_val, kBinaryVal, sizeof(kBinaryVal)-1) == 0);
  delete[] binary_val;

  // delete the value
  EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1, kValNameBinary));

  // check that the value is gone
  EXPECT_FALSE(RegKey::HasValue(kFullRkey1, kValNameBinary));

  // special case - set a binary value with length 0
  EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1, kValNameBinary,
      reinterpret_cast<const uint8*>(kBinaryVal), 0));

  // check that the value exists
  EXPECT_TRUE(RegKey::HasValue(kFullRkey1, kValNameBinary));

  // read it back
  EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameBinary,
      &binary_val, &uint8_count));
  EXPECT_EQ(uint8_count, 0);
  EXPECT_TRUE(binary_val == NULL);
  delete[] binary_val;

  // delete the value
  EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1, kValNameBinary));

  // check that the value is gone
  EXPECT_FALSE(RegKey::HasValue(kFullRkey1, kValNameBinary));

  // special case - set a NULL binary value
  EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1, kValNameBinary, NULL, 100));

  // check that the value exists
  EXPECT_TRUE(RegKey::HasValue(kFullRkey1, kValNameBinary));

  // read it back
  EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameBinary,
                                    &binary_val, &uint8_count));
  EXPECT_EQ(uint8_count, 0);
  EXPECT_TRUE(binary_val == NULL);
  delete[] binary_val;

  // delete the value
  EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1, kValNameBinary));

  // check that the value is gone
  EXPECT_FALSE(RegKey::HasValue(kFullRkey1, kValNameBinary));

  // test read/write REG_MULTI_SZ value
  std::vector<std::wstring> result;
  EXPECT_SUCCEEDED(RegKey::SetValueMultiSZ(kFullRkey1, kValNameMultiStr,
      reinterpret_cast<const uint8*>(kMultiSZ), sizeof(kMultiSZ)));
  EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameMultiStr, &result));
  EXPECT_EQ(result.size(), 3);
  EXPECT_STREQ(result[0].c_str(), L"abc");
  EXPECT_STREQ(result[1].c_str(), L"def");
  EXPECT_STREQ(result[2].c_str(), L"P12345");
  EXPECT_SUCCEEDED(RegKey::SetValueMultiSZ(kFullRkey1, kValNameMultiStr,
      reinterpret_cast<const uint8*>(kEmptyMultiSZ), sizeof(kEmptyMultiSZ)));
  EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameMultiStr, &result));
  EXPECT_EQ(result.size(), 0);
  // writing REG_MULTI_SZ value will automatically add ending null characters
  EXPECT_SUCCEEDED(RegKey::SetValueMultiSZ(kFullRkey1, kValNameMultiStr,
      reinterpret_cast<const uint8*>(kInvalidMultiSZ), sizeof(kInvalidMultiSZ)));
  EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameMultiStr, &result));
  EXPECT_EQ(result.size(), 1);
  EXPECT_STREQ(result[0].c_str(), L"678");

  // Run the following test only in dev machine
  // This is because the build machine might not have admin privilege
#ifdef IS_PRIVATE_BUILD
  // get a temp file name
  wchar_t temp_path[MAX_PATH] = {0};
  EXPECT_LT(::GetTempPath(ARRAY_SIZE(temp_path), temp_path),
            static_cast<DWORD>(ARRAY_SIZE(temp_path)));
  wchar_t temp_file[MAX_PATH] = {0};
  EXPECT_NE(::GetTempFileName(temp_path, L"rkut_",
                              ::GetTickCount(), temp_file), 0);

  // test save
  EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1Subkey, kValNameInt, kIntVal));
  EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1Subkey, kValNameInt64, kIntVal64));
  EXPECT_SUCCEEDED(RegKey::Save(kFullRkey1Subkey, temp_file));
  EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1Subkey, kValNameInt));
  EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1Subkey, kValNameInt64));

  // test restore
  EXPECT_SUCCEEDED(RegKey::Restore(kFullRkey1Subkey, temp_file));
  int_val = 0;
  EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1Subkey, kValNameInt, &int_val));
  EXPECT_EQ(int_val, kIntVal);
  int64_val = 0;
  EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1Subkey,
                                    kValNameInt64,
                                    &int64_val));
  EXPECT_EQ(int64_val, kIntVal64);

  // delete the temp file
  EXPECT_EQ(TRUE, ::DeleteFile(temp_file));
#endif

  // whack the whole key
  EXPECT_SUCCEEDED(RegKey::DeleteKey(kFullRkey1));
}

}  // namespace talk_base
