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; }
internal StringCollection GenerateNewPathsWithGlobLeaf(StringCollection currentDirs, 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 = null; Collection<PSObject> collection3 = this.GetChildNamesInDir(str2, leafElement, !isLastLeaf, context, true, null, 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 str5 = childName; if (provider2 != null) { str5 = provider2.MakePath(modifiedDirPath, childName, context); } tracer.WriteLine("Adding child path to dirs {0}", new object[] { str5 }); strings.Add(str5); } } } } } return strings; } tracer.WriteLine("LeafElement does not contain any glob characters so do a MakePath", new object[0]); foreach (string str6 in currentDirs) { using (pathResolutionTracer.TraceScope("Expanding intermediate containers under '{0}'", new object[] { str6 })) { if (context.Stopping) { throw new PipelineStoppedException(); } string child = ConvertMshEscapeToRegexEscape(leafElement); string parent = context.SuppressWildcardExpansion ? str6 : RemoveGlobEscaping(str6); string path = child; if (provider2 != null) { path = provider2.MakePath(parent, child, context); } if (provider.ItemExists(path, context)) { tracer.WriteLine("Adding child path to dirs {0}", new object[] { path }); strings.Add(path); pathResolutionTracer.WriteLine("Valid intermediate container: {0}", new object[] { path }); } } } return strings; }
} // 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
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; } }
} // 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