winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

Registry.cpp (5950B)


      1 // Copyright (c) Microsoft Corporation.
      2 // Licensed under the MIT License.
      3 #include "pch.h"
      4 #include "TestCommon.h"
      5 #include <AppInstallerStrings.h>
      6 #include <winget/Registry.h>
      7 
      8 using namespace std::string_literals;
      9 using namespace std::string_view_literals;
     10 using namespace AppInstaller::Registry;
     11 using namespace AppInstaller::Utility;
     12 using namespace TestCommon;
     13 
     14 TEST_CASE("EmptyKey", "[registry]")
     15 {
     16     Key key;
     17     REQUIRE(!key);
     18 }
     19 
     20 TEST_CASE("Constructor_NotFound", "[registry]")
     21 {
     22     Key key;
     23     REQUIRE_THROWS_HR(key = Key(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Foo\\Bar\\Does\\Not\\Exist"), HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));
     24 }
     25 
     26 TEST_CASE("OpenIfExists_NotFound", "[registry]")
     27 {
     28     Key key = Key::OpenIfExists(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Foo\\Bar\\Does\\Not\\Exist");
     29     REQUIRE(!key);
     30 }
     31 
     32 TEST_CASE("CreateKeyAndDelete", "[registry]")
     33 {
     34     std::wstring subkey = L"Foo\\Bar";
     35     wil::unique_hkey root = RegCreateVolatileTestRoot();
     36     Key key = Key::Create(root.get(), subkey, REG_OPTION_VOLATILE);
     37     REQUIRE(key);
     38     Key::Delete(root.get(), subkey, KEY_WOW64_64KEY);
     39     Key secondKey = Key::OpenIfExists(root.get(), subkey);
     40     REQUIRE(!secondKey);
     41 }
     42 
     43 TEST_CASE("SetKeyValue", "[registry]")
     44 {
     45     std::wstring valueName = L"TestValueName";
     46     std::wstring valueValue = L"TestValueValue";
     47     std::wstring subkey = L"FooBar";
     48 
     49     wil::unique_hkey root = RegCreateVolatileTestRoot();
     50     Key key = Key::Create(root.get(), subkey, REG_OPTION_VOLATILE);
     51     key.SetValue(valueName, valueValue, REG_SZ);
     52     auto value = key[valueName];
     53     REQUIRE(value);
     54     REQUIRE(value->GetType() == Value::Type::String);
     55     REQUIRE(value->GetValue<Value::Type::String>() == ConvertToUTF8(valueValue));
     56 }
     57 
     58 TEST_CASE("EnumerateKeys", "[registry]")
     59 {
     60     wil::unique_hkey root = RegCreateVolatileTestRoot();
     61 
     62     std::vector<std::wstring> subKeyNames = { L"A", L"BEE", L"SEE", L"deigh" };
     63     for (const auto& name : subKeyNames)
     64     {
     65         RegCreateVolatileSubKey(root.get(), name);
     66     }
     67 
     68     Key key{ root.get(), L"" };
     69 
     70     for (const auto& subkey : key)
     71     {
     72         INFO(subkey.Name());
     73 
     74         std::wstring nameUtf16 = ConvertToUTF16(subkey.Name());
     75 
     76         auto itr = std::find(subKeyNames.begin(), subKeyNames.end(), nameUtf16);
     77         if (itr == subKeyNames.end())
     78         {
     79             FAIL();
     80         }
     81         else
     82         {
     83             subKeyNames.erase(itr);
     84         }
     85 
     86         Key sk = subkey.Open();
     87         REQUIRE(sk);
     88     }
     89 
     90     REQUIRE(subKeyNames.empty());
     91 }
     92 
     93 TEST_CASE("Values_String", "[registry]")
     94 {
     95     std::wstring valueName = L"TestValueName";
     96     std::wstring valueValue = L"TestValueValue";
     97 
     98     wil::unique_hkey root = RegCreateVolatileTestRoot();
     99     SetRegistryValue(root.get(), valueName, valueValue);
    100 
    101     Key key{ root.get(), L"" };
    102 
    103     auto value = key[valueName];
    104     REQUIRE(value);
    105     REQUIRE(value->GetType() == Value::Type::String);
    106     REQUIRE(value->GetValue<Value::Type::String>() == ConvertToUTF8(valueValue));
    107 }
    108 
    109 TEST_CASE("Values_WideStringWithNarrowNull", "[registry]")
    110 {
    111     std::wstring valueName = L"TestValueName";
    112     std::wstring valueValue = L"TestValueValue";
    113 
    114     wil::unique_hkey root = RegCreateVolatileTestRoot();
    115 
    116     // Copy the bytes from the string value into a byte vector
    117     std::vector<BYTE> valueBytes;
    118     valueBytes.resize((valueValue.length() + 1) * sizeof(wchar_t));
    119     memcpy_s(valueBytes.data(), valueBytes.size(), valueValue.c_str(), (valueValue.length() + 1) * sizeof(wchar_t));
    120     // Remove the last byte to make a narrow null
    121     valueBytes.resize(valueBytes.size() - 1);
    122 
    123     SetRegistryValue(root.get(), valueName, valueBytes, REG_SZ);
    124 
    125     Key key{ root.get(), L"" };
    126 
    127     auto value = key[valueName];
    128     REQUIRE(value);
    129     REQUIRE(value->GetType() == Value::Type::String);
    130     REQUIRE(value->GetValue<Value::Type::String>() == ConvertToUTF8(valueValue));
    131 }
    132 
    133 TEST_CASE("Values_ExpandString", "[registry]")
    134 {
    135     std::wstring valueName = L"TestValueName";
    136     std::wstring valueValue = L"%TEMP%";
    137 
    138     wil::unique_hkey root = RegCreateVolatileTestRoot();
    139     SetRegistryValue(root.get(), valueName, valueValue, REG_EXPAND_SZ);
    140 
    141     Key key{ root.get(), L"" };
    142 
    143     auto value = key[valueName];
    144     REQUIRE(value);
    145     REQUIRE(value->GetType() == Value::Type::ExpandString);
    146     REQUIRE(value->GetValue<Value::Type::String>() == ConvertToUTF8(valueValue));
    147 
    148     wchar_t buffer[MAX_PATH];
    149     GetTempPathW(ARRAYSIZE(buffer), buffer);
    150 
    151     std::string tempPath = ConvertToUTF8(buffer);
    152     if (!tempPath.empty() && tempPath.back() == '\\')
    153     {
    154         tempPath.resize(tempPath.size() - 1);
    155     }
    156 
    157     REQUIRE(value->GetValue<Value::Type::ExpandString>() == tempPath);
    158 }
    159 
    160 TEST_CASE("Values_Binary", "[registry]")
    161 {
    162     std::wstring valueName = L"TestValueName";
    163     std::vector<BYTE> valueValue = { 2, 7, 3, 14, 42 };
    164 
    165     wil::unique_hkey root = RegCreateVolatileTestRoot();
    166     SetRegistryValue(root.get(), valueName, valueValue);
    167 
    168     Key key{ root.get(), L"" };
    169 
    170     auto value = key[valueName];
    171     REQUIRE(value);
    172     REQUIRE(value->GetType() == Value::Type::Binary);
    173 
    174     auto result = value->GetValue<Value::Type::Binary>();
    175     REQUIRE(result.size() == valueValue.size());
    176     for (size_t i = 0; i < result.size(); ++i)
    177     {
    178         INFO(i);
    179         REQUIRE(result[i] == valueValue[i]);
    180     }
    181 }
    182 
    183 TEST_CASE("Values_DWORD", "[registry]")
    184 {
    185     std::wstring valueName = L"TestValueName";
    186     DWORD valueValue = 42;
    187 
    188     wil::unique_hkey root = RegCreateVolatileTestRoot();
    189     SetRegistryValue(root.get(), valueName, valueValue);
    190 
    191     Key key{ root.get(), L"" };
    192 
    193     auto value = key[valueName];
    194     REQUIRE(value);
    195     REQUIRE(value->GetType() == Value::Type::DWord);
    196     REQUIRE(value->GetValue<Value::Type::DWord>() == valueValue);
    197 }