예제 #1
0
 internal Collection<string> GetGlobbedProviderPathsFromProviderPath(string path, bool allowNonexistingPaths, string providerId, out CmdletProvider providerInstance)
 {
     providerInstance = null;
     if (path == null)
     {
         throw PSTraceSource.NewArgumentNullException("path");
     }
     CmdletProviderContext context = new CmdletProviderContext(this.sessionState.Internal.ExecutionContext);
     Collection<string> collection = this.GetGlobbedProviderPathsFromProviderPath(path, allowNonexistingPaths, providerId, context, out providerInstance);
     if (context.HasErrors())
     {
         ErrorRecord record = context.GetAccumulatedErrorObjects()[0];
         if (record != null)
         {
             throw record.Exception;
         }
     }
     return collection;
 }
예제 #2
0
 internal string GetProviderPath(string path, out ProviderInfo provider)
 {
     if (path == null)
     {
         throw PSTraceSource.NewArgumentNullException("path");
     }
     CmdletProviderContext context = new CmdletProviderContext(this.sessionState.Internal.ExecutionContext);
     PSDriveInfo drive = null;
     provider = null;
     string str = this.GetProviderPath(path, context, out provider, out drive);
     if (context.HasErrors())
     {
         Collection<ErrorRecord> accumulatedErrorObjects = context.GetAccumulatedErrorObjects();
         if ((accumulatedErrorObjects != null) && (accumulatedErrorObjects.Count > 0))
         {
             throw accumulatedErrorObjects[0].Exception;
         }
     }
     return str;
 }
예제 #3
0
        } // GetProviderPath


        /// <summary>
        /// Gets a provider specific path when given an Msh path without resolving the
        /// glob characters.
        /// </summary>
        /// 
        /// <param name="path">
        /// An Msh path.
        /// </param>
        /// 
        /// <param name="provider">
        /// The information of the provider that was used to resolve the path.
        /// </param>
        /// 
        /// <returns>
        /// A provider specific path that the Msh path represents.
        /// </returns>
        /// 
        /// <exception cref="ArgumentNullException">
        /// If <paramref name="path"/> is null.
        /// </exception>
        /// 
        /// <exception cref="ProviderNotFoundException">
        /// If the path is a provider-qualified path for a provider that is
        /// not loaded into the system.
        /// </exception>
        /// 
        /// <exception cref="DriveNotFoundException">
        /// If the <paramref name="path"/> refers to a drive that could not be found.
        /// </exception>
        /// 
        /// <exception cref="ProviderInvocationException">
        /// If the provider used to build the path threw an exception.
        /// </exception>
        /// 
        /// <exception cref="NotSupportedException">
        /// If the provider that the <paramref name="path"/> represents is not a NavigationCmdletProvider
        /// or ContainerCmdletProvider.
        /// </exception>
        /// 
        /// <exception cref="InvalidOperationException">
        /// If the <paramref name="path"/> starts with "~" and the home location is not set for 
        /// the provider.
        /// </exception>
        /// 
        /// <exception cref="ProviderInvocationException">
        /// If the provider specified by <paramref name="provider"/> threw an
        /// exception when its GetParentPath or MakePath was called while
        /// processing the <paramref name="path"/>.
        /// </exception>
        /// 
        /// <exception>
        /// Any exception can be thrown by the provider that is called to build
        /// the provider path.
        /// </exception>
        /// 
        internal string GetProviderPath(string path, out ProviderInfo provider)
        {
            if (path == null)
            {
                throw PSTraceSource.NewArgumentNullException("path");
            }

            CmdletProviderContext context =
                new CmdletProviderContext(_sessionState.Internal.ExecutionContext);

            PSDriveInfo drive = null;
            provider = null;

            string result = GetProviderPath(path, context, out provider, out drive);

            if (context.HasErrors())
            {
                Collection<ErrorRecord> errors = context.GetAccumulatedErrorObjects();

                if (errors != null &&
                    errors.Count > 0)
                {
                    throw errors[0].Exception;
                }
            }

            return result;
        } // GetProviderPath
예제 #4
0
        } // GenerateNewPathsWithGlobLeaf

        /// <summary>
        /// Gets the child names in the specified path by using the provider
        /// </summary>
        /// 
        /// <param name="dir">
        /// The path of the directory to get the child names from. If this is an Msh Path,
        /// dirIsProviderPath must be false, If this is a provider-internal path,
        /// dirIsProviderPath must be true.
        /// </param>
        /// 
        /// <param name="leafElement">
        /// The element that we are ultimately looking for. Used to set filters on the context
        /// if desired.
        /// </param>
        /// 
        /// <param name="getAllContainers">
        /// Determines if the GetChildNames call should get all containers even if they don't
        /// match the filter.
        /// </param>
        /// 
        /// <param name="context">
        /// The context to be used for the command. The context is copied to a new context, the
        /// results are accumulated and then returned.
        /// </param>
        /// 
        /// <param name="dirIsProviderPath">
        /// Specifies whether the dir parameter is a provider-internal path (true) or Msh Path (false).
        /// </param>
        /// 
        /// <param name="drive">
        /// The drive to use to qualify the Msh path if dirIsProviderPath is false.
        /// </param>
        /// 
        /// <param name="provider">
        /// The provider to use to get the child names.
        /// </param>
        /// 
        /// <param name="modifiedDirPath">
        /// Returns the modified dir path. If dirIsProviderPath is true, this is the unescaped dir path.
        /// If dirIsProviderPath is false, this is the unescaped resolved provider path.
        /// </param>
        /// 
        /// <returns>
        /// A collection of PSObjects whose BaseObject is a string that contains the name of the child.
        /// </returns>
        /// 
        /// <exception cref="ArgumentNullException">
        /// If <paramref name="dir"/> or <paramref name="drive"/> is null.
        /// </exception>
        /// 
        /// <exception cref="ProviderNotFoundException">
        /// If the path is a provider-qualified path for a provider that is
        /// not loaded into the system.
        /// </exception>
        /// 
        /// <exception cref="DriveNotFoundException">
        /// If the <paramref name="path"/> refers to a drive that could not be found.
        /// </exception>
        /// 
        /// <exception cref="ProviderInvocationException">
        /// If the provider used to build the path threw an exception.
        /// </exception>
        /// 
        /// <exception cref="NotSupportedException">
        /// If the provider that the <paramref name="path"/> represents is not a NavigationCmdletProvider
        /// or ContainerCmdletProvider.
        /// </exception>
        /// 
        /// <exception cref="InvalidOperationException">
        /// If the <paramref name="path"/> starts with "~" and the home location is not set for 
        /// the provider.
        /// </exception>
        /// 
        /// <exception cref="ProviderInvocationException">
        /// If the provider associated with the <paramref name="path"/> threw an
        /// exception when its GetParentPath or MakePath was called while
        /// processing the <paramref name="path"/>.
        /// </exception>
        /// 
        /// <exception cref="PipelineStoppedException">
        /// If <paramref name="context"/> has been signaled for
        /// StopProcessing.
        /// </exception>
        /// 
        /// <exception>
        /// Any exception can be thrown by the provider that is called to build
        /// the provider path.
        /// </exception>
        /// 
        private Collection<PSObject> GetChildNamesInDir(
            string dir,
            string leafElement,
            bool getAllContainers,
            CmdletProviderContext context,
            bool dirIsProviderPath,
            PSDriveInfo drive,
            ContainerCmdletProvider provider,
            out string modifiedDirPath)
        {
            // See if the provider wants to convert the path and filter
            string convertedPath = null;
            string convertedFilter = null;
            string originalFilter = context.Filter;
            bool changedPathOrFilter = provider.ConvertPath(leafElement, context.Filter, ref convertedPath, ref convertedFilter, context);

            if (changedPathOrFilter)
            {
                if (s_tracer.IsEnabled)
                {
                    s_tracer.WriteLine("Provider converted path and filter.");
                    s_tracer.WriteLine("Original path: {0}", leafElement);
                    s_tracer.WriteLine("Converted path: {0}", convertedPath);
                    s_tracer.WriteLine("Original filter: {0}", context.Filter);
                    s_tracer.WriteLine("Converted filter: {0}", convertedFilter);
                }

                leafElement = convertedPath;
                context.Filter = convertedFilter;
            }

            ReturnContainers returnContainers = ReturnContainers.ReturnAllContainers;
            if (!getAllContainers)
            {
                returnContainers = ReturnContainers.ReturnMatchingContainers;
            }

            CmdletProviderContext getChildNamesContext =
                new CmdletProviderContext(context);

            // Remove the include/exclude filters from the new context
            getChildNamesContext.SetFilters(
                new Collection<string>(),
                new Collection<string>(),
                context.Filter);

            try
            {
                // Use the provider to get the children
                string unescapedDir = null;
                modifiedDirPath = null;

                if (dirIsProviderPath)
                {
                    modifiedDirPath = unescapedDir = context.SuppressWildcardExpansion ? dir : RemoveGlobEscaping(dir);
                }
                else
                {
                    Dbg.Diagnostics.Assert(
                        drive != null,
                        "Caller should verify that drive is not null when dirIsProviderPath is false");

                    // If the directory is an MSH path we must resolve it before calling GetChildNames()
                    // -- If the path is passed in by LiteralPath (context.SuppressWildcardExpansion == false), we surely should use 'dir' unchanged.
                    // -- If the path is passed in by Path (context.SuppressWildcardExpansion == true), we still should use 'dir' unchanged, in case that the special character
                    //    in 'dir' is escaped
                    modifiedDirPath = GetMshQualifiedPath(dir, drive);

                    ProviderInfo providerIgnored = null;
                    CmdletProvider providerInstanceIgnored = null;
                    Collection<string> resolvedPaths =
                        GetGlobbedProviderPathsFromMonadPath(
                            modifiedDirPath,
                            false,
                            getChildNamesContext,
                            out providerIgnored,
                            out providerInstanceIgnored);

                    // After resolving the path, we unescape the modifiedDirPath if necessary.
                    modifiedDirPath = context.SuppressWildcardExpansion
                                          ? modifiedDirPath
                                          : RemoveGlobEscaping(modifiedDirPath);
                    if (resolvedPaths.Count > 0)
                    {
                        unescapedDir = resolvedPaths[0];
                    }
                    else
                    {
                        // If there were no results from globbing but no
                        // exception was thrown, that means there was filtering.
                        // So return an empty collection and let the caller deal
                        // with it.

                        if (changedPathOrFilter)
                        {
                            context.Filter = originalFilter;
                        }

                        return new Collection<PSObject>();
                    }
                }

                if (provider.HasChildItems(unescapedDir, getChildNamesContext))
                {
                    provider.GetChildNames(
                        unescapedDir,
                        returnContainers,
                        getChildNamesContext);
                }

                // First check to see if there were any errors, and write them
                // to the real context if there are.

                if (getChildNamesContext.HasErrors())
                {
                    Collection<ErrorRecord> errors = getChildNamesContext.GetAccumulatedErrorObjects();

                    if (errors != null &&
                        errors.Count > 0)
                    {
                        foreach (ErrorRecord errorRecord in errors)
                        {
                            context.WriteError(errorRecord);
                        }
                    }
                }

                Collection<PSObject> childNamesObjectArray = getChildNamesContext.GetAccumulatedObjects();

                if (changedPathOrFilter)
                {
                    context.Filter = originalFilter;
                }

                return childNamesObjectArray;
            }
            finally
            {
                getChildNamesContext.RemoveStopReferral();
            }
        } // GetChildNamesInDir
예제 #5
0
        } //NormalizeRelativePath

        /// <summary>
        /// Normalizes the path that was passed in and returns the normalized path
        /// as a relative path to the basePath that was passed.
        /// </summary>
        /// 
        /// <param name="path">
        /// An MSH path to an item. The item should exist
        /// or the provider should write out an error.
        /// </param>
        /// 
        /// <param name="basePath">
        /// The path that the return value should be relative to.
        /// </param>
        /// 
        /// <param name="context">
        /// The context under which the command is running.
        /// </param>
        /// 
        /// <returns>
        /// A normalized path that is relative to the basePath that was passed. 
        /// </returns>
        ///
        /// <exception cref="ArgumentNullException">
        /// If <paramref name="path"/> is null.
        /// </exception>
        /// 
        /// <exception cref="NotSupportedException">
        /// If the <paramref name="providerInstance"/> does not support this operation.
        /// </exception>
        /// 
        /// <exception cref="PipelineStoppedException">
        /// If the pipeline is being stopped while executing the command.
        /// </exception>
        /// 
        /// <exception cref="ProviderInvocationException">
        /// If the provider threw an exception.
        /// </exception>
        /// 
        internal string NormalizeRelativePath(
            string path,
            string basePath,
            CmdletProviderContext context)
        {
            if (path == null)
            {
                throw PSTraceSource.NewArgumentNullException("path");
            }

            CmdletProviderContext getProviderPathContext =
                new CmdletProviderContext(context);

            try
            {
                PSDriveInfo drive = null;
                ProviderInfo provider = null;

                string workingPath = Globber.GetProviderPath(
                     path,
                     getProviderPathContext,
                     out provider,
                     out drive);

                if (getProviderPathContext.HasErrors())
                {
                    getProviderPathContext.WriteErrorsToContext(context);
                    return null;
                }

                if (workingPath == null ||
                    provider == null)
                {
                    // Since the provider didn't write an error, and we didn't get any
                    // results ourselves, we need to write out our own error.

                    Exception e = PSTraceSource.NewArgumentException("path");
                    context.WriteError(new ErrorRecord(e, "NormalizePathNullResult", ErrorCategory.InvalidArgument, path));
                    return null;
                }

                if (basePath != null)
                {
                    PSDriveInfo baseDrive = null;
                    ProviderInfo baseProvider = null;

                    Globber.GetProviderPath(
                         basePath,
                         getProviderPathContext,
                         out baseProvider,
                         out baseDrive);

                    if (drive != null && baseDrive != null)
                    {
                        if (!drive.Name.Equals(baseDrive.Name, StringComparison.OrdinalIgnoreCase))
                        {
                            // Make sure they are from physically different drives
                            // Doing StartsWith from both directions covers the following cases
                            // C:\ and C:\Temp
                            // C:\Temp and C:\
                            if (!(drive.Root.StartsWith(baseDrive.Root, StringComparison.OrdinalIgnoreCase) ||
                                (baseDrive.Root.StartsWith(drive.Root, StringComparison.OrdinalIgnoreCase))))
                            {
                                // In this case, no normalization is necessary
                                return path;
                            }
                        }
                    }
                }

                if (drive != null)
                {
                    context.Drive = drive;

                    // Detect if the original path was already a
                    // provider path. This happens when a drive doesn't
                    // have a rooted root -- such as HKEY_LOCAL_MACHINE instead of
                    // \\HKEY_LOCAL_MACHINE
                    if (
                        (GetProviderInstance(provider) is NavigationCmdletProvider) &&
                        (!String.IsNullOrEmpty(drive.Root)) &&
                        (path.StartsWith(drive.Root, StringComparison.OrdinalIgnoreCase)))
                    {
                        //
                        // If the drive root doesn't end with a path separator then there is a chance the
                        // path starts with the drive root name but doesn't actually refer to it.  For example,
                        // (see Win8 bug 922001) consider drive with root HKEY_LOCAL_MACHINE named 
                        // HKEY_LOCAL_MACHINE_foo.  The path would start with the drive root but is not a provider
                        // path.
                        //
                        // We will remediate this by only considering this a provider path if 
                        // 1.  The drive root ends with a path separator.
                        // OR
                        // 2.  The path starts with the drive root followed by a path separator
                        // OR
                        // 3.  The path exactly matches the drive root.
                        // 

                        // 1. Test for the drive root ending with a path separator.
                        bool driveRootEndsWithPathSeparator = IsPathSeparator(drive.Root[drive.Root.Length - 1]);


                        // 2. Test for the path starting with the drive root followed by a path separator
                        int indexAfterDriveRoot = drive.Root.Length;
                        bool pathStartsWithDriveRootAndPathSeparator = indexAfterDriveRoot < path.Length && IsPathSeparator(path[indexAfterDriveRoot]);


                        // 3. Test for the drive root exactly matching the path.
                        //    Since we know the path starts with the drive root then they are equal if the lengths are equal.
                        bool pathEqualsDriveRoot = drive.Root.Length == path.Length;


                        if (driveRootEndsWithPathSeparator || pathStartsWithDriveRootAndPathSeparator || pathEqualsDriveRoot)
                        {
                            workingPath = path;
                        }
                    }
                }

                return NormalizeRelativePath(provider, workingPath, basePath, context);
            }
            finally
            {
                getProviderPathContext.RemoveStopReferral();
            }
        } // NormalizeRelativePath
예제 #6
0
        } // SetLocation

        /// <summary>
        /// Determines if the specified path is the current working directory
        /// or a parent of the current working directory.
        /// </summary>
        /// 
        /// <param name="path">
        /// A monad namespace absolute or relative path.
        /// </param>
        /// 
        /// <param name="context">
        /// The context the provider uses when performing the operation.
        /// </param>
        /// 
        /// <returns>
        /// true, if the path is the current working directory or a parent of the current
        /// working directory. false, otherwise.
        /// </returns>
        /// 
        /// <exception cref="ArgumentNullException">
        /// If <paramref name="path"/> is null.
        /// </exception>
        /// 
        /// <exception cref="ProviderNotFoundException">
        /// If the path is a provider-qualified path for a provider that is
        /// not loaded into the system.
        /// </exception>
        /// 
        /// <exception cref="DriveNotFoundException">
        /// If the <paramref name="path"/> refers to a drive that could not be found.
        /// </exception>
        /// 
        /// <exception cref="ProviderInvocationException">
        /// If the provider used to build the path threw an exception.
        /// </exception>
        /// 
        /// <exception cref="NotSupportedException">
        /// If the provider that the <paramref name="path"/> represents is not a NavigationCmdletProvider
        /// or ContainerCmdletProvider.
        /// </exception>
        /// 
        /// <exception cref="InvalidOperationException">
        /// If the <paramref name="path"/> starts with "~" and the home location is not set for 
        /// the provider.
        /// </exception>
        /// 
        /// <exception cref="ProviderInvocationException">
        /// If the provider specified by <paramref name="providerId"/> threw an
        /// exception when its GetParentPath or MakePath was called while
        /// processing the <paramref name="path"/>.
        /// </exception>
        /// 
        internal bool IsCurrentLocationOrAncestor(string path, CmdletProviderContext context)
        {
            bool result = false;

            if (path == null)
            {
                throw PSTraceSource.NewArgumentNullException("path");
            }

            PSDriveInfo drive = null;
            ProviderInfo provider = null;

            string providerSpecificPath =
                Globber.GetProviderPath(
                    path,
                    context,
                    out provider,
                    out drive);

            if (drive != null)
            {
                s_tracer.WriteLine("Tracing drive");
                drive.Trace();
            }

            Dbg.Diagnostics.Assert(
                providerSpecificPath != null,
                "There should always be a way to generate a provider path for a " +
                "given path");

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

            // Check to see if the path that was specified is within the current
            // working drive

            if (drive == CurrentDrive)
            {
                // The path needs to be normalized to get rid of relative path tokens
                // so they don't interfere with our path comparisons below

                CmdletProviderContext normalizePathContext
                    = new CmdletProviderContext(context);

                try
                {
                    providerSpecificPath = NormalizeRelativePath(path, null, 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;
                }
                finally
                {
                    normalizePathContext.RemoveStopReferral();
                }

                if (normalizePathContext.HasErrors())
                {
                    normalizePathContext.ThrowFirstErrorOrDoNothing();
                }

                s_tracer.WriteLine("Provider path = {0}", providerSpecificPath);

                // Get the current working directory provider specific path

                PSDriveInfo currentWorkingDrive = null;
                ProviderInfo currentDriveProvider = null;

                string currentWorkingPath =
                    Globber.GetProviderPath(
                        ".",
                        context,
                        out currentDriveProvider,
                        out currentWorkingDrive);

                Dbg.Diagnostics.Assert(
                    currentWorkingDrive == CurrentDrive,
                    "The current working drive should be the CurrentDrive.");

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

                // See if the path is the current working directory or a parent
                // of the current working directory

                s_tracer.WriteLine(
                    "Comparing {0} to {1}",
                    providerSpecificPath,
                    currentWorkingPath);

                if (String.Compare(providerSpecificPath, currentWorkingPath, StringComparison.CurrentCultureIgnoreCase) == 0)
                {
                    // The path is the current working directory so
                    // return true

                    s_tracer.WriteLine("The path is the current working directory");

                    result = true;
                }
                else
                {
                    // Check to see if the specified path is a parent
                    // of the current working directory

                    string lockedDirectory = currentWorkingPath;

                    while (lockedDirectory.Length > 0)
                    {
                        // We need to allow the provider to go as far up the tree
                        // as it can even if that means it has to traverse higher
                        // than the mount point for this drive. That is
                        // why we are passing the empty string as the root here.

                        lockedDirectory =
                            GetParentPath(
                                drive.Provider,
                                lockedDirectory,
                                String.Empty,
                                context);

                        s_tracer.WriteLine(
                            "Comparing {0} to {1}",
                            lockedDirectory,
                            providerSpecificPath);

                        if (String.Compare(lockedDirectory, providerSpecificPath, StringComparison.CurrentCultureIgnoreCase) == 0)
                        {
                            // The path is a parent of the current working
                            // directory

                            s_tracer.WriteLine(
                                "The path is a parent of the current working directory: {0}",
                                lockedDirectory);

                            result = true;
                            break;
                        }
                    }
                }
            }
            else
            {
                s_tracer.WriteLine("Drives are not the same");
            }

            return result;
        } // IsCurrentLocationOrAncestor
예제 #7
0
 internal void RemoveDrive(PSDriveInfo drive, bool force, string scopeID)
 {
     if (drive == null)
     {
         throw PSTraceSource.NewArgumentNullException("drive");
     }
     CmdletProviderContext context = new CmdletProviderContext(this.ExecutionContext);
     this.RemoveDrive(drive, force, scopeID, context);
     if (context.HasErrors() && !force)
     {
         context.ThrowFirstErrorOrDoNothing();
     }
 }
예제 #8
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);
        }
예제 #9
0
 internal bool IsCurrentLocationOrAncestor(string path, CmdletProviderContext context)
 {
     bool flag = false;
     if (path == null)
     {
         throw PSTraceSource.NewArgumentNullException("path");
     }
     PSDriveInfo drive = null;
     ProviderInfo provider = null;
     string strA = this.Globber.GetProviderPath(path, context, out provider, out drive);
     if (drive != null)
     {
         tracer.WriteLine("Tracing drive", new object[0]);
         drive.Trace();
     }
     if (drive != null)
     {
         context.Drive = drive;
     }
     if (drive == this.CurrentDrive)
     {
         CmdletProviderContext context2 = new CmdletProviderContext(context);
         try
         {
             strA = this.NormalizeRelativePath(path, null, context2);
         }
         catch (NotSupportedException)
         {
         }
         catch (LoopFlowException)
         {
             throw;
         }
         catch (PipelineStoppedException)
         {
             throw;
         }
         catch (ActionPreferenceStopException)
         {
             throw;
         }
         finally
         {
             context2.RemoveStopReferral();
         }
         if (context2.HasErrors())
         {
             context2.ThrowFirstErrorOrDoNothing();
         }
         tracer.WriteLine("Provider path = {0}", new object[] { strA });
         PSDriveInfo info3 = null;
         ProviderInfo info4 = null;
         string strB = this.Globber.GetProviderPath(".", context, out info4, out info3);
         tracer.WriteLine("Current working path = {0}", new object[] { strB });
         tracer.WriteLine("Comparing {0} to {1}", new object[] { strA, strB });
         if (string.Compare(strA, strB, true, Thread.CurrentThread.CurrentCulture) == 0)
         {
             tracer.WriteLine("The path is the current working directory", new object[0]);
             flag = true;
         }
         else
         {
             string str3 = strB;
             while (str3.Length > 0)
             {
                 str3 = this.GetParentPath(drive.Provider, str3, string.Empty, context);
                 tracer.WriteLine("Comparing {0} to {1}", new object[] { str3, strA });
                 if (string.Compare(str3, strA, true, Thread.CurrentThread.CurrentCulture) == 0)
                 {
                     tracer.WriteLine("The path is a parent of the current working directory: {0}", new object[] { str3 });
                     flag = true;
                     break;
                 }
             }
         }
     }
     else
     {
         tracer.WriteLine("Drives are not the same", new object[0]);
     }
     tracer.WriteLine("result = {0}", new object[] { flag });
     return flag;
 }
예제 #10
0
 internal string NormalizeRelativePath(string path, string basePath, CmdletProviderContext context)
 {
     string str2;
     if (path == null)
     {
         throw PSTraceSource.NewArgumentNullException("path");
     }
     CmdletProviderContext context2 = new CmdletProviderContext(context);
     try
     {
         PSDriveInfo drive = null;
         ProviderInfo provider = null;
         string str = this.Globber.GetProviderPath(path, context2, out provider, out drive);
         if (context2.HasErrors())
         {
             context2.WriteErrorsToContext(context);
             return null;
         }
         if ((str == null) || (provider == null))
         {
             Exception exception = PSTraceSource.NewArgumentException("path");
             context.WriteError(new ErrorRecord(exception, "NormalizePathNullResult", ErrorCategory.InvalidArgument, path));
             return null;
         }
         if (drive != null)
         {
             context.Drive = drive;
             if (((this.GetProviderInstance(provider) is NavigationCmdletProvider) && !string.IsNullOrEmpty(drive.Root)) && path.StartsWith(drive.Root, StringComparison.OrdinalIgnoreCase))
             {
                 str = path;
             }
         }
         str2 = this.NormalizeRelativePath(provider, str, basePath, context);
     }
     finally
     {
         context2.RemoveStopReferral();
     }
     return str2;
 }
예제 #11
0
 internal string GetParentPath(string path, string root, CmdletProviderContext context, bool useDefaultProvider)
 {
     string str4;
     if (path == null)
     {
         throw PSTraceSource.NewArgumentNullException("path");
     }
     CmdletProviderContext context2 = new CmdletProviderContext(context);
     try
     {
         PSDriveInfo drive = null;
         ProviderInfo provider = null;
         try
         {
             this.Globber.GetProviderPath(path, context2, out provider, out drive);
         }
         catch (System.Management.Automation.DriveNotFoundException)
         {
             if (!useDefaultProvider)
             {
                 throw;
             }
             provider = this.PublicSessionState.Internal.GetSingleProvider("FileSystem");
         }
         if (context2.HasErrors())
         {
             context2.WriteErrorsToContext(context);
             return null;
         }
         if (drive != null)
         {
             context.Drive = drive;
         }
         bool isProviderQualified = false;
         bool isDriveQualified = false;
         string qualifier = null;
         string str2 = this.RemoveQualifier(path, out qualifier, out isProviderQualified, out isDriveQualified);
         string str3 = this.GetParentPath(provider, str2, root, context);
         if (!string.IsNullOrEmpty(qualifier) && !string.IsNullOrEmpty(str3))
         {
             str3 = this.AddQualifier(str3, qualifier, isProviderQualified, isDriveQualified);
         }
         tracer.WriteLine("result = {0}", new object[] { str3 });
         str4 = str3;
     }
     finally
     {
         context2.RemoveStopReferral();
     }
     return str4;
 }
예제 #12
0
        private PSDriveInfo AutomountFileSystemDrive(DriveInfo systemDriveInfo)
        {
            PSDriveInfo newDrive = null;
            if (!this.IsProviderLoaded(this.ExecutionContext.ProviderNames.FileSystem))
            {
                tracer.WriteLine("The {0} provider is not loaded", new object[] { this.ExecutionContext.ProviderNames.FileSystem });
                return newDrive;
            }
            try
            {
                DriveCmdletProvider driveProviderInstance = this.GetDriveProviderInstance(this.ExecutionContext.ProviderNames.FileSystem);
                if (driveProviderInstance == null)
                {
                    return newDrive;
                }
				string name = OSHelper.IsUnix ? systemDriveInfo.Name : systemDriveInfo.Name.Substring(0, 1);
                string description = string.Empty;
                try
                {
                    description = systemDriveInfo.VolumeLabel;
                }
                catch (UnauthorizedAccessException)
                {
                }
                PSDriveInfo drive = new PSDriveInfo(name, driveProviderInstance.ProviderInfo, systemDriveInfo.RootDirectory.FullName, description, null) {
                    IsAutoMounted = true
                };
                CmdletProviderContext context = new CmdletProviderContext(this.ExecutionContext);
                drive.DriveBeingCreated = true;
                newDrive = this.ValidateDriveWithProvider(driveProviderInstance, drive, context, false);
                drive.DriveBeingCreated = false;
                if ((newDrive != null) && !context.HasErrors())
                {
                    this._globalScope.NewDrive(newDrive);
                }
            }
            catch (LoopFlowException)
            {
                throw;
            }
            catch (PipelineStoppedException)
            {
                throw;
            }
            catch (ActionPreferenceStopException)
            {
                throw;
            }
            catch (Exception exception)
            {
                CommandProcessorBase.CheckForSevereException(exception);
                MshLog.LogProviderHealthEvent(this.ExecutionContext, this.ExecutionContext.ProviderNames.FileSystem, exception, Severity.Warning);
            }
            return newDrive;
        }
예제 #13
0
        } // AutomountFileSystemDrive

        private PSDriveInfo AutomountFileSystemDrive(System.IO.DriveInfo systemDriveInfo)
        {
            PSDriveInfo result = null;

            if (!IsProviderLoaded(this.ExecutionContext.ProviderNames.FileSystem))
            {
                s_tracer.WriteLine("The {0} provider is not loaded", this.ExecutionContext.ProviderNames.FileSystem);
                return null;
            }

            // Since the drive does exist, add it.

            try
            {
                // Get the FS provider

                DriveCmdletProvider driveProvider =
                    GetDriveProviderInstance(this.ExecutionContext.ProviderNames.FileSystem);

                if (driveProvider != null)
                {
                    // Create a new drive
                    string systemDriveName = systemDriveInfo.Name.Substring(0, 1);
                    string volumeLabel = String.Empty;
                    string displayRoot = null;

                    try
                    {
                        // When run in an AppContainer, we may not have access to the volume label.
                        volumeLabel = systemDriveInfo.VolumeLabel;
                    }
                    catch (UnauthorizedAccessException) { }

                    // Get the actual root path for Network type drives
                    if (systemDriveInfo.DriveType == DriveType.Network)
                    {
                        try
                        {
                            displayRoot = Microsoft.PowerShell.Commands.FileSystemProvider
                                            .GetRootPathForNetworkDriveOrDosDevice(systemDriveInfo);
                        }
                        // We want to get root path of the network drive as extra information to display to the user.
                        // It's okay we failed to get the root path for some reason. We don't want to throw exception
                        // here as it would break the current behavior.
                        catch (Win32Exception) { }
                        catch (InvalidOperationException) { }
                    }

                    PSDriveInfo newPSDriveInfo =
                        new PSDriveInfo(
                            systemDriveName,
                            driveProvider.ProviderInfo,
                            systemDriveInfo.RootDirectory.FullName,
                            volumeLabel,
                            null,
                            displayRoot);

                    newPSDriveInfo.IsAutoMounted = true;

                    CmdletProviderContext context = new CmdletProviderContext(this.ExecutionContext);

                    newPSDriveInfo.DriveBeingCreated = true;

                    // Validate the drive with the provider
                    result = ValidateDriveWithProvider(driveProvider, newPSDriveInfo, context, false);

                    newPSDriveInfo.DriveBeingCreated = false;

                    if (result != null && !context.HasErrors())
                    {
                        // Create the drive in the global scope.
                        GlobalScope.NewDrive(result);
                    }
                }
            }
            catch (LoopFlowException)
            {
                throw;
            }
            catch (PipelineStoppedException)
            {
                throw;
            }
            catch (ActionPreferenceStopException)
            {
                throw;
            }
            catch (Exception e)
            {
                CommandProcessorBase.CheckForSevereException(e);
                // Since the user isn't expecting this behavior, we don't
                // want to let errors find their way out. If there are any
                // failures we just don't mount the drive.


                MshLog.LogProviderHealthEvent(
                    this.ExecutionContext,
                    this.ExecutionContext.ProviderNames.FileSystem,
                    e,
                    Severity.Warning);
            }
            return result;
        } // AutomountFileSystemDrive
예제 #14
0
 private Collection<PSObject> GetChildNamesInDir(string dir, string leafElement, bool getAllContainers, CmdletProviderContext context, bool dirIsProviderPath, PSDriveInfo drive, ContainerCmdletProvider provider, out string modifiedDirPath)
 {
     string updatedPath = null;
     string updatedFilter = null;
     Collection<PSObject> collection4;
     string filter = context.Filter;
     bool flag = provider.ConvertPath(leafElement, context.Filter, ref updatedPath, ref updatedFilter, context);
     if (flag)
     {
         tracer.WriteLine("Provider converted path and filter.", new object[0]);
         tracer.WriteLine("Original path: " + leafElement, new object[0]);
         tracer.WriteLine("Converted path: " + updatedPath, new object[0]);
         tracer.WriteLine("Original filter: " + context.Filter, new object[0]);
         tracer.WriteLine("Converted filter: " + updatedFilter, new object[0]);
         leafElement = updatedPath;
         context.Filter = updatedFilter;
     }
     ReturnContainers returnAllContainers = ReturnContainers.ReturnAllContainers;
     if (!getAllContainers)
     {
         returnAllContainers = ReturnContainers.ReturnMatchingContainers;
     }
     CmdletProviderContext context2 = new CmdletProviderContext(context);
     context2.SetFilters(new Collection<string>(), new Collection<string>(), context.Filter);
     try
     {
         string path = null;
         modifiedDirPath = null;
         if (dirIsProviderPath)
         {
             modifiedDirPath = path = context.SuppressWildcardExpansion ? dir : RemoveGlobEscaping(dir);
         }
         else
         {
             modifiedDirPath = GetMshQualifiedPath(dir, drive);
             ProviderInfo info = null;
             CmdletProvider providerInstance = null;
             Collection<string> collection = this.GetGlobbedProviderPathsFromMonadPath(modifiedDirPath, false, context2, out info, out providerInstance);
             modifiedDirPath = context.SuppressWildcardExpansion ? modifiedDirPath : RemoveGlobEscaping(modifiedDirPath);
             if (collection.Count > 0)
             {
                 path = collection[0];
             }
             else
             {
                 if (flag)
                 {
                     context.Filter = filter;
                 }
                 return new Collection<PSObject>();
             }
         }
         if (provider.HasChildItems(path, context2))
         {
             provider.GetChildNames(path, returnAllContainers, context2);
         }
         if (context2.HasErrors())
         {
             Collection<ErrorRecord> accumulatedErrorObjects = context2.GetAccumulatedErrorObjects();
             if ((accumulatedErrorObjects != null) && (accumulatedErrorObjects.Count > 0))
             {
                 foreach (ErrorRecord record in accumulatedErrorObjects)
                 {
                     context.WriteError(record);
                 }
             }
         }
         Collection<PSObject> accumulatedObjects = context2.GetAccumulatedObjects();
         if (flag)
         {
             context.Filter = filter;
         }
         collection4 = accumulatedObjects;
     }
     finally
     {
         context2.RemoveStopReferral();
     }
     return collection4;
 }
예제 #15
0
        internal PathInfo SetLocation (string path, CmdletProviderContext context)
		{
			if (string.IsNullOrEmpty (path) && OSHelper.IsUnix)
				path = "/";
			else if (path == null) {
				throw PSTraceSource.NewArgumentNullException ("path");
			}
			string str = path;
			string driveName = null;
			ProviderInfo provider = null;
			string providerId = null;
			PSDriveInfo currentDrive = this.CurrentDrive;
			if (LocationGlobber.IsHomePath (path)) {
				path = this.Globber.GetHomeRelativePath (path);
			}

			if (LocationGlobber.IsProviderDirectPath (path)) {
				provider = this.CurrentLocation.Provider;
				PSDriveInfo drive = null;
				if (PathIntrinsics.FinDriveFromPath (path, provider, out drive))
				{
					this.CurrentDrive = drive;
				}
				else if (LocationGlobber.IsProviderQualifiedPath (path, out providerId)) {
					provider = this.GetSingleProvider (providerId);
					if (PathIntrinsics.FinDriveFromPath (path, provider, out drive))
					{
						this.CurrentDrive = drive;
					}
					else if (this.Globber.IsAbsolutePath(path, out driveName))
					{
						drive = this.GetDrive(driveName);
						this.CurrentDrive = drive;
					}
				}
			} else if (LocationGlobber.IsProviderQualifiedPath (path, out providerId)) {
				provider = this.GetSingleProvider (providerId);
				PSDriveInfo drive = null;
				if (PathIntrinsics.FinDriveFromPath (path, provider, out drive))
				{
					this.CurrentDrive = drive;
				}
				else if (this.Globber.IsAbsolutePath(path, out driveName))
				{
					drive = this.GetDrive(driveName);
					this.CurrentDrive = drive;
				}
			} 
			else if (this.Globber.IsAbsolutePath(path, out driveName))
			{
				PSDriveInfo drive = this.GetDrive(driveName);
				this.CurrentDrive = drive;
			}
            if (context == null)
            {
                context = new CmdletProviderContext(this.ExecutionContext);
            }
            if (this.CurrentDrive != null)
            {
                context.Drive = this.CurrentDrive;
            }
            CmdletProvider providerInstance = null;
            Collection<PathInfo> collection = null;
            try
            {
                collection = this.Globber.GetGlobbedMonadPathsFromMonadPath(path, false, context, out providerInstance);

			}
            catch (LoopFlowException)
            {
                throw;
            }
            catch (PipelineStoppedException)
            {
                throw;
            }
            catch (ActionPreferenceStopException)
            {
                throw;
            }
            catch (Exception exception)
            {
                CommandProcessorBase.CheckForSevereException(exception);
                this.CurrentDrive = currentDrive;
                throw;
            }
            if (collection.Count == 0)
            {
                this.CurrentDrive = currentDrive;
                throw new ItemNotFoundException(path, "PathNotFound", SessionStateStrings.PathNotFound);
            }
            bool flag = false;
            bool flag2 = false;
            bool flag3 = false;
            bool flag4 = false;
            for (int i = 0; i < collection.Count; i++)
            {
                CmdletProviderContext context2 = new CmdletProviderContext(context);
                PathInfo info4 = collection[i];
                string str4 = path;
                try
                {
                    string str5 = null;
                    flag4 = LocationGlobber.IsProviderQualifiedPath(info4.Path, out str5);
                    if (flag4)
                    {
                        string str6 = LocationGlobber.RemoveProviderQualifier(info4.Path);
                        try
                        {
                            str4 = this.NormalizeRelativePath(this.GetSingleProvider(str5), str6, string.Empty, context2);
                            goto Label_01DF;
                        }
                        catch (NotSupportedException)
                        {
                            goto Label_01DF;
                        }
                        catch (LoopFlowException)
                        {
                            throw;
                        }
                        catch (PipelineStoppedException)
                        {
                            throw;
                        }
                        catch (ActionPreferenceStopException)
                        {
                            throw;
                        }
                        catch (Exception exception2)
                        {
                            CommandProcessorBase.CheckForSevereException(exception2);
                            this.CurrentDrive = currentDrive;
                            throw;
                        }
                    }
                    try
                    {
                    	str4 = this.NormalizeRelativePath(info4.Path, this.CurrentDrive.Root, context2);
                    }
                    catch (NotSupportedException)
                    {
                    }
                    catch (LoopFlowException)
                    {
                        throw;
                    }
                    catch (PipelineStoppedException)
                    {
                        throw;
                    }
                    catch (ActionPreferenceStopException)
                    {
                        throw;
                    }
                    catch (Exception exception3)
                    {
                        CommandProcessorBase.CheckForSevereException(exception3);
                        this.CurrentDrive = currentDrive;
                        throw;
                    }
                Label_01DF:
                    if (context2.HasErrors())
                    {
                        this.CurrentDrive = currentDrive;
                        context2.ThrowFirstErrorOrDoNothing();
                    }
                }
                finally
                {
                    context2.RemoveStopReferral();
                }
                bool flag5 = false;
                CmdletProviderContext context3 = new CmdletProviderContext(context) {
                    SuppressWildcardExpansion = true
                };
                try
                {
                    flag5 = this.IsItemContainer(info4.Path, context3);
                    if (context3.HasErrors())
                    {
                        this.CurrentDrive = currentDrive;
                        context3.ThrowFirstErrorOrDoNothing();
                    }
                }
                catch (NotSupportedException)
                {
                    if (str4.Length == 0)
                    {
                        flag5 = true;
                    }
                }
                finally
                {
                    context3.RemoveStopReferral();
                }
                if (flag5)
                {
                    if (flag)
                    {
                        this.CurrentDrive = currentDrive;
                        throw PSTraceSource.NewArgumentException("path", "SessionStateStrings", "PathResolvedToMultiple", new object[] { str });
                    }
                    path = str4;
                    flag2 = true;
                    flag3 = flag4;
                    flag = true;
                }
            }
            if (flag2)
            {
				if (!OSHelper.IsUnix)
				{
	                if (!LocationGlobber.IsProviderDirectPath(path))
	                {
	                    char ch = '\\';
	                    if (path.StartsWith(ch.ToString(), StringComparison.CurrentCulture) && !flag3)
	                    {
	                        path = path.Substring(1);
	                    }
	                }
				}
				tracer.WriteLine("New working path = {0}", new object[] { path });
				this.CurrentDrive.CurrentLocation = path;
            }
            else
            {
                this.CurrentDrive = currentDrive;
                throw new ItemNotFoundException(str, "PathNotFound", SessionStateStrings.PathNotFound);
            }
            this.ProvidersCurrentWorkingDrive[this.CurrentDrive.Provider] = this.CurrentDrive;
            this.SetVariable(SpecialVariables.PWDVarPath, this.CurrentLocation, false, true, CommandOrigin.Internal);
            return this.CurrentLocation;
        }
        } // 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
예제 #17
0
        } // 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 e) // Catch-all OK, 3rd party callout
            {
                CommandProcessorBase.CheckForSevereException(e);

                // 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 e) // Catch-all OK, 3rd party callout
                        {
                            CommandProcessorBase.CheckForSevereException(e);

                            // 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 e) // Catch-all OK, 3rd party callout
                        {
                            CommandProcessorBase.CheckForSevereException(e);

                            // 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
예제 #18
0
        /// <summary>
        /// Determines if the specified path is the current working directory
        /// or a parent of the current working directory.
        /// </summary>
        /// <param name="path">
        /// A monad namespace absolute or relative path.
        /// </param>
        /// <param name="context">
        /// The context the provider uses when performing the operation.
        /// </param>
        /// <returns>
        /// true, if the path is the current working directory or a parent of the current
        /// working directory. false, otherwise.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// If <paramref name="path"/> is null.
        /// </exception>
        /// <exception cref="ProviderNotFoundException">
        /// If the path is a provider-qualified path for a provider that is
        /// not loaded into the system.
        /// </exception>
        /// <exception cref="DriveNotFoundException">
        /// If the <paramref name="path"/> refers to a drive that could not be found.
        /// </exception>
        /// <exception cref="ProviderInvocationException">
        /// If the provider used to build the path threw an exception.
        /// </exception>
        /// <exception cref="NotSupportedException">
        /// If the provider that the <paramref name="path"/> represents is not a NavigationCmdletProvider
        /// or ContainerCmdletProvider.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        /// If the <paramref name="path"/> starts with "~" and the home location is not set for
        /// the provider.
        /// </exception>
        /// <exception cref="ProviderInvocationException">
        /// If the provider specified by <paramref name="providerId"/> threw an
        /// exception when its GetParentPath or MakePath was called while
        /// processing the <paramref name="path"/>.
        /// </exception>
        internal bool IsCurrentLocationOrAncestor(string path, CmdletProviderContext context)
        {
            bool result = false;

            if (path == null)
            {
                throw PSTraceSource.NewArgumentNullException("path");
            }

            PSDriveInfo  drive    = null;
            ProviderInfo provider = null;

            string providerSpecificPath =
                Globber.GetProviderPath(
                    path,
                    context,
                    out provider,
                    out drive);

            if (drive != null)
            {
                s_tracer.WriteLine("Tracing drive");
                drive.Trace();
            }

            Dbg.Diagnostics.Assert(
                providerSpecificPath != null,
                "There should always be a way to generate a provider path for a " +
                "given path");

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

            // Check to see if the path that was specified is within the current
            // working drive
            if (drive == CurrentDrive)
            {
                // The path needs to be normalized to get rid of relative path tokens
                // so they don't interfere with our path comparisons below
                CmdletProviderContext normalizePathContext
                    = new CmdletProviderContext(context);

                try
                {
                    providerSpecificPath = NormalizeRelativePath(path, null, 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;
                }
                finally
                {
                    normalizePathContext.RemoveStopReferral();
                }

                if (normalizePathContext.HasErrors())
                {
                    normalizePathContext.ThrowFirstErrorOrDoNothing();
                }

                s_tracer.WriteLine("Provider path = {0}", providerSpecificPath);

                // Get the current working directory provider specific path
                PSDriveInfo  currentWorkingDrive  = null;
                ProviderInfo currentDriveProvider = null;

                string currentWorkingPath =
                    Globber.GetProviderPath(
                        ".",
                        context,
                        out currentDriveProvider,
                        out currentWorkingDrive);

                Dbg.Diagnostics.Assert(
                    currentWorkingDrive == CurrentDrive,
                    "The current working drive should be the CurrentDrive.");

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

                // See if the path is the current working directory or a parent
                // of the current working directory
                s_tracer.WriteLine(
                    "Comparing {0} to {1}",
                    providerSpecificPath,
                    currentWorkingPath);

                if (String.Compare(providerSpecificPath, currentWorkingPath, StringComparison.CurrentCultureIgnoreCase) == 0)
                {
                    // The path is the current working directory so
                    // return true
                    s_tracer.WriteLine("The path is the current working directory");

                    result = true;
                }
                else
                {
                    // Check to see if the specified path is a parent
                    // of the current working directory
                    string lockedDirectory = currentWorkingPath;

                    while (lockedDirectory.Length > 0)
                    {
                        // We need to allow the provider to go as far up the tree
                        // as it can even if that means it has to traverse higher
                        // than the mount point for this drive. That is
                        // why we are passing the empty string as the root here.
                        lockedDirectory =
                            GetParentPath(
                                drive.Provider,
                                lockedDirectory,
                                String.Empty,
                                context);

                        s_tracer.WriteLine(
                            "Comparing {0} to {1}",
                            lockedDirectory,
                            providerSpecificPath);

                        if (String.Compare(lockedDirectory, providerSpecificPath, StringComparison.CurrentCultureIgnoreCase) == 0)
                        {
                            // The path is a parent of the current working
                            // directory
                            s_tracer.WriteLine(
                                "The path is a parent of the current working directory: {0}",
                                lockedDirectory);

                            result = true;
                            break;
                        }
                    }
                }
            }
            else
            {
                s_tracer.WriteLine("Drives are not the same");
            }

            return(result);
        }
예제 #19
0
        /// <summary>
        /// Gets the path to the parent object for the given object.
        /// Allow to use FileSystem as the default provider when the
        /// given path is drive-qualified and the drive cannot be found.
        /// </summary>
        /// 
        /// <param name="path">
        /// The path to the object to get the parent path from
        /// </param>
        /// 
        /// <param name="root">
        /// The root of the drive. Namespace providers should
        /// return the root if GetParentPath is called for the root.
        /// </param>
        /// 
        /// <param name="context">
        /// The context which the core command is running.
        /// </param>
        /// 
        /// <param name="useDefaultProvider">
        /// Specify whether to use default provider when needed.
        /// </param>
        /// 
        /// <returns>
        /// The path to the parent object
        /// </returns>
        internal string GetParentPath(
            string path,
            string root,
            CmdletProviderContext context,
            bool useDefaultProvider)
        {
            if (path == null)
            {
                throw PSTraceSource.NewArgumentNullException("path");
            }

            CmdletProviderContext getProviderPathContext =
                new CmdletProviderContext(context);

            try
            {
                PSDriveInfo drive = null;
                ProviderInfo provider = null;

                try
                {
                    Globber.GetProviderPath(
                        path,
                        getProviderPathContext,
                        out provider,
                        out drive);
                }
                catch (DriveNotFoundException)
                {
                    // the path is sure to be drive_qualified and it is absolute path, otherwise the
                    // drive would be set to the current drive and the DriveNotFoundException will not happen
                    if (useDefaultProvider)
                    {
                        // the default provider is FileSystem
                        provider = PublicSessionState.Internal.GetSingleProvider(Microsoft.PowerShell.Commands.FileSystemProvider.ProviderName);
                    }
                    else
                    {
                        throw;
                    }
                }

                if (getProviderPathContext.HasErrors())
                {
                    getProviderPathContext.WriteErrorsToContext(context);
                    return null;
                }

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

                bool isProviderQualified = false;
                bool isDriveQualified = false;
                string qualifier = null;
                string pathNoQualifier = RemoveQualifier(path, provider, out qualifier, out isProviderQualified, out isDriveQualified);

                string result = GetParentPath(provider, pathNoQualifier, root, context);

                if (!String.IsNullOrEmpty(qualifier) && !String.IsNullOrEmpty(result))
                {
                    result = AddQualifier(result, provider, qualifier, isProviderQualified, isDriveQualified);
                }

                return result;
            }
            finally
            {
                getProviderPathContext.RemoveStopReferral();
            }
        } // GetParentPath