Example #1
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;
 }
Example #2
0
 internal Collection<string> ExpandGlobPath(string path, bool allowNonexistingPaths, ContainerCmdletProvider provider, CmdletProviderContext context)
 {
     if (path == null)
     {
         throw PSTraceSource.NewArgumentNullException("path");
     }
     if (provider == null)
     {
         throw PSTraceSource.NewArgumentNullException("provider");
     }
     string updatedPath = null;
     string updatedFilter = null;
     string filter = context.Filter;
     bool flag = provider.ConvertPath(path, context.Filter, ref updatedPath, ref updatedFilter, context);
     if (flag)
     {
         tracer.WriteLine("Provider converted path and filter.", new object[0]);
         tracer.WriteLine("Original path: " + path, 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]);
         path = updatedPath;
         filter = context.Filter;
     }
     NavigationCmdletProvider provider2 = provider as NavigationCmdletProvider;
     tracer.WriteLine("path = {0}", new object[] { path });
     Collection<string> collection = new Collection<string>();
     using (pathResolutionTracer.TraceScope("EXPANDING WILDCARDS", new object[0]))
     {
         if (ShouldPerformGlobbing(path, context))
         {
             StringCollection currentDirs = new StringCollection();
             Stack<string> stack = new Stack<string>();
             using (pathResolutionTracer.TraceScope("Tokenizing path", new object[0]))
             {
                 while (StringContainsGlobCharacters(path))
                 {
                     if (context.Stopping)
                     {
                         throw new PipelineStoppedException();
                     }
                     string childName = path;
                     if (provider2 != null)
                     {
                         childName = provider2.GetChildName(path, context);
                     }
                     if (string.IsNullOrEmpty(childName))
                     {
                         break;
                     }
                     tracer.WriteLine("Pushing leaf element: {0}", new object[] { childName });
                     pathResolutionTracer.WriteLine("Leaf element: {0}", new object[] { childName });
                     stack.Push(childName);
                     if (provider2 != null)
                     {
                         string root = string.Empty;
                         if (context != null)
                         {
                             PSDriveInfo drive = context.Drive;
                             if (drive != null)
                             {
                                 root = drive.Root;
                             }
                         }
                         string a = provider2.GetParentPath(path, root, context);
                         if (string.Equals(a, path, StringComparison.OrdinalIgnoreCase))
                         {
                             throw PSTraceSource.NewInvalidOperationException("SessionStateStrings", "ProviderImplementationInconsistent", new object[] { provider.ProviderInfo.Name, path });
                         }
                         path = a;
                     }
                     else
                     {
                         path = string.Empty;
                     }
                     tracer.WriteLine("New path: {0}", new object[] { path });
                     pathResolutionTracer.WriteLine("Parent path: {0}", new object[] { path });
                 }
                 tracer.WriteLine("Base container path: {0}", new object[] { path });
                 if (stack.Count == 0)
                 {
                     string str7 = path;
                     if (provider2 != null)
                     {
                         str7 = provider2.GetChildName(path, context);
                         if (!string.IsNullOrEmpty(str7))
                         {
                             path = provider2.GetParentPath(path, null, context);
                         }
                     }
                     else
                     {
                         path = string.Empty;
                     }
                     stack.Push(str7);
                     pathResolutionTracer.WriteLine("Leaf element: {0}", new object[] { str7 });
                 }
                 pathResolutionTracer.WriteLine("Root path of resolution: {0}", new object[] { path });
             }
             currentDirs.Add(path);
             while (stack.Count > 0)
             {
                 if (context.Stopping)
                 {
                     throw new PipelineStoppedException();
                 }
                 string leafElement = stack.Pop();
                 currentDirs = this.GenerateNewPathsWithGlobLeaf(currentDirs, leafElement, stack.Count == 0, provider, context);
                 if (stack.Count > 0)
                 {
                     using (pathResolutionTracer.TraceScope("Checking matches to ensure they are containers", new object[0]))
                     {
                         int index = 0;
                         while (index < currentDirs.Count)
                         {
                             if (context.Stopping)
                             {
                                 throw new PipelineStoppedException();
                             }
                             if ((provider2 != null) && !provider2.IsItemContainer(currentDirs[index], context))
                             {
                                 tracer.WriteLine("Removing {0} because it is not a container", new object[] { currentDirs[index] });
                                 pathResolutionTracer.WriteLine("{0} is not a container", new object[] { currentDirs[index] });
                                 currentDirs.RemoveAt(index);
                             }
                             else if (provider2 != null)
                             {
                                 pathResolutionTracer.WriteLine("{0} is a container", new object[] { currentDirs[index] });
                                 index++;
                             }
                         }
                         continue;
                     }
                 }
             }
             foreach (string str9 in currentDirs)
             {
                 pathResolutionTracer.WriteLine("RESOLVED PATH: {0}", new object[] { str9 });
                 collection.Add(str9);
             }
         }
         else
         {
             string str10 = context.SuppressWildcardExpansion ? path : RemoveGlobEscaping(path);
             if (allowNonexistingPaths || provider.ItemExists(str10, context))
             {
                 pathResolutionTracer.WriteLine("RESOLVED PATH: {0}", new object[] { str10 });
                 collection.Add(str10);
             }
             else
             {
                 ItemNotFoundException exception2 = new ItemNotFoundException(path, "PathNotFound", SessionStateStrings.PathNotFound);
                 pathResolutionTracer.TraceError("Item does not exist: {0}", new object[] { path });
                 throw exception2;
             }
         }
     }
     if (flag)
     {
         context.Filter = filter;
     }
     return collection;
 }
Example #3
0
        private Collection<string> ExpandMshGlobPath(string path, bool allowNonexistingPaths, PSDriveInfo drive, ContainerCmdletProvider provider, CmdletProviderContext context)
        {
            if (path == null)
            {
                throw PSTraceSource.NewArgumentNullException("path");
            }
            if (provider == null)
            {
                throw PSTraceSource.NewArgumentNullException("provider");
            }
            if (drive == null)
            {
                throw PSTraceSource.NewArgumentNullException("drive");
            }
            tracer.WriteLine("path = {0}", new object[] { path });
            NavigationCmdletProvider provider2 = provider as NavigationCmdletProvider;
            Collection<string> collection = new Collection<string>();
            using (pathResolutionTracer.TraceScope("EXPANDING WILDCARDS", new object[0]))
            {
                if (ShouldPerformGlobbing(path, context))
                {
                    StringCollection currentDirs = new StringCollection();
                    Stack<string> stack = new Stack<string>();
                    using (pathResolutionTracer.TraceScope("Tokenizing path", new object[0]))
                    {
                        while (StringContainsGlobCharacters(path))
                        {
                            if (context.Stopping)
                            {
                                throw new PipelineStoppedException();
                            }
                            string childName = path;
                            if (provider2 != null)
                            {
                                childName = provider2.GetChildName(path, context);
                            }
                            if (string.IsNullOrEmpty(childName))
                            {
                                break;
                            }
                            tracer.WriteLine("Pushing leaf element: {0}", new object[] { childName });
                            pathResolutionTracer.WriteLine("Leaf element: {0}", new object[] { childName });
                            stack.Push(childName);
                            if (provider2 != null)
                            {
                                string a = provider2.GetParentPath(path, drive.Root, context);
                                if (string.Equals(a, path, StringComparison.OrdinalIgnoreCase))
                                {
                                    throw PSTraceSource.NewInvalidOperationException("SessionStateStrings", "ProviderImplementationInconsistent", new object[] { provider.ProviderInfo.Name, path });
                                }
                                path = a;
                            }
                            else
                            {
                                path = string.Empty;
                            }
                            tracer.WriteLine("New path: {0}", new object[] { path });
                            pathResolutionTracer.WriteLine("Parent path: {0}", new object[] { path });
                        }
                        tracer.WriteLine("Base container path: {0}", new object[] { path });
                        if (stack.Count == 0)
                        {
                            string str3 = path;
                            if (provider2 != null)
                            {
                                str3 = provider2.GetChildName(path, context);
                                if (!string.IsNullOrEmpty(str3))
                                {
                                    path = provider2.GetParentPath(path, null, context);
                                }
                            }
                            else
                            {
                                path = string.Empty;
                            }
                            stack.Push(str3);
                            pathResolutionTracer.WriteLine("Leaf element: {0}", new object[] { str3 });
                        }
                        pathResolutionTracer.WriteLine("Root path of resolution: {0}", new object[] { path });
                    }
                    currentDirs.Add(path);
                    while (stack.Count > 0)
                    {
                        if (context.Stopping)
                        {
                            throw new PipelineStoppedException();
                        }
                        string leafElement = stack.Pop();
                        currentDirs = this.GenerateNewPSPathsWithGlobLeaf(currentDirs, drive, leafElement, stack.Count == 0, provider, context);
                        if (stack.Count > 0)
                        {
                            using (pathResolutionTracer.TraceScope("Checking matches to ensure they are containers", new object[0]))
                            {
                                int index = 0;
                                while (index < currentDirs.Count)
                                {
                                    if (context.Stopping)
                                    {
                                        throw new PipelineStoppedException();
                                    }
                                    string mshQualifiedPath = GetMshQualifiedPath(currentDirs[index], drive);
                                    if ((provider2 != null) && !this.sessionState.Internal.IsItemContainer(mshQualifiedPath, context))
                                    {
                                        tracer.WriteLine("Removing {0} because it is not a container", new object[] { currentDirs[index] });
                                        pathResolutionTracer.WriteLine("{0} is not a container", new object[] { currentDirs[index] });
                                        currentDirs.RemoveAt(index);
                                    }
                                    else if (provider2 != null)
                                    {
                                        pathResolutionTracer.WriteLine("{0} is a container", new object[] { currentDirs[index] });
                                        index++;
                                    }
                                }
                                continue;
                            }
                        }
                    }
                    foreach (string str6 in currentDirs)
                    {
                        pathResolutionTracer.WriteLine("RESOLVED PATH: {0}", new object[] { str6 });
                        collection.Add(str6);
                    }
                    return collection;
                }
                string str7 = context.SuppressWildcardExpansion ? path : RemoveGlobEscaping(path);
				string format = OSHelper.IsUnix && provider.GetType () == typeof(Microsoft.PowerShell.Commands.FileSystemProvider) ? (str7.StartsWith ("/") ? "{1}" : "{0}/{1}") : "{0}:" + '\\' + "{1}";
                if (drive.Hidden)
                {
                    if (IsProviderDirectPath(str7))
                    {
                        format = "{1}";
                    }
                    else
                    {
                        format = "{0}::{1}";
                    }
                }
                else
                {
					char ch = OSHelper.IsUnix && provider.GetType () == typeof(Microsoft.PowerShell.Commands.FileSystemProvider) ? '/' : '\\';
                    if (path.StartsWith(ch.ToString(), StringComparison.Ordinal))
                    {
						format = OSHelper.IsUnix && provider.GetType () == typeof(Microsoft.PowerShell.Commands.FileSystemProvider) ? "{1}" : "{0}:{1}";
                    }
                }
                string str9 = string.Format(CultureInfo.InvariantCulture, format, new object[] { drive.Name, str7 });
                if (allowNonexistingPaths || provider.ItemExists(this.GetProviderPath(str9, context), context))
                {
                    pathResolutionTracer.WriteLine("RESOLVED PATH: {0}", new object[] { str9 });
                    collection.Add(str9);
                    return collection;
                }
                ItemNotFoundException exception2 = new ItemNotFoundException(str9, "PathNotFound", SessionStateStrings.PathNotFound);
                pathResolutionTracer.TraceError("Item does not exist: {0}", new object[] { path });
                throw exception2;
            }
        }
Example #4
0
 private StringCollection GenerateNewPSPathsWithGlobLeaf(StringCollection currentDirs, PSDriveInfo drive, string leafElement, bool isLastLeaf, ContainerCmdletProvider provider, CmdletProviderContext context)
 {
     if (currentDirs == null)
     {
         throw PSTraceSource.NewArgumentNullException("currentDirs");
     }
     if (provider == null)
     {
         throw PSTraceSource.NewArgumentNullException("provider");
     }
     NavigationCmdletProvider provider2 = provider as NavigationCmdletProvider;
     StringCollection strings = new StringCollection();
     if ((((leafElement != null) && (leafElement.Length > 0)) && StringContainsGlobCharacters(leafElement)) || isLastLeaf)
     {
         WildcardPattern stringMatcher = new WildcardPattern(ConvertMshEscapeToRegexEscape(leafElement), WildcardOptions.IgnoreCase);
         Collection<WildcardPattern> includeMatcher = SessionStateUtilities.CreateWildcardsFromStrings(context.Include, WildcardOptions.IgnoreCase);
         Collection<WildcardPattern> excludeMatcher = SessionStateUtilities.CreateWildcardsFromStrings(context.Exclude, WildcardOptions.IgnoreCase);
         foreach (string str2 in currentDirs)
         {
             using (pathResolutionTracer.TraceScope("Expanding wildcards for items under '{0}'", new object[] { str2 }))
             {
                 if (context.Stopping)
                 {
                     throw new PipelineStoppedException();
                 }
                 string modifiedDirPath = string.Empty;
                 Collection<PSObject> collection3 = this.GetChildNamesInDir(str2, leafElement, !isLastLeaf, context, false, drive, provider, out modifiedDirPath);
                 if (collection3 == null)
                 {
                     tracer.TraceError("GetChildNames returned a null array", new object[0]);
                     pathResolutionTracer.WriteLine("No child names returned for '{0}'", new object[] { str2 });
                 }
                 else
                 {
                     foreach (PSObject obj2 in collection3)
                     {
                         if (context.Stopping)
                         {
                             throw new PipelineStoppedException();
                         }
                         string childName = string.Empty;
                         if (IsChildNameAMatch(obj2, stringMatcher, includeMatcher, excludeMatcher, out childName))
                         {
                             string pattern = childName;
                             if (provider2 != null)
                             {
                                 string parent = RemoveMshQualifier(modifiedDirPath, drive);
                                 pattern = GetMshQualifiedPath(this.sessionState.Internal.MakePath(parent, childName, context), drive);
                             }
                             tracer.WriteLine("Adding child path to dirs {0}", new object[] { pattern });
                             pattern = isLastLeaf ? pattern : WildcardPattern.Escape(pattern);
                             strings.Add(pattern);
                         }
                     }
                 }
             }
         }
         return strings;
     }
     tracer.WriteLine("LeafElement does not contain any glob characters so do a MakePath", new object[0]);
     foreach (string str7 in currentDirs)
     {
         using (pathResolutionTracer.TraceScope("Expanding intermediate containers under '{0}'", new object[] { str7 }))
         {
             if (context.Stopping)
             {
                 throw new PipelineStoppedException();
             }
             string child = ConvertMshEscapeToRegexEscape(leafElement);
             string path = context.SuppressWildcardExpansion ? str7 : RemoveGlobEscaping(str7);
             string mshQualifiedPath = GetMshQualifiedPath(path, drive);
             string str11 = child;
             if (provider2 != null)
             {
                 string str12 = RemoveMshQualifier(mshQualifiedPath, drive);
                 str11 = GetMshQualifiedPath(this.sessionState.Internal.MakePath(str12, child, context), drive);
             }
             if (this.sessionState.Internal.ItemExists(str11, context))
             {
                 tracer.WriteLine("Adding child path to dirs {0}", new object[] { str11 });
                 pathResolutionTracer.WriteLine("Valid intermediate container: {0}", new object[] { str11 });
                 strings.Add(str11);
             }
         }
     }
     return strings;
 }
Example #5
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
Example #6
0
 internal Collection<string> GetGlobbedProviderPathsFromProviderPath(string path, bool allowNonexistingPaths, ContainerCmdletProvider containerProvider, CmdletProviderContext context)
 {
     if (path == null)
     {
         throw PSTraceSource.NewArgumentNullException("path");
     }
     if (containerProvider == null)
     {
         throw PSTraceSource.NewArgumentNullException("containerProvider");
     }
     if (context == null)
     {
         throw PSTraceSource.NewArgumentNullException("context");
     }
     return this.ExpandGlobPath(path, allowNonexistingPaths, containerProvider, context);
 }
Example #7
0
        } // GenerateNewPSPathsWithGlobLeaf

        /// <summary>
        /// Generates an array of provider specific paths from the single provider specific
        /// path using globing rules.
        /// </summary>
        /// 
        /// <param name="path">
        /// A path that may or may not contain globing characters.
        /// </param>
        /// 
        /// <param name="allowNonexistingPaths">
        /// If true, a ItemNotFoundException will not be thrown for non-existing
        /// paths. Instead an appropriate path will be returned as if it did exist.
        /// </param>
        /// 
        /// <param name="provider">
        /// The provider that implements the namespace for the path that we are globing over.
        /// </param>
        /// 
        /// <param name="context">
        /// The context the provider uses when performing the operation.
        /// </param>
        /// 
        /// <returns>
        /// An array of path strings that match the globing rules applied to the path parameter.
        /// </returns>
        /// 
        /// <remarks>
        /// First the path is checked to see if it contains any globing characters ('?' or '*').
        /// If it doesn't then the path is returned as the only element in the array.
        /// If it does, GetParentPath and GetLeafPathName is called on the path and each element
        /// is stored until the path doesn't contain any globing characters. At that point 
        /// GetChildPathNames() is called on the provider with the last parent path that doesn't
        /// contain a globing character. All the results are then matched against leaf element
        /// of that parent path (which did contain a glob character). We then walk out of the
        /// recursion and apply the same procedure to each leaf element that contained globing
        /// characters.
        /// 
        /// The procedure above allows us to match globing strings in multiple sub-containers
        /// in the namespace without having to have knowledge of the namespace paths, or
        /// their syntax.
        /// 
        /// Example:
        /// dir c:\foo\*\bar\*a??.cs
        /// 
        /// Calling this method for the path above would return all files that end in 'a' and
        /// any other two characters followed by ".cs" in all the subdirectories of
        /// foo that have a bar subdirectory.
        /// 
        /// </remarks>
        /// 
        /// <exception cref="ArgumentNullException">
        /// If <paramref name="path"/> or <paramref name="provider"/> is null.
        /// </exception>
        /// 
        /// 
        /// <exception cref="ProviderInvocationException">
        /// If the provider used to build the path threw an exception.
        /// </exception>
        /// 
        /// <exception cref="InvalidOperationException">
        /// If the <paramref name="path"/> starts with "~" and the home location is not set for 
        /// the provider.
        /// or if the provider is implemented in such a way as to cause the globber to go
        /// into an infinite loop.
        /// </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>
        /// 
        internal Collection<string> ExpandGlobPath(
            string path,
            bool allowNonexistingPaths,
            ContainerCmdletProvider provider,
            CmdletProviderContext context)
        {
            if (path == null)
            {
                throw PSTraceSource.NewArgumentNullException("path");
            }

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

            // 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(path, 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}", path);
                    s_tracer.WriteLine("Converted path: {0}", convertedPath);
                    s_tracer.WriteLine("Original filter: {0}", context.Filter);
                    s_tracer.WriteLine("Converted filter: {0}", convertedFilter);
                }

                path = convertedPath;
                originalFilter = context.Filter;
            }

            NavigationCmdletProvider navigationProvider = provider as NavigationCmdletProvider;

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

            Collection<string> result = new Collection<string>();

            using (s_pathResolutionTracer.TraceScope("EXPANDING WILDCARDS"))
            {
                if (ShouldPerformGlobbing(path, context))
                {
                    // This collection contains the directories for which a leaf is being added.
                    // If the directories are being globed over as well, then there will be
                    // many directories in this collection which will have to be iterated over
                    // every time there is a child being added

                    List<string> dirs = new List<string>();

                    // Each leaf element that is pulled off the path is pushed on the stack in
                    // order such that we can generate the path again.

                    Stack<String> leafElements = new Stack<String>();

                    using (s_pathResolutionTracer.TraceScope("Tokenizing path"))
                    {
                        // If the path contains glob characters then iterate through pulling the
                        // leaf elements off and pushing them on to the leafElements stack until
                        // there are no longer any glob characters in the path.

                        while (StringContainsGlobCharacters(path))
                        {
                            // Make sure to obey StopProcessing
                            if (context.Stopping)
                            {
                                throw new PipelineStoppedException();
                            }

                            // Use the provider to get the leaf element string

                            string leafElement = path;

                            if (navigationProvider != null)
                            {
                                leafElement = navigationProvider.GetChildName(path, context);
                            }

                            if (String.IsNullOrEmpty(leafElement))
                            {
                                break;
                            }

                            s_tracer.WriteLine("Pushing leaf element: {0}", leafElement);

                            s_pathResolutionTracer.WriteLine("Leaf element: {0}", leafElement);

                            // Push the leaf element onto the leaf element stack for future use

                            leafElements.Push(leafElement);

                            // Now use the parent path for the next iteration

                            if (navigationProvider != null)
                            {
                                // See if we can get the root from the context

                                string root = String.Empty;

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

                                    if (drive != null)
                                    {
                                        root = drive.Root;
                                    }
                                }

                                // Now call GetParentPath with the root

                                string newParentPath = navigationProvider.GetParentPath(path, root, context);

                                if (String.Equals(
                                        newParentPath,
                                        path,
                                        StringComparison.OrdinalIgnoreCase))
                                {
                                    // The provider is implemented in an inconsistent way. 
                                    // GetChildName returned a non-empty/non-null result but
                                    // GetParentPath with the same path returns the same path.
                                    // This would cause the globber to go into an infinite loop,
                                    // so instead an exception is thrown.

                                    PSInvalidOperationException invalidOperation =
                                        PSTraceSource.NewInvalidOperationException(
                                            SessionStateStrings.ProviderImplementationInconsistent,
                                            provider.ProviderInfo.Name,
                                            path);
                                    throw invalidOperation;
                                }
                                path = newParentPath;
                            }
                            else
                            {
                                // If the provider doesn't implement NavigationCmdletProvider then at most
                                // it can have only one segment in its path. So after removing
                                // the leaf all we have left is the empty string.

                                path = String.Empty;
                            }

                            s_tracer.WriteLine("New path: {0}", path);
                            s_pathResolutionTracer.WriteLine("Parent path: {0}", path);
                        }

                        s_tracer.WriteLine("Base container path: {0}", path);

                        // If no glob elements were found there must be an include and/or
                        // exclude specified. Use the parent path to iterate over to 
                        // resolve the include/exclude filters

                        if (leafElements.Count == 0)
                        {
                            string leafElement = path;

                            if (navigationProvider != null)
                            {
                                leafElement = navigationProvider.GetChildName(path, context);

                                if (!String.IsNullOrEmpty(leafElement))
                                {
                                    path = navigationProvider.GetParentPath(path, null, context);
                                }
                            }
                            else
                            {
                                path = String.Empty;
                            }
                            leafElements.Push(leafElement);
                            s_pathResolutionTracer.WriteLine("Leaf element: {0}", leafElement);
                        }

                        s_pathResolutionTracer.WriteLine("Root path of resolution: {0}", path);
                    }
                    // Once the container path with no glob characters are found store it
                    // so that it's children can be iterated over.

                    dirs.Add(path);

                    // Reconstruct the path one leaf element at a time, expanding where-ever
                    // we encounter glob characters

                    while (leafElements.Count > 0)
                    {
                        // Make sure to obey StopProcessing
                        if (context.Stopping)
                        {
                            throw new PipelineStoppedException();
                        }

                        string leafElement = leafElements.Pop();

                        Dbg.Diagnostics.Assert(
                            leafElement != null,
                            "I am only pushing strings onto this stack so I should be able " +
                            "to cast any Pop to a string without failure.");

                        dirs =
                            GenerateNewPathsWithGlobLeaf(
                                dirs,
                                leafElement,
                                leafElements.Count == 0,
                                provider,
                                context);

                        // If there are more leaf elements in the stack we need
                        // to make sure that only containers where added to dirs
                        // in GenerateNewPathsWithGlobLeaf

                        if (leafElements.Count > 0)
                        {
                            using (s_pathResolutionTracer.TraceScope("Checking matches to ensure they are containers"))
                            {
                                int index = 0;

                                while (index < dirs.Count)
                                {
                                    // Make sure to obey StopProcessing
                                    if (context.Stopping)
                                    {
                                        throw new PipelineStoppedException();
                                    }

                                    // Check to see if the matching item is a container

                                    if (navigationProvider != null &&
                                        !navigationProvider.IsItemContainer(
                                            dirs[index],
                                            context))
                                    {
                                        // If not, remove it from the collection

                                        s_tracer.WriteLine(
                                            "Removing {0} because it is not a container",
                                            dirs[index]);

                                        s_pathResolutionTracer.WriteLine("{0} is not a container", dirs[index]);
                                        dirs.RemoveAt(index);
                                    }
                                    else if (navigationProvider == null)
                                    {
                                        Dbg.Diagnostics.Assert(
                                            navigationProvider != null,
                                            "The path in the dirs should never be a container unless " +
                                            "the provider implements the NavigationCmdletProvider interface. If it " +
                                            "doesn't, there should be no more leafElements in the stack " +
                                            "when this check is done");
                                    }
                                    else
                                    {
                                        s_pathResolutionTracer.WriteLine("{0} is a container", dirs[index]);

                                        // If so, leave it and move on to the next one

                                        ++index;
                                    }
                                }
                            }
                        }
                    } // while (leafElements.Count > 0)

                    Dbg.Diagnostics.Assert(
                        dirs != null,
                        "GenerateNewPathsWithGlobLeaf() should return the base path as an element " +
                        "even if there are no globing characters");

                    foreach (string dir in dirs)
                    {
                        s_pathResolutionTracer.WriteLine("RESOLVED PATH: {0}", dir);
                        result.Add(dir);
                    }

                    Dbg.Diagnostics.Assert(
                        dirs.Count == result.Count,
                        "The result of copying the globed strings should be the same " +
                        "as from the collection");
                }
                else
                {
                    string unescapedPath = context.SuppressWildcardExpansion ? path : RemoveGlobEscaping(path);

                    if (allowNonexistingPaths ||
                        provider.ItemExists(unescapedPath, context))
                    {
                        s_pathResolutionTracer.WriteLine("RESOLVED PATH: {0}", unescapedPath);
                        result.Add(unescapedPath);
                    }
                    else
                    {
                        ItemNotFoundException pathNotFound =
                            new ItemNotFoundException(
                                path,
                                "PathNotFound",
                                SessionStateStrings.PathNotFound);

                        s_pathResolutionTracer.TraceError("Item does not exist: {0}", path);

                        throw pathNotFound;
                    }
                }
            }
            Dbg.Diagnostics.Assert(
                result != null,
                "This method should at least return the path or more if it has glob characters");

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

            return result;
        } // ExpandGlobPath
 private void GetItemOrChildItems(ContainerCmdletProvider provider, string path, bool recurse, ProviderRuntime runtime)
 {
     // If path identifies a container it gets all child items (recursively or not). Otherwise it returns the leaf
     if (Item.IsContainer(provider, path, runtime))
     {
         provider.GetChildItems(path, recurse, runtime);
         return;
     }
     provider.GetItem(path, runtime);
 }
Example #9
0
 private Stack<string> PathToStack(ContainerCmdletProvider provider, string path, ProviderRuntime runtime)
 {
     var componentStack = new Stack<string>();
     while (!String.IsNullOrEmpty(path))
     {
         var child = Path.ParseChildName(provider, path, runtime);
         componentStack.Push(child);
         var parentPath = Path.ParseParent(provider, path, "", runtime);
         if (parentPath.Equals(path))
         {
             throw new PSInvalidOperationException("Provider's implementation of GetParentPath is inconsistent",
                 "ParentOfPathIsPath", ErrorCategory.InvalidResult);
         }
         path = parentPath;
     }
     return componentStack;
 }
Example #10
0
        } // RemoveProviderQualifier

        /// <summary>
        /// Generates a collection of containers and/or leaves that are children of the containers
        /// in the currentDirs parameter and match the glob expression in the 
        /// <paramref name="leafElement" /> parameter.
        /// </summary>
        /// 
        /// <param name="currentDirs">
        /// A collection of paths that should be searched for leaves that match the 
        /// <paramref name="leafElement" /> expression.
        /// </param>
        /// 
        /// <param name="drive">
        /// The drive the Msh path is relative to.
        /// </param>
        ///
        /// <param name="leafElement">
        /// A single element of a path that may or may not contain a glob expression. This parameter
        /// is used to search the containers in <paramref name="currentDirs" /> for children that 
        /// match the glob expression.
        /// </param>
        /// 
        /// <param name="isLastLeaf">
        /// True if the <paramref name="leafElement" /> is the last element to glob over. If false, we 
        /// need to get all container names from the provider even if they don't match the filter.
        /// </param>
        /// 
        /// <param name="provider">
        /// The provider associated with the paths that are being passed in the 
        /// <paramref name="currentDirs" /> and <paramref name="leafElement" /> parameters.
        /// The provider must derive from ContainerCmdletProvider or NavigationCmdletProvider 
        /// in order to get globbing.
        /// </param>
        /// 
        /// <param name="context">
        /// The context the provider uses when performing the operation.
        /// </param>
        /// 
        /// <returns>
        /// A collection of fully qualified namespace paths whose leaf element matches the 
        /// <paramref name="leafElement" /> expression.
        /// </returns>
        /// 
        /// <exception cref="ArgumentNullException">
        /// If <paramref name="currentDirs" /> or <paramref name="provider" />
        /// is null.
        /// </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 List<string> GenerateNewPSPathsWithGlobLeaf(
            List<string> currentDirs,
            PSDriveInfo drive,
            string leafElement,
            bool isLastLeaf,
            ContainerCmdletProvider provider,
            CmdletProviderContext context)
        {
            if (currentDirs == null)
            {
                throw PSTraceSource.NewArgumentNullException("currentDirs");
            }

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

            NavigationCmdletProvider navigationProvider = provider as NavigationCmdletProvider;

            List<string> newDirs = new List<string>();

            // Only loop through the child names if the leafElement contains a glob character

            if (!string.IsNullOrEmpty(leafElement) &&
                StringContainsGlobCharacters(leafElement) ||
                isLastLeaf)
            {
                string regexEscapedLeafElement = ConvertMshEscapeToRegexEscape(leafElement);

                // Construct the glob filter

                WildcardPattern stringMatcher =
                    WildcardPattern.Get(
                        regexEscapedLeafElement,
                        WildcardOptions.IgnoreCase);

                // Construct the include filter

                Collection<WildcardPattern> includeMatcher =
                    SessionStateUtilities.CreateWildcardsFromStrings(
                        context.Include,
                        WildcardOptions.IgnoreCase);


                // Construct the exclude filter

                Collection<WildcardPattern> excludeMatcher =
                    SessionStateUtilities.CreateWildcardsFromStrings(
                        context.Exclude,
                        WildcardOptions.IgnoreCase);

                // Loop through the current dirs and add the appropriate children

                foreach (string dir in currentDirs)
                {
                    using (s_pathResolutionTracer.TraceScope("Expanding wildcards for items under '{0}'", dir))
                    {
                        // Make sure to obey StopProcessing
                        if (context.Stopping)
                        {
                            throw new PipelineStoppedException();
                        }

                        // Now continue on with the names that were returned

                        string mshQualifiedParentPath = String.Empty;
                        Collection<PSObject> childNamesObjectArray =
                            GetChildNamesInDir(
                                dir,
                                leafElement,
                                !isLastLeaf,
                                context,
                                false,
                                drive,
                                provider,
                                out mshQualifiedParentPath);

                        if (childNamesObjectArray == null)
                        {
                            s_tracer.TraceError("GetChildNames returned a null array");
                            s_pathResolutionTracer.WriteLine("No child names returned for '{0}'", dir);
                            continue;
                        }


                        // Loop through each child to see if they match the glob expression

                        foreach (PSObject childObject in childNamesObjectArray)
                        {
                            // Make sure to obey StopProcessing
                            if (context.Stopping)
                            {
                                throw new PipelineStoppedException();
                            }

                            string child = String.Empty;

                            if (IsChildNameAMatch(
                                    childObject,
                                    stringMatcher,
                                    includeMatcher,
                                    excludeMatcher,
                                    out child))
                            {
                                string childPath = child;

                                if (navigationProvider != null)
                                {
                                    string parentPath = RemoveMshQualifier(mshQualifiedParentPath, drive);

                                    childPath =
                                        _sessionState.Internal.
                                            MakePath(
                                                parentPath,
                                                child,
                                                context);

                                    childPath = GetMshQualifiedPath(childPath, drive);
                                }

                                s_tracer.WriteLine("Adding child path to dirs {0}", childPath);

                                // -- If there are more leafElements, the current childPath will be treated as a container path later,
                                //    we should escape the childPath in case the actual childPath contains wildcard characters such as '[' or ']'.
                                // -- If there is no more leafElement, the childPath will not be further processed, and we don't need to
                                //    escape it.
                                childPath = isLastLeaf ? childPath : WildcardPattern.Escape(childPath);
                                newDirs.Add(childPath);
                            }
                        } // foreach (child in childNames)
                    }
                } // foreach (dir in currentDirs)
            } // if (StringContainsGlobCharacters(leafElement))
            else
            {
                s_tracer.WriteLine(
                    "LeafElement does not contain any glob characters so do a MakePath");

                // Loop through the current dirs and add the leafElement to each of 
                // the dirs

                foreach (string dir in currentDirs)
                {
                    using (s_pathResolutionTracer.TraceScope("Expanding intermediate containers under '{0}'", dir))
                    {
                        // Make sure to obey StopProcessing
                        if (context.Stopping)
                        {
                            throw new PipelineStoppedException();
                        }

                        string backslashEscapedLeafElement = ConvertMshEscapeToRegexEscape(leafElement);

                        string unescapedDir = context.SuppressWildcardExpansion ? dir : RemoveGlobEscaping(dir);
                        string resolvedPath = GetMshQualifiedPath(unescapedDir, drive);

                        string childPath = backslashEscapedLeafElement;

                        if (navigationProvider != null)
                        {
                            string parentPath = RemoveMshQualifier(resolvedPath, drive);

                            childPath =
                                _sessionState.Internal.
                                    MakePath(
                                        parentPath,
                                        backslashEscapedLeafElement,
                                        context);

                            childPath = GetMshQualifiedPath(childPath, drive);
                        }


                        if (_sessionState.Internal.ItemExists(childPath, context))
                        {
                            s_tracer.WriteLine("Adding child path to dirs {0}", childPath);
                            s_pathResolutionTracer.WriteLine("Valid intermediate container: {0}", childPath);

                            newDirs.Add(childPath);
                        }
                    }
                } // foreach (dir in currentDirs)
            } // if (StringContainsGlobCharacters(leafElement))


            return newDirs;
        } // GenerateNewPSPathsWithGlobLeaf
 private void ManuallyGetChildNames(ContainerCmdletProvider provider, string providerPath, string relativePath,
     ReturnContainers returnContainers, bool recurse, IncludeExcludeFilter filter, ProviderRuntime runtime)
 {
     // Affected by #trailingSeparatorAmbiguity
     // Sometimes, PS removes or appends a trailing slash to the providerPath
     // E.g. when the recurse == true, there is a trailing slash, but not when recurse == false.
     // As it calls the method with the slash being appended and not appended, PS doesn't seem to make
     // promises to the provider implementation whether or not the path has a trailing slash
     var childNames = GetValidChildNames(provider, providerPath, returnContainers, runtime);
     foreach (var childName in childNames)
     {
         // add the child only if the filter accepts it
         if (!filter.Accepts(childName))
         {
             continue;
         }
         var path = Path.Combine(provider, relativePath, childName, runtime);
         runtime.WriteObject(path);
     }
     // check if we need to handle this recursively
     if (!recurse)
     {
         return;
     }
     // okay, we should use recursion, so get all child containers and call this function again
     childNames = GetValidChildNames(provider, providerPath, ReturnContainers.ReturnAllContainers, runtime);
     foreach (var childName in childNames)
     {
         var providerChildPath = Path.Combine(provider, providerPath, childName, runtime);
         if (Item.IsContainer(providerChildPath, runtime))
         {
             // recursive call wirth child's provider path and relative path
             var relativeChildPath = Path.Combine(provider, relativePath, childName, runtime);
             ManuallyGetChildNames(provider, providerChildPath, relativeChildPath, returnContainers,
                 true, filter, runtime);
         }
     }
 }
 private void ManuallyGetChildItemsFromContainer(ContainerCmdletProvider provider, string path, bool recurse, 
                                                 IncludeExcludeFilter filter, ProviderRuntime runtime)
 {
     // we deal with a container: get all child items (all containers if we recurse)
     Dictionary<string, bool> matches = null;
     // When a provider specific filter is set, and we need to recurse, we need to check recurse into all
     // containers, but just get those that match the internal filter. Therefore we construct a lookup dict.
     // Looking up in a dictionary whether or not the itemis a match should be faster than using a list
     // If there is no filter, then ReturnAllContainers and ReturnMatchingContainers don't differ
     if (!String.IsNullOrEmpty(runtime.Filter))
     {
         matches = GetValidChildNames(provider, path, ReturnContainers.ReturnMatchingContainers,
                                      runtime).ToDictionary(c => c, c => true);
     }
     var childNames = GetValidChildNames(provider, path, ReturnContainers.ReturnAllContainers, runtime);
     foreach (var childName in childNames)
     {
         var childPath = Path.Combine(provider, path, childName, runtime);
         // if the filter accepts the child (leaf or container) and it's potentially a filter match, get it
         if (filter.Accepts(childName) && (matches == null || matches.ContainsKey(childName)))
         {
             provider.GetItem(childPath, runtime);
         }
         // if we need to recurse and deal with a container, dive into it
         if (recurse && Item.IsContainer(childPath, runtime))
         {
             ManuallyGetChildItemsFromContainer(provider, childPath, true, filter, runtime);
         }
     }
 }
 private void ManuallyGetChildItems(ContainerCmdletProvider provider, string path, bool recurse, 
                                    IncludeExcludeFilter filter, ProviderRuntime runtime)
 {
     // recursively get child names of containers or just the current child if the filter accepts it
     if (recurse && Item.IsContainer(path, runtime))
     {
         ManuallyGetChildItemsFromContainer(provider, path, recurse, filter, runtime);
         return;
     }
     var childName = Path.ParseChildName(provider, path, runtime);
     if (filter.Accepts(childName))
     {
         provider.GetItem(path, runtime);
     }
 }
 internal bool IsContainer(ContainerCmdletProvider provider, string path, ProviderRuntime runtime)
 {
     var navProvider = provider as NavigationCmdletProvider;
     // path is an expanded path to a single location. no globbing and filtering is performed
     if (navProvider != null)
     {
         return navProvider.IsItemContainer(path, runtime);
     }
     // otherwise it's just a ContainerCmdletProvider. It doesn't support hierarchies,
     // only drives can be containers
     // an empty path means "root" path in a drive
     return path.Length == 0 || path.Equals(runtime.PSDriveInfo.Root);
 }
Example #15
0
        } // ExpandGlobPath


        /// <summary>
        /// Generates a collection of containers and/or leaves that are children of the containers
        /// in the currentDirs parameter and match the glob expression in the 
        /// <paramref name="leafElement" /> parameter.
        /// </summary>
        /// 
        /// <param name="currentDirs">
        /// A collection of paths that should be searched for leaves that match the 
        /// <paramref name="leafElement" /> expression.
        /// </param>
        /// 
        /// <param name="leafElement">
        /// A single element of a path that may or may not contain a glob expression. This parameter
        /// is used to search the containers in <paramref name="currentDirs" /> for children that 
        /// match the glob expression.
        /// </param>
        /// 
        /// <param name="isLastLeaf">
        /// True if the <paramref name="leafElement" /> is the last element to glob over. If false, we 
        /// need to get all container names from the provider even if they don't match the filter.
        /// </param>
        /// 
        /// <param name="provider">
        /// The provider associated with the paths that are being passed in the 
        /// <paramref name="currentDirs" /> and <paramref name="leafElement" /> parameters.
        /// The provider must derive from ContainerCmdletProvider or NavigationCmdletProvider 
        /// in order to get globbing.
        /// </param>
        /// 
        /// <param name="context">
        /// The context the provider uses when performing the operation.
        /// </param>
        /// 
        /// <returns>
        /// A collection of fully qualified namespace paths whose leaf element matches the 
        /// <paramref name="leafElement" /> expression.
        /// </returns>
        /// 
        /// <exception cref="ArgumentNullException">
        /// If <paramref name="currentDirs" /> or <paramref name="provider" />
        /// is null.
        /// </exception>
        /// 
        /// <exception cref="ProviderInvocationException">
        /// If the provider used to build the path threw an exception.
        /// </exception>
        /// 
        /// <exception cref="InvalidOperationException">
        /// If the <paramref name="path"/> starts with "~" and the home location is not set for 
        /// the provider.
        /// </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>
        /// 
        internal List<string> GenerateNewPathsWithGlobLeaf(
            List<string> currentDirs,
            string leafElement,
            bool isLastLeaf,
            ContainerCmdletProvider provider,
            CmdletProviderContext context)
        {
            if (currentDirs == null)
            {
                throw PSTraceSource.NewArgumentNullException("currentDirs");
            }

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

            NavigationCmdletProvider navigationProvider = provider as NavigationCmdletProvider;

            List<string> newDirs = new List<string>();

            // Only loop through the child names if the leafElement contains a glob character

            if (!string.IsNullOrEmpty(leafElement) &&
                (StringContainsGlobCharacters(leafElement) ||
                 isLastLeaf))
            {
                string regexEscapedLeafElement = ConvertMshEscapeToRegexEscape(leafElement);

                // Construct the glob filter

                WildcardPattern stringMatcher =
                    WildcardPattern.Get(
                        regexEscapedLeafElement,
                        WildcardOptions.IgnoreCase);

                // Construct the include filter

                Collection<WildcardPattern> includeMatcher =
                    SessionStateUtilities.CreateWildcardsFromStrings(
                        context.Include,
                        WildcardOptions.IgnoreCase);


                // Construct the exclude filter

                Collection<WildcardPattern> excludeMatcher =
                    SessionStateUtilities.CreateWildcardsFromStrings(
                        context.Exclude,
                        WildcardOptions.IgnoreCase);

                // Loop through the current dirs and add the appropriate children

                foreach (string dir in currentDirs)
                {
                    using (s_pathResolutionTracer.TraceScope("Expanding wildcards for items under '{0}'", dir))
                    {
                        // Make sure to obey StopProcessing
                        if (context.Stopping)
                        {
                            throw new PipelineStoppedException();
                        }

                        string unescapedDir = null;

                        Collection<PSObject> childNamesObjectArray =
                            GetChildNamesInDir(dir, leafElement, !isLastLeaf, context, true, null, provider, out unescapedDir);

                        if (childNamesObjectArray == null)
                        {
                            s_tracer.TraceError("GetChildNames returned a null array");

                            s_pathResolutionTracer.WriteLine("No child names returned for '{0}'", dir);
                            continue;
                        }

                        // Loop through each child to see if they match the glob expression

                        foreach (PSObject childObject in childNamesObjectArray)
                        {
                            // Make sure to obey StopProcessing
                            if (context.Stopping)
                            {
                                throw new PipelineStoppedException();
                            }

                            string child = String.Empty;
                            if (IsChildNameAMatch(childObject, stringMatcher, includeMatcher, excludeMatcher, out child))
                            {
                                string childPath = child;

                                if (navigationProvider != null)
                                {
                                    childPath =
                                        navigationProvider.
                                        MakePath(
                                            unescapedDir,
                                            child,
                                            context);
                                }

                                s_tracer.WriteLine("Adding child path to dirs {0}", childPath);

                                newDirs.Add(childPath);
                            }
                        } // foreach (child in childNames)
                    }
                } // foreach (dir in currentDirs)
            } // if (StringContainsGlobCharacters(leafElement))
            else
            {
                s_tracer.WriteLine(
                    "LeafElement does not contain any glob characters so do a MakePath");

                // Loop through the current dirs and add the leafElement to each of 
                // the dirs

                foreach (string dir in currentDirs)
                {
                    using (s_pathResolutionTracer.TraceScope("Expanding intermediate containers under '{0}'", dir))
                    {
                        // Make sure to obey StopProcessing
                        if (context.Stopping)
                        {
                            throw new PipelineStoppedException();
                        }

                        string backslashEscapedLeafElement = ConvertMshEscapeToRegexEscape(leafElement);

                        string unescapedDir = context.SuppressWildcardExpansion ? dir : RemoveGlobEscaping(dir);

                        string childPath = backslashEscapedLeafElement;

                        if (navigationProvider != null)
                        {
                            childPath =
                                navigationProvider.
                                    MakePath(
                                        unescapedDir,
                                        backslashEscapedLeafElement,
                                        context);
                        }


                        if (provider.ItemExists(childPath, context))
                        {
                            s_tracer.WriteLine("Adding child path to dirs {0}", childPath);

                            newDirs.Add(childPath);

                            s_pathResolutionTracer.WriteLine("Valid intermediate container: {0}", childPath);
                        }
                    }
                } // foreach (dir in currentDirs)
            } // if (StringContainsGlobCharacters(leafElement))


            return newDirs;
        } // GenerateNewPathsWithGlobLeaf
 void CopyContainerToContainer(ContainerCmdletProvider provider, string srcPath, string destPath, bool recurse,
                               CopyContainers copyContainers, ProviderRuntime runtime)
 {
     // the "usual" case: if we don't use recursion (empty container is copied) or we want to maintain the
     // original hierarchy
     if (!recurse || copyContainers.Equals(CopyContainers.CopyTargetContainer))
     {
         provider.CopyItem(srcPath, destPath, recurse, runtime);
         return;
     }
     // Otherwise we want a flat-hierachy copy of a folder (because copyContainers is CopyChildrenOfTargetContainer)
     // Make sure recurse is set
     if (!recurse)
     {
         var error = new PSArgumentException("Cannot copy container to existing leaf",
             "CopyContainerItemToLeafError", ErrorCategory.InvalidArgument).ErrorRecord;
         runtime.WriteError(error);
         return;
     }
     // otherwise do the flat copy. To do this: get all child names (recursively) and invoke copying without recursion
     var childNames = ChildItem.GetNames(srcPath, ReturnContainers.ReturnMatchingContainers, true);
     foreach (var child in childNames)
     {
         var childPath = Path.Combine(provider, srcPath, child, runtime);
         provider.CopyItem(childPath, destPath, false, runtime);
     }
 }
 internal List<string> GetValidChildNames(ContainerCmdletProvider provider, string providerPath, ReturnContainers returnContainers, ProviderRuntime runtime)
 {
     var subRuntime = new ProviderRuntime(runtime);
     subRuntime.PassThru = false; // so we can catch the results
     provider.GetChildNames(providerPath, returnContainers, subRuntime);
     var results = subRuntime.ThrowFirstErrorOrReturnResults();
     return (from c in results
         where c.BaseObject is string
         select ((string)c.BaseObject)).ToList();
 }