Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes308downloads
DataStoreAdapter.cs833 linesDownload Raw Back to engine
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4#pragma warning disable 1634, 16915 6using System.Threading;7using Dbg = System.Management.Automation;8 9namespace System.Management.Automation10{11    /// <summary>12    /// Defines a drive that exposes a provider path to the user.13    /// </summary>14    /// <remarks>15    /// A cmdlet provider may want to derive from this class to provide their16    /// own public members or to cache information related to the drive. For instance,17    /// if a drive is a connection to a remote machine and making that connection18    /// is expensive, then the provider may want keep a handle to the connection as19    /// a member of their derived <see cref="PSDriveInfo"/> class and use it when20    /// the provider is invoked.21    /// </remarks>22    public class PSDriveInfo : IComparable23    {24        /// <summary>25        /// An instance of the PSTraceSource class used for trace output26        /// using "SessionState" as the category.27        /// This is the same category as the SessionState tracer class.28        /// </summary>29        [Dbg.TraceSource(30             "PSDriveInfo",31             "The namespace navigation tracer")]32        private static readonly Dbg.PSTraceSource s_tracer =33            Dbg.PSTraceSource.GetTracer("PSDriveInfo",34             "The namespace navigation tracer");35 36        /// <summary>37        /// Gets or sets the current working directory for the drive.38        /// </summary>39        public string CurrentLocation40        {41            get42            {43                return _currentWorkingDirectory;44            }45 46            set47            {48                _currentWorkingDirectory = value;49            }50        }51 52        /// <summary>53        /// The current working directory for the virtual drive54        /// as a relative path from Root.55        /// </summary>56        private string _currentWorkingDirectory;57 58        /// <summary>59        /// Gets the name of the drive.60        /// </summary>61        public string Name62        {63            get64            {65                return _name;66            }67        }68 69        /// <summary>70        /// The name of the virtual drive.71        /// </summary>72        private string _name;73 74        /// <summary>75        /// Gets the name of the provider that root path76        /// of the drive represents.77        /// </summary>78        public ProviderInfo Provider79        {80            get81            {82                return _provider;83            }84        }85 86        /// <summary>87        /// The provider information for the provider that implements88        /// the functionality for the drive.89        /// </summary>90        private ProviderInfo _provider;91 92        /// <summary>93        /// Gets the root path of the drive.94        /// </summary>95        public string Root96        {97            get98            {99                return _root;100            }101 102            internal set103            {104                _root = value;105            }106        }107 108        /// <summary>109        /// Sets the root of the drive.110        /// </summary>111        /// <param name="path">112        /// The root path to set for the drive.113        /// </param>114        /// <remarks>115        /// This method can only be called during drive116        /// creation. A NotSupportedException if this method117        /// is called outside of drive creation.118        /// </remarks>119        /// <exception cref="ArgumentNullException">120        /// If <paramref name="path"/> is null.121        /// </exception>122        /// <exception cref="NotSupportedException">123        /// If this method gets called any other time except124        /// during drive creation.125        /// </exception>126        internal void SetRoot(string path)127        {128            if (path == null)129            {130                throw PSTraceSource.NewArgumentNullException(nameof(path));131            }132 133            if (!DriveBeingCreated)134            {135                NotSupportedException e =136                    PSTraceSource.NewNotSupportedException();137                throw e;138            }139 140            _root = path;141        }142 143        /// <summary>144        /// The root of the virtual drive.145        /// </summary>146        private string _root;147 148        /// <summary>149        /// Gets or sets the description for the drive.150        /// </summary>151        public string Description { get; set; }152 153        /// <summary>154        /// When supported by provider this specifies a maximum drive size.155        /// </summary>156        public long? MaximumSize { get; internal set; }157 158        /// <summary>159        /// Gets the credential to use with the drive.160        /// </summary>161        public PSCredential Credential { get; } = PSCredential.Empty;162 163        /// <summary>164        /// Determines if the root of the drive can165        /// be modified during drive creation through166        /// the SetRoot method.167        /// </summary>168        /// <value>169        /// True if the drive is being created and the170        /// root can be modified through the SetRoot method.171        /// False otherwise.172        /// </value>173        internal bool DriveBeingCreated { get; set; }174 175        /// <summary>176        /// True if the drive was automounted by the system,177        /// false otherwise.178        /// </summary>179        /// <value></value>180        internal bool IsAutoMounted { get; set; }181 182        /// <summary>183        /// True if the drive was automounted by the system,184        /// and then manually removed by the user.185        /// </summary>186        internal bool IsAutoMountedManuallyRemoved { get; set; }187 188        /// <summary>189        /// Gets or sets the Persist Switch parameter.190        /// If this switch parameter is set then the created PSDrive191        /// would be persisted across PowerShell sessions.192        /// </summary>193        internal bool Persist { get; } = false;194 195        /// <summary>196        /// Get or sets the value indicating if the created drive is a network drive.197        /// </summary>198        internal bool IsNetworkDrive { get; set; } = false;199 200        /// <summary>201        /// Gets or sets the UNC path of the drive. This property would be populated only202        /// if the created PSDrive is targeting a network drive or else this property203        /// would be null.204        /// </summary>205        public string DisplayRoot { get; internal set; } = null;206 207        /// <summary>208        /// Gets or sets if the drive-root relative paths on this drive are separated by a209        /// colon or not.210        ///211        /// This is true for all PSDrives on all platforms, except for filesystems on212        /// non-Windows platforms.213        ///214        /// This is not a path separator in the sense of separating paths in a single215        /// string.216        ///217        /// The biggest difference in filesystem handling between PS internally, and Unix218        /// style systems is, that paths on Windows separate the drive letter from the219        /// actual path by a colon. The second difference is, that a path that starts with220        /// a \ or / on Windows is considered to be a relative path (drive-relative in221        /// that case) where a similar path on a Unix style filesystem would be222        /// root-relative, which is basically drive-relative for the filesystem, as there223        /// is only one filesystem drive.224        ///225        /// This property indicates, that a path can be checked for that drive-relativity226        /// by checking for a colon. The main reason for this can be seen in all the227        /// places that use this property, where PowerShell's code checks/splits/string228        /// manipulates paths according to the colon character. This happens in many229        /// places.230        ///231        /// The idea here was to introduce a property that allows a code to query if a232        /// PSDrive expects colon to be such a separator or not. I talked to Jim back then233        /// about the problem, and this seemed to be a reasonable solution, given that234        /// there is no other way to know for a PSDrive if paths can be qualified only in235        /// a certain windows way on all platforms, or need special treatment on platforms236        /// where colon does not exist as drive separator (regular filesystems on Unix237        /// platforms are the only exception).238        ///239        /// Globally this property can also be only true for one single PSDrive, because240        /// if there is no drive separator, there is also no drive, and because there is241        /// no drive there is no way to match against multiple such drives.242        ///243        /// Additional data:244        /// It seems that on single rooted filesystems, only the default245        /// drive of "/" needs to set this VolumeSeparatedByColon to false246        /// otherwise, creating new drives from the filesystem should actually247        /// have this set to true as all the drives will have <string>: except248        /// for "/"249        /// </summary>250        public bool VolumeSeparatedByColon { get; internal set; } = true;251 252        #region ctor253 254        /// <summary>255        /// Constructs a new instance of the PSDriveInfo using another PSDriveInfo256        /// as a template.257        /// </summary>258        /// <param name="driveInfo">259        /// An existing PSDriveInfo object that should be copied to this instance.260        /// </param>261        /// <remarks>262        /// A protected constructor that derived classes can call with an instance263        /// of this class. This allows for easy creation of derived PSDriveInfo objects264        /// which can be created in CmdletProvider's NewDrive method using the PSDriveInfo265        /// that is passed in.266        /// </remarks>267        /// <exception cref="ArgumentNullException">268        /// If <paramref name="PSDriveInfo"/> is null.269        /// </exception>270        protected PSDriveInfo(PSDriveInfo driveInfo)271        {272            if (driveInfo == null)273            {274                throw PSTraceSource.NewArgumentNullException(nameof(driveInfo));275            }276 277            _name = driveInfo.Name;278            _provider = driveInfo.Provider;279            Credential = driveInfo.Credential;280            _currentWorkingDirectory = driveInfo.CurrentLocation;281            Description = driveInfo.Description;282            this.MaximumSize = driveInfo.MaximumSize;283            DriveBeingCreated = driveInfo.DriveBeingCreated;284            _hidden = driveInfo._hidden;285            IsAutoMounted = driveInfo.IsAutoMounted;286            _root = driveInfo._root;287            Persist = driveInfo.Persist;288            this.Trace();289        }290 291        /// <summary>292        /// Constructs a drive that maps a PowerShell Path in293        /// the shell to a Cmdlet Provider.294        /// </summary>295        /// <param name="name">296        /// The name of the drive.297        /// </param>298        /// <param name="provider">299        /// The name of the provider which implements the functionality300        /// for the root path of the drive.301        /// </param>302        /// <param name="root">303        /// The root path of the drive. For example, the root of a304        /// drive in the file system can be c:\windows\system32305        /// </param>306        /// <param name="description">307        /// The description for the drive.308        /// </param>309        /// <param name="credential">310        /// The credentials under which all operations on the drive should occur.311        /// If null, the current user credential is used.312        /// </param>313        /// <throws>314        /// ArgumentNullException - if <paramref name="name"/>,315        /// <paramref name="provider"/>, or <paramref name="root"/>316        /// is null.317        /// </throws>318        public PSDriveInfo(319            string name,320            ProviderInfo provider,321            string root,322            string description,323            PSCredential credential)324        {325            // Verify the parameters326 327            if (name == null)328            {329                throw PSTraceSource.NewArgumentNullException(nameof(name));330            }331 332            if (provider == null)333            {334                throw PSTraceSource.NewArgumentNullException(nameof(provider));335            }336 337            if (root == null)338            {339                throw PSTraceSource.NewArgumentNullException(nameof(root));340            }341 342            // Copy the parameters to the local members343 344            _name = name;345            _provider = provider;346            _root = root;347            Description = description;348 349            if (credential != null)350            {351                Credential = credential;352            }353 354            // Set the current working directory to the empty355            // string since it is relative to the root.356 357            _currentWorkingDirectory = string.Empty;358 359            Dbg.Diagnostics.Assert(360                _currentWorkingDirectory != null,361                "The currentWorkingDirectory cannot be null");362 363            // Trace out the fields364 365            this.Trace();366        }367 368        /// <summary>369        /// Constructs a drive that maps a PowerShell Path in370        /// the shell to a Cmdlet Provider.371        /// </summary>372        /// <param name="name">373        /// The name of the drive.374        /// </param>375        /// <param name="provider">376        /// The name of the provider which implements the functionality377        /// for the root path of the drive.378        /// </param>379        /// <param name="root">380        /// The root path of the drive. For example, the root of a381        /// drive in the file system can be c:\windows\system32382        /// </param>383        /// <param name="description">384        /// The description for the drive.385        /// </param>386        /// <param name="credential">387        /// The credentials under which all operations on the drive should occur.388        /// If null, the current user credential is used.389        /// </param>390        /// <param name="displayRoot">391        /// The network path of the drive. This field would be populated only if PSDriveInfo392        /// is targeting the network drive or else this filed is null for local drives.393        /// </param>394        /// <throws>395        /// ArgumentNullException - if <paramref name="name"/>,396        /// <paramref name="provider"/>, or <paramref name="root"/>397        /// is null.398        /// </throws>399        public PSDriveInfo(400            string name,401            ProviderInfo provider,402            string root,403            string description,404            PSCredential credential, string displayRoot)405            : this(name, provider, root, description, credential)406        {407            DisplayRoot = displayRoot;408        }409 410        /// <summary>411        /// Constructs a drive that maps a PowerShell Path in412        /// the shell to a Cmdlet Provider.413        /// </summary>414        /// <param name="name">415        /// The name of the drive.416        /// </param>417        /// <param name="provider">418        /// The name of the provider which implements the functionality419        /// for the root path of the drive.420        /// </param>421        /// <param name="root">422        /// The root path of the drive. For example, the root of a423        /// drive in the file system can be c:\windows\system32424        /// </param>425        /// <param name="description">426        /// The description for the drive.427        /// </param>428        /// <param name="credential">429        /// The credentials under which all operations on the drive should occur.430        /// If null, the current user credential is used.431        /// </param>432        /// <param name="persist">433        /// It indicates if the created PSDrive would be434        /// persisted across PowerShell sessions.435        /// </param>436        /// <throws>437        /// ArgumentNullException - if <paramref name="name"/>,438        /// <paramref name="provider"/>, or <paramref name="root"/>439        /// is null.440        /// </throws>441        public PSDriveInfo(442            string name,443            ProviderInfo provider,444            string root,445            string description,446            PSCredential credential,447            bool persist)448            : this(name, provider, root, description, credential)449        {450            Persist = persist;451        }452 453        #endregion ctor454 455        /// <summary>456        /// Gets the name of the drive as a string.457        /// </summary>458        /// <returns>459        /// Returns a String that is that name of the drive.460        /// </returns>461        public override string ToString()462        {463            return Name;464        }465 466        /// <summary>467        /// Gets or sets the hidden property. The hidden property468        /// determines if the drive should be hidden from the user.469        /// </summary>470        /// <value>471        /// True if the drive should be hidden from the user, false472        /// otherwise.473        /// </value>474        internal bool Hidden475        {476            get477            {478                return _hidden;479            }480 481            set482            {483                _hidden = value;484            }485        }486 487        /// <summary>488        /// Determines if the drive should be hidden from the user.489        /// </summary>490        private bool _hidden;491 492        /// <summary>493        /// Sets the name of the drive to a new name.494        /// </summary>495        /// <param name="newName">496        /// The new name for the drive.497        /// </param>498        /// <remarks>499        /// This must be internal so that we allow the renaming of drives500        /// via the Core Command API but not through a reference to the501        /// drive object. More goes in to renaming a drive than just modifying502        /// the name in this class.503        /// </remarks>504        /// <exception cref="ArgumentException">505        /// If <paramref name="newName"/> is null or empty.506        /// </exception>507        internal void SetName(string newName)508        {509            if (string.IsNullOrEmpty(newName))510            {511                throw PSTraceSource.NewArgumentException(nameof(newName));512            }513 514            _name = newName;515        }516 517        /// <summary>518        /// Sets the provider of the drive to a new provider.519        /// </summary>520        /// <param name="newProvider">521        /// The new provider for the drive.522        /// </param>523        /// <remarks>524        /// This must be internal so that we allow the renaming of providers.525        /// All drives must be associated with the new provider name and can526        /// be changed using the Core Command API but not through a reference to the527        /// drive object. More goes in to renaming a provider than just modifying528        /// the provider in this class.529        /// </remarks>530        /// <exception cref="ArgumentNullException">531        /// If <paramref name="newProvider"/> is null.532        /// </exception>533        internal void SetProvider(ProviderInfo newProvider)534        {535            if (newProvider == null)536            {537                throw PSTraceSource.NewArgumentNullException(nameof(newProvider));538            }539 540            _provider = newProvider;541        }542 543        /// <summary>544        /// Traces the virtual drive.545        /// </summary>546        internal void Trace()547        {548            s_tracer.WriteLine(549                "A drive was found:");550 551            if (Name != null)552            {553                s_tracer.WriteLine(554                    "\tName: {0}",555                    Name);556            }557 558            if (Provider != null)559            {560                s_tracer.WriteLine(561                    "\tProvider: {0}",562                    Provider);563            }564 565            if (Root != null)566            {567                s_tracer.WriteLine(568                    "\tRoot: {0}",569                    Root);570            }571 572            if (CurrentLocation != null)573            {574                s_tracer.WriteLine(575                    "\tCWD: {0}",576                    CurrentLocation);577            }578 579            if (Description != null)580            {581                s_tracer.WriteLine(582                    "\tDescription: {0}",583                    Description);584            }585        }586 587        /// <summary>588        /// Compares this instance to the specified drive.589        /// </summary>590        /// <param name="drive">591        /// A PSDriveInfo object to compare.592        /// </param>593        /// <returns>594        /// A signed number indicating the relative values of this instance and object specified.595        /// Return Value: Less than zero        Meaning: This instance is less than object.596        /// Return Value: Zero                  Meaning: This instance is equal to object.597        /// Return Value: Greater than zero     Meaning: This instance is greater than object or object is a null reference.598        /// </returns>599        public int CompareTo(PSDriveInfo drive)600        {601#pragma warning disable 56506602 603            if (drive == null)604            {605                throw PSTraceSource.NewArgumentNullException(nameof(drive));606            }607 608            return string.Compare(Name, drive.Name, StringComparison.OrdinalIgnoreCase);609 610#pragma warning restore 56506611        }612 613        /// <summary>614        /// Compares this instance to the specified object. The object must be a PSDriveInfo.615        /// </summary>616        /// <param name="obj">617        /// An object to compare.618        /// </param>619        /// <returns>620        /// A signed number indicating the relative values of this621        /// instance and object specified.622        /// </returns>623        /// <exception cref="ArgumentException">624        /// If <paramref name="obj"/> is not a PSDriveInfo instance.625        /// </exception>626        public int CompareTo(object obj)627        {628            PSDriveInfo drive = obj as PSDriveInfo;629 630            if (drive == null)631            {632                ArgumentException e =633                    PSTraceSource.NewArgumentException(634                        nameof(obj),635                        SessionStateStrings.OnlyAbleToComparePSDriveInfo);636                throw e;637            }638 639            return (CompareTo(drive));640        }641 642        /// <summary>643        /// Compares this instance to the specified object.644        /// </summary>645        /// <param name="obj">646        /// An object to compare.647        /// </param>648        /// <returns>649        /// True if the drive names are equal, false otherwise.650        /// </returns>651        public override bool Equals(object obj)652        {653            if (obj is PSDriveInfo)654            {655                return CompareTo(obj) == 0;656            }657            else658            {659                return false;660            }661        }662 663        /// <summary>664        /// Compares this instance to the specified object.665        /// </summary>666        /// <param name="drive">667        /// An object to compare.668        /// </param>669        /// <returns>670        /// True if the drive names are equal, false otherwise.671        /// </returns>672        public bool Equals(PSDriveInfo drive)673        {674            return CompareTo(drive) == 0;675        }676 677        /// <summary>678        /// Equality operator for the drive determines if the drives679        /// are equal by having the same name.680        /// </summary>681        /// <param name="drive1">682        /// The first object to compare to the second.683        /// </param>684        /// <param name="drive2">685        /// The second object to compare to the first.686        /// </param>687        /// <returns>688        /// True if the objects are PSDriveInfo objects and have the same name,689        /// false otherwise.690        /// </returns>691        public static bool operator ==(PSDriveInfo drive1, PSDriveInfo drive2)692        {693            object drive1Object = drive1;694            object drive2Object = drive2;695 696            if ((drive1Object == null) == (drive2Object == null))697            {698                if (drive1Object != null)699                {700                    return drive1.Equals(drive2);701                }702 703                return true;704            }705            else706            {707                return false;708            }709        }710 711        /// <summary>712        /// Inequality operator for the drive determines if the drives713        /// are not equal by using the drive name.714        /// </summary>715        /// <param name="drive1">716        /// The first object to compare to the second.717        /// </param>718        /// <param name="drive2">719        /// The second object to compare to the first.720        /// </param>721        /// <returns>722        /// True if the PSDriveInfo objects do not have the same name,723        /// false otherwise.724        /// </returns>725        public static bool operator !=(PSDriveInfo drive1, PSDriveInfo drive2)726        {727            return !(drive1 == drive2);728        }729 730        /// <summary>731        /// Compares the specified drives to determine if drive1 is less than732        /// drive2.733        /// </summary>734        /// <param name="drive1">735        /// The drive to determine if it is less than the other drive.736        /// </param>737        /// <param name="drive2">738        /// The drive to compare drive1 against.739        /// </param>740        /// <returns>741        /// True if the lexical comparison of drive1's name is less than drive2's name.742        /// </returns>743        public static bool operator <(PSDriveInfo drive1, PSDriveInfo drive2)744        {745            object drive1Object = drive1;746            object drive2Object = drive2;747 748            if (drive1Object == null)749            {750                return (drive2Object != null);751            }752            else753            {754                if (drive2Object == null)755                {756                    // Since drive1 is not null and drive2 is, drive1 is greater than drive2757                    return false;758                }759                else760                {761                    // Since drive1 and drive2 are not null use the CompareTo762 763                    return drive1.CompareTo(drive2) < 0;764                }765            }766        }767 768        /// <summary>769        /// Compares the specified drives to determine if drive1 is greater than770        /// drive2.771        /// </summary>772        /// <param name="drive1">773        /// The drive to determine if it is greater than the other drive.774        /// </param>775        /// <param name="drive2">776        /// The drive to compare drive1 against.777        /// </param>778        /// <returns>779        /// True if the lexical comparison of drive1's name is greater than drive2's name.780        /// </returns>781        public static bool operator >(PSDriveInfo drive1, PSDriveInfo drive2)782        {783            object drive1Object = drive1;784            object drive2Object = drive2;785 786            if ((drive1Object == null))787            {788                // Since both drives are null, they are equal789                // Since drive1 is null it is less than drive2 which is not null790                return false;791            }792            else793            {794                if (drive2Object == null)795                {796                    // Since drive1 is not null and drive2 is, drive1 is greater than drive2797                    return true;798                }799                else800                {801                    // Since drive1 and drive2 are not null use the CompareTo802 803                    return drive1.CompareTo(drive2) > 0;804                }805            }806        }807 808        /// <summary>809        /// Gets the hash code for this instance.810        /// </summary>811        /// <returns>The result of base.GetHashCode().</returns>812        /// <!-- Override the base GetHashCode because the compiler complains813        /// if you don't when you implement operator== and operator!= -->814        public override int GetHashCode()815        {816            return base.GetHashCode();817        }818 819        private PSNoteProperty _noteProperty;820 821        internal PSNoteProperty GetNotePropertyForProviderCmdlets(string name)822        {823            if (_noteProperty == null)824            {825                Interlocked.CompareExchange(ref _noteProperty,826                                            new PSNoteProperty(name, this), null);827            }828 829            return _noteProperty;830        }831    }832}833