GpoValueChecker.cs
1 // Copyright (c) Microsoft Corporation 2 // The Microsoft Corporation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using Microsoft.Win32; 6 7 namespace Microsoft.CmdPal.UI.Helpers; 8 9 internal enum GpoRuleConfiguredValue 10 { 11 WrongValue = -3, 12 Unavailable = -2, 13 NotConfigured = -1, 14 Disabled = 0, 15 Enabled = 1, 16 } 17 18 /* 19 * Contains methods extracted from PowerToys gpo.h 20 * The idea is to keep CmdPal codebase take as little dependences on the PowerToys codebase as possible. 21 * Having this class to check GPO being contained in CmdPal means we don't need to depend on GPOWrapper. 22 */ 23 internal static class GpoValueChecker 24 { 25 private const string PoliciesPath = @"SOFTWARE\Policies\PowerToys"; 26 private static readonly RegistryKey PoliciesScopeMachine = Registry.LocalMachine; 27 private static readonly RegistryKey PoliciesScopeUser = Registry.CurrentUser; 28 private const string PolicyConfigureEnabledCmdPal = @"ConfigureEnabledUtilityCmdPal"; 29 private const string PolicyConfigureEnabledGlobalAllUtilities = @"ConfigureGlobalUtilityEnabledState"; 30 31 private static GpoRuleConfiguredValue GetConfiguredValue(string registryValueName) 32 { 33 // For GPO policies, machine scope should take precedence over user scope 34 var value = ReadRegistryValue(PoliciesScopeMachine, PoliciesPath, registryValueName); 35 36 if (!value.HasValue) 37 { 38 // If not found in machine scope, check user scope 39 value = ReadRegistryValue(PoliciesScopeUser, PoliciesPath, registryValueName); 40 if (!value.HasValue) 41 { 42 return GpoRuleConfiguredValue.NotConfigured; 43 } 44 } 45 46 return value switch 47 { 48 0 => GpoRuleConfiguredValue.Disabled, 49 1 => GpoRuleConfiguredValue.Enabled, 50 _ => GpoRuleConfiguredValue.WrongValue, 51 }; 52 } 53 54 // Reads an integer registry value if it exists. 55 private static int? ReadRegistryValue(RegistryKey rootKey, string subKeyPath, string valueName) 56 { 57 using (RegistryKey? key = rootKey.OpenSubKey(subKeyPath, false)) 58 { 59 if (key is null) 60 { 61 return null; 62 } 63 64 var value = key.GetValue(valueName); 65 if (value is int intValue) 66 { 67 return intValue; 68 } 69 70 return null; 71 } 72 } 73 74 private static GpoRuleConfiguredValue GetUtilityEnabledValue(string utilityName) 75 { 76 var individualValue = GetConfiguredValue(utilityName); 77 78 if (individualValue == GpoRuleConfiguredValue.Disabled || individualValue == GpoRuleConfiguredValue.Enabled) 79 { 80 return individualValue; 81 } 82 else 83 { 84 // If the individual utility value is not set, check the global all utilities policy value. 85 return GetConfiguredValue(PolicyConfigureEnabledGlobalAllUtilities); 86 } 87 } 88 89 internal static GpoRuleConfiguredValue GetConfiguredCmdPalEnabledValue() 90 { 91 return GetUtilityEnabledValue(PolicyConfigureEnabledCmdPal); 92 } 93 }