// Copyright 2026 sjackson0109 — Apache License 2.0
using Microsoft.Win32;
namespace RDPWrap.Common;
///
/// Thin wrappers around that mirror the
/// Delphi TRegistry usage in RDPWInst and RDPConf, with optional WOW64 flag
/// support (KEY_WOW64_64KEY) for 64-bit registry views from 32-bit processes.
///
public static class RegistryHelper
{
// On 64-bit Windows we always open the 64-bit view to match the Delphi code
// that passes KEY_WOW64_64KEY when Arch = 64.
private static RegistryView ViewForArch() =>
ArchHelper.Is64Bit ? RegistryView.Registry64 : RegistryView.Default;
// ── Convenience open helpers ──────────────────────────────────────────────
/// Opens a read-only key under HKLM, respecting the host architecture.
public static RegistryKey? OpenHklmRead(string subKey)
{
using var hive = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, ViewForArch());
return hive.OpenSubKey(subKey, writable: false);
}
/// Opens a writable key under HKLM (creates if absent).
public static RegistryKey OpenHklmWrite(string subKey)
{
using var hive = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, ViewForArch());
return hive.CreateSubKey(subKey, writable: true)
?? throw new InvalidOperationException($"Cannot open/create HKLM\\{subKey}");
}
// ── Typed read helpers ────────────────────────────────────────────────────
///
/// Reads a string value from HKLM. Returns null if the key or
/// value does not exist.
///
public static string? ReadString(string subKey, string valueName)
{
using var key = OpenHklmRead(subKey);
return key?.GetValue(valueName) as string;
}
///
/// Reads a DWORD value from HKLM. Returns
/// if the key or value does not exist.
///
public static int ReadInt(string subKey, string valueName, int defaultValue = 0)
{
using var key = OpenHklmRead(subKey);
if (key is null) return defaultValue;
var raw = key.GetValue(valueName);
return raw is int i ? i : defaultValue;
}
///
/// Reads a DWORD as a bool (non-zero = true). Returns
/// if absent.
///
public static bool ReadBool(string subKey, string valueName, bool defaultValue = false)
{
using var key = OpenHklmRead(subKey);
if (key is null) return defaultValue;
var raw = key.GetValue(valueName);
return raw is int i ? i != 0 : defaultValue;
}
// ── Typed write helpers ───────────────────────────────────────────────────
/// Writes a REG_SZ string value.
public static void WriteString(string subKey, string valueName, string value)
{
using var key = OpenHklmWrite(subKey);
key.SetValue(valueName, value, RegistryValueKind.String);
}
/// Writes a REG_EXPAND_SZ string value (mirrors Delphi WriteExpandString).
public static void WriteExpandString(string subKey, string valueName, string value)
{
using var key = OpenHklmWrite(subKey);
key.SetValue(valueName, value, RegistryValueKind.ExpandString);
}
/// Writes a DWORD integer value.
public static void WriteInt(string subKey, string valueName, int value)
{
using var key = OpenHklmWrite(subKey);
key.SetValue(valueName, value, RegistryValueKind.DWord);
}
/// Writes a boolean as a DWORD (1/0).
public static void WriteBool(string subKey, string valueName, bool value)
=> WriteInt(subKey, valueName, value ? 1 : 0);
}