Beispiel #1
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);
        }