// Copyright (c) Microsoft Corporation // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using Microsoft.CmdPal.Ext.Registry.Constants; namespace Microsoft.CmdPal.Ext.Registry.Helpers; /// /// Helper class to easier work with queries /// internal static partial class QueryHelper { /// /// The character to distinguish if the search query contain multiple parts (typically "\\") /// internal const string QuerySplitCharacter = "\\\\"; /// /// A list that contain short names of all registry base keys /// private static readonly IReadOnlyDictionary _shortBaseKeys = new Dictionary(6) { { Win32.Registry.ClassesRoot.Name, KeyName.ClassRootShort }, { Win32.Registry.CurrentConfig.Name, KeyName.CurrentConfigShort }, { Win32.Registry.CurrentUser.Name, KeyName.CurrentUserShort }, { Win32.Registry.LocalMachine.Name, KeyName.LocalMachineShort }, { Win32.Registry.PerformanceData.Name, KeyName.PerformanceDataShort }, { Win32.Registry.Users.Name, KeyName.UsersShort }, }; [GeneratedRegex(@"/(?<=^(?:[^""]*""[^""]*"")*[^""]*)(? /// Sanitize the query to avoid issues with the regex /// /// Query containing front-slash /// A string replacing all the front-slashes with back-slashes private static string SanitizeQuery(in string query) { var sanitizedQuery = FrontToBackSlashRegex().Replace(query, "\\"); return sanitizedQuery.Replace("\"", string.Empty); } /// /// Return the parts of a given query /// /// The query that could contain parts /// The key part of the query /// The value name part of the query /// when the query search for a key and a value name, otherwise internal static bool GetQueryParts(in string query, out string queryKey, out string queryValueName) { var sanitizedQuery = SanitizeQuery(query); if (!sanitizedQuery.Contains(QuerySplitCharacter, StringComparison.InvariantCultureIgnoreCase)) { queryKey = sanitizedQuery; queryValueName = string.Empty; return false; } var querySplit = sanitizedQuery.Split(QuerySplitCharacter); queryKey = querySplit.First(); queryValueName = querySplit.Last(); return true; } /// /// Return a registry key with a long base key /// /// A registry key with a short base key /// A registry key with a long base key internal static string GetKeyWithLongBaseKey(in string registryKey) { foreach (var shortName in _shortBaseKeys) { if (!registryKey.StartsWith(shortName.Value, StringComparison.InvariantCultureIgnoreCase)) { continue; } return registryKey.Replace(shortName.Value, shortName.Key, StringComparison.InvariantCultureIgnoreCase); } return registryKey; } /// /// Return a registry key with a short base key (useful to reduce the text length of a registry key) /// /// A registry key with a full base key /// A registry key with a short base key internal static string GetKeyWithShortBaseKey(in string registryKey) { foreach (var shortName in _shortBaseKeys) { if (!registryKey.StartsWith(shortName.Key, StringComparison.InvariantCultureIgnoreCase)) { continue; } return registryKey.Replace(shortName.Key, shortName.Value, StringComparison.InvariantCultureIgnoreCase); } return registryKey; } }