// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome_elf/third_party_dlls/main.h"

#include <windows.h>

#include <string>

#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/path_service.h"
#include "base/process/launch.h"
#include "base/scoped_native_library.h"
#include "base/sha1.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/test_reg_util_win.h"
#include "base/test/test_timeouts.h"
#include "build/build_config.h"
#include "chrome/install_static/install_util.h"
#include "chrome_elf/nt_registry/nt_registry.h"
#include "chrome_elf/sha1/sha1.h"
#include "chrome_elf/third_party_dlls/hook.h"
#include "chrome_elf/third_party_dlls/main_unittest_exe.h"
#include "chrome_elf/third_party_dlls/packed_list_file.h"
#include "chrome_elf/third_party_dlls/packed_list_format.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace third_party_dlls {
namespace {

constexpr wchar_t kTestExeFilename[] = L"third_party_dlls_test_exe.exe";
constexpr wchar_t kTestBlFileName[] = L"blfile";
constexpr wchar_t kTestDllName1[] = L"main_unittest_dll_1.dll";
constexpr wchar_t kTestDllName1MixedCase[] = L"MaiN_uniTtest_dLL_1.Dll";
constexpr wchar_t kTestDllName2[] = L"main_unittest_dll_2.dll";
constexpr wchar_t kChineseUnicode[] = {0x68D5, 0x8272, 0x72D0, 0x72F8, 0x002E,
                                       0x0064, 0x006C, 0x006C, 0x0000};
constexpr wchar_t kOldBlacklistDllName[] = L"libapi2hook.dll";

struct TestModuleData {
  std::string image_name;
  std::string section_path;
  std::string section_basename;
  DWORD timedatestamp;
  DWORD imagesize;
};

// NOTE: TestTimeouts::action_max_timeout() is not long enough here.
base::TimeDelta g_timeout = ::IsDebuggerPresent()
                                ? base::TimeDelta::FromMilliseconds(INFINITE)
                                : base::TimeDelta::FromMilliseconds(5000);

// Centralize child test process control.
void LaunchChildAndWait(const base::CommandLine& command_line, int* exit_code) {
  base::Process proc =
      base::LaunchProcess(command_line, base::LaunchOptionsForTest());
  ASSERT_TRUE(proc.IsValid());

  *exit_code = 0;
  if (!proc.WaitForExitWithTimeout(g_timeout, exit_code)) {
    // Timeout while waiting.  Try to cleanup.
    proc.Terminate(1, false);
    ADD_FAILURE();
  }

  return;
}

// Given the name and path of a test DLL, mine the data of interest out of it
// and return it via |test_module|.
// - Note: the DLL must be loaded into memory by NTLoader to mine all of the
//         desired data (not just read from disk).
bool GetTestModuleData(const std::wstring& file_name,
                       const std::wstring& file_path,
                       TestModuleData* test_module) {
  base::FilePath path(file_path);
  path = path.Append(file_name);

  // Map the target DLL into memory just long enough to mine data out of it.
  base::ScopedNativeLibrary test_dll(path);
  if (!test_dll.is_valid())
    return false;

  return GetDataFromImageForTesting(
      test_dll.get(), &test_module->timedatestamp, &test_module->imagesize,
      &test_module->image_name, &test_module->section_path,
      &test_module->section_basename);
}

// Turn given data into a PackedListModule structure.
// - |image_name| should be utf-8 at this point.
PackedListModule GeneratePackedListModule(const std::string& image_name,
                                          DWORD timedatestamp,
                                          DWORD imagesize) {
  // Internally, an empty string should not be passed in here.
  assert(!image_name.empty());

  // SHA1 hash the two strings into the new struct.
  PackedListModule packed_module;
  packed_module.code_id_hash =
      elf_sha1::SHA1HashString(GetFingerprintString(timedatestamp, imagesize));
  packed_module.basename_hash = elf_sha1::SHA1HashString(image_name);

  return packed_module;
}

inline std::wstring MakePath(const std::wstring& path,
                             const std::wstring& name) {
  std::wstring full_path(path);
  full_path.push_back(L'\\');
  full_path.append(name);
  return full_path;
}

inline bool MakeFileCopy(const std::wstring& old_path,
                         const std::wstring& old_name,
                         const std::wstring& new_path,
                         const std::wstring& new_name) {
  base::FilePath source(MakePath(old_path, old_name));
  base::FilePath destination(MakePath(new_path, new_name));
  return base::CopyFileW(source, destination);
}

// Utility function for protecting local registry.
void RegRedirect(nt::ROOT_KEY key,
                 registry_util::RegistryOverrideManager* rom) {
  ASSERT_NE(key, nt::AUTO);
  HKEY root = (key == nt::HKCU ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE);
  base::string16 temp;

  ASSERT_NO_FATAL_FAILURE(rom->OverrideRegistry(root, &temp));
  ASSERT_TRUE(nt::SetTestingOverride(key, temp));
}

// Utility function to disable local registry protection.
void CancelRegRedirect(nt::ROOT_KEY key) {
  ASSERT_NE(key, nt::AUTO);
  ASSERT_TRUE(nt::SetTestingOverride(key, base::string16()));
}

// Use NtRegistry to query status codes (it's more handy than base).
// - Returns true if the key value exists and is type REG_BINARY.
bool QueryStatusCodes(std::vector<ThirdPartyStatus>* status_array) {
  HANDLE handle = nullptr;
  if (!nt::OpenRegKey(nt::HKCU,
                      install_static::GetRegistryPath()
                          .append(kThirdPartyRegKeyName)
                          .c_str(),
                      KEY_QUERY_VALUE, &handle, nullptr)) {
    return false;
  }

  ULONG type = REG_NONE;
  std::vector<uint8_t> temp_buffer;
  bool success =
      nt::QueryRegKeyValue(handle, kStatusCodesRegValue, &type, &temp_buffer);
  nt::CloseRegKey(handle);

  if (!success || type != REG_BINARY)
    return false;

  ConvertBufferToStatusCodes(temp_buffer, status_array);

  return true;
}

//------------------------------------------------------------------------------
// ThirdPartyTest class
//------------------------------------------------------------------------------

class ThirdPartyTest : public testing::Test {
 protected:
  ThirdPartyTest() = default;

  void SetUp() override {
    // Setup temp test dir.
    ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir());

    // Store full path to test file.
    base::FilePath path = scoped_temp_dir_.GetPath();
    path = path.Append(kTestBlFileName);
    bl_test_file_path_ = std::move(path.value());

    // Also store a copy of current exe directory for efficiency.
    base::FilePath exe;
    ASSERT_TRUE(base::PathService::Get(base::DIR_EXE, &exe));
    exe_dir_ = std::move(exe.value());

    // Create the blacklist file empty.
    base::File file(base::FilePath(bl_test_file_path_),
                    base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
                        base::File::FLAG_SHARE_DELETE |
                        base::File::FLAG_DELETE_ON_CLOSE);
    ASSERT_TRUE(file.IsValid());

    // Leave file handle open for DELETE_ON_CLOSE.
    bl_file_ = std::move(file);
  }

  void TearDown() override {}

  // Overwrite the content of the blacklist file.
  bool WriteModulesToBlacklist(const std::vector<PackedListModule>& list) {
    bl_file_.SetLength(0);

    // Write content {metadata}{array_of_modules}.
    PackedListMetadata meta = {kInitialVersion,
                               static_cast<uint32_t>(list.size())};

    if (bl_file_.Write(0, reinterpret_cast<const char*>(&meta), sizeof(meta)) !=
        static_cast<int>(sizeof(meta))) {
      return false;
    }
    int size = static_cast<int>(list.size() * sizeof(PackedListModule));
    if (bl_file_.Write(sizeof(PackedListMetadata),
                       reinterpret_cast<const char*>(list.data()),
                       size) != size) {
      return false;
    }

    return true;
  }

  const base::string16& GetBlTestFilePath() { return bl_test_file_path_; }
  const base::string16& GetExeDir() { return exe_dir_; }
  const std::wstring& GetScopedTempDirValue() {
    return scoped_temp_dir_.GetPath().value();
  }

 private:
  base::ScopedTempDir scoped_temp_dir_;
  base::File bl_file_;
  base::string16 bl_test_file_path_;
  base::string16 exe_dir_;

  DISALLOW_COPY_AND_ASSIGN(ThirdPartyTest);
};

//------------------------------------------------------------------------------
// Third-party tests
//
// These tests spawn a child test process to keep the hooking contained to a
// separate process.  This prevents test clashes in certain testing
// configurations.
//------------------------------------------------------------------------------

#if defined(OS_WIN)
#define MAYBE_Base DISABLED_Base
#else
#define MAYBE_Base Base
#endif
// Note: The test module used in this unittest has no export table.
TEST_F(ThirdPartyTest, MAYBE_Base) {
  // 1. Spawn the test process with NO blacklist.  Expect successful
  // initialization.
  base::CommandLine cmd_line1 = base::CommandLine::FromString(kTestExeFilename);
  cmd_line1.AppendArgNative(GetBlTestFilePath());
  cmd_line1.AppendArgNative(
      base::IntToString16(main_unittest_exe::kTestOnlyInitialization));

  int exit_code = 0;
  LaunchChildAndWait(cmd_line1, &exit_code);
  ASSERT_EQ(main_unittest_exe::kDllLoadSuccess, exit_code);

  //----------------------------------------------------------------------------
  // 2. Spawn the test process with NO blacklist.  Expect successful DLL load.
  base::CommandLine cmd_line2 = base::CommandLine::FromString(kTestExeFilename);
  cmd_line2.AppendArgNative(GetBlTestFilePath());
  cmd_line2.AppendArgNative(
      base::IntToString16(main_unittest_exe::kTestSingleDllLoad));
  cmd_line2.AppendArgNative(MakePath(GetExeDir(), kTestDllName1));

  LaunchChildAndWait(cmd_line2, &exit_code);
  ASSERT_EQ(main_unittest_exe::kDllLoadSuccess, exit_code);

  //----------------------------------------------------------------------------
  // 3. Spawn the test process with blacklist.  Expect failed DLL load.
  TestModuleData module_data = {};
  ASSERT_TRUE(GetTestModuleData(kTestDllName1, GetExeDir(), &module_data));

  // Note: image_name will be empty, as there is no export table in this test
  //       module.
  EXPECT_TRUE(module_data.image_name.empty());

  std::vector<PackedListModule> vector(1);
  vector.emplace_back(GeneratePackedListModule(module_data.section_basename,
                                               module_data.timedatestamp,
                                               module_data.imagesize));
  ASSERT_TRUE(WriteModulesToBlacklist(vector));

  base::CommandLine cmd_line3 = base::CommandLine::FromString(kTestExeFilename);
  cmd_line3.AppendArgNative(GetBlTestFilePath());
  cmd_line3.AppendArgNative(
      base::IntToString16(main_unittest_exe::kTestSingleDllLoad));
  cmd_line3.AppendArgNative(MakePath(GetExeDir(), kTestDllName1));

  LaunchChildAndWait(cmd_line3, &exit_code);
  ASSERT_EQ(main_unittest_exe::kDllLoadFailed, exit_code);

  //----------------------------------------------------------------------------
  // 4. Spawn the test process with blacklist.  Expect failed DLL load.
  //    ** Rename the module with some upper-case characters to test that
  //       the hook matching handles case properly.
  ASSERT_TRUE(MakeFileCopy(GetExeDir(), kTestDllName1, GetScopedTempDirValue(),
                           kTestDllName1MixedCase));

  // Note: the blacklist is already set from the previous test.
  // Note: using the module with no export table for this test, to ensure that
  //       the section name (the rename) is used in the comparison.

  base::CommandLine cmd_line4 = base::CommandLine::FromString(kTestExeFilename);
  cmd_line4.AppendArgNative(GetBlTestFilePath());
  cmd_line4.AppendArgNative(
      base::IntToString16(main_unittest_exe::kTestSingleDllLoad));
  cmd_line4.AppendArgNative(
      MakePath(GetScopedTempDirValue(), kTestDllName1MixedCase));

  LaunchChildAndWait(cmd_line4, &exit_code);
  ASSERT_EQ(main_unittest_exe::kDllLoadFailed, exit_code);
}

// Note: The test module used in this unittest has no export table.
TEST_F(ThirdPartyTest, WideCharEncoding) {
  // Rename module to chinese unicode (kChineseUnicode).  Be sure to handle
  // any conversions to UTF8 appropriately here.  No ASCII.
  ASSERT_TRUE(MakeFileCopy(GetExeDir(), kTestDllName1, GetScopedTempDirValue(),
                           kChineseUnicode));

  // 1) Test a successful DLL load with no blacklist.
  base::CommandLine cmd_line1 = base::CommandLine::FromString(kTestExeFilename);
  cmd_line1.AppendArgNative(GetBlTestFilePath());
  cmd_line1.AppendArgNative(
      base::IntToString16(main_unittest_exe::kTestSingleDllLoad));
  cmd_line1.AppendArgNative(MakePath(GetScopedTempDirValue(), kChineseUnicode));

  int exit_code = 0;
  LaunchChildAndWait(cmd_line1, &exit_code);
  ASSERT_EQ(main_unittest_exe::kDllLoadSuccess, exit_code);

  //----------------------------------------------------------------------------
  // 2) Test a failed DLL load with blacklist.
  TestModuleData module_data = {};
  ASSERT_TRUE(GetTestModuleData(kChineseUnicode, GetScopedTempDirValue(),
                                &module_data));

  // Note: image_name will be empty, as there is no export table in this test
  //       module.
  EXPECT_TRUE(module_data.image_name.empty());

  std::vector<PackedListModule> vector;
  vector.emplace_back(GeneratePackedListModule(module_data.section_basename,
                                               module_data.timedatestamp,
                                               module_data.imagesize));
  ASSERT_TRUE(WriteModulesToBlacklist(vector));

  base::CommandLine cmd_line2 = base::CommandLine::FromString(kTestExeFilename);
  cmd_line2.AppendArgNative(GetBlTestFilePath());
  cmd_line2.AppendArgNative(
      base::IntToString16(main_unittest_exe::kTestSingleDllLoad));
  cmd_line2.AppendArgNative(MakePath(GetScopedTempDirValue(), kChineseUnicode));

  LaunchChildAndWait(cmd_line2, &exit_code);
  ASSERT_EQ(main_unittest_exe::kDllLoadFailed, exit_code);
}

// Note: The test module used in this unittest has an export table.
TEST_F(ThirdPartyTest, WideCharEncodingWithExportDir) {
  // Rename module to chinese unicode (kChineseUnicode).  Be sure to handle
  // any conversions to UTF8 appropriately here.  No ASCII.
  ASSERT_TRUE(MakeFileCopy(GetExeDir(), kTestDllName2, GetScopedTempDirValue(),
                           kChineseUnicode));

  // 1) Test a successful DLL load with no blacklist.
  base::CommandLine cmd_line1 = base::CommandLine::FromString(kTestExeFilename);
  cmd_line1.AppendArgNative(GetBlTestFilePath());
  cmd_line1.AppendArgNative(
      base::IntToString16(main_unittest_exe::kTestSingleDllLoad));
  cmd_line1.AppendArgNative(MakePath(GetScopedTempDirValue(), kChineseUnicode));

  int exit_code = 0;
  LaunchChildAndWait(cmd_line1, &exit_code);
  ASSERT_EQ(main_unittest_exe::kDllLoadSuccess, exit_code);

  //----------------------------------------------------------------------------
  // 2) Test a failed DLL load with blacklist.
  TestModuleData module_data = {};
  ASSERT_TRUE(GetTestModuleData(kChineseUnicode, GetScopedTempDirValue(),
                                &module_data));
  // Ensure the export section was found as expected.
  EXPECT_FALSE(module_data.image_name.empty());

  // NOTE: a file rename does not affect the module name mined from the export
  //       table in the PE.  So image_name and section_basename will be
  //       different. Ensure blacklisting both section name and image name
  //       works!

  // 2a) Only blacklist the original DLL name, which should be mined out of the
  //     export table by the hook, and the load should be blocked.
  std::vector<PackedListModule> vector;
  vector.emplace_back(GeneratePackedListModule(
      base::UTF16ToASCII(kTestDllName2), module_data.timedatestamp,
      module_data.imagesize));
  ASSERT_TRUE(WriteModulesToBlacklist(vector));

  base::CommandLine cmd_line2 = base::CommandLine::FromString(kTestExeFilename);
  cmd_line2.AppendArgNative(GetBlTestFilePath());
  cmd_line2.AppendArgNative(
      base::IntToString16(main_unittest_exe::kTestSingleDllLoad));
  cmd_line2.AppendArgNative(MakePath(GetScopedTempDirValue(), kChineseUnicode));

  LaunchChildAndWait(cmd_line2, &exit_code);
  ASSERT_EQ(main_unittest_exe::kDllLoadFailed, exit_code);

  // 2b) Only blacklist the new DLL file name, which should be mined out of the
  //     section by the hook, and the load should be blocked.
  vector.clear();
  vector.emplace_back(GeneratePackedListModule(
      base::UTF16ToUTF8(kChineseUnicode), module_data.timedatestamp,
      module_data.imagesize));
  ASSERT_TRUE(WriteModulesToBlacklist(vector));

  base::CommandLine cmd_line3 = base::CommandLine::FromString(kTestExeFilename);
  cmd_line3.AppendArgNative(GetBlTestFilePath());
  cmd_line3.AppendArgNative(
      base::IntToString16(main_unittest_exe::kTestSingleDllLoad));
  cmd_line3.AppendArgNative(MakePath(GetScopedTempDirValue(), kChineseUnicode));

  LaunchChildAndWait(cmd_line3, &exit_code);
  ASSERT_EQ(main_unittest_exe::kDllLoadFailed, exit_code);
}

// Note: The test module used in this unittest has no export table.
TEST_F(ThirdPartyTest, DeprecatedBlacklistSanityCheck) {
  // Rename module to something on the old, deprecated, hard-coded blacklist.
  ASSERT_TRUE(MakeFileCopy(GetExeDir(), kTestDllName1, GetScopedTempDirValue(),
                           kOldBlacklistDllName));

  // 1) Test a failed DLL load with no blacklist (the old, hard-coded blacklist
  //    should trigger a block).
  base::CommandLine cmd_line1 = base::CommandLine::FromString(kTestExeFilename);
  cmd_line1.AppendArgNative(GetBlTestFilePath());
  cmd_line1.AppendArgNative(
      base::IntToString16(main_unittest_exe::kTestSingleDllLoad));
  cmd_line1.AppendArgNative(
      MakePath(GetScopedTempDirValue(), kOldBlacklistDllName));

  int exit_code = 0;
  LaunchChildAndWait(cmd_line1, &exit_code);
  ASSERT_EQ(main_unittest_exe::kDllLoadFailed, exit_code);
}

// Note: This test only sanity checks the two SHA1 libraries used on either side
//       of the Third-Party block.
//       This Side: chrome_elf\third_party_dlls\*,
//                  elf_sha1::SHA1HashString().
//       The Other Side: chrome\browser\conflicts\module_list_filter_win.cc,
//                       base::SHA1HashString().
TEST_F(ThirdPartyTest, SHA1SanityCheck) {
  // Rename module to chinese unicode (kChineseUnicode).  Be sure to handle
  // any conversions to UTF8 appropriately here.  No ASCII.
  ASSERT_TRUE(MakeFileCopy(GetExeDir(), kTestDllName1, GetScopedTempDirValue(),
                           kChineseUnicode));

  TestModuleData module_data = {};
  ASSERT_TRUE(GetTestModuleData(kChineseUnicode, GetScopedTempDirValue(),
                                &module_data));

  // Get hashes from elf_sha1.
  PackedListModule elf_sha1_generated = GeneratePackedListModule(
      base::UTF16ToUTF8(kChineseUnicode), module_data.timedatestamp,
      module_data.imagesize);

  // Get hashes from base_sha1.
  const std::string module_basename_hash =
      base::SHA1HashString(base::UTF16ToUTF8(kChineseUnicode));
  const std::string module_code_id_hash = base::SHA1HashString(
      GetFingerprintString(module_data.timedatestamp, module_data.imagesize));

  // Compare the hashes.
  EXPECT_EQ(::memcmp(&elf_sha1_generated.basename_hash[0],
                     module_basename_hash.data(), elf_sha1::kSHA1Length),
            0);
  EXPECT_EQ(::memcmp(&elf_sha1_generated.code_id_hash[0],
                     module_code_id_hash.data(), elf_sha1::kSHA1Length),
            0);
}

// Flaky: crbug.com/868233
#if defined(OS_WIN)
#define MAYBE_PathCaseSensitive DISABLED_PathCaseSensitive
#else
#define MAYBE_PathCaseSensitive PathCaseSensitive
#endif

// Test that full section path is left alone, in terms of case.
TEST_F(ThirdPartyTest, MAYBE_PathCaseSensitive) {
  // Rename module to have mixed case.
  ASSERT_TRUE(MakeFileCopy(GetExeDir(), kTestDllName2, GetScopedTempDirValue(),
                           kTestDllName1MixedCase));

  // 1) Sanity check that the hook GetDataFromImage() mining leaves the
  // section path alone.
  TestModuleData module_data = {};
  ASSERT_TRUE(GetTestModuleData(kTestDllName1MixedCase, GetScopedTempDirValue(),
                                &module_data));
  // Reminder: this string is actually UTF-8, but this test ensures it is ascii.
  // Also, |section_path| will be a device path, so convert to drive letter
  // before comparing.
  base::FilePath drive;
  ASSERT_TRUE(base::DevicePathToDriveLetterPath(
      base::FilePath(base::ASCIIToUTF16(module_data.section_path)), &drive));

  EXPECT_EQ(drive.value().compare(
                MakePath(GetScopedTempDirValue(), kTestDllName1MixedCase)),
            0);

  // 2) Now check an actual log.  Successful DLL load with no blacklist is fine
  //    for this test.
  base::CommandLine cmd_line1 = base::CommandLine::FromString(kTestExeFilename);
  cmd_line1.AppendArgNative(GetBlTestFilePath());
  cmd_line1.AppendArgNative(
      base::IntToString16(main_unittest_exe::kTestSingleDllLoad));
  cmd_line1.AppendArgNative(
      MakePath(GetScopedTempDirValue(), kTestDllName1MixedCase));

  int exit_code = 0;
  LaunchChildAndWait(cmd_line1, &exit_code);
  ASSERT_EQ(main_unittest_exe::kDllLoadSuccess, exit_code);
}

// Test the status-code passing in registry.
TEST_F(ThirdPartyTest, StatusCodes) {
  // 1. Enable reg override for test net.
  registry_util::RegistryOverrideManager override_manager;
  ASSERT_NO_FATAL_FAILURE(RegRedirect(nt::HKCU, &override_manager));

  // 2. Reset the registry key and value to empty.
  ASSERT_TRUE(ResetStatusCodesForTesting());

  // 3. Confirm key and empty value.
  std::vector<ThirdPartyStatus> code_array;
  EXPECT_TRUE(QueryStatusCodes(&code_array));
  EXPECT_EQ(0u, code_array.size());

  // 4. Add status codes, then verify.
  ASSERT_NO_FATAL_FAILURE(
      AddStatusCodeForTesting(ThirdPartyStatus::kFileEmpty));
  ASSERT_NO_FATAL_FAILURE(
      AddStatusCodeForTesting(ThirdPartyStatus::kLogsCreateMutexFailure));
  ASSERT_NO_FATAL_FAILURE(
      AddStatusCodeForTesting(ThirdPartyStatus::kHookVirtualProtectFailure));
  EXPECT_TRUE(QueryStatusCodes(&code_array));
  ASSERT_EQ(3u, code_array.size());
  EXPECT_EQ(ThirdPartyStatus::kFileEmpty, code_array[0]);
  EXPECT_EQ(ThirdPartyStatus::kLogsCreateMutexFailure, code_array[1]);
  EXPECT_EQ(ThirdPartyStatus::kHookVirtualProtectFailure, code_array[2]);

  // 5. Reset the registry value to empty.
  EXPECT_TRUE(ResetStatusCodesForTesting());
  EXPECT_TRUE(QueryStatusCodes(&code_array));
  EXPECT_EQ(0u, code_array.size());

  // 6. Disable reg override.
  ASSERT_NO_FATAL_FAILURE(CancelRegRedirect(nt::HKCU));
}

}  // namespace
}  // namespace third_party_dlls
