Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
RegistryProvider.cs4181 linesDownload Raw Back to namespaces
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4#if !UNIX5 6using System;7using System.Collections.ObjectModel;8using System.Globalization;9using System.Text;10using Microsoft.Win32;11using System.Management.Automation;12using System.Management.Automation.Internal;13using System.Management.Automation.Provider;14using Dbg = System.Management.Automation;15using Microsoft.PowerShell.Commands.Internal;16 17namespace Microsoft.PowerShell.Commands18{19    /// <summary>20    /// Provider that provides access to Registry through cmdlets. This provider21    /// implements <see cref="System.Management.Automation.Provider.NavigationCmdletProvider"/>,22    /// <see cref="System.Management.Automation.Provider.IPropertyCmdletProvider"/>,23    /// <see cref="System.Management.Automation.Provider.IDynamicPropertyCmdletProvider"/>,24    /// <see cref="System.Management.Automation.Provider.ISecurityDescriptorCmdletProvider"/>25    /// interfaces.26    /// </summary>27    /// <!--28    ///29    /// INSTALLATION:30    ///31    /// Type the following at a PowerShell prompt:32    ///33    /// new-PSProvider -Path "REG.cmdletprovider" -description "My registry navigation provider"34    ///35    /// TO EXERCISE THE PROVIDER:36    ///37    /// Get-PSDrive38    /// set-location HKLM:\software39    /// get-childitem40    /// New-PSDrive -PSProvider REG -name HKCR -root HKEY_CLASSES_ROOT\CLSID41    /// set-location HKCR:42    /// get-childitem "{0000*"43    ///44    /// The CmdletProvider attribute defines the name and capabilities of the provider.45    /// The first parameter is the default friendly name for the provider. The second parameter46    /// is the provider name which, along with some assembly information like version, company, etc.47    /// is used as a fully-qualified provider name which can be used for disambiguation.48    /// The third parameter states the capabilities of the provider.49    ///50    /// -->51#if CORECLR // System.Transaction namespace is not in CoreClr.52    [CmdletProvider(RegistryProvider.ProviderName, ProviderCapabilities.ShouldProcess)]53#else54    [CmdletProvider(RegistryProvider.ProviderName, ProviderCapabilities.ShouldProcess | ProviderCapabilities.Transactions)]55#endif56    [OutputType(typeof(string), ProviderCmdlet = ProviderCmdlet.MoveItemProperty)]57    [OutputType(typeof(RegistryKey), typeof(string), ProviderCmdlet = ProviderCmdlet.GetChildItem)]58    [OutputType(typeof(RegistryKey), ProviderCmdlet = ProviderCmdlet.GetItem)]59    [OutputType(typeof(System.Security.AccessControl.RegistrySecurity), ProviderCmdlet = ProviderCmdlet.GetAcl)]60    [OutputType(typeof(Microsoft.Win32.RegistryKey), ProviderCmdlet = ProviderCmdlet.GetChildItem)]61    [OutputType(typeof(RegistryKey), ProviderCmdlet = ProviderCmdlet.GetItem)]62    [OutputType(typeof(RegistryKey), typeof(string), typeof(Int32), typeof(Int64), ProviderCmdlet = ProviderCmdlet.GetItemProperty)]63    [OutputType(typeof(RegistryKey), ProviderCmdlet = ProviderCmdlet.NewItem)]64    [OutputType(typeof(string), typeof(PathInfo), ProviderCmdlet = ProviderCmdlet.ResolvePath)]65    [OutputType(typeof(PathInfo), ProviderCmdlet = ProviderCmdlet.PushLocation)]66    [OutputType(typeof(PathInfo), ProviderCmdlet = ProviderCmdlet.PopLocation)]67    public sealed partial class RegistryProvider :68        NavigationCmdletProvider,69        IPropertyCmdletProvider,70        IDynamicPropertyCmdletProvider,71        ISecurityDescriptorCmdletProvider72    {73        #region tracer74 75        /// <summary>76        /// An instance of the PSTraceSource class used for trace output77        /// using "ProviderProvider" as the category.78        /// </summary>79        [Dbg.TraceSourceAttribute(80            "RegistryProvider",81            "The namespace navigation provider for the Windows Registry")]82        private static readonly Dbg.PSTraceSource s_tracer =83            Dbg.PSTraceSource.GetTracer("RegistryProvider",84            "The namespace navigation provider for the Windows Registry");85 86        #endregion tracer87 88        /// <summary>89        /// Gets the name of the provider.90        /// </summary>91        public const string ProviderName = "Registry";92 93        #region CmdletProvider overrides94 95        /// <summary>96        /// Gets the alternate item separator character for this provider.97        /// </summary>98        public override char AltItemSeparator => ItemSeparator;99 100        #endregion101 102        #region DriveCmdletProvider overrides103 104        /// <summary>105        /// Verifies that the new drive has a valid root.106        /// </summary>107        /// <returns>A PSDriveInfo object.</returns>108        /// <!--109        /// It also givesthe provider an opportunity to return a110        /// derived class of PSDriveInfo which can contain provider specific111        /// information about the drive.This may be done for performance112        /// or reliability reasons or toprovide extra data to all calls113        /// using the drive114        /// -->115        protected override PSDriveInfo NewDrive(PSDriveInfo drive)116        {117            if (drive == null)118            {119                throw PSTraceSource.NewArgumentNullException(nameof(drive));120            }121 122            if (!ItemExists(drive.Root))123            {124                Exception e = new ArgumentException(RegistryProviderStrings.NewDriveRootDoesNotExist);125                WriteError(new ErrorRecord(126                    e,127                    e.GetType().FullName,128                    ErrorCategory.InvalidArgument,129                    drive.Root));130            }131 132            return drive;133        }134 135        /// <summary>136        /// Creates HKEY_LOCAL_MACHINE and HKEY_CURRENT_USER registry drives during provider initialization.137        /// </summary>138        /// <remarks>139        /// After the Start method is called on a provider, the InitializeDefaultDrives140        /// method is called. This is an opportunity for the provider to141        /// mount drives that are important to it. For instance, the Active Directory142        /// provider might mount a drive for the defaultNamingContext if the143        /// machine is joined to a domain.  The FileSystem mounts all drives then available.144        /// </remarks>145        protected override Collection<PSDriveInfo> InitializeDefaultDrives()146        {147            Collection<PSDriveInfo> drives = new Collection<PSDriveInfo>();148 149            drives.Add(150                new PSDriveInfo(151                    "HKLM",152                    ProviderInfo,153                    "HKEY_LOCAL_MACHINE",154                    RegistryProviderStrings.HKLMDriveDescription,155                    null));156 157            drives.Add(158                new PSDriveInfo(159                    "HKCU",160                    ProviderInfo,161                    "HKEY_CURRENT_USER",162                    RegistryProviderStrings.HKCUDriveDescription,163                    null));164 165            return drives;166        }167 168        #endregion DriveCmdletProvider overrides169 170        #region ItemCmdletProvider overrides171 172        /// <summary>173        /// Determines if the specified <paramref name="path"/> is syntactically and semantically valid.174        /// </summary>175        /// <param name="path">176        /// The path to validate.177        /// </param>178        /// <returns>179        /// True if the path is valid, or False otherwise.180        /// </returns>181        protected override bool IsValidPath(string path)182        {183            bool result = true;184 185            do // false loop186            {187                // There really aren't any illegal characters or syntactical patterns188                // to validate, so just ensure that the path starts with one of the hive roots.189 190                string root = NormalizePath(path);191                root = root.TrimStart(StringLiterals.DefaultPathSeparator);192                root = root.TrimEnd(StringLiterals.DefaultPathSeparator);193 194                int pathSeparator = root.IndexOf(StringLiterals.DefaultPathSeparator);195 196                if (pathSeparator != -1)197                {198                    root = root.Substring(0, pathSeparator);199                }200 201                if (string.IsNullOrEmpty(root))202                {203                    // An empty path means that we are at the root and should204                    // enumerate the hives. So that is a valid path.205                    result = true;206                    break;207                }208 209                if (GetHiveRoot(root) == null)210                {211                    result = false;212                }213            } while (false);214 215            return result;216        }217 218        /// <summary>219        /// Gets the RegistryKey item at the specified <paramref name="path"/>220        /// and writes it to the pipeline using the WriteObject method.221        /// Any non-terminating exceptions are written to the WriteError method.222        /// </summary>223        /// <param name="path">224        /// The path to the key to retrieve.225        /// </param>226        protected override void GetItem(string path)227        {228            // Get the registry item229 230            IRegistryWrapper result = GetRegkeyForPathWriteIfError(path, false);231 232            if (result == null)233            {234                return;235            }236 237            // Write out the result238 239            WriteRegistryItemObject(result, path);240        }241 242        /// <summary>243        /// Sets registry values at <paramref name="path "/> to the <paramref name="value"/> specified.244        /// </summary>245        /// <param name="path">246        /// The path to the item that is to be set. Only registry values can be set using247        /// this method.248        /// </param>249        /// <param name="value">250        /// The new value for the registry value.251        /// </param>252        protected override void SetItem(string path, object value)253        {254            if (string.IsNullOrEmpty(path))255            {256                throw PSTraceSource.NewArgumentException(nameof(path));257            }258 259            // Confirm the set item with the user260 261            string action = RegistryProviderStrings.SetItemAction;262 263            string resourceTemplate = RegistryProviderStrings.SetItemResourceTemplate;264 265            string resource =266                string.Format(267                    Host.CurrentCulture,268                    resourceTemplate,269                    path,270                    value);271 272            if (ShouldProcess(resource, action))273            {274                // Get the registry item275 276                IRegistryWrapper key = GetRegkeyForPathWriteIfError(path, true);277 278                if (key == null)279                {280                    return;281                }282 283                // Check to see if the type was specified by the user284 285                bool valueSet = false;286                if (DynamicParameters != null)287                {288                    RegistryProviderSetItemDynamicParameter dynParams =289                        DynamicParameters as RegistryProviderSetItemDynamicParameter;290 291                    if (dynParams != null)292                    {293                        try294                        {295                            // Convert the parameter to a RegistryValueKind296 297                            RegistryValueKind kind = dynParams.Type;298 299                            key.SetValue(null, value, kind);300                            valueSet = true;301                        }302                        catch (ArgumentException argException)303                        {304                            WriteError(new ErrorRecord(argException, argException.GetType().FullName, ErrorCategory.InvalidArgument, null));305                            key.Close();306                            return;307                        }308                        catch (System.IO.IOException ioException)309                        {310                            // An exception occurred while trying to get the key. Write311                            // out the error.312 313                            WriteError(new ErrorRecord(ioException, ioException.GetType().FullName, ErrorCategory.WriteError, path));314                            key.Close();315                            return;316                        }317                        catch (System.Security.SecurityException securityException)318                        {319                            // An exception occurred while trying to get the key. Write320                            // out the error.321 322                            WriteError(new ErrorRecord(securityException, securityException.GetType().FullName, ErrorCategory.PermissionDenied, path));323                            key.Close();324                            return;325                        }326                        catch (System.UnauthorizedAccessException unauthorizedAccessException)327                        {328                            // An exception occurred while trying to get the key. Write329                            // out the error.330                            WriteError(new ErrorRecord(unauthorizedAccessException, unauthorizedAccessException.GetType().FullName, ErrorCategory.PermissionDenied, path));331                            key.Close();332                            return;333                        }334                    }335                }336 337                if (!valueSet)338                {339                    try340                    {341                        // Set the value342                        key.SetValue(null, value);343                    }344                    catch (System.IO.IOException ioException)345                    {346                        // An exception occurred while trying to get the key. Write347                        // out the error.348 349                        WriteError(new ErrorRecord(ioException, ioException.GetType().FullName, ErrorCategory.WriteError, path));350                        key.Close();351                        return;352                    }353                    catch (System.Security.SecurityException securityException)354                    {355                        // An exception occurred while trying to get the key. Write356                        // out the error.357 358                        WriteError(new ErrorRecord(securityException, securityException.GetType().FullName, ErrorCategory.PermissionDenied, path));359                        key.Close();360                        return;361                    }362                    catch (System.UnauthorizedAccessException unauthorizedAccessException)363                    {364                        // An exception occurred while trying to get the key. Write365                        // out the error.366 367                        WriteError(new ErrorRecord(unauthorizedAccessException, unauthorizedAccessException.GetType().FullName, ErrorCategory.PermissionDenied, path));368                        key.Close();369                        return;370                    }371                }372 373                // Write out the result374                object result = value;375 376                // Since SetValue can munge the data to a specified377                // type (RegistryValueKind), retrieve the value again378                // to output it in the correct form to the user.379                result = ReadExistingKeyValue(key, null);380                key.Close();381 382                WriteItemObject(result, path, false);383            }384        }385 386        /// <summary>387        /// Gets the dynamic parameters for the SetItem method.388        /// </summary>389        /// <param name="path">390        /// Ignored.391        /// </param>392        /// <param name="value">393        /// Ignored.394        /// </param>395        /// <returns>396        /// An instance of the <see cref="Microsoft.PowerShell.Commands.RegistryProviderSetItemDynamicParameter"/> class which397        /// contains a parameter for the Type.398        /// </returns>399        protected override object SetItemDynamicParameters(string path, object value)400        {401            return new RegistryProviderSetItemDynamicParameter();402        }403 404        /// <summary>405        /// Clears the item at the specified <paramref name="path"/>.406        /// </summary>407        /// <param name="path">408        /// The path to the item that is to be cleared. Only registry values can be cleared using409        /// this method.410        /// </param>411        /// <remarks>412        /// The registry provider implements this by removing all the values for the specified key.413        /// The item that is cleared is written to the WriteObject method.414        /// If the path is to a value, then an ArgumentException is written.415        /// </remarks>416        protected override void ClearItem(string path)417        {418            if (string.IsNullOrEmpty(path))419            {420                throw PSTraceSource.NewArgumentException(nameof(path));421            }422 423            // Confirm the clear item with the user424 425            string action = RegistryProviderStrings.ClearItemAction;426 427            string resourceTemplate = RegistryProviderStrings.ClearItemResourceTemplate;428 429            string resource =430                string.Format(431                    Host.CurrentCulture,432                    resourceTemplate,433                    path);434 435            if (ShouldProcess(resource, action))436            {437                // Get the registry item438 439                IRegistryWrapper key = GetRegkeyForPathWriteIfError(path, true);440 441                if (key == null)442                {443                    return;444                }445 446                string[] valueNames;447 448                try449                {450                    // Remove each value451                    valueNames = key.GetValueNames();452                }453                catch (System.IO.IOException ioException)454                {455                    // An exception occurred while trying to get the key. Write456                    // out the error.457 458                    WriteError(new ErrorRecord(ioException, ioException.GetType().FullName, ErrorCategory.ReadError, path));459                    return;460                }461                catch (System.Security.SecurityException securityException)462                {463                    // An exception occurred while trying to get the key. Write464                    // out the error.465 466                    WriteError(new ErrorRecord(securityException, securityException.GetType().FullName, ErrorCategory.PermissionDenied, path));467                    return;468                }469                catch (System.UnauthorizedAccessException unauthorizedAccessException)470                {471                    // An exception occurred while trying to get the key. Write472                    // out the error.473 474                    WriteError(new ErrorRecord(unauthorizedAccessException, unauthorizedAccessException.GetType().FullName, ErrorCategory.PermissionDenied, path));475                    return;476                }477 478                for (int index = 0; index < valueNames.Length; ++index)479                {480                    try481                    {482                        key.DeleteValue(valueNames[index]);483                    }484                    catch (System.IO.IOException ioException)485                    {486                        // An exception occurred while trying to delete the value. Write487                        // out the error.488 489                        WriteError(new ErrorRecord(ioException, ioException.GetType().FullName, ErrorCategory.WriteError, path));490                    }491                    catch (System.Security.SecurityException securityException)492                    {493                        // An exception occurred while trying to delete the value. Write494                        // out the error.495 496                        WriteError(new ErrorRecord(securityException, securityException.GetType().FullName, ErrorCategory.PermissionDenied, path));497                    }498                    catch (System.UnauthorizedAccessException unauthorizedAccessException)499                    {500                        // An exception occurred while trying to get the key. Write501                        // out the error.502 503                        WriteError(new ErrorRecord(unauthorizedAccessException, unauthorizedAccessException.GetType().FullName, ErrorCategory.PermissionDenied, path));504                    }505                }506 507                // Write out the key508 509                WriteRegistryItemObject(key, path);510            }511        }512 513        #endregion ItemCmdletProvider overrides514 515        #region ContainerCmdletProvider overrides516 517        /// <summary>518        /// Gets all the child keys and values of the key at the specified <paramref name="path"/>.519        /// </summary>520        /// <param name="path">521        /// The path to the key to get the child keys of.522        /// </param>/523        /// <param name="recurse">524        /// Determines if the call should be recursive. If true, all subkeys of525        /// the key at the specified path will be written. If false, only the526        /// immediate children of the key at the specified path will be written.527        /// </param>528        /// <param name="depth">529        /// Current depth of recursion; special case uint.MaxValue performs full recursion.530        /// </param>531        protected override void GetChildItems(532            string path,533            bool recurse,534            uint depth)535        {536            s_tracer.WriteLine("recurse = {0}, depth = {1}", recurse, depth);537 538            if (path == null)539            {540                throw PSTraceSource.NewArgumentNullException(nameof(path));541            }542 543            if (IsHiveContainer(path))544            {545                // If the path is empty or it is / or \, return all the hives546 547                foreach (string hiveName in s_hiveNames)548                {549                    // Making sure to obey the StopProcessing.550                    if (Stopping)551                    {552                        return;553                    }554 555                    GetItem(hiveName);556                }557            }558            else559            {560                // Get the key at the specified path561 562                IRegistryWrapper key = GetRegkeyForPathWriteIfError(path, false);563 564                if (key == null)565                {566                    return;567                }568 569                try570                {571                    // Get all the subkeys of the specified path572 573                    string[] keyNames = key.GetSubKeyNames();574                    key.Close();575 576                    if (keyNames != null)577                    {578                        foreach (string subkeyName in keyNames)579                        {580                            // Making sure to obey the StopProcessing.581                            if (Stopping)582                            {583                                return;584                            }585 586                            if (!string.IsNullOrEmpty(subkeyName))587                            {588                                string keypath = path;589 590                                try591                                {592                                    // Generate the path for each key name593 594                                    keypath = MakePath(path, subkeyName, childIsLeaf: true);595 596                                    if (!string.IsNullOrEmpty(keypath))597                                    {598                                        // Call GetItem to retrieve the RegistryKey object599                                        // and write it to the WriteObject method.600 601                                        IRegistryWrapper resultKey = GetRegkeyForPath(keypath, false);602 603                                        if (resultKey != null)604                                        {605                                            WriteRegistryItemObject(resultKey, keypath);606                                        }607 608                                        // Now recurse if necessary609 610                                        if (recurse)611                                        {612                                            // Limiter for recursion613                                            if (depth > 0) // this includes special case 'depth == uint.MaxValue' for unlimited recursion614                                            {615                                                GetChildItems(keypath, recurse, depth - 1);616                                            }617                                        }618                                    }619                                }620                                catch (System.IO.IOException ioException)621                                {622                                    // An exception occurred while trying to get the key. Write623                                    // out the error.624 625                                    WriteError(new ErrorRecord(ioException, ioException.GetType().FullName, ErrorCategory.ReadError, keypath));626                                }627                                catch (System.Security.SecurityException securityException)628                                {629                                    // An exception occurred while trying to get the key. Write630                                    // out the error.631 632                                    WriteError(new ErrorRecord(securityException, securityException.GetType().FullName, ErrorCategory.PermissionDenied, keypath));633                                }634                                catch (System.UnauthorizedAccessException unauthorizedAccessException)635                                {636                                    // An exception occurred while trying to get the key. Write637                                    // out the error.638 639                                    WriteError(new ErrorRecord(unauthorizedAccessException, unauthorizedAccessException.GetType().FullName, ErrorCategory.PermissionDenied, keypath));640                                }641                            }642                        }643                    }644                }645                catch (System.IO.IOException ioException)646                {647                    // An exception occurred while trying to get the key. Write648                    // out the error.649 650                    WriteError(new ErrorRecord(ioException, ioException.GetType().FullName, ErrorCategory.ReadError, path));651                }652                catch (System.Security.SecurityException securityException)653                {654                    // An exception occurred while trying to get the key. Write655                    // out the error.656 657                    WriteError(new ErrorRecord(securityException, securityException.GetType().FullName, ErrorCategory.PermissionDenied, path));658                }659                catch (System.UnauthorizedAccessException unauthorizedAccessException)660                {661                    // An exception occurred while trying to get the key. Write662                    // out the error.663 664                    WriteError(new ErrorRecord(unauthorizedAccessException, unauthorizedAccessException.GetType().FullName, ErrorCategory.PermissionDenied, path));665                }666            }667        }668 669        /// <summary>670        /// Gets all the child key and value names of the key at the specified <paramref name="path"/>.671        /// </summary>672        /// <param name="path">673        /// The path to the key to get the child names from.674        /// </param>675        /// <param name="returnContainers">676        /// Ignored since the registry provider does not implement filtering.677        /// Normally, if this parameter is ReturnAllContainers then all subkeys should be678        /// returned. If it is false, then only those subkeys that match the679        /// filter should be returned.680        /// </param>681        protected override void GetChildNames(682            string path,683            ReturnContainers returnContainers)684        {685            if (path == null)686            {687                throw PSTraceSource.NewArgumentNullException(nameof(path));688            }689 690            if (path.Length == 0)691            {692                // If the path is empty get the names of the hives693 694                foreach (string hiveName in s_hiveNames)695                {696                    // Making sure to obey the StopProcessing.697                    if (Stopping)698                    {699                        return;700                    }701 702                    WriteItemObject(hiveName, hiveName, true);703                }704            }705            else706            {707                // Get the key at the specified path708 709                IRegistryWrapper key = GetRegkeyForPathWriteIfError(path, false);710 711                if (key == null)712                {713                    return;714                }715 716                try717                {718                    // Get the child key names719 720                    string[] results = key.GetSubKeyNames();721                    key.Close();722 723                    // Write the child key names to the WriteItemObject method724 725                    for (int index = 0; index < results.Length; ++index)726                    {727                        // Making sure to obey the StopProcessing.728                        if (Stopping)729                        {730                            return;731                        }732 733                        string childName = EscapeChildName(results[index]);734                        string childPath = MakePath(path, childName, childIsLeaf: true);735 736                        WriteItemObject(childName, childPath, true);737                    }738                }739                catch (System.IO.IOException ioException)740                {741                    // An exception occurred while trying to get the key. Write742                    // out the error.743 744                    WriteError(new ErrorRecord(ioException, ioException.GetType().FullName, ErrorCategory.ReadError, path));745                }746                catch (System.Security.SecurityException securityException)747                {748                    // An exception occurred while trying to get the key. Write749                    // out the error.750 751                    WriteError(new ErrorRecord(securityException, securityException.GetType().FullName, ErrorCategory.PermissionDenied, path));752                }753                catch (System.UnauthorizedAccessException unauthorizedAccessException)754                {755                    // An exception occurred while trying to get the key. Write756                    // out the error.757 758                    WriteError(new ErrorRecord(unauthorizedAccessException, unauthorizedAccessException.GetType().FullName, ErrorCategory.PermissionDenied, path));759                }760            }761        }762 763        private const string charactersThatNeedEscaping = ".*?[]:";764 765        /// <summary>766        /// Escapes the characters in the registry key path that are used by globbing and767        /// path.768        /// </summary>769        /// <param name="path">770        /// The path to escape.771        /// </param>772        /// <returns>773        /// The escaped path.774        /// </returns>775        /// <remarks>776        /// This method handles surrogate pairs. Please see msdn documentation777        /// </remarks>778        private static string EscapeSpecialChars(string path)779        {780            StringBuilder result = new StringBuilder();781 782            // Get the text enumerator..this will iterate through each character783            // the character can be a surrogate pair784            System.Globalization.TextElementEnumerator textEnumerator =785                System.Globalization.StringInfo.GetTextElementEnumerator(path);786 787            Dbg.Diagnostics.Assert(788                textEnumerator != null,789                string.Create(CultureInfo.CurrentCulture, $"Cannot get a text enumerator for name {path}"));790 791            while (textEnumerator.MoveNext())792            {793                // Iterate through each element and findout whether794                // any text needs escaping795                string textElement = textEnumerator.GetTextElement();796 797                // NTRAID#Windows Out of Band Releases-939036-2006/07/12-LeeHolm798                // A single character can never contain a string of799                // charactersThatNeedEscaping, so this method does nothing.  The fix800                // is to remove all calls to this escaping code, though, as this escaping801                // should not be done.802                if (textElement.Contains(charactersThatNeedEscaping))803                {804                    // This text element needs escaping805                    result.Append('`');806                }807 808                result.Append(textElement);809            }810 811            return result.ToString();812        }813 814        /// <summary>815        /// Escapes the characters in the registry key name that are used by globbing and816        /// path.817        /// </summary>818        /// <param name="name">819        /// The name to escape.820        /// </param>821        /// <returns>822        /// The escaped name.823        /// </returns>824        /// <remarks>825        /// This method handles surrogate pairs. Please see msdn documentation826        /// </remarks>827        private static string EscapeChildName(string name)828        {829            StringBuilder result = new StringBuilder();830 831            // Get the text enumerator..this will iterate through each character832            // the character can be a surrogate pair833            System.Globalization.TextElementEnumerator textEnumerator =834                System.Globalization.StringInfo.GetTextElementEnumerator(name);835 836            Dbg.Diagnostics.Assert(837                textEnumerator != null,838                string.Create(CultureInfo.CurrentCulture, $"Cannot get a text enumerator for name {name}"));839 840            while (textEnumerator.MoveNext())841            {842                // Iterate through each element and findout whether843                // any text needs escaping844                string textElement = textEnumerator.GetTextElement();845 846                // NTRAID#Windows Out of Band Releases-939036-2006/07/12-LeeHolm847                // A single character can never contain a string of848                // charactersThatNeedEscaping, so this method does nothing.  The fix849                // is to remove all calls to this escaping code, though, as this escaping850                // should not be done.851                if (textElement.Contains(charactersThatNeedEscaping))852                {853                    // This text element needs escaping854                    result.Append('`');855                }856 857                result.Append(textElement);858            }859 860            return result.ToString();861        }862 863        /// <summary>864        /// Renames the key at the specified <paramref name="path"/> to <paramref name="newName"/>.865        /// </summary>866        /// <param name="path">867        /// The path to the key to rename.868        /// </param>869        /// <param name="newName">870        /// The new name of the key.871        /// </param>872        protected override void RenameItem(873            string path,874            string newName)875        {876            if (string.IsNullOrEmpty(path))877            {878                throw PSTraceSource.NewArgumentException(nameof(path));879            }880 881            if (string.IsNullOrEmpty(newName))882            {883                throw PSTraceSource.NewArgumentException(nameof(newName));884            }885 886            s_tracer.WriteLine("newName = {0}", newName);887 888            string parentPath = GetParentPath(path, null);889            string newPath = MakePath(parentPath, newName);890 891            // Make sure we aren't going to overwrite an existing item892 893            bool exists = ItemExists(newPath);894 895            if (exists)896            {897                Exception e = new ArgumentException(RegistryProviderStrings.RenameItemAlreadyExists);898                WriteError(new ErrorRecord(899                    e,900                    e.GetType().FullName,901                    ErrorCategory.InvalidArgument,902                    newPath));903 904                return;905            }906            // Confirm the rename item with the user907 908            string action = RegistryProviderStrings.RenameItemAction;909 910            string resourceTemplate = RegistryProviderStrings.RenameItemResourceTemplate;911 912            string resource =913                string.Format(914                    Host.CurrentCulture,915                    resourceTemplate,916                    path,917                    newPath);918 919            if (ShouldProcess(resource, action))920            {921                // Implement rename as a move operation922 923                MoveRegistryItem(path, newPath);924            }925        }926 927        /// <summary>928        /// Creates a new registry key or value at the specified <paramref name="path"/>.929        /// </summary>930        /// <param name="path">931        /// The path to the new key to create.932        /// </param>933        /// <param name="type">934        /// The type is ignored because this provider only creates935        /// registry keys.936        /// </param>937        /// <param name="newItem">938        /// The newItem is ignored because the provider creates the939        /// key based on the path.940        /// </param>941        protected override void NewItem(942            string path,943            string type,944            object newItem)945        {946            if (string.IsNullOrEmpty(path))947            {948                throw PSTraceSource.NewArgumentException(nameof(path));949            }950 951            // Confirm the new item with the user952 953            string action = RegistryProviderStrings.NewItemAction;954 955            string resourceTemplate = RegistryProviderStrings.NewItemResourceTemplate;956 957            string resource =958                string.Format(959                    Host.CurrentCulture,960                    resourceTemplate,961                    path);962            if (ShouldProcess(resource, action))963            {964                // Check to see if the key already exists965                IRegistryWrapper resultKey = GetRegkeyForPath(path, false);966 967                if (resultKey != null)968                {969                    if (!Force)970                    {971                        Exception e = new System.IO.IOException(RegistryProviderStrings.KeyAlreadyExists);972                        WriteError(new ErrorRecord(973                            e,974                            e.GetType().FullName,975                            ErrorCategory.ResourceExists,976                            resultKey));977 978                        resultKey.Close();979                        return;980                    }981                    else982                    {983                        // Remove the existing key before creating the new one984                        resultKey.Close();985                        RemoveItem(path, false);986                    }987                }988 989                if (Force)990                {991                    if (!CreateIntermediateKeys(path))992                    {993                        // We are unable to create Intermediate keys. Just return.994                        return;995                    }996                }997 998                // Get the parent and child portions of the path999 1000                string parentPath = GetParentPath(path, null);1001                string childName = GetChildName(path);1002 1003                // Get the key at the specified path1004                IRegistryWrapper key = GetRegkeyForPathWriteIfError(parentPath, true);1005 1006                if (key == null)1007                {1008                    return;1009                }1010 1011                try1012                {1013                    // Create the new subkey1014                    IRegistryWrapper newKey = key.CreateSubKey(childName);1015                    key.Close();1016 1017                    try1018                    {1019                        // Set the default key value if the value and type were specified1020 1021                        if (newItem != null)1022                        {1023                            RegistryValueKind kind;1024                            if (!ParseKind(type, out kind))1025                            {1026                                return;1027                            }1028 1029                            SetRegistryValue(newKey, string.Empty, newItem, kind, path, false);1030                        }1031                    }1032                    catch (Exception exception)1033                    {1034                        // The key has been created, but the default value failed to be set.1035                        // If possible, just write an error instead of failing the entire operation.1036 1037                        if ((exception is ArgumentException) ||1038                            (exception is InvalidCastException) ||1039                            (exception is System.IO.IOException) ||1040                            (exception is System.Security.SecurityException) ||1041                            (exception is System.UnauthorizedAccessException) ||1042                            (exception is NotSupportedException))1043                        {1044                            ErrorRecord rec = new ErrorRecord(1045                                exception,1046                                exception.GetType().FullName,1047                                ErrorCategory.WriteError,1048                                newKey);1049                            rec.ErrorDetails = new ErrorDetails(StringUtil.Format(RegistryProviderStrings.KeyCreatedValueFailed, childName));1050                            WriteError(rec);1051                        }1052                        else1053                            throw;1054                    }1055 1056                    // Write the new key out.1057                    WriteRegistryItemObject(newKey, path);1058                }1059                catch (System.IO.IOException ioException)1060                {1061                    // An exception occurred while trying to get the key. Write1062                    // out the error.1063 1064                    WriteError(new ErrorRecord(ioException, ioException.GetType().FullName, ErrorCategory.WriteError, path));1065                }1066                catch (System.Security.SecurityException securityException)1067                {1068                    // An exception occurred while trying to get the key. Write1069                    // out the error.1070 1071                    WriteError(new ErrorRecord(securityException, securityException.GetType().FullName, ErrorCategory.PermissionDenied, path));1072                }1073                catch (System.UnauthorizedAccessException unauthorizedAccessException)1074                {1075                    // An exception occurred while trying to get the key. Write1076                    // out the error.1077 1078                    WriteError(new ErrorRecord(unauthorizedAccessException, unauthorizedAccessException.GetType().FullName, ErrorCategory.PermissionDenied, path));1079                }1080                catch (ArgumentException argException)1081                {1082                    WriteError(new ErrorRecord(argException, argException.GetType().FullName, ErrorCategory.InvalidArgument, path));1083                }1084                catch (NotSupportedException notSupportedException)1085                {1086                    WriteError(new ErrorRecord(notSupportedException, notSupportedException.GetType().FullName, ErrorCategory.InvalidOperation, path));1087                }1088            }1089        }1090 1091        /// <summary>1092        /// Removes the specified registry key and all sub-keys.1093        /// </summary>1094        /// <param name="path">1095        /// The path to the key to remove.1096        /// </param>1097        /// <param name="recurse">1098        /// Ignored. All removes are recursive because the1099        /// registry provider does not support filters.1100        /// </param>1101        protected override void RemoveItem(1102            string path,1103            bool recurse)1104        {1105            if (string.IsNullOrEmpty(path))1106            {1107                throw PSTraceSource.NewArgumentException(nameof(path));1108            }1109 1110            s_tracer.WriteLine("recurse = {0}", recurse);1111 1112            // Get the parent and child portions of the path1113 1114            string parentPath = GetParentPath(path, null);1115            string childName = GetChildName(path);1116 1117            // Get the parent key1118 1119            IRegistryWrapper key = GetRegkeyForPathWriteIfError(parentPath, true);1120 1121            if (key == null)1122            {1123                return;1124            }1125 1126            // Confirm the remove item with the user1127 1128            string action = RegistryProviderStrings.RemoveKeyAction;1129 1130            string resourceTemplate = RegistryProviderStrings.RemoveKeyResourceTemplate;1131 1132            string resource =1133                    string.Format(1134                        Host.CurrentCulture,1135                        resourceTemplate,1136                        path);1137 1138            if (ShouldProcess(resource, action))1139            {1140                try1141                {1142                    key.DeleteSubKeyTree(childName);1143                }1144                catch (ArgumentException argumentException)1145                {1146                    WriteError(new ErrorRecord(argumentException, argumentException.GetType().FullName, ErrorCategory.WriteError, path));1147                }1148                catch (System.IO.IOException ioException)1149                {1150                    // An exception occurred while trying to get the key. Write1151                    // out the error.1152 1153                    WriteError(new ErrorRecord(ioException, ioException.GetType().FullName, ErrorCategory.WriteError, path));1154                }1155                catch (System.Security.SecurityException securityException)1156                {1157                    // An exception occurred while trying to get the key. Write1158                    // out the error.1159 1160                    WriteError(new ErrorRecord(securityException, securityException.GetType().FullName, ErrorCategory.PermissionDenied, path));1161                }1162                catch (System.UnauthorizedAccessException unauthorizedAccessException)1163                {1164                    // An exception occurred while trying to get the key. Write1165                    // out the error.1166 1167                    WriteError(new ErrorRecord(unauthorizedAccessException, unauthorizedAccessException.GetType().FullName, ErrorCategory.PermissionDenied, path));1168                }1169                catch (NotSupportedException notSupportedException)1170                {1171                    WriteError(new ErrorRecord(notSupportedException, notSupportedException.GetType().FullName, ErrorCategory.InvalidOperation, path));1172                }1173            }1174 1175            key.Close();1176        }1177 1178        /// <summary>1179        /// Determines if the key at the specified path exists.1180        /// </summary>1181        /// <param name="path">1182        /// The path to the key to determine if it exists.1183        /// </param>1184        /// <returns>1185        /// True if the key at the specified path exists, false otherwise.1186        /// </returns>1187        protected override bool ItemExists(string path)1188        {1189            bool result = false;1190 1191            if (path == null)1192            {1193                throw PSTraceSource.NewArgumentNullException(nameof(path));1194            }1195 1196            try1197            {1198                if (IsHiveContainer(path))1199                {1200                    // an empty path, \ or / are valid because

Showing the first 1,200 of 4181 lines. Download the file for the rest.