// Copyright Epic Games, Inc. All Rights Reserved. using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Runtime.Versioning; using Microsoft.Extensions.Configuration; using Microsoft.Win32; namespace EpicGames.Core { /// /// Configuration source which reads values from the Registry on Windows /// [SupportedOSPlatform("windows")] public class RegistryConfigurationSource : IConfigurationSource { readonly RegistryKey _baseKey; readonly string _keyPath; readonly string _baseConfigName; readonly Func? _filter; /// /// Constructor /// /// Hive to resolve keyPath relative to /// Path within the registry to enumerate /// Prefix for returned configuration values /// Optional filter for keys to include public RegistryConfigurationSource(RegistryKey baseKey, string keyPath, string baseConfigName, Func? filter = null) { _baseKey = baseKey; _keyPath = keyPath; _baseConfigName = baseConfigName; _filter = filter; } /// /// Get the registry key used /// /// public string GetRegistryKey() => _baseKey + "\\" + _keyPath; /// public IConfigurationProvider Build(IConfigurationBuilder builder) => new RegistryConfigProvider(_baseKey, _keyPath, _baseConfigName, _filter); } class RegistryConfigProvider : ConfigurationProvider { readonly RegistryKey _baseKey; readonly string _keyPath; readonly string _baseConfigName; readonly Func? _filter; public RegistryConfigProvider(RegistryKey baseKey, string keyPath, string baseConfigName, Func? filter) { _baseKey = baseKey; _keyPath = keyPath; _baseConfigName = baseConfigName; _filter = filter; } public override void Load() { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { Dictionary data = []; GetValues(_baseKey, _keyPath, _baseConfigName, _filter, data); Data = data; } } [SupportedOSPlatform("windows")] static void GetValues(RegistryKey baseKey, string keyPath, string baseConfigName, Func? filter, Dictionary data) { using RegistryKey? registryKey = baseKey.OpenSubKey(keyPath); if (registryKey != null) { string[] subKeyNames = registryKey.GetSubKeyNames(); foreach (string subKeyName in subKeyNames) { GetValues(registryKey, subKeyName, $"{baseConfigName}:{subKeyName}", filter, data); } string[] valueNames = registryKey.GetValueNames(); foreach (string valueName in valueNames) { object? value = registryKey.GetValue(valueName); if (value != null) { string name = $"{baseConfigName}:{valueName}"; if (filter == null || filter(name)) { data[name] = value.ToString(); } } } } } } }