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