Esempio n. 1
0
        private static bool IsQualifiedPSPath(string commandName)
        {
            bool flag = LocationGlobber.IsAbsolutePath(commandName) || LocationGlobber.IsProviderQualifiedPath(commandName) || LocationGlobber.IsHomePath(commandName) || LocationGlobber.IsProviderDirectPath(commandName);

            CommandSearcher.tracer.WriteLine("result = {0}", (object)flag);
            return(flag);
        }
Esempio n. 2
0
        /// <summary>
        /// Check if string is prefixed by psdrive, if so, expand it if filesystem path.
        /// </summary>
        /// <param name="path">The potential PSPath to resolve.</param>
        /// <param name="context">The current ExecutionContext.</param>
        /// <returns>Resolved PSPath if applicable otherwise the original path</returns>
        internal static string ResolvePath(string path, ExecutionContext context)
        {
            if (ExperimentalFeature.IsEnabled("PSNativePSPathResolution"))
            {
#if !UNIX
                // on Windows, we need to expand ~ to point to user's home path
                if (string.Equals(path, "~", StringComparison.Ordinal) || path.StartsWith(TildeDirectorySeparator, StringComparison.Ordinal) || path.StartsWith(TildeAltDirectorySeparator, StringComparison.Ordinal))
                {
                    try
                    {
                        ProviderInfo fileSystemProvider = context.EngineSessionState.GetSingleProvider(FileSystemProvider.ProviderName);
                        return(new StringBuilder(fileSystemProvider.Home)
                               .Append(path.Substring(1))
                               .Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar)
                               .ToString());
                    }
                    catch
                    {
                        return(path);
                    }
                }

                // check if the driveName is an actual disk drive on Windows, if so, no expansion
                if (path.Length >= 2 && path[1] == ':')
                {
                    foreach (var drive in DriveInfo.GetDrives())
                    {
                        if (drive.Name.StartsWith(new string(path[0], 1), StringComparison.OrdinalIgnoreCase))
                        {
                            return(path);
                        }
                    }
                }
#endif

                if (path.Contains(':'))
                {
                    LocationGlobber globber = new LocationGlobber(context.SessionState);
                    try
                    {
                        ProviderInfo providerInfo;

                        // replace the argument with resolved path if it's a filesystem path
                        string pspath = globber.GetProviderPath(path, out providerInfo);
                        if (string.Equals(providerInfo.Name, FileSystemProvider.ProviderName, StringComparison.OrdinalIgnoreCase))
                        {
                            path = pspath;
                        }
                    }
                    catch
                    {
                        // if it's not a provider path, do nothing
                    }
                }
            }

            return(path);
        }
        }     // CurrentLocation

        /// <summary>
        /// Gets the namespace specific path of the current working directory
        /// for the specified namespace.
        /// </summary>
        ///
        /// <param name="namespaceID">
        /// An identifier that uniquely identifies the namespace to get the
        /// current working directory for.
        /// </param>
        ///
        /// <returns>
        /// The namespace specific path of the current working directory for
        /// the specified namespace.
        /// </returns>
        ///
        /// <exception cref="ArgumentNullException">
        /// If <paramref name="namespaceID"/> is null.
        /// </exception>
        ///
        /// <exception cref="ProviderNotFoundException">
        /// If <paramref name="namespacesID"/> refers to a provider that does not exist.
        /// </exception>
        ///
        /// <exception cref="DriveNotFoundException">
        /// If a current drive cannot be found for the provider <paramref name="namespaceID"/>
        /// </exception>
        ///
        internal PathInfo GetNamespaceCurrentLocation(string namespaceID)
        {
            if (namespaceID == null)
            {
                throw PSTraceSource.NewArgumentNullException("namespaceID");
            }

            // If namespace ID is empty, we will use the current working drive

            PSDriveInfo drive = null;

            if (namespaceID.Length == 0)
            {
                ProvidersCurrentWorkingDrive.TryGetValue(CurrentDrive.Provider, out drive);
            }
            else
            {
                // First check to see if the provider exists

                ProvidersCurrentWorkingDrive.TryGetValue(GetSingleProvider(namespaceID), out drive);
            }

            if (drive == null)
            {
                DriveNotFoundException e =
                    new DriveNotFoundException(
                        namespaceID,
                        "DriveNotFound",
                        SessionStateStrings.DriveNotFound);
                throw e;
            }

            CmdletProviderContext context = new CmdletProviderContext(this.ExecutionContext);

            context.Drive = drive;

            // Now make the namespace specific path

            string path = null;

            if (drive.Hidden)
            {
                if (LocationGlobber.IsProviderDirectPath(drive.CurrentLocation))
                {
                    path = drive.CurrentLocation;
                }
                else
                {
                    path = LocationGlobber.GetProviderQualifiedPath(drive.CurrentLocation, drive.Provider);
                }
            }
            else
            {
                path = LocationGlobber.GetDriveQualifiedPath(drive.CurrentLocation, drive);
            }
            return(new PathInfo(drive, drive.Provider, path, new SessionState(this)));
        } // GetNamespaceCurrentLocation
Esempio n. 4
0
 public override string ToString()
 {
     using (PathInfo.tracer.TraceMethod(this.path, new object[0]))
     {
         string path = this.path;
         string str  = this.drive == (PSDriveInfo)null || this.drive.Hidden ? LocationGlobber.GetProviderQualifiedPath(this.path, this.provider) : LocationGlobber.GetDriveQualifiedPath(this.path, this.drive);
         PathInfo.tracer.WriteLine("result = {0}", (object)str);
         return(str);
     }
 }
Esempio n. 5
0
        public override string ToString()
        {
            string path = this.path;

            if ((this.drive == null) || this.drive.Hidden)
            {
                return(LocationGlobber.GetProviderQualifiedPath(path, this.provider));
            }
            path = LocationGlobber.GetDriveQualifiedPath(path, this.drive);
            return(path);
        }
Esempio n. 6
0
        /// <summary>
        /// Gets a string representing the MSH path.
        /// </summary>
        /// <returns>
        /// A string representing the MSH path.
        /// </returns>
        public override string ToString()
        {
            string result = _path;

            if (_drive is null ||
                _drive.Hidden)
            {
                // For hidden drives just return the current location
                result =
                    LocationGlobber.GetProviderQualifiedPath(
                        _path,
                        _provider);
            }
Esempio n. 7
0
        private PSObject WrapOutputInPSObject(object item, string path)
        {
            if (item == null)
            {
                throw PSTraceSource.NewArgumentNullException("item");
            }
            PSObject obj2 = new PSObject(item);
            PSObject obj3 = item as PSObject;

            if (obj3 != null)
            {
                obj2.InternalTypeNames = new ConsolidatedString(obj3.InternalTypeNames);
            }
            string providerQualifiedPath = LocationGlobber.GetProviderQualifiedPath(path, this.ProviderInfo);

            obj2.AddOrSetProperty("PSPath", providerQualifiedPath);
            providerBaseTracer.WriteLine("Attaching {0} = {1}", new object[] { "PSPath", providerQualifiedPath });
            NavigationCmdletProvider provider = this as NavigationCmdletProvider;

            if ((provider != null) && (path != null))
            {
                string str2 = null;
                if (this.PSDriveInfo != null)
                {
                    str2 = provider.GetParentPath(path, this.PSDriveInfo.Root, this.Context);
                }
                else
                {
                    str2 = provider.GetParentPath(path, string.Empty, this.Context);
                }
                string str3 = string.Empty;
                if (!string.IsNullOrEmpty(str2))
                {
                    str3 = LocationGlobber.GetProviderQualifiedPath(str2, this.ProviderInfo);
                }
                obj2.AddOrSetProperty("PSParentPath", str3);
                providerBaseTracer.WriteLine("Attaching {0} = {1}", new object[] { "PSParentPath", str3 });
                string childName = provider.GetChildName(path, this.Context);
                obj2.AddOrSetProperty("PSChildName", childName);
                providerBaseTracer.WriteLine("Attaching {0} = {1}", new object[] { "PSChildName", childName });
            }
            if (this.PSDriveInfo != null)
            {
                obj2.AddOrSetProperty(this.PSDriveInfo.GetNotePropertyForProviderCmdlets("PSDrive"));
                providerBaseTracer.WriteLine("Attaching {0} = {1}", new object[] { "PSDrive", this.PSDriveInfo });
            }
            obj2.AddOrSetProperty(this.ProviderInfo.GetNotePropertyForProviderCmdlets("PSProvider"));
            providerBaseTracer.WriteLine("Attaching {0} = {1}", new object[] { "PSProvider", this.ProviderInfo });
            return(obj2);
        }
        /// <summary>
        /// Test if the path is an absolute path
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        private bool IsAbsolutePath(string path)
        {
            bool result = false;

            if (LocationGlobber.IsAbsolutePath(path))
            {
                result = true;
            }
            else if (this.PSDriveInfo != null && !String.IsNullOrEmpty(this.PSDriveInfo.Root) &&
                     path.StartsWith(this.PSDriveInfo.Root, StringComparison.OrdinalIgnoreCase))
            {
                result = true;
            }

            return(result);
        }
Esempio n. 9
0
 private PSObject WrapOutputInPSObject(object item, string path)
 {
     using (CmdletProvider.providerBaseTracer.TraceMethod(path, new object[0]))
     {
         PSObject psObject1 = item != null ? new PSObject(item) : throw CmdletProvider.providerBaseTracer.NewArgumentNullException(nameof(item));
         if (item is PSObject psObject)
         {
             psObject1.TypeNames.Clear();
             foreach (string typeName in psObject.TypeNames)
             {
                 psObject1.TypeNames.Add(typeName);
             }
         }
         string         providerQualifiedPath = LocationGlobber.GetProviderQualifiedPath(path, this.ProviderInfo);
         PSNoteProperty psNoteProperty1       = new PSNoteProperty("PSPath", (object)providerQualifiedPath);
         psObject1.Properties.Add((PSPropertyInfo)psNoteProperty1, true);
         CmdletProvider.providerBaseTracer.WriteLine("Attaching {0} = {1}", (object)"PSPath", (object)providerQualifiedPath);
         if (this is NavigationCmdletProvider navigationCmdletProvider && path != null)
         {
             string path1 = !(this.PSDriveInfo != (PSDriveInfo)null) ? navigationCmdletProvider.GetParentPath(path, string.Empty, this.Context) : navigationCmdletProvider.GetParentPath(path, this.PSDriveInfo.Root, this.Context);
             string str   = string.Empty;
             if (!string.IsNullOrEmpty(path1))
             {
                 str = LocationGlobber.GetProviderQualifiedPath(path1, this.ProviderInfo);
             }
             PSNoteProperty psNoteProperty2 = new PSNoteProperty("PSParentPath", (object)str);
             psObject1.Properties.Add((PSPropertyInfo)psNoteProperty2, true);
             CmdletProvider.providerBaseTracer.WriteLine("Attaching {0} = {1}", (object)"PSParentPath", (object)str);
             string         childName       = navigationCmdletProvider.GetChildName(path, this.Context);
             PSNoteProperty psNoteProperty3 = new PSNoteProperty("PSChildName", (object)childName);
             psObject1.Properties.Add((PSPropertyInfo)psNoteProperty3, true);
             CmdletProvider.providerBaseTracer.WriteLine("Attaching {0} = {1}", (object)"PSChildName", (object)childName);
         }
         if (this.PSDriveInfo != (PSDriveInfo)null)
         {
             PSNoteProperty psNoteProperty2 = new PSNoteProperty("PSDrive", (object)this.PSDriveInfo);
             psObject1.Properties.Add((PSPropertyInfo)psNoteProperty2, true);
             CmdletProvider.providerBaseTracer.WriteLine("Attaching {0} = {1}", (object)"PSDrive", (object)this.PSDriveInfo);
         }
         PSNoteProperty psNoteProperty4 = new PSNoteProperty("PSProvider", (object)this.ProviderInfo);
         psObject1.Properties.Add((PSPropertyInfo)psNoteProperty4, true);
         CmdletProvider.providerBaseTracer.WriteLine("Attaching {0} = {1}", (object)"PSProvider", (object)this.ProviderInfo);
         return(psObject1);
     }
 }
Esempio n. 10
0
        private PathInfo GetNewPushPathInfo()
        {
            // Create a new instance of the directory/drive pair
            ProviderInfo provider         = CurrentDrive.Provider;
            string       mshQualifiedPath =
                LocationGlobber.GetMshQualifiedPath(CurrentDrive.CurrentLocation, CurrentDrive);

            PathInfo newPushLocation =
                new PathInfo(
                    CurrentDrive,
                    provider,
                    mshQualifiedPath,
                    new SessionState(this));

            s_tracer.WriteLine(
                "Pushing drive: {0} directory: {1}",
                CurrentDrive.Name,
                mshQualifiedPath);

            return(newPushLocation);
        }
        /// <summary>
        /// Pushes the current location onto the working
        /// location stack so that it can be retrieved later.
        /// </summary>
        ///
        /// <param name="stackName">
        /// The ID of the stack to push the location on. If
        /// it is null or empty the default stack is used.
        /// </param>
        ///
        internal void PushCurrentLocation(string stackName)
        {
            if (String.IsNullOrEmpty(stackName))
            {
                stackName = _defaultStackName;
            }

            // Create a new instance of the directory/drive pair

            ProviderInfo provider         = CurrentDrive.Provider;
            string       mshQualifiedPath =
                LocationGlobber.GetMshQualifiedPath(CurrentDrive.CurrentLocation, CurrentDrive);

            PathInfo newPushLocation =
                new PathInfo(
                    CurrentDrive,
                    provider,
                    mshQualifiedPath,
                    new SessionState(this));

            s_tracer.WriteLine(
                "Pushing drive: {0} directory: {1}",
                CurrentDrive.Name,
                mshQualifiedPath);

            // Get the location stack from the hashtable

            Stack <PathInfo> locationStack = null;

            if (!_workingLocationStack.TryGetValue(stackName, out locationStack))
            {
                locationStack = new Stack <PathInfo>();
                _workingLocationStack[stackName] = locationStack;
            }

            // Push the directory/drive pair onto the stack

            locationStack.Push(newPushLocation);
        }
Esempio n. 12
0
        /// <summary>
        /// Resolves using module to a collection of PSModuleInfos. Doesn't throw.
        /// PSModuleInfo objects are returned in the right order: i.e. if multiply versions of the module
        /// is presented on the system and user didn't specify version, we will return all of them, but newer one would go first.
        /// </summary>
        /// <param name="usingStatementAst">Using statement.</param>
        /// <param name="exception">If exception happens, return exception object.</param>
        /// <param name="wildcardCharactersUsed">
        /// True if in the module name uses wildcardCharacter.
        /// We don't want to resolve any wild-cards in using module.
        /// </param>
        /// <param name="isConstant">True if module hashtable contains constant value (it's our requirement).</param>
        /// <returns>Modules, if can resolve it. null if any problems happens.</returns>
        private Collection <PSModuleInfo> GetModulesFromUsingModule(UsingStatementAst usingStatementAst, out Exception exception, out bool wildcardCharactersUsed, out bool isConstant)
        {
            exception = null;
            wildcardCharactersUsed = false;
            isConstant             = true;

            // fullyQualifiedName can be string or hashtable
            object fullyQualifiedName;

            if (usingStatementAst.ModuleSpecification != null)
            {
                object resultObject;
                if (!IsConstantValueVisitor.IsConstant(usingStatementAst.ModuleSpecification, out resultObject, forAttribute: false, forRequires: true))
                {
                    isConstant = false;
                    return(null);
                }

                var hashtable = resultObject as System.Collections.Hashtable;
                var ms        = new ModuleSpecification();
                exception = ModuleSpecification.ModuleSpecificationInitHelper(ms, hashtable);
                if (exception != null)
                {
                    return(null);
                }

                if (WildcardPattern.ContainsWildcardCharacters(ms.Name))
                {
                    wildcardCharactersUsed = true;
                    return(null);
                }

                fullyQualifiedName = ms;
            }
            else
            {
                string fullyQualifiedNameStr = usingStatementAst.Name.Value;

                if (WildcardPattern.ContainsWildcardCharacters(fullyQualifiedNameStr))
                {
                    wildcardCharactersUsed = true;
                    return(null);
                }

                // case 1: relative path. Relative for file in the same folder should include .\
                bool isPath = fullyQualifiedNameStr.Contains(@"\");
                if (isPath && !LocationGlobber.IsAbsolutePath(fullyQualifiedNameStr))
                {
                    string rootPath = Path.GetDirectoryName(_parser._fileName);
                    if (rootPath != null)
                    {
                        fullyQualifiedNameStr = Path.Combine(rootPath, fullyQualifiedNameStr);
                    }
                }

                // case 2: Module by name
                // case 3: Absolute Path
                // We don't need to do anything for these cases, FullyQualifiedName already handle it.

                fullyQualifiedName = fullyQualifiedNameStr;
            }

            var commandInfo = new CmdletInfo("Get-Module", typeof(GetModuleCommand));

            // TODO(sevoroby): we should consider an async call with cancellation here.
            UsingStatementResolvePowerShell.Commands.Clear();
            try
            {
                return(UsingStatementResolvePowerShell.AddCommand(commandInfo)
                       .AddParameter("FullyQualifiedName", fullyQualifiedName)
                       .AddParameter("ListAvailable", true)
                       .Invoke <PSModuleInfo>());
            }
            catch (Exception e)
            {
                exception = e;
                return(null);
            }
        }
Esempio n. 13
0
 private static bool IsQualifiedPSPath(string commandName)
 {
     return(((LocationGlobber.IsAbsolutePath(commandName) || LocationGlobber.IsProviderQualifiedPath(commandName)) || LocationGlobber.IsHomePath(commandName)) || LocationGlobber.IsProviderDirectPath(commandName));
 }
Esempio n. 14
0
        protected override void ProcessRecord()
        {
            PathInfo           pathInfo;
            List <PSDriveInfo> matchingDrives;
            string             parameterSetName = base.ParameterSetName;
            string             str = parameterSetName;

            if (parameterSetName != null)
            {
                if (str == "Location")
                {
                    pathInfo = null;
                    if (this.PSDrive == null || (int)this.PSDrive.Length <= 0)
                    {
                        if ((this.PSDrive == null || (int)this.PSDrive.Length == 0) && this.PSProvider != null && (int)this.PSProvider.Length > 0)
                        {
                            string[] pSProvider = this.PSProvider;
                            for (int i = 0; i < (int)pSProvider.Length; i++)
                            {
                                string str1 = pSProvider[i];
                                bool   flag = WildcardPattern.ContainsWildcardCharacters(str1);
                                if (!flag)
                                {
                                    try
                                    {
                                        base.SessionState.Provider.GetOne(str1);
                                    }
                                    catch (ProviderNotFoundException providerNotFoundException1)
                                    {
                                        ProviderNotFoundException providerNotFoundException = providerNotFoundException1;
                                        ErrorRecord errorRecord = new ErrorRecord(providerNotFoundException, "GetLocationNoMatchingProvider", ErrorCategory.ObjectNotFound, str1);
                                        base.WriteError(errorRecord);
                                        goto Label0;
                                    }
                                }
                                foreach (ProviderInfo all in base.SessionState.Provider.GetAll())
                                {
                                    if (!all.IsMatch(str1))
                                    {
                                        continue;
                                    }
                                    try
                                    {
                                        base.WriteObject(base.SessionState.Path.CurrentProviderLocation(all.FullName));
                                    }
                                    catch (ProviderNotFoundException providerNotFoundException3)
                                    {
                                        ProviderNotFoundException providerNotFoundException2 = providerNotFoundException3;
                                        base.WriteError(new ErrorRecord(providerNotFoundException2.ErrorRecord, providerNotFoundException2));
                                    }
                                    catch (DriveNotFoundException driveNotFoundException1)
                                    {
                                        DriveNotFoundException driveNotFoundException = driveNotFoundException1;
                                        if (!flag)
                                        {
                                            base.WriteError(new ErrorRecord(driveNotFoundException.ErrorRecord, driveNotFoundException));
                                        }
                                    }
                                }
Label0:
                                continue;
                            }
                            return;
                        }
                        else
                        {
                            base.WriteObject(base.SessionState.Path.CurrentLocation);
                            return;
                        }
                    }
                    else
                    {
                        string[] pSDrive = this.PSDrive;
                        for (int j = 0; j < (int)pSDrive.Length; j++)
                        {
                            string str2 = pSDrive[j];
                            matchingDrives = null;
                            try
                            {
                                matchingDrives = base.GetMatchingDrives(str2, this.PSProvider, null);
                                goto Label1;
                            }
                            catch (DriveNotFoundException driveNotFoundException3)
                            {
                                DriveNotFoundException driveNotFoundException2 = driveNotFoundException3;
                                ErrorRecord            errorRecord1            = new ErrorRecord(driveNotFoundException2, "GetLocationNoMatchingDrive", ErrorCategory.ObjectNotFound, str2);
                                base.WriteError(errorRecord1);
                            }
                            catch (ProviderNotFoundException providerNotFoundException5)
                            {
                                ProviderNotFoundException providerNotFoundException4 = providerNotFoundException5;
                                ErrorRecord errorRecord2 = new ErrorRecord(providerNotFoundException4, "GetLocationNoMatchingProvider", ErrorCategory.ObjectNotFound, this.PSProvider);
                                base.WriteError(errorRecord2);
                            }
                            catch (ArgumentException argumentException1)
                            {
                                ArgumentException argumentException = argumentException1;
                                ErrorRecord       errorRecord3      = new ErrorRecord(argumentException, "GetLocationNoMatchingDrive", ErrorCategory.ObjectNotFound, str2);
                                base.WriteError(errorRecord3);
                            }
                        }
                        return;
                    }
                }
                else
                {
                    if (str == "Stack")
                    {
                        if (this.stackNames == null)
                        {
                            try
                            {
                                base.WriteObject(base.SessionState.Path.LocationStack(null), false);
                            }
                            catch (PSArgumentException pSArgumentException1)
                            {
                                PSArgumentException pSArgumentException = pSArgumentException1;
                                base.WriteError(new ErrorRecord(pSArgumentException.ErrorRecord, pSArgumentException));
                            }
                        }
                        else
                        {
                            string[] strArrays = this.stackNames;
                            for (int k = 0; k < (int)strArrays.Length; k++)
                            {
                                string str3 = strArrays[k];
                                try
                                {
                                    base.WriteObject(base.SessionState.Path.LocationStack(str3), false);
                                }
                                catch (PSArgumentException pSArgumentException3)
                                {
                                    PSArgumentException pSArgumentException2 = pSArgumentException3;
                                    base.WriteError(new ErrorRecord(pSArgumentException2.ErrorRecord, pSArgumentException2));
                                }
                            }
                            return;
                        }
                    }
                    else
                    {
                        return;
                    }
                }
            }
            return;

Label1:
            List <PSDriveInfo> .Enumerator enumerator = matchingDrives.GetEnumerator();
            try
            {
                while (enumerator.MoveNext())
                {
                    PSDriveInfo current = enumerator.Current;
                    try
                    {
                        string driveQualifiedPath = LocationGlobber.GetDriveQualifiedPath(current.CurrentLocation, current);
                        pathInfo = new PathInfo(current, current.Provider, driveQualifiedPath, base.SessionState);
                        base.WriteObject(pathInfo);
                    }
                    catch (ProviderNotFoundException providerNotFoundException7)
                    {
                        ProviderNotFoundException providerNotFoundException6 = providerNotFoundException7;
                        base.WriteError(new ErrorRecord(providerNotFoundException6.ErrorRecord, providerNotFoundException6));
                    }
                }
                return;
            }
            finally
            {
                enumerator.Dispose();
            }
        }
Esempio n. 15
0
        /// <summary>
        /// Resets the current working drive and directory to the first
        /// entry on the working directory stack and removes that entry
        /// from the stack.
        /// </summary>
        /// <param name="stackName">
        /// The ID of the stack to pop the location from. If it is null or
        /// empty the default stack is used.
        /// </param>
        /// <returns>
        /// A PathInfo object representing the location that was popped
        /// from the location stack and set as the new location.
        /// </returns>
        /// <exception cref="ArgumentException">
        /// If the path on the stack does not exist, is not a container, or
        /// resolved to multiple containers.
        /// or
        /// If <paramref name="stackName"/> contains wildcard characters and resolves
        /// to multiple location stacks.
        /// or
        /// A stack was not found with the specified name.
        /// </exception>
        /// <exception cref="ProviderNotFoundException">
        /// If the path on the stack refers to a provider that does not exist.
        /// </exception>
        /// <exception cref="DriveNotFoundException">
        /// If the path on the stack refers to a drive that does not exist.
        /// </exception>
        /// <exception cref="ProviderInvocationException">
        /// If the provider associated with the path on the stack threw an
        /// exception.
        /// </exception>
        internal PathInfo PopLocation(string stackName)
        {
            if (String.IsNullOrEmpty(stackName))
            {
                stackName = _defaultStackName;
            }

            if (WildcardPattern.ContainsWildcardCharacters(stackName))
            {
                // Need to glob the stack name, but it can only glob to a single.
                bool haveMatch = false;

                WildcardPattern stackNamePattern =
                    WildcardPattern.Get(stackName, WildcardOptions.IgnoreCase);

                foreach (string key in _workingLocationStack.Keys)
                {
                    if (stackNamePattern.IsMatch(key))
                    {
                        if (haveMatch)
                        {
                            throw
                                PSTraceSource.NewArgumentException(
                                    "stackName",
                                    SessionStateStrings.StackNameResolvedToMultiple,
                                    stackName);
                        }

                        haveMatch = true;
                        stackName = key;
                    }
                }
            }

            PathInfo result = CurrentLocation;

            try
            {
                Stack <PathInfo> locationStack = null;
                if (!_workingLocationStack.TryGetValue(stackName, out locationStack))
                {
                    if (!string.Equals(stackName, startingDefaultStackName, StringComparison.OrdinalIgnoreCase))
                    {
                        throw
                            PSTraceSource.NewArgumentException(
                                "stackName",
                                SessionStateStrings.StackNotFound,
                                stackName);
                    }

                    return(null);
                }

                PathInfo poppedWorkingDirectory = locationStack.Pop();

                Dbg.Diagnostics.Assert(
                    poppedWorkingDirectory != null,
                    "All items in the workingLocationStack should be " +
                    "of type PathInfo");

                string newPath =
                    LocationGlobber.GetMshQualifiedPath(
                        WildcardPattern.Escape(poppedWorkingDirectory.Path),
                        poppedWorkingDirectory.GetDrive());

                result = SetLocation(newPath);

                if (locationStack.Count == 0 &&
                    !String.Equals(stackName, startingDefaultStackName, StringComparison.OrdinalIgnoreCase))
                {
                    // Remove the stack from the stack list if it
                    // no longer contains any paths.
                    _workingLocationStack.Remove(stackName);
                }
            }
            catch (InvalidOperationException)
            {
                // This is a no-op. We stay with the current working
                // directory.
            }

            return(result);
        }
        private void ResolveCurrentDirectoryInLookupPaths()
        {
            var indexesToRemove  = new SortedDictionary <int, int>();
            int removalListCount = 0;

            string fileSystemProviderName = _context.ProviderNames.FileSystem;

            SessionStateInternal sessionState = _context.EngineSessionState;

            // Only use the directory if it gets resolved by the FileSystemProvider
            bool isCurrentDriveValid =
                sessionState.CurrentDrive != null &&
                sessionState.CurrentDrive.Provider.NameEquals(fileSystemProviderName) &&
                sessionState.IsProviderLoaded(fileSystemProviderName);

            string environmentCurrentDirectory = Directory.GetCurrentDirectory();

            LocationGlobber pathResolver = _context.LocationGlobber;

            // Loop through the relative paths and resolve them

            foreach (int index in _lookupPaths.IndexOfRelativePath())
            {
                string?resolvedDirectory = null;
                string?resolvedPath      = null;

                CommandDiscovery.discoveryTracer.WriteLine(
                    "Lookup directory \"{0}\" appears to be a relative path. Attempting resolution...",
                    _lookupPaths[index]);

                if (isCurrentDriveValid)
                {
                    try
                    {
                        ProviderInfo provider;
                        resolvedPath =
                            pathResolver.GetProviderPath(
                                _lookupPaths[index],
                                out provider);
                    }
                    catch (ProviderInvocationException providerInvocationException)
                    {
                        CommandDiscovery.discoveryTracer.WriteLine(
                            "The relative path '{0}', could not be resolved because the provider threw an exception: '{1}'",
                            _lookupPaths[index],
                            providerInvocationException.Message);
                    }
                    catch (InvalidOperationException)
                    {
                        CommandDiscovery.discoveryTracer.WriteLine(
                            "The relative path '{0}', could not resolve a home directory for the provider",
                            _lookupPaths[index]);
                    }

                    // Note, if the directory resolves to multiple paths, only the first is used.

                    if (!string.IsNullOrEmpty(resolvedPath))
                    {
                        CommandDiscovery.discoveryTracer.TraceError(
                            "The relative path resolved to: {0}",
                            resolvedPath);

                        resolvedDirectory = resolvedPath;
                    }
                    else
                    {
                        CommandDiscovery.discoveryTracer.WriteLine(
                            "The relative path was not a file system path. {0}",
                            _lookupPaths[index]);
                    }
                }
                else
                {
                    CommandDiscovery.discoveryTracer.TraceWarning(
                        "The current drive is not set, using the process current directory: {0}",
                        environmentCurrentDirectory);

                    resolvedDirectory = environmentCurrentDirectory;
                }

                // If we successfully resolved the path, make sure it is unique. Remove
                // any duplicates found after the first occurrence of the path.

                if (resolvedDirectory != null)
                {
                    int existingIndex = _lookupPaths.IndexOf(resolvedDirectory);

                    if (existingIndex != -1)
                    {
                        if (existingIndex > index)
                        {
                            // The relative path index is less than the explicit path,
                            // so remove the explicit path.

                            indexesToRemove.Add(removalListCount++, existingIndex);
                            _lookupPaths[index] = resolvedDirectory;
                        }
                        else
                        {
                            // The explicit path index is less than the relative path
                            // index, so remove the relative path.

                            indexesToRemove.Add(removalListCount++, index);
                        }
                    }
                    else
                    {
                        // Change the relative path to the resolved path.

                        _lookupPaths[index] = resolvedDirectory;
                    }
                }
                else
                {
                    // The directory couldn't be resolved so remove it from the
                    // lookup paths.

                    indexesToRemove.Add(removalListCount++, index);
                }
            }

            // Now remove all the duplicates starting from the back of the collection.
            // As each element is removed, elements that follow are moved up to occupy
            // the emptied index.

            for (int removeIndex = indexesToRemove.Count; removeIndex > 0; --removeIndex)
            {
                int indexToRemove = indexesToRemove[removeIndex - 1];
                _lookupPaths.RemoveAt(indexToRemove);
            }
        }
Esempio n. 17
0
        /// <summary>
        /// Changes the current working directory to the path specified.
        /// </summary>
        /// <param name="path">
        /// The path of the new current working directory.
        /// </param>
        /// <param name="context">
        /// The context the provider uses when performing the operation.
        /// </param>
        /// <param name="literalPath">
        /// Indicate if the path is a literal path.
        /// </param>
        /// <returns>
        /// The PathInfo object representing the path of the location
        /// that was set.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// If <paramref name="path"/> is null.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// If <paramref name="path"/> does not exist, is not a container, or
        /// resolved to multiple containers.
        /// </exception>
        /// <exception cref="ProviderNotFoundException">
        /// If <paramref name="path"/> refers to a provider that does not exist.
        /// </exception>
        /// <exception cref="DriveNotFoundException">
        /// If <paramref name="path"/> refers to a drive that does not exist.
        /// </exception>
        /// <exception cref="ProviderInvocationException">
        /// If the provider associated with <paramref name="path"/> threw an
        /// exception.
        /// </exception>
        /// <exception cref="ItemNotFoundException">
        /// If the <paramref name="path"/> could not be resolved.
        /// </exception>
        internal PathInfo SetLocation(string path, CmdletProviderContext context, bool literalPath)
        {
            if (path == null)
            {
                throw PSTraceSource.NewArgumentNullException("path");
            }

            PathInfo     current      = CurrentLocation;
            string       originalPath = path;
            string       driveName    = null;
            ProviderInfo provider     = null;
            string       providerId   = null;

            switch (originalPath)
            {
            case string originalPathSwitch when !literalPath && originalPathSwitch.Equals("-", StringComparison.Ordinal):
                if (_setLocationHistory.UndoCount <= 0)
                {
                    throw new InvalidOperationException(SessionStateStrings.LocationUndoStackIsEmpty);
                }

                path = _setLocationHistory.Undo(this.CurrentLocation).Path;
                break;

            case string originalPathSwitch when !literalPath && originalPathSwitch.Equals("+", StringComparison.Ordinal):
                if (_setLocationHistory.RedoCount <= 0)
                {
                    throw new InvalidOperationException(SessionStateStrings.LocationRedoStackIsEmpty);
                }

                path = _setLocationHistory.Redo(this.CurrentLocation).Path;
                break;

            default:
                var pushPathInfo = GetNewPushPathInfo();
                _setLocationHistory.Push(pushPathInfo);
                break;
            }

            PSDriveInfo previousWorkingDrive = CurrentDrive;

            // First check to see if the path is a home path
            if (LocationGlobber.IsHomePath(path))
            {
                path = Globber.GetHomeRelativePath(path);
            }

            if (LocationGlobber.IsProviderDirectPath(path))
            {
                // The path is a provider-direct path so use the current
                // provider and its hidden drive but don't modify the path
                // at all.
                provider     = CurrentLocation.Provider;
                CurrentDrive = provider.HiddenDrive;
            }
            else if (LocationGlobber.IsProviderQualifiedPath(path, out providerId))
            {
                provider     = GetSingleProvider(providerId);
                CurrentDrive = provider.HiddenDrive;
            }
            else
            {
                // See if the path is a relative or absolute
                // path.
                if (Globber.IsAbsolutePath(path, out driveName))
                {
                    // Since the path is an absolute path
                    // we need to change the current working
                    // drive
                    PSDriveInfo newWorkingDrive = GetDrive(driveName);
                    CurrentDrive = newWorkingDrive;

                    // If the path is simply a colon-terminated drive,
                    // not a slash-terminated path to the root of a drive,
                    // set the path to the current working directory of that drive.
                    string colonTerminatedVolume = CurrentDrive.Name + ':';
                    if (CurrentDrive.VolumeSeparatedByColon && (path.Length == colonTerminatedVolume.Length))
                    {
                        path = Path.Combine(colonTerminatedVolume + Path.DirectorySeparatorChar, CurrentDrive.CurrentLocation);
                    }

                    // Now that the current working drive is set,
                    // process the rest of the path as a relative path.
                }
            }

            if (context == null)
            {
                context = new CmdletProviderContext(this.ExecutionContext);
            }

            if (CurrentDrive != null)
            {
                context.Drive = CurrentDrive;
            }

            CmdletProvider providerInstance = null;

            Collection <PathInfo> workingPath = null;

            try
            {
                workingPath =
                    Globber.GetGlobbedMonadPathsFromMonadPath(
                        path,
                        false,
                        context,
                        out providerInstance);
            }
            catch (LoopFlowException)
            {
                throw;
            }
            catch (PipelineStoppedException)
            {
                throw;
            }
            catch (ActionPreferenceStopException)
            {
                throw;
            }
            catch (Exception)
            {
                // Reset the drive to the previous drive and
                // then rethrow the error
                CurrentDrive = previousWorkingDrive;
                throw;
            }

            if (workingPath.Count == 0)
            {
                // Set the current working drive back to the previous
                // one in case it was changed.
                CurrentDrive = previousWorkingDrive;

                throw
                    new ItemNotFoundException(
                        path,
                        "PathNotFound",
                        SessionStateStrings.PathNotFound);
            }

            // We allow globbing the location as long as it only resolves a single container.
            bool foundContainer                     = false;
            bool pathIsContainer                    = false;
            bool pathIsProviderQualifiedPath        = false;
            bool currentPathisProviderQualifiedPath = false;

            for (int index = 0; index < workingPath.Count; ++index)
            {
                CmdletProviderContext normalizePathContext =
                    new CmdletProviderContext(context);

                PathInfo resolvedPath = workingPath[index];
                string   currentPath  = path;
                try
                {
                    string providerName = null;
                    currentPathisProviderQualifiedPath = LocationGlobber.IsProviderQualifiedPath(resolvedPath.Path, out providerName);
                    if (currentPathisProviderQualifiedPath)
                    {
                        // The path should be the provider-qualified path without the provider ID
                        // or ::
                        string providerInternalPath = LocationGlobber.RemoveProviderQualifier(resolvedPath.Path);

                        try
                        {
                            currentPath = NormalizeRelativePath(GetSingleProvider(providerName), providerInternalPath, string.Empty, normalizePathContext);
                        }
                        catch (NotSupportedException)
                        {
                            // Since the provider does not support normalizing the path, just
                            // use the path we currently have.
                        }
                        catch (LoopFlowException)
                        {
                            throw;
                        }
                        catch (PipelineStoppedException)
                        {
                            throw;
                        }
                        catch (ActionPreferenceStopException)
                        {
                            throw;
                        }
                        catch (Exception)
                        {
                            // Reset the drive to the previous drive and
                            // then rethrow the error
                            CurrentDrive = previousWorkingDrive;
                            throw;
                        }
                    }
                    else
                    {
                        try
                        {
                            currentPath = NormalizeRelativePath(resolvedPath.Path, CurrentDrive.Root, normalizePathContext);
                        }
                        catch (NotSupportedException)
                        {
                            // Since the provider does not support normalizing the path, just
                            // use the path we currently have.
                        }
                        catch (LoopFlowException)
                        {
                            throw;
                        }
                        catch (PipelineStoppedException)
                        {
                            throw;
                        }
                        catch (ActionPreferenceStopException)
                        {
                            throw;
                        }
                        catch (Exception)
                        {
                            // Reset the drive to the previous drive and
                            // then rethrow the error
                            CurrentDrive = previousWorkingDrive;
                            throw;
                        }
                    }

                    // Now see if there was errors while normalizing the path
                    if (normalizePathContext.HasErrors())
                    {
                        // Set the current working drive back to the previous
                        // one in case it was changed.
                        CurrentDrive = previousWorkingDrive;

                        normalizePathContext.ThrowFirstErrorOrDoNothing();
                    }
                }
                finally
                {
                    normalizePathContext.RemoveStopReferral();
                }

                bool isContainer = false;

                CmdletProviderContext itemContainerContext =
                    new CmdletProviderContext(context);
                itemContainerContext.SuppressWildcardExpansion = true;

                try
                {
                    isContainer =
                        IsItemContainer(
                            resolvedPath.Path,
                            itemContainerContext);

                    if (itemContainerContext.HasErrors())
                    {
                        // Set the current working drive back to the previous
                        // one in case it was changed.
                        CurrentDrive = previousWorkingDrive;

                        itemContainerContext.ThrowFirstErrorOrDoNothing();
                    }
                }
                catch (NotSupportedException)
                {
                    if (currentPath.Length == 0)
                    {
                        // Treat this as a container because providers that only
                        // support the ContainerCmdletProvider interface are really
                        // containers at their root.
                        isContainer = true;
                    }
                }
                finally
                {
                    itemContainerContext.RemoveStopReferral();
                }

                if (isContainer)
                {
                    if (foundContainer)
                    {
                        // The path resolved to more than one container
                        // Set the current working drive back to the previous
                        // one in case it was changed.
                        CurrentDrive = previousWorkingDrive;

                        throw
                            PSTraceSource.NewArgumentException(
                                "path",
                                SessionStateStrings.PathResolvedToMultiple,
                                originalPath);
                    }
                    else
                    {
                        // Set the path to use
                        path = currentPath;

                        // Mark it as a container
                        pathIsContainer = true;

                        // Mark whether or not it was provider-qualified
                        pathIsProviderQualifiedPath = currentPathisProviderQualifiedPath;

                        // Mark that we have already found one container. Finding additional
                        // should be an error
                        foundContainer = true;
                    }
                }
            }

            if (pathIsContainer)
            {
                // Remove the root slash since it is implied that the
                // current working directory is relative to the root.
                if (!LocationGlobber.IsProviderDirectPath(path) &&
                    path.StartsWith(StringLiterals.DefaultPathSeparator) &&
                    !pathIsProviderQualifiedPath)
                {
                    path = path.Substring(1);
                }

                s_tracer.WriteLine(
                    "New working path = {0}",
                    path);

                CurrentDrive.CurrentLocation = path;
            }
            else
            {
                // Set the current working drive back to the previous
                // one in case it was changed.
                CurrentDrive = previousWorkingDrive;

                throw
                    new ItemNotFoundException(
                        originalPath,
                        "PathNotFound",
                        SessionStateStrings.PathNotFound);
            }

            // Now make sure the current drive is set in the provider's
            // current working drive hashtable
            ProvidersCurrentWorkingDrive[CurrentDrive.Provider] =
                CurrentDrive;

            // Set the $PWD variable to the new location
            this.SetVariable(SpecialVariables.PWDVarPath, this.CurrentLocation, false, true, CommandOrigin.Internal);

            // If an action has been defined for location changes, invoke it now.
            if (PublicSessionState.InvokeCommand.LocationChangedAction != null)
            {
                var eventArgs = new LocationChangedEventArgs(PublicSessionState, current, CurrentLocation);
                PublicSessionState.InvokeCommand.LocationChangedAction.Invoke(ExecutionContext.CurrentRunspace, eventArgs);
                s_tracer.WriteLine("Invoked LocationChangedAction");
            }

            return(this.CurrentLocation);
        }
Esempio n. 18
0
        private void ResolveCurrentDirectoryInLookupPaths()
        {
            SortedList           list               = new SortedList();
            int                  num                = 0;
            string               fileSystem         = this._context.ProviderNames.FileSystem;
            SessionStateInternal engineSessionState = this._context.EngineSessionState;
            bool                 flag               = ((engineSessionState.CurrentDrive != null) && engineSessionState.CurrentDrive.Provider.NameEquals(fileSystem)) && engineSessionState.IsProviderLoaded(fileSystem);
            string               currentDirectory   = Environment.CurrentDirectory;

            if (string.IsNullOrEmpty(currentDirectory) && OSHelper.IsUnix)
            {
                currentDirectory = "/";
            }

            LocationGlobber locationGlobber = this._context.LocationGlobber;

            foreach (int num2 in this.lookupPaths.IndexOfRelativePath())
            {
                string item         = null;
                string providerPath = null;
                CommandDiscovery.discoveryTracer.WriteLine("Lookup directory \"{0}\" appears to be a relative path. Attempting resolution...", new object[] { this.lookupPaths[num2] });
                if (flag)
                {
                    ProviderInfo provider = null;
                    try
                    {
                        providerPath = locationGlobber.GetProviderPath(this.lookupPaths[num2], out provider);
                    }
                    catch (ProviderInvocationException exception)
                    {
                        CommandDiscovery.discoveryTracer.WriteLine("The relative path '{0}', could not be resolved because the provider threw an exception: '{1}'", new object[] { this.lookupPaths[num2], exception.Message });
                    }
                    catch (InvalidOperationException)
                    {
                        CommandDiscovery.discoveryTracer.WriteLine("The relative path '{0}', could not resolve a home directory for the provider", new object[] { this.lookupPaths[num2] });
                    }
                    if (!string.IsNullOrEmpty(providerPath))
                    {
                        CommandDiscovery.discoveryTracer.TraceError("The relative path resolved to: {0}", new object[] { providerPath });
                        item = providerPath;
                    }
                    else
                    {
                        CommandDiscovery.discoveryTracer.WriteLine("The relative path was not a file system path. {0}", new object[] { this.lookupPaths[num2] });
                    }
                }
                else
                {
                    CommandDiscovery.discoveryTracer.TraceWarning("The current drive is not set, using the process current directory: {0}", new object[] { currentDirectory });
                    item = currentDirectory;
                }
                if (item != null)
                {
                    int index = this.lookupPaths.IndexOf(item);
                    if (index == -1)
                    {
                        this.lookupPaths[num2] = item;
                    }
                    else if (index > num2)
                    {
                        list.Add(num++, index);
                        this.lookupPaths[num2] = item;
                    }
                    else
                    {
                        list.Add(num++, num2);
                    }
                }
                else
                {
                    list.Add(num++, num2);
                }
            }
            for (int i = list.Count; i > 0; i--)
            {
                int num5 = (int)list[i - 1];
                this.lookupPaths.RemoveAt(num5);
            }
        }
Esempio n. 19
0
        private void ResolveCurrentDirectoryInLookupPaths()
        {
            SortedList           sortedList         = new SortedList();
            int                  num1               = 0;
            string               fileSystem         = this._context.ProviderNames.FileSystem;
            SessionStateInternal engineSessionState = this._context.EngineSessionState;
            bool                 flag               = engineSessionState.CurrentDrive != (PSDriveInfo)null && engineSessionState.CurrentDrive.Provider.NameEquals(fileSystem) && engineSessionState.IsProviderLoaded(fileSystem);
            string               currentDirectory   = Environment.CurrentDirectory;
            LocationGlobber      locationGlobber    = this._context.LocationGlobber;

            foreach (int index in this.lookupPaths.IndexOfRelativePath())
            {
                string str1 = (string)null;
                string str2 = (string)null;
                CommandDiscovery.discoveryTracer.WriteLine("Lookup directory \"{0}\" appears to be a relative path. Attempting resolution...", (object)this.lookupPaths[index]);
                if (flag)
                {
                    ProviderInfo provider = (ProviderInfo)null;
                    try
                    {
                        str2 = locationGlobber.GetProviderPath(this.lookupPaths[index], out provider);
                    }
                    catch (ProviderInvocationException ex)
                    {
                        CommandDiscovery.discoveryTracer.WriteLine("The relative path '{0}', could not be resolved because the provider threw an exception: '{1}'", (object)this.lookupPaths[index], (object)ex.Message);
                    }
                    catch (InvalidOperationException ex)
                    {
                        CommandDiscovery.discoveryTracer.WriteLine("The relative path '{0}', could not resolve a home directory for the provider", (object)this.lookupPaths[index]);
                    }
                    if (!string.IsNullOrEmpty(str2))
                    {
                        CommandDiscovery.discoveryTracer.TraceError("The relative path resolved to: {0}", (object)str2);
                        str1 = str2;
                    }
                    else
                    {
                        CommandDiscovery.discoveryTracer.WriteLine("The relative path was not a file system path. {0}", (object)this.lookupPaths[index]);
                    }
                }
                else
                {
                    CommandDiscovery.discoveryTracer.TraceWarning("The current drive is not set, using the process current directory: {0}", (object)currentDirectory);
                    str1 = currentDirectory;
                }
                if (str1 != null)
                {
                    int num2 = this.lookupPaths.IndexOf(str1);
                    if (num2 != -1)
                    {
                        if (num2 > index)
                        {
                            sortedList.Add((object)num1++, (object)num2);
                            this.lookupPaths[index] = str1;
                        }
                        else
                        {
                            sortedList.Add((object)num1++, (object)index);
                        }
                    }
                    else
                    {
                        this.lookupPaths[index] = str1;
                    }
                }
                else
                {
                    sortedList.Add((object)num1++, (object)index);
                }
            }
            for (int count = sortedList.Count; count > 0; --count)
            {
                this.lookupPaths.RemoveAt((int)sortedList[(object)(count - 1)]);
            }
        }
Esempio n. 20
0
 public bool IsProviderQualified(string path)
 {
     return(LocationGlobber.IsProviderQualifiedPath(path));
 }
Esempio n. 21
0
 public bool IsProviderQualified(string path)
 {
     using (PathIntrinsics.tracer.TraceMethod())
         return(LocationGlobber.IsProviderQualifiedPath(path));
 }
        } // SetLocation

        /// <summary>
        /// Changes the current working directory to the path specified
        /// </summary>
        ///
        /// <param name="path">
        /// The path of the new current working directory
        /// </param>
        ///
        /// <param name="context">
        /// The context the provider uses when performing the operation.
        /// </param>
        ///
        /// <returns>
        /// The PathInfo object representing the path of the location
        /// that was set.
        /// </returns>
        ///
        /// <exception cref="ArgumentNullException">
        /// If <paramref name="path"/> is null.
        /// </exception>
        ///
        /// <exception cref="ArgumentException">
        /// If <paramref name="path"/> does not exist, is not a container, or
        /// resolved to multiple containers.
        /// </exception>
        ///
        /// <exception cref="ProviderNotFoundException">
        /// If <paramref name="path"/> refers to a provider that does not exist.
        /// </exception>
        ///
        /// <exception cref="DriveNotFoundException">
        /// If <paramref name="path"/> refers to a drive that does not exist.
        /// </exception>
        ///
        /// <exception cref="ProviderInvocationException">
        /// If the provider associated with <paramref name="path"/> threw an
        /// exception.
        /// </exception>
        ///
        /// <exception cref="ItemNotFoundException">
        /// If the <paramref name="path"/> could not be resolved.
        /// </exception>
        ///
        internal PathInfo SetLocation(string path, CmdletProviderContext context)
        {
            if (path == null)
            {
                throw PSTraceSource.NewArgumentNullException("path");
            }

            string       originalPath = path;
            string       driveName    = null;
            ProviderInfo provider     = null;
            string       providerId   = null;

            PSDriveInfo previousWorkingDrive = CurrentDrive;

            // First check to see if the path is a home path

            if (LocationGlobber.IsHomePath(path))
            {
                path = Globber.GetHomeRelativePath(path);
            }

            if (LocationGlobber.IsProviderDirectPath(path))
            {
                // The path is a provider-direct path so use the current
                // provider and its hidden drive but don't modify the path
                // at all.

                provider     = CurrentLocation.Provider;
                CurrentDrive = provider.HiddenDrive;
            }
            else if (LocationGlobber.IsProviderQualifiedPath(path, out providerId))
            {
                provider     = GetSingleProvider(providerId);
                CurrentDrive = provider.HiddenDrive;
            }
            else
            {
                // See if the path is a relative or absolute
                // path.

                if (Globber.IsAbsolutePath(path, out driveName))
                {
                    // Since the path is an absolute path
                    // we need to change the current working
                    // drive

                    PSDriveInfo newWorkingDrive = GetDrive(driveName);
                    CurrentDrive = newWorkingDrive;

                    // Now that the current working drive is set,
                    // process the rest of the path as a relative path.
                }
            }

            if (context == null)
            {
                context = new CmdletProviderContext(this.ExecutionContext);
            }

            if (CurrentDrive != null)
            {
                context.Drive = CurrentDrive;
            }

            CmdletProvider providerInstance = null;

            Collection <PathInfo> workingPath = null;

            try
            {
                workingPath =
                    Globber.GetGlobbedMonadPathsFromMonadPath(
                        path,
                        false,
                        context,
                        out providerInstance);
            }
            catch (LoopFlowException)
            {
                throw;
            }
            catch (PipelineStoppedException)
            {
                throw;
            }
            catch (ActionPreferenceStopException)
            {
                throw;
            }
            catch (Exception) // Catch-all OK, 3rd party callout
            {
                // Reset the drive to the previous drive and
                // then rethrow the error

                CurrentDrive = previousWorkingDrive;
                throw;
            }

            if (workingPath.Count == 0)
            {
                // Set the current working drive back to the previous
                // one in case it was changed.

                CurrentDrive = previousWorkingDrive;

                throw
                    new ItemNotFoundException(
                        path,
                        "PathNotFound",
                        SessionStateStrings.PathNotFound);
            }

            // We allow globbing the location as long as it only resolves a single container.

            bool foundContainer                     = false;
            bool pathIsContainer                    = false;
            bool pathIsProviderQualifiedPath        = false;
            bool currentPathisProviderQualifiedPath = false;

            for (int index = 0; index < workingPath.Count; ++index)
            {
                CmdletProviderContext normalizePathContext =
                    new CmdletProviderContext(context);

                PathInfo resolvedPath = workingPath[index];
                string   currentPath  = path;
                try
                {
                    string providerName = null;
                    currentPathisProviderQualifiedPath = LocationGlobber.IsProviderQualifiedPath(resolvedPath.Path, out providerName);
                    if (currentPathisProviderQualifiedPath)
                    {
                        // The path should be the provider-qualified path without the provider ID
                        // or ::

                        string providerInternalPath = LocationGlobber.RemoveProviderQualifier(resolvedPath.Path);

                        try
                        {
                            currentPath = NormalizeRelativePath(GetSingleProvider(providerName), providerInternalPath, String.Empty, normalizePathContext);
                        }
                        catch (NotSupportedException)
                        {
                            // Since the provider does not support normalizing the path, just
                            // use the path we currently have.
                        }
                        catch (LoopFlowException)
                        {
                            throw;
                        }
                        catch (PipelineStoppedException)
                        {
                            throw;
                        }
                        catch (ActionPreferenceStopException)
                        {
                            throw;
                        }
                        catch (Exception) // Catch-all OK, 3rd party callout
                        {
                            // Reset the drive to the previous drive and
                            // then rethrow the error

                            CurrentDrive = previousWorkingDrive;
                            throw;
                        }
                    }
                    else
                    {
                        try
                        {
                            currentPath = NormalizeRelativePath(resolvedPath.Path, CurrentDrive.Root, normalizePathContext);
                        }
                        catch (NotSupportedException)
                        {
                            // Since the provider does not support normalizing the path, just
                            // use the path we currently have.
                        }
                        catch (LoopFlowException)
                        {
                            throw;
                        }
                        catch (PipelineStoppedException)
                        {
                            throw;
                        }
                        catch (ActionPreferenceStopException)
                        {
                            throw;
                        }
                        catch (Exception) // Catch-all OK, 3rd party callout
                        {
                            // Reset the drive to the previous drive and
                            // then rethrow the error

                            CurrentDrive = previousWorkingDrive;
                            throw;
                        }
                    }

                    // Now see if there was errors while normalizing the path

                    if (normalizePathContext.HasErrors())
                    {
                        // Set the current working drive back to the previous
                        // one in case it was changed.

                        CurrentDrive = previousWorkingDrive;

                        normalizePathContext.ThrowFirstErrorOrDoNothing();
                    }
                }
                finally
                {
                    normalizePathContext.RemoveStopReferral();
                }

                // Check to see if the path is a container

                bool isContainer = false;

                CmdletProviderContext itemContainerContext =
                    new CmdletProviderContext(context);
                itemContainerContext.SuppressWildcardExpansion = true;

                try
                {
                    isContainer =
                        IsItemContainer(
                            resolvedPath.Path,
                            itemContainerContext);

                    if (itemContainerContext.HasErrors())
                    {
                        // Set the current working drive back to the previous
                        // one in case it was changed.

                        CurrentDrive = previousWorkingDrive;

                        itemContainerContext.ThrowFirstErrorOrDoNothing();
                    }
                }
                catch (NotSupportedException)
                {
                    if (currentPath.Length == 0)
                    {
                        // Treat this as a container because providers that only
                        // support the ContainerCmdletProvider interface are really
                        // containers at their root.

                        isContainer = true;
                    }
                }
                finally
                {
                    itemContainerContext.RemoveStopReferral();
                }

                if (isContainer)
                {
                    if (foundContainer)
                    {
                        // The path resolved to more than one container

                        // Set the current working drive back to the previous
                        // one in case it was changed.

                        CurrentDrive = previousWorkingDrive;

                        throw
                            PSTraceSource.NewArgumentException(
                                "path",
                                SessionStateStrings.PathResolvedToMultiple,
                                originalPath);
                    }
                    else
                    {
                        // Set the path to use
                        path = currentPath;

                        // Mark it as a container
                        pathIsContainer = true;

                        // Mark whether or not it was provider-qualified
                        pathIsProviderQualifiedPath = currentPathisProviderQualifiedPath;

                        // Mark that we have already found one container. Finding additional
                        // should be an error
                        foundContainer = true;
                    }
                }
            }

            if (pathIsContainer)
            {
                // Remove the root slash since it is implied that the
                // current working directory is relative to the root.

                if (!LocationGlobber.IsProviderDirectPath(path) &&
                    path.StartsWith(StringLiterals.DefaultPathSeparatorString, StringComparison.CurrentCulture) &&
                    !pathIsProviderQualifiedPath)
                {
                    path = path.Substring(1);
                }

                s_tracer.WriteLine(
                    "New working path = {0}",
                    path);

                CurrentDrive.CurrentLocation = path;
            }
            else
            {
                // Set the current working drive back to the previous
                // one in case it was changed.

                CurrentDrive = previousWorkingDrive;

                throw
                    new ItemNotFoundException(
                        originalPath,
                        "PathNotFound",
                        SessionStateStrings.PathNotFound);
            }

            // Now make sure the current drive is set in the provider's
            // current working drive hashtable

            ProvidersCurrentWorkingDrive[CurrentDrive.Provider] =
                CurrentDrive;

            // Set the $PWD variable to the new location

            this.SetVariable(SpecialVariables.PWDVarPath, this.CurrentLocation, false, true, CommandOrigin.Internal);
            return(this.CurrentLocation);
        } // SetLocation