internal void NewDrive(PSDriveInfo drive, string scopeID, CmdletProviderContext context) { if (drive == null) { throw PSTraceSource.NewArgumentNullException("drive"); } if (context == null) { throw PSTraceSource.NewArgumentNullException("context"); } if (!IsValidDriveName(drive.Name)) { throw PSTraceSource.NewArgumentException("drive.Name", "SessionStateStrings", "DriveNameIllegalCharacters", new object[0]); } PSDriveInfo newDrive = this.ValidateDriveWithProvider(drive, context, true); if (newDrive != null) { if (string.Compare(newDrive.Name, drive.Name, true, Thread.CurrentThread.CurrentCulture) != 0) { throw this.NewProviderInvocationException("NewDriveProviderFailed", SessionStateStrings.NewDriveProviderFailed, drive.Provider, drive.Root, PSTraceSource.NewArgumentException("root")); } try { SessionStateScope currentScope = this.currentScope; if (!string.IsNullOrEmpty(scopeID)) { currentScope = this.GetScopeByID(scopeID); } currentScope.NewDrive(newDrive); } catch (ArgumentException exception2) { context.WriteError(new ErrorRecord(exception2, "NewDriveError", ErrorCategory.InvalidArgument, newDrive)); return; } catch (SessionStateException) { throw; } if (this.ProvidersCurrentWorkingDrive[drive.Provider] == null) { this.ProvidersCurrentWorkingDrive[drive.Provider] = drive; } context.WriteObject(newDrive); } }
internal void GetChildNames(string path, ReturnContainers returnContainers, bool recurse, CmdletProviderContext context) { if (path == null) { throw PSTraceSource.NewArgumentNullException("path"); } Collection<WildcardPattern> includeMatcher = SessionStateUtilities.CreateWildcardsFromStrings(context.Include, WildcardOptions.IgnoreCase); Collection<WildcardPattern> excludeMatcher = SessionStateUtilities.CreateWildcardsFromStrings(context.Exclude, WildcardOptions.IgnoreCase); if (LocationGlobber.ShouldPerformGlobbing(path, context)) { ProviderInfo info = null; CmdletProvider providerInstance = null; CmdletProviderContext context2 = new CmdletProviderContext(context); context2.SetFilters(new Collection<string>(), new Collection<string>(), null); Collection<string> collection3 = this.Globber.GetGlobbedProviderPathsFromMonadPath(path, false, context2, out info, out providerInstance); if (context2.Drive != null) { context.Drive = context2.Drive; } bool flag = LocationGlobber.StringContainsGlobCharacters(path); foreach (string str in collection3) { if (context.Stopping) { break; } if ((!flag || recurse) && this.IsItemContainer(providerInstance, str, context)) { this.DoGetChildNamesManually(providerInstance, str, string.Empty, returnContainers, includeMatcher, excludeMatcher, context, recurse); } else if (providerInstance is NavigationCmdletProvider) { string text = this.GetChildName(providerInstance, str, context, false); bool flag2 = SessionStateUtilities.MatchesAnyWildcardPattern(text, includeMatcher, true); bool flag3 = SessionStateUtilities.MatchesAnyWildcardPattern(text, excludeMatcher, false); if (flag2 && !flag3) { context.WriteObject(text); } } else { context.WriteObject(str); } } } else { ProviderInfo provider = null; PSDriveInfo drive = null; string str3 = this.Globber.GetProviderPath(path, context, out provider, out drive); ContainerCmdletProvider containerProviderInstance = this.GetContainerProviderInstance(provider); if (drive != null) { context.Drive = drive; } if (!containerProviderInstance.ItemExists(str3, context)) { ItemNotFoundException exception = new ItemNotFoundException(str3, "PathNotFound", SessionStateStrings.PathNotFound); throw exception; } if (recurse) { this.DoGetChildNamesManually(containerProviderInstance, str3, string.Empty, returnContainers, includeMatcher, excludeMatcher, context, recurse); } else { this.GetChildNames(containerProviderInstance, str3, returnContainers, context); } } }
private void DoGetChildNamesManually(CmdletProvider providerInstance, string providerPath, string relativePath, ReturnContainers returnContainers, Collection<WildcardPattern> includeMatcher, Collection<WildcardPattern> excludeMatcher, CmdletProviderContext context, bool recurse) { string path = this.MakePath(providerInstance, providerPath, relativePath, context); CmdletProviderContext context2 = new CmdletProviderContext(context); try { this.GetChildNames(providerInstance, path, ReturnContainers.ReturnMatchingContainers, context2); foreach (PSObject obj2 in context2.GetAccumulatedObjects()) { if (context.Stopping) { return; } string baseObject = obj2.BaseObject as string; if (((baseObject != null) && SessionStateUtilities.MatchesAnyWildcardPattern(baseObject, includeMatcher, true)) && !SessionStateUtilities.MatchesAnyWildcardPattern(baseObject, excludeMatcher, false)) { string str3 = this.MakePath(providerInstance, relativePath, baseObject, context); context.WriteObject(str3); } } if (recurse) { this.GetChildNames(providerInstance, path, ReturnContainers.ReturnAllContainers, context2); foreach (PSObject obj3 in context2.GetAccumulatedObjects()) { if (context.Stopping) { return; } string child = obj3.BaseObject as string; if (child != null) { string str5 = this.MakePath(providerInstance, relativePath, child, context); string str6 = this.MakePath(providerInstance, providerPath, str5, context); if (this.IsItemContainer(providerInstance, str6, context)) { this.DoGetChildNamesManually(providerInstance, providerPath, str5, returnContainers, includeMatcher, excludeMatcher, context, true); } } } } } finally { context2.RemoveStopReferral(); } }
} // NewDrive /// <summary> /// Adds a drive to the PowerShell namespace. /// </summary> /// /// <param name="drive"> /// The new drive to be added. /// </param> /// /// <param name="scopeID"> /// The ID for the scope to add the drive to. The scope ID can be any of the /// "special" scope identifiers like "global", "local", or "private" or it /// can be a numeric identifier that is a count of the number of parent /// scopes up from the current scope to put the drive in. /// If this parameter is null or empty the drive will be placed in the /// current scope. /// </param> /// /// <param name="context"> /// The context which the core command is running. /// </param> /// /// <exception cref="ArgumentNullException"> /// If <paramref name="drive"/> or <paramref name="context"/> is null. /// </exception> /// /// <exception cref="ArgumentException"> /// If the drive already exists /// or /// If <paramref name="drive"/>.Name contains one or more invalid characters; ~ / \\ . : /// </exception> /// /// <exception cref="ArgumentOutOfRangeException"> /// If <paramref name="scopeID"/> is less than zero or greater than the number of currently /// active scopes. /// </exception> /// /// <exception cref="NotSupportedException"> /// If the provider is not a DriveCmdletProvider. /// </exception> /// /// <exception cref="ProviderNotFoundException"> /// The provider for the <paramref name="drive"/> could not be found. /// </exception> /// /// <exception cref="ProviderInvocationException"> /// If the provider threw an exception or returned null. /// </exception> /// /// <exception cref="SessionStateOverflowException"> /// If creating the drive will overflow the MaximumDriveCount limit. /// </exception> /// internal void NewDrive(PSDriveInfo drive, string scopeID, CmdletProviderContext context) { if (drive == null) { throw PSTraceSource.NewArgumentNullException("drive"); } if (context == null) { throw PSTraceSource.NewArgumentNullException("context"); } if (!IsValidDriveName(drive.Name)) { ArgumentException e = PSTraceSource.NewArgumentException( "drive.Name", SessionStateStrings.DriveNameIllegalCharacters); throw e; } // Allow the provider a chance to approve the drive and set // provider specific data PSDriveInfo result = ValidateDriveWithProvider(drive, context, true); // We assume that the provider wrote the error message as they // are suppose to. if (result == null) { return; } if (String.Compare(result.Name, drive.Name, StringComparison.CurrentCultureIgnoreCase) == 0) { // Set the drive in the current scope. try { SessionStateScope scope = _currentScope; if (!String.IsNullOrEmpty(scopeID)) { scope = GetScopeByID(scopeID); } scope.NewDrive(result); } catch (ArgumentException argumentException) { // Wrap up the exception and write it to the error stream context.WriteError( new ErrorRecord( argumentException, "NewDriveError", ErrorCategory.InvalidArgument, result)); return; } catch (SessionStateException) { // This should be a pipeline terminating condition throw; } if (ProvidersCurrentWorkingDrive[drive.Provider] == null) { // Set the new drive as the current // drive for the provider since there isn't one set. ProvidersCurrentWorkingDrive[drive.Provider] = drive; } // Upon success, write the drive to the pipeline context.WriteObject(result); } else { ProviderInvocationException e = NewProviderInvocationException( "NewDriveProviderFailed", SessionStateStrings.NewDriveProviderFailed, drive.Provider, drive.Root, PSTraceSource.NewArgumentException("root")); throw e; } } // NewDrive
} // GetChildNames /// <summary> /// Gets the child names of the item at the specified path by /// manually recursing through all the containers instead of /// allowing the provider to do the recursion. /// </summary> /// /// <param name="providerInstance"> /// The provider instance to use. /// </param> /// /// <param name="providerPath"> /// The path to the item if it was specified on the command line. /// </param> /// /// <param name="relativePath"> /// The path the name is relative to. /// </param> /// /// <param name="recurse"> /// If true all names in the subtree should be returned. /// </param> /// /// <param name="depth"> /// Current depth of recursion; special case uint.MaxValue performs full recursion. /// </param> /// /// <param name="returnContainers"> /// Determines if all containers should be returned or only those containers that match the /// filter(s). /// </param> /// /// <param name="includeMatcher"> /// A set of filters that the names must match to be returned. /// </param> /// /// <param name="excludeMatcher"> /// A set of filters that the names cannot match to be returned. /// </param> /// /// <param name="context"> /// The context which the core command is running. /// </param> /// /// <exception cref="NotSupportedException"> /// If the <paramref name="providerInstance"/> does not support this operation. /// </exception> /// /// <exception cref="PipelineStoppedException"> /// If the pipeline is being stopped while executing the command. /// </exception> /// /// <exception cref="ProviderInvocationException"> /// If the provider threw an exception. /// </exception> /// private void DoGetChildNamesManually( CmdletProvider providerInstance, string providerPath, string relativePath, ReturnContainers returnContainers, Collection<WildcardPattern> includeMatcher, Collection<WildcardPattern> excludeMatcher, CmdletProviderContext context, bool recurse, uint depth) { Dbg.Diagnostics.Assert( providerInstance != null, "The providerInstance should have been verified by the caller"); Dbg.Diagnostics.Assert( providerPath != null, "The paths should have been verified by the caller"); Dbg.Diagnostics.Assert( context != null, "The context should have been verified by the caller"); string newProviderPath = MakePath( providerInstance, providerPath, relativePath, context); CmdletProviderContext childNamesContext = new CmdletProviderContext(context); try { // First get all children that match the filters and write them out GetChildNames( providerInstance, newProviderPath, ReturnContainers.ReturnMatchingContainers, childNamesContext); Collection<PSObject> results = childNamesContext.GetAccumulatedObjects(); foreach (PSObject result in results) { // Making sure to obey the StopProcessing. if (context.Stopping) { return; } string name = result.BaseObject as string; if (name == null) { continue; } bool isIncludeMatch = SessionStateUtilities.MatchesAnyWildcardPattern( name, includeMatcher, true); if (isIncludeMatch) { if (!SessionStateUtilities.MatchesAnyWildcardPattern( name, excludeMatcher, false)) { string resultPath = MakePath(providerInstance, relativePath, name, context); context.WriteObject(resultPath); } } } if (recurse) { // Now get all the children that are containers and recurse into them // Limiter for recursion if (depth > 0) // this includes special case 'depth == uint.MaxValue' for unlimited recursion { GetChildNames( providerInstance, newProviderPath, ReturnContainers.ReturnAllContainers, childNamesContext); results = childNamesContext.GetAccumulatedObjects(); foreach (PSObject result in results) { // Making sure to obey the StopProcessing. if (context.Stopping) { return; } string name = result.BaseObject as string; if (name == null) { continue; } // Generate the relative path from the provider path string resultRelativePath = MakePath( providerInstance, relativePath, name, context); // Generate the provider path for the child item to see // if it is a container string resultProviderPath = MakePath( providerInstance, providerPath, resultRelativePath, context); // If the item is a container recurse into it and output its // child names if (IsItemContainer(providerInstance, resultProviderPath, context)) { DoGetChildNamesManually( providerInstance, providerPath, resultRelativePath, returnContainers, includeMatcher, excludeMatcher, context, true, depth - 1); } } // foreach } // if } // recurse } finally { childNamesContext.RemoveStopReferral(); } } // DoGetChildNamesRecurseManually
} // GetChildNames /// <summary> /// Gets names of the children of the specified path. /// </summary> /// /// <param name="path"> /// The path to the item from which to retrieve the child names. /// </param> /// /// <param name="returnContainers"> /// Determines if all containers should be returned or only those containers that match the /// filter(s). /// </param> /// /// <param name="recurse"> /// If true, gets all the relative paths of all the children /// in all the sub-containers of the specified /// container. If false, only gets the immediate child names of the specified /// container. /// </param> /// /// <param name="depth"> /// Limits the depth of recursion; uint.MaxValue performs full recursion. /// </param> /// /// <param name="context"> /// The context which the core command is running. /// </param> /// /// <returns> /// Nothing is returned, but all names should be written to the context object. /// </returns> /// /// <remarks> /// The child names are the leaf portion of the path. Example, for the file system /// the name for the path c:\windows\system32\foo.dll would be foo.dll or for /// the directory c:\windows\system32 would be system32. For Active Directory the /// child names would be RDN values of the child objects of the container. /// </remarks> /// /// <exception cref="ArgumentNullException"> /// If <paramref name="path"/> or <paramref name="propertyToClear"/> is null. /// </exception> /// /// <exception cref="ProviderNotFoundException"> /// If the <paramref name="path"/> refers to a provider that could not be found. /// </exception> /// /// <exception cref="DriveNotFoundException"> /// If the <paramref name="path"/> refers to a drive that could not be found. /// </exception> /// /// <exception cref="NotSupportedException"> /// If the provider that the <paramref name="path"/> refers to does /// not support this operation. /// </exception> /// /// <exception cref="ProviderInvocationException"> /// If the provider threw an exception. /// </exception> /// /// <exception cref="ItemNotFoundException"> /// If <paramref name="path"/> does not contain glob characters and /// could not be found. /// </exception> /// internal void GetChildNames( string path, ReturnContainers returnContainers, bool recurse, uint depth, CmdletProviderContext context) { if (path == null) { throw PSTraceSource.NewArgumentNullException("path"); } // 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); if (LocationGlobber.ShouldPerformGlobbing(path, context)) { ProviderInfo provider = null; CmdletProvider providerInstance = null; // We don't want to process include/exclude filters // when globbing the targets of the operation, so // copy the context without the filters. CmdletProviderContext resolvePathContext = new CmdletProviderContext(context); resolvePathContext.SetFilters( new Collection<string>(), new Collection<string>(), null); // Resolve the path Collection<string> providerPaths = Globber.GetGlobbedProviderPathsFromMonadPath( path, false, resolvePathContext, out provider, out providerInstance); if (resolvePathContext.Drive != null) { context.Drive = resolvePathContext.Drive; } bool pathContainsGlobCharacters = LocationGlobber.StringContainsGlobCharacters(path); foreach (string providerPath in providerPaths) { // Making sure to obey the StopProcessing. if (context.Stopping) { return; } if ((!pathContainsGlobCharacters || recurse) && IsItemContainer(providerInstance, providerPath, context)) { // Since the path contained glob characters or we are recursing and the // path is a container, do the name enumeration manually DoGetChildNamesManually( providerInstance, providerPath, String.Empty, returnContainers, includeMatcher, excludeMatcher, context, recurse, depth); } else { // Since the original path did not contain glob characters, // if the provider is a NavigationCmdletProvider, write // out the child name, else write out the name as it // was resolved. if (providerInstance is NavigationCmdletProvider) { string childName = GetChildName( providerInstance, providerPath, context, false); bool isIncludeMatch = SessionStateUtilities.MatchesAnyWildcardPattern( childName, includeMatcher, true); bool isExcludeMatch = SessionStateUtilities.MatchesAnyWildcardPattern( childName, excludeMatcher, false); if (isIncludeMatch && !isExcludeMatch) { context.WriteObject(childName); } } else { context.WriteObject(providerPath); } } } } else { // Figure out which provider to use ProviderInfo provider = null; PSDriveInfo drive = null; string providerPath = Globber.GetProviderPath( path, context, out provider, out drive); ContainerCmdletProvider providerInstance = GetContainerProviderInstance(provider); if (drive != null) { context.Drive = drive; } if (!providerInstance.ItemExists(providerPath, context)) { ItemNotFoundException pathNotFound = new ItemNotFoundException( providerPath, "PathNotFound", SessionStateStrings.PathNotFound); throw pathNotFound; } if (recurse) { // The path did not contain glob characters but recurse was specified // so do the enumeration manually DoGetChildNamesManually( providerInstance, providerPath, String.Empty, returnContainers, includeMatcher, excludeMatcher, context, recurse, depth); } else { // Since the path did not contain glob characters and recurse wasn't // specified, we can have the provider write out the child names directly GetChildNames( providerInstance, providerPath, returnContainers, context); } } } // GetChildNames