/// <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); }