/// <summary> /// Get a Hashtable object out of a PowerShell data file (.psd1) /// </summary> /// <param name="parameterName"> /// Name of the parameter that takes the specified .psd1 file as a value /// </param> /// <param name="psDataFilePath"> /// Path to the powershell data file /// </param> /// <param name="context"> /// ExecutionContext to use /// </param> /// <param name="allowedCommands"> /// Set of command names that are allowed to use in the .psd1 file /// </param> /// <param name="allowedVariables"> /// Set of variable names that are allowed to use in the .psd1 file /// </param> /// <param name="allowEnvironmentVariables"> /// If true, allow to use environment variables in the .psd1 file /// </param> /// <param name="skipPathValidation"> /// If true, caller guarantees the path is valid /// </param> /// <returns></returns> internal static Hashtable EvaluatePowerShellDataFile( string parameterName, string psDataFilePath, ExecutionContext context, IEnumerable <string> allowedCommands, IEnumerable <string> allowedVariables, bool allowEnvironmentVariables, bool skipPathValidation) { if (!skipPathValidation && string.IsNullOrEmpty(parameterName)) { throw PSTraceSource.NewArgumentNullException(nameof(parameterName)); } if (string.IsNullOrEmpty(psDataFilePath)) { throw PSTraceSource.NewArgumentNullException(nameof(psDataFilePath)); } if (context == null) { throw PSTraceSource.NewArgumentNullException(nameof(context)); } string resolvedPath; if (skipPathValidation) { resolvedPath = psDataFilePath; } else { #region "ValidatePowerShellDataFilePath" bool isPathValid = true; // File extension needs to be .psd1 string pathExt = Path.GetExtension(psDataFilePath); if (string.IsNullOrEmpty(pathExt) || !StringLiterals.PowerShellDataFileExtension.Equals(pathExt, StringComparison.OrdinalIgnoreCase)) { isPathValid = false; } ProviderInfo provider; var resolvedPaths = context.SessionState.Path.GetResolvedProviderPathFromPSPath(psDataFilePath, out provider); // ConfigPath should be resolved as FileSystem provider if (provider == null || !Microsoft.PowerShell.Commands.FileSystemProvider.ProviderName.Equals(provider.Name, StringComparison.OrdinalIgnoreCase)) { isPathValid = false; } // ConfigPath should be resolved to a single path if (resolvedPaths.Count != 1) { isPathValid = false; } if (!isPathValid) { throw PSTraceSource.NewArgumentException( parameterName, ParserStrings.CannotResolvePowerShellDataFilePath, psDataFilePath); } resolvedPath = resolvedPaths[0]; #endregion "ValidatePowerShellDataFilePath" } #region "LoadAndEvaluatePowerShellDataFile" object evaluationResult; try { // Create the scriptInfo for the .psd1 file string dataFileName = Path.GetFileName(resolvedPath); var dataFileScriptInfo = new ExternalScriptInfo(dataFileName, resolvedPath, context); ScriptBlock scriptBlock = dataFileScriptInfo.ScriptBlock; // Validate the scriptblock scriptBlock.CheckRestrictedLanguage(allowedCommands, allowedVariables, allowEnvironmentVariables); // Evaluate the scriptblock object oldPsScriptRoot = context.GetVariableValue(SpecialVariables.PSScriptRootVarPath); try { // Set the $PSScriptRoot before the evaluation context.SetVariable(SpecialVariables.PSScriptRootVarPath, Path.GetDirectoryName(resolvedPath)); evaluationResult = PSObject.Base(scriptBlock.InvokeReturnAsIs()); } finally { context.SetVariable(SpecialVariables.PSScriptRootVarPath, oldPsScriptRoot); } } catch (RuntimeException ex) { throw PSTraceSource.NewInvalidOperationException( ex, ParserStrings.CannotLoadPowerShellDataFile, psDataFilePath, ex.Message); } if (!(evaluationResult is Hashtable retResult)) { throw PSTraceSource.NewInvalidOperationException( ParserStrings.InvalidPowerShellDataFile, psDataFilePath); } #endregion "LoadAndEvaluatePowerShellDataFile" return(retResult); }
internal static System.Management.Automation.Signature SignFile(SigningOption option, string fileName, X509Certificate2 certificate, string timeStampServerUrl, string hashAlgorithm) { bool flag = false; System.Management.Automation.Signature signature = null; IntPtr zero = IntPtr.Zero; uint error = 0; string pszOID = null; Utils.CheckArgForNullOrEmpty(fileName, "fileName"); Utils.CheckArgForNull(certificate, "certificate"); if (!string.IsNullOrEmpty(timeStampServerUrl) && ((timeStampServerUrl.Length <= 7) || (timeStampServerUrl.IndexOf("http://", StringComparison.OrdinalIgnoreCase) != 0))) { throw PSTraceSource.NewArgumentException("certificate", "Authenticode", "TimeStampUrlRequired", new object[0]); } if (!string.IsNullOrEmpty(hashAlgorithm)) { IntPtr pvKey = Marshal.StringToHGlobalUni(hashAlgorithm); IntPtr ptr = System.Management.Automation.Security.NativeMethods.CryptFindOIDInfo(2, pvKey, 0); if (ptr == IntPtr.Zero) { throw PSTraceSource.NewArgumentException("certificate", "Authenticode", "InvalidHashAlgorithm", new object[0]); } System.Management.Automation.Security.NativeMethods.CRYPT_OID_INFO crypt_oid_info = (System.Management.Automation.Security.NativeMethods.CRYPT_OID_INFO)Marshal.PtrToStructure(ptr, typeof(System.Management.Automation.Security.NativeMethods.CRYPT_OID_INFO)); pszOID = crypt_oid_info.pszOID; } if (!SecuritySupport.CertIsGoodForSigning(certificate)) { throw PSTraceSource.NewArgumentException("certificate", "Authenticode", "CertNotGoodForSigning", new object[0]); } SecuritySupport.CheckIfFileExists(fileName); try { string str2 = null; if (!string.IsNullOrEmpty(timeStampServerUrl)) { str2 = timeStampServerUrl; } System.Management.Automation.Security.NativeMethods.CRYPTUI_WIZ_DIGITAL_SIGN_INFO structure = System.Management.Automation.Security.NativeMethods.InitSignInfoStruct(fileName, certificate, str2, pszOID, option); zero = Marshal.AllocCoTaskMem(Marshal.SizeOf(structure)); Marshal.StructureToPtr(structure, zero, false); flag = System.Management.Automation.Security.NativeMethods.CryptUIWizDigitalSign(1, IntPtr.Zero, IntPtr.Zero, zero, IntPtr.Zero); Marshal.DestroyStructure(structure.pSignExtInfo, typeof(System.Management.Automation.Security.NativeMethods.CRYPTUI_WIZ_DIGITAL_SIGN_EXTENDED_INFO)); Marshal.FreeCoTaskMem(structure.pSignExtInfo); if (!flag) { error = GetLastWin32Error(); switch (error) { case 0x80004005: case 0x80070001: case 0x80072ee7: flag = true; goto Label_01CF; case 0x80090008: throw PSTraceSource.NewArgumentException("certificate", "Authenticode", "InvalidHashAlgorithm", new object[0]); } tracer.TraceError("CryptUIWizDigitalSign: failed: {0:x}", new object[] { error }); } Label_01CF: if (flag) { return(GetSignature(fileName, null)); } signature = new System.Management.Automation.Signature(fileName, error); } finally { Marshal.DestroyStructure(zero, typeof(System.Management.Automation.Security.NativeMethods.CRYPTUI_WIZ_DIGITAL_SIGN_INFO)); Marshal.FreeCoTaskMem(zero); } return(signature); }
} // SetFunction /// <summary> /// Set a function in the current scope of session state. /// </summary> /// /// <param name="name"> /// The name of the function to set. /// </param> /// /// <param name="function"> /// The new value of the function being set. /// </param> /// /// <param name="originalFunction"> /// The original function (if any) from which the ScriptBlock is derived. /// </param> /// /// <param name="force"> /// If true, the function will be set even if its ReadOnly. /// </param> /// /// <param name="origin"> /// The origin of the caller /// </param> /// /// <exception cref="ArgumentException"> /// If <paramref name="name"/> is null or empty. /// or /// If <paramref name="function"/> is not a <see cref="FilterInfo">FilterInfo</see> /// or <see cref="FunctionInfo">FunctionInfo</see> /// </exception> /// /// <exception cref="ArgumentNullException"> /// If <paramref name="function"/> is null. /// </exception> /// /// <exception cref="SessionStateUnauthorizedAccessException"> /// If the function is read-only or constant. /// </exception> /// internal FunctionInfo SetFunction( string name, ScriptBlock function, FunctionInfo originalFunction, bool force, CommandOrigin origin) { if (String.IsNullOrEmpty(name)) { throw PSTraceSource.NewArgumentException("name"); } if (function == null) { throw PSTraceSource.NewArgumentNullException("function"); } string originalName = name; FunctionLookupPath path = new FunctionLookupPath(name); name = path.UnqualifiedPath; if (String.IsNullOrEmpty(name)) { SessionStateException exception = new SessionStateException( originalName, SessionStateCategory.Function, "ScopedFunctionMustHaveName", SessionStateStrings.ScopedFunctionMustHaveName, ErrorCategory.InvalidArgument); throw exception; } ScopedItemOptions options = ScopedItemOptions.None; if (path.IsPrivate) { options |= ScopedItemOptions.Private; } FunctionScopeItemSearcher searcher = new FunctionScopeItemSearcher( this, path, origin); FunctionInfo result = null; SessionStateScope scope = searcher.InitialScope; if (searcher.MoveNext()) { scope = searcher.CurrentLookupScope; name = searcher.Name; if (path.IsPrivate) { // Need to add the Private flag FunctionInfo existingFunction = scope.GetFunction(name); options |= existingFunction.Options; result = scope.SetFunction(name, function, originalFunction, options, force, origin, ExecutionContext); } else { result = scope.SetFunction(name, function, force, origin, ExecutionContext); } } else { if (path.IsPrivate) { result = scope.SetFunction(name, function, originalFunction, options, force, origin, ExecutionContext); } else { result = scope.SetFunction(name, function, force, origin, ExecutionContext); } } return(result); }
internal static Signature SignFile(SigningOption option, string fileName, X509Certificate2 certificate, string timeStampServerUrl, string hashAlgorithm) { bool result = false; Signature signature = null; IntPtr pSignInfo = IntPtr.Zero; DWORD error = 0; string hashOid = null; Utils.CheckArgForNullOrEmpty(fileName, "fileName"); Utils.CheckArgForNull(certificate, "certificate"); // If given, TimeStamp server URLs must begin with http:// if (!string.IsNullOrEmpty(timeStampServerUrl)) { if ((timeStampServerUrl.Length <= 7) || (timeStampServerUrl.IndexOf("http://", StringComparison.OrdinalIgnoreCase) != 0)) { throw PSTraceSource.NewArgumentException( "certificate", Authenticode.TimeStampUrlRequired); } } // Validate that the hash algorithm is valid if (!string.IsNullOrEmpty(hashAlgorithm)) { IntPtr intptrAlgorithm = Marshal.StringToHGlobalUni(hashAlgorithm); IntPtr oidPtr = NativeMethods.CryptFindOIDInfo(NativeConstants.CRYPT_OID_INFO_NAME_KEY, intptrAlgorithm, 0); // If we couldn't find an OID for the hash // algorithm, it was invalid. if (oidPtr == IntPtr.Zero) { throw PSTraceSource.NewArgumentException( "certificate", Authenticode.InvalidHashAlgorithm); } else { NativeMethods.CRYPT_OID_INFO oidInfo = Marshal.PtrToStructure <NativeMethods.CRYPT_OID_INFO>(oidPtr); hashOid = oidInfo.pszOID; } } if (!SecuritySupport.CertIsGoodForSigning(certificate)) { throw PSTraceSource.NewArgumentException( "certificate", Authenticode.CertNotGoodForSigning); } SecuritySupport.CheckIfFileExists(fileName); // SecurityUtils.CheckIfFileSmallerThan4Bytes(fileName); try { // CryptUI is not documented either way, but does not // support empty strings for the timestamp server URL. // It expects null, only. Instead, it randomly AVs if you // try. string timeStampServerUrlForCryptUI = null; if (!string.IsNullOrEmpty(timeStampServerUrl)) { timeStampServerUrlForCryptUI = timeStampServerUrl; } // // first initialize the struct to pass to // CryptUIWizDigitalSign() function // NativeMethods.CRYPTUI_WIZ_DIGITAL_SIGN_INFO si = NativeMethods.InitSignInfoStruct(fileName, certificate, timeStampServerUrlForCryptUI, hashOid, option); pSignInfo = Marshal.AllocCoTaskMem(Marshal.SizeOf(si)); Marshal.StructureToPtr(si, pSignInfo, false); // // sign the file // // The GetLastWin32Error of this is checked, but PreSharp doesn't seem to be // able to see that. #pragma warning disable 56523 result = NativeMethods.CryptUIWizDigitalSign( (DWORD)NativeMethods.CryptUIFlags.CRYPTUI_WIZ_NO_UI, IntPtr.Zero, IntPtr.Zero, pSignInfo, IntPtr.Zero); #pragma warning enable 56523 if (si.pSignExtInfo != null) { Marshal.DestroyStructure <NativeMethods.CRYPTUI_WIZ_DIGITAL_SIGN_EXTENDED_INFO>(si.pSignExtInfo); Marshal.FreeCoTaskMem(si.pSignExtInfo); } if (!result) { error = GetLastWin32Error(); // // ISSUE-2004/05/08-kumarp : there seems to be a bug // in CryptUIWizDigitalSign(). // It returns 80004005 or 80070001 // but it signs the file correctly. Mask this error // till we figure out this odd behavior. // if ((error == 0x80004005) || (error == 0x80070001) || // CryptUIWizDigitalSign introduced a breaking change in Win8 to return this // error code (ERROR_INTERNET_NAME_NOT_RESOLVED) when you provide an invalid // timestamp server. It used to be 0x80070001. // Also masking this out so that we don't introduce a breaking change ourselves. (error == 0x80072EE7) ) { result = true; } else { if (error == Win32Errors.NTE_BAD_ALGID) { throw PSTraceSource.NewArgumentException( "certificate", Authenticode.InvalidHashAlgorithm); } s_tracer.TraceError("CryptUIWizDigitalSign: failed: {0:x}", error); } } if (result) { signature = GetSignature(fileName, null); } else { signature = new Signature(fileName, (DWORD)error); } } finally { Marshal.DestroyStructure <NativeMethods.CRYPTUI_WIZ_DIGITAL_SIGN_INFO>(pSignInfo); Marshal.FreeCoTaskMem(pSignInfo); } return(signature); }
} // SetLocation /// <summary> /// Changes the current working directory to the path specified /// </summary> /// <param name="path"> /// The path of the new current working directory /// </param> /// <param name="context"> /// The context the provider uses when performing the operation. /// </param> /// <returns> /// The PathInfo object representing the path of the location /// that was set. /// </returns> /// <exception cref="ArgumentNullException"> /// If <paramref name="path"/> is null. /// </exception> /// <exception cref="ArgumentException"> /// If <paramref name="path"/> does not exist, is not a container, or /// resolved to multiple containers. /// </exception> /// <exception cref="ProviderNotFoundException"> /// If <paramref name="path"/> refers to a provider that does not exist. /// </exception> /// <exception cref="DriveNotFoundException"> /// If <paramref name="path"/> refers to a drive that does not exist. /// </exception> /// <exception cref="ProviderInvocationException"> /// If the provider associated with <paramref name="path"/> threw an /// exception. /// </exception> /// <exception cref="ItemNotFoundException"> /// If the <paramref name="path"/> could not be resolved. /// </exception> internal PathInfo SetLocation(string path, CmdletProviderContext context) { if (path == null) { throw PSTraceSource.NewArgumentNullException("path"); } string originalPath = path; string driveName = null; ProviderInfo provider = null; string providerId = null; // Replace path with last working directory when '-' was passed. bool pushNextLocation = true; if (originalPath.Equals("-", StringComparison.OrdinalIgnoreCase)) { if (_SetLocationHistory.Count <= 0) { throw new InvalidOperationException(SessionStateStrings.SetContentToLastLocationWhenHistoryIsEmpty); } var previousLocation = _SetLocationHistory.Pop(); path = previousLocation.Path; pushNextLocation = false; } if (pushNextLocation) { var newPushPathInfo = GetNewPushPathInfo(); _SetLocationHistory.Push(newPushPathInfo); } PSDriveInfo previousWorkingDrive = CurrentDrive; // First check to see if the path is a home path if (LocationGlobber.IsHomePath(path)) { path = Globber.GetHomeRelativePath(path); } if (LocationGlobber.IsProviderDirectPath(path)) { // The path is a provider-direct path so use the current // provider and its hidden drive but don't modify the path // at all. provider = CurrentLocation.Provider; CurrentDrive = provider.HiddenDrive; } else if (LocationGlobber.IsProviderQualifiedPath(path, out providerId)) { provider = GetSingleProvider(providerId); CurrentDrive = provider.HiddenDrive; } else { // See if the path is a relative or absolute // path. if (Globber.IsAbsolutePath(path, out driveName)) { // Since the path is an absolute path // we need to change the current working // drive PSDriveInfo newWorkingDrive = GetDrive(driveName); CurrentDrive = newWorkingDrive; // If the path is simply a colon-terminated drive, // not a slash-terminated path to the root of a drive, // set the path to the current working directory of that drive. string colonTerminatedVolume = CurrentDrive.Name + ':'; if (CurrentDrive.VolumeSeparatedByColon && (path.Length == colonTerminatedVolume.Length)) { path = Path.Combine((colonTerminatedVolume + Path.DirectorySeparatorChar), CurrentDrive.CurrentLocation); } // Now that the current working drive is set, // process the rest of the path as a relative path. } } if (context == null) { context = new CmdletProviderContext(this.ExecutionContext); } if (CurrentDrive != null) { context.Drive = CurrentDrive; } CmdletProvider providerInstance = null; Collection <PathInfo> workingPath = null; try { workingPath = Globber.GetGlobbedMonadPathsFromMonadPath( path, false, context, out providerInstance); } catch (LoopFlowException) { throw; } catch (PipelineStoppedException) { throw; } catch (ActionPreferenceStopException) { throw; } catch (Exception) // Catch-all OK, 3rd party callout { // Reset the drive to the previous drive and // then rethrow the error CurrentDrive = previousWorkingDrive; throw; } if (workingPath.Count == 0) { // Set the current working drive back to the previous // one in case it was changed. CurrentDrive = previousWorkingDrive; throw new ItemNotFoundException( path, "PathNotFound", SessionStateStrings.PathNotFound); } // We allow globbing the location as long as it only resolves a single container. bool foundContainer = false; bool pathIsContainer = false; bool pathIsProviderQualifiedPath = false; bool currentPathisProviderQualifiedPath = false; for (int index = 0; index < workingPath.Count; ++index) { CmdletProviderContext normalizePathContext = new CmdletProviderContext(context); PathInfo resolvedPath = workingPath[index]; string currentPath = path; try { string providerName = null; currentPathisProviderQualifiedPath = LocationGlobber.IsProviderQualifiedPath(resolvedPath.Path, out providerName); if (currentPathisProviderQualifiedPath) { // The path should be the provider-qualified path without the provider ID // or :: string providerInternalPath = LocationGlobber.RemoveProviderQualifier(resolvedPath.Path); try { currentPath = NormalizeRelativePath(GetSingleProvider(providerName), providerInternalPath, String.Empty, normalizePathContext); } catch (NotSupportedException) { // Since the provider does not support normalizing the path, just // use the path we currently have. } catch (LoopFlowException) { throw; } catch (PipelineStoppedException) { throw; } catch (ActionPreferenceStopException) { throw; } catch (Exception) // Catch-all OK, 3rd party callout { // Reset the drive to the previous drive and // then rethrow the error CurrentDrive = previousWorkingDrive; throw; } } else { try { currentPath = NormalizeRelativePath(resolvedPath.Path, CurrentDrive.Root, normalizePathContext); } catch (NotSupportedException) { // Since the provider does not support normalizing the path, just // use the path we currently have. } catch (LoopFlowException) { throw; } catch (PipelineStoppedException) { throw; } catch (ActionPreferenceStopException) { throw; } catch (Exception) // Catch-all OK, 3rd party callout { // Reset the drive to the previous drive and // then rethrow the error CurrentDrive = previousWorkingDrive; throw; } } // Now see if there was errors while normalizing the path if (normalizePathContext.HasErrors()) { // Set the current working drive back to the previous // one in case it was changed. CurrentDrive = previousWorkingDrive; normalizePathContext.ThrowFirstErrorOrDoNothing(); } } finally { normalizePathContext.RemoveStopReferral(); } // Check to see if the path is a container bool isContainer = false; CmdletProviderContext itemContainerContext = new CmdletProviderContext(context); itemContainerContext.SuppressWildcardExpansion = true; try { isContainer = IsItemContainer( resolvedPath.Path, itemContainerContext); if (itemContainerContext.HasErrors()) { // Set the current working drive back to the previous // one in case it was changed. CurrentDrive = previousWorkingDrive; itemContainerContext.ThrowFirstErrorOrDoNothing(); } } catch (NotSupportedException) { if (currentPath.Length == 0) { // Treat this as a container because providers that only // support the ContainerCmdletProvider interface are really // containers at their root. isContainer = true; } } finally { itemContainerContext.RemoveStopReferral(); } if (isContainer) { if (foundContainer) { // The path resolved to more than one container // Set the current working drive back to the previous // one in case it was changed. CurrentDrive = previousWorkingDrive; throw PSTraceSource.NewArgumentException( "path", SessionStateStrings.PathResolvedToMultiple, originalPath); } else { // Set the path to use path = currentPath; // Mark it as a container pathIsContainer = true; // Mark whether or not it was provider-qualified pathIsProviderQualifiedPath = currentPathisProviderQualifiedPath; // Mark that we have already found one container. Finding additional // should be an error foundContainer = true; } } } if (pathIsContainer) { // Remove the root slash since it is implied that the // current working directory is relative to the root. if (!LocationGlobber.IsProviderDirectPath(path) && path.StartsWith(StringLiterals.DefaultPathSeparatorString, StringComparison.CurrentCulture) && !pathIsProviderQualifiedPath) { path = path.Substring(1); } s_tracer.WriteLine( "New working path = {0}", path); CurrentDrive.CurrentLocation = path; } else { // Set the current working drive back to the previous // one in case it was changed. CurrentDrive = previousWorkingDrive; throw new ItemNotFoundException( originalPath, "PathNotFound", SessionStateStrings.PathNotFound); } // Now make sure the current drive is set in the provider's // current working drive hashtable ProvidersCurrentWorkingDrive[CurrentDrive.Provider] = CurrentDrive; // Set the $PWD variable to the new location this.SetVariable(SpecialVariables.PWDVarPath, this.CurrentLocation, false, true, CommandOrigin.Internal); return(this.CurrentLocation); } // SetLocation
/// <summary> /// Resets the current working drive and directory to the first /// entry on the working directory stack and removes that entry /// from the stack. /// </summary> /// <param name="stackName"> /// The ID of the stack to pop the location from. If it is null or /// empty the default stack is used. /// </param> /// <returns> /// A PathInfo object representing the location that was popped /// from the location stack and set as the new location. /// </returns> /// <exception cref="ArgumentException"> /// If the path on the stack does not exist, is not a container, or /// resolved to multiple containers. /// or /// If <paramref name="stackName"/> contains wildcard characters and resolves /// to multiple location stacks. /// or /// A stack was not found with the specified name. /// </exception> /// <exception cref="ProviderNotFoundException"> /// If the path on the stack refers to a provider that does not exist. /// </exception> /// <exception cref="DriveNotFoundException"> /// If the path on the stack refers to a drive that does not exist. /// </exception> /// <exception cref="ProviderInvocationException"> /// If the provider associated with the path on the stack threw an /// exception. /// </exception> internal PathInfo PopLocation(string stackName) { if (String.IsNullOrEmpty(stackName)) { stackName = _defaultStackName; } if (WildcardPattern.ContainsWildcardCharacters(stackName)) { // Need to glob the stack name, but it can only glob to a single. bool haveMatch = false; WildcardPattern stackNamePattern = WildcardPattern.Get(stackName, WildcardOptions.IgnoreCase); foreach (string key in _workingLocationStack.Keys) { if (stackNamePattern.IsMatch(key)) { if (haveMatch) { throw PSTraceSource.NewArgumentException( "stackName", SessionStateStrings.StackNameResolvedToMultiple, stackName); } haveMatch = true; stackName = key; } } } PathInfo result = CurrentLocation; try { Stack <PathInfo> locationStack = null; if (!_workingLocationStack.TryGetValue(stackName, out locationStack)) { if (!string.Equals(stackName, startingDefaultStackName, StringComparison.OrdinalIgnoreCase)) { throw PSTraceSource.NewArgumentException( "stackName", SessionStateStrings.StackNotFound, stackName); } return(null); } PathInfo poppedWorkingDirectory = locationStack.Pop(); Dbg.Diagnostics.Assert( poppedWorkingDirectory != null, "All items in the workingLocationStack should be " + "of type PathInfo"); string newPath = LocationGlobber.GetMshQualifiedPath( WildcardPattern.Escape(poppedWorkingDirectory.Path), poppedWorkingDirectory.GetDrive()); result = SetLocation(newPath); if (locationStack.Count == 0 && !String.Equals(stackName, startingDefaultStackName, StringComparison.OrdinalIgnoreCase)) { // Remove the stack from the stack list if it // no longer contains any paths. _workingLocationStack.Remove(stackName); } } catch (InvalidOperationException) { // This is a no-op. We stay with the current working // directory. } return(result); }
/// <summary> /// Constructs an instance of the CompiledCommandAttribute using the reflection information retrieved /// from the enclosing bindable object type. /// </summary> /// /// <param name="member"> /// The member information for the parameter /// </param> /// /// <param name="processingDynamicParameters"> /// True if dynamic parameters are being processed, or false otherwise. /// </param> /// /// <exception cref="ArgumentNullException"> /// If <paramref name="member"/> is null. /// </exception> /// /// <exception cref="ArgumentException"> /// If <paramref name="member"/> is not a field or a property. /// </exception> /// /// <exception cref="MetadataException"> /// If the member has more than one <see cref="ParameterAttribute">ParameterAttribute</see> /// that defines the same parameter-set name. /// </exception> /// internal CompiledCommandParameter(MemberInfo member, bool processingDynamicParameters) { if (member == null) { throw PSTraceSource.NewArgumentNullException("member"); } this.Name = member.Name; this.DeclaringType = member.DeclaringType; this.IsDynamic = processingDynamicParameters; var propertyInfo = member as PropertyInfo; if (propertyInfo != null) { this.Type = propertyInfo.PropertyType; } else { var fieldInfo = member as FieldInfo; if (fieldInfo != null) { this.Type = fieldInfo.FieldType; } else { ArgumentException e = PSTraceSource.NewArgumentException( "member", DiscoveryExceptions.CompiledCommandParameterMemberMustBeFieldOrProperty); throw e; } } this.CollectionTypeInformation = new ParameterCollectionTypeInformation(this.Type); this.CompiledAttributes = new Collection <Attribute>(); this.ParameterSetData = new Dictionary <string, ParameterSetSpecificMetadata>(StringComparer.OrdinalIgnoreCase); // We do not want to get the inherited custom attributes, only the attributes exposed // directly on the member var memberAttributes = member.GetCustomAttributes(false); Collection <ValidateArgumentsAttribute> validationAttributes = null; Collection <ArgumentTransformationAttribute> argTransformationAttributes = null; string[] aliases = null; foreach (Attribute attr in memberAttributes) { switch (attr) { case ExperimentalAttribute _: case ParameterAttribute param when param.ToHide: break; default: ProcessAttribute(member.Name, attr, ref validationAttributes, ref argTransformationAttributes, ref aliases); break; } } this.ValidationAttributes = validationAttributes == null ? Utils.EmptyArray <ValidateArgumentsAttribute>() : validationAttributes.ToArray(); this.ArgumentTransformationAttributes = argTransformationAttributes == null ? Utils.EmptyArray <ArgumentTransformationAttribute>() : argTransformationAttributes.ToArray(); this.Aliases = aliases ?? Utils.EmptyArray <string>(); }
/// <summary> /// Given a scope identifier, returns the proper session state scope. /// </summary> /// <param name="scopeID"> /// A scope identifier that is either one of the "special" scopes like /// "global", "local", or "private, or a numeric ID of a relative scope /// to the current scope. /// </param> /// <returns> /// The scope identified by the scope ID or the current scope if the /// scope ID is not defined as a special or numeric scope identifier. /// </returns> /// <exception cref="ArgumentException"> /// If <paramref name="scopeID"/> is less than zero, or not /// a number and not "script", "global", "local", or "private" /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// If <paramref name="scopeID"/> is less than zero or greater than the number of currently /// active scopes. /// </exception> internal SessionStateScope GetScopeByID(string scopeID) { SessionStateScope result = _currentScope; if (!string.IsNullOrEmpty(scopeID)) { if (string.Equals( scopeID, StringLiterals.Global, StringComparison.OrdinalIgnoreCase)) { result = GlobalScope; } else if (string.Equals( scopeID, StringLiterals.Local, StringComparison.OrdinalIgnoreCase)) { result = _currentScope; } else if (string.Equals( scopeID, StringLiterals.Private, StringComparison.OrdinalIgnoreCase)) { result = _currentScope; } else if (string.Equals( scopeID, StringLiterals.Script, StringComparison.OrdinalIgnoreCase)) { // Get the current script scope from the stack. result = _currentScope.ScriptScope; } else { // Since the scope is not any of the special scopes // try parsing it as an ID try { int scopeNumericID = Int32.Parse(scopeID, System.Globalization.CultureInfo.CurrentCulture); if (scopeNumericID < 0) { throw PSTraceSource.NewArgumentOutOfRangeException(ScopeParameterName, scopeID); } result = GetScopeByID(scopeNumericID) ?? _currentScope; } catch (FormatException) { throw PSTraceSource.NewArgumentException(ScopeParameterName, AutomationExceptions.InvalidScopeIdArgument, ScopeParameterName); } catch (OverflowException) { throw PSTraceSource.NewArgumentOutOfRangeException(ScopeParameterName, scopeID); } } } return(result); }
/// <summary> /// Gets the parameters by matching its name. /// </summary> /// /// <param name="name"> /// The name of the parameter. /// </param> /// /// <param name="throwOnParameterNotFound"> /// If true and a matching parameter is not found, an exception will be /// throw. If false and a matching parameter is not found, null is returned. /// </param> /// /// <param name="tryExactMatching"> /// If true we do exact matching, otherwise we do not. /// </param> /// /// <param name="invocationInfo"> /// The invocation information about the code being run. /// </param> /// /// <returns> /// The a collection of the metadata associated with the parameters that /// match the specified name. If no matches were found, an empty collection /// is returned. /// </returns> /// /// <exception cref="ArgumentException"> /// If <paramref name="name"/> is null or empty. /// </exception> /// internal MergedCompiledCommandParameter GetMatchingParameter( string name, bool throwOnParameterNotFound, bool tryExactMatching, InvocationInfo invocationInfo) { if (string.IsNullOrEmpty(name)) { throw PSTraceSource.NewArgumentException("name"); } Collection <MergedCompiledCommandParameter> matchingParameters = new Collection <MergedCompiledCommandParameter>(); // Skip the leading '-' if present if (name.Length > 0 && SpecialCharacters.IsDash(name[0])) { name = name.Substring(1); } // First try to match the bindable parameters foreach (string parameterName in _bindableParameters.Keys) { if (CultureInfo.InvariantCulture.CompareInfo.IsPrefix(parameterName, name, CompareOptions.IgnoreCase)) { // If it is an exact match then only return the exact match // as the result if (tryExactMatching && String.Equals(parameterName, name, StringComparison.OrdinalIgnoreCase)) { return(_bindableParameters[parameterName]); } else { matchingParameters.Add(_bindableParameters[parameterName]); } } } // Now check the aliases foreach (string parameterName in _aliasedParameters.Keys) { if (CultureInfo.InvariantCulture.CompareInfo.IsPrefix(parameterName, name, CompareOptions.IgnoreCase)) { // If it is an exact match then only return the exact match // as the result if (tryExactMatching && String.Equals(parameterName, name, StringComparison.OrdinalIgnoreCase)) { return(_aliasedParameters[parameterName]); } else { if (!matchingParameters.Contains(_aliasedParameters[parameterName])) { matchingParameters.Add(_aliasedParameters[parameterName]); } } } } if (matchingParameters.Count > 1) { // Prefer parameters in the cmdlet over common parameters Collection <MergedCompiledCommandParameter> filteredParameters = new Collection <MergedCompiledCommandParameter>(); foreach (MergedCompiledCommandParameter matchingParameter in matchingParameters) { if ((matchingParameter.BinderAssociation == ParameterBinderAssociation.DeclaredFormalParameters) || (matchingParameter.BinderAssociation == ParameterBinderAssociation.DynamicParameters)) { filteredParameters.Add(matchingParameter); } } if (filteredParameters.Count == 1) { matchingParameters = filteredParameters; } else { StringBuilder possibleMatches = new StringBuilder(); foreach (MergedCompiledCommandParameter matchingParameter in matchingParameters) { possibleMatches.Append(" -"); possibleMatches.Append(matchingParameter.Parameter.Name); } ParameterBindingException exception = new ParameterBindingException( ErrorCategory.InvalidArgument, invocationInfo, null, name, null, null, ParameterBinderStrings.AmbiguousParameter, "AmbiguousParameter", possibleMatches); throw exception; } } else if (matchingParameters.Count == 0) { if (throwOnParameterNotFound) { ParameterBindingException exception = new ParameterBindingException( ErrorCategory.InvalidArgument, invocationInfo, null, name, null, null, ParameterBinderStrings.NamedParameterNotFound, "NamedParameterNotFound"); throw exception; } } MergedCompiledCommandParameter result = null; if (matchingParameters.Count > 0) { result = matchingParameters[0]; } return(result); } // GetMatchingParameter
/// <summary> /// Constructs a scoped item lookup path. /// </summary> /// <param name="path">The path to parse.</param> /// <param name="knownFlags"> /// These flags for anything known about the path (such as, is it a function) before /// being scanned. /// </param> /// <exception cref="ArgumentNullException"> /// If <paramref name="path"/> is null. /// </exception> internal VariablePath(string path, VariablePathFlags knownFlags) { if (string.IsNullOrEmpty(path)) { throw PSTraceSource.NewArgumentException(nameof(path)); } _userPath = path; _flags = knownFlags; string candidateScope = null; string candidateScopeUpper = null; VariablePathFlags candidateFlags = VariablePathFlags.Unqualified; int currentCharIndex = 0; int lastScannedColon = -1; scanScope: switch (path[0]) { case 'g': case 'G': candidateScope = "lobal"; candidateScopeUpper = "LOBAL"; candidateFlags = VariablePathFlags.Global; break; case 'l': case 'L': candidateScope = "ocal"; candidateScopeUpper = "OCAL"; candidateFlags = VariablePathFlags.Local; break; case 'p': case 'P': candidateScope = "rivate"; candidateScopeUpper = "RIVATE"; candidateFlags = VariablePathFlags.Private; break; case 's': case 'S': candidateScope = "cript"; candidateScopeUpper = "CRIPT"; candidateFlags = VariablePathFlags.Script; break; case 'v': case 'V': if (knownFlags == VariablePathFlags.None) { // If we see 'variable:', our namespaceId will be empty, and // we'll also need to scan for the scope again. candidateScope = "ariable"; candidateScopeUpper = "ARIABLE"; candidateFlags = VariablePathFlags.Variable; } break; } if (candidateScope != null) { currentCharIndex += 1; // First character already matched. int j; for (j = 0; currentCharIndex < path.Length && j < candidateScope.Length; ++j, ++currentCharIndex) { if (path[currentCharIndex] != candidateScope[j] && path[currentCharIndex] != candidateScopeUpper[j]) { break; } } if (j == candidateScope.Length && currentCharIndex < path.Length && path[currentCharIndex] == ':') { if (_flags == VariablePathFlags.None) { _flags = VariablePathFlags.Variable; } _flags |= candidateFlags; lastScannedColon = currentCharIndex; currentCharIndex += 1; // If saw 'variable:', we need to look for a scope after 'variable:'. if (candidateFlags == VariablePathFlags.Variable) { knownFlags = VariablePathFlags.Variable; candidateScope = candidateScopeUpper = null; candidateFlags = VariablePathFlags.None; goto scanScope; } } } if (_flags == VariablePathFlags.None) { lastScannedColon = path.IndexOf(':', currentCharIndex); // No colon, or a colon as the first character means we have // a simple variable, otherwise it's a drive. if (lastScannedColon > 0) { _flags = VariablePathFlags.DriveQualified; } } if (lastScannedColon == -1) { _unqualifiedPath = _userPath; } else { _unqualifiedPath = _userPath.Substring(lastScannedColon + 1); } if (_flags == VariablePathFlags.None) { _flags = VariablePathFlags.Unqualified | VariablePathFlags.Variable; } }
/// <summary> /// Gets the ResourceManager from the cache or gets an instance of the ResourceManager /// and returns it if it isn't already present in the cache. /// </summary> /// <param name="assembly"> /// The assembly to be used as the base for resource lookup. /// </param> /// <param name="baseName"> /// The base name of the resources to get the ResourceManager for. /// </param> /// <returns> /// A ResourceManager instance for the assembly and base name that were specified. /// </returns> internal static ResourceManager GetResourceManager( Assembly assembly, string baseName) { if (assembly == null) { throw PSTraceSource.NewArgumentNullException("assembly"); } if (String.IsNullOrEmpty(baseName)) { throw PSTraceSource.NewArgumentException("baseName"); } // Check to see if the manager is already in the cache ResourceManager manager = null; Dictionary <string, ResourceManager> baseNameCache; string assemblyManifestFileLocation = assembly.Location; lock (s_syncRoot) { // First do the lookup based on the assembly location if (s_resourceManagerCache.TryGetValue(assemblyManifestFileLocation, out baseNameCache) && baseNameCache != null) { // Now do the lookup based on the resource base name baseNameCache.TryGetValue(baseName, out manager); } } // If it's not in the cache, create it an add it. if (manager == null) { manager = InitRMWithAssembly(baseName, assembly); // Add the new resource manager to the hash if (baseNameCache != null) { lock (s_syncRoot) { // Since the assembly is already cached, we just have // to cache the base name entry baseNameCache[baseName] = manager; } } else { // Since the assembly wasn't cached, we have to create base name // cache entry and then add it into the cache keyed by the assembly // location var baseNameCacheEntry = new Dictionary <string, ResourceManager>(); baseNameCacheEntry[baseName] = manager; lock (s_syncRoot) { s_resourceManagerCache[assemblyManifestFileLocation] = baseNameCacheEntry; } } } Diagnostics.Assert( manager != null, "If the manager was not already created, it should have been dynamically created or an exception should have been thrown"); return(manager); }
internal VariablePath(string path, VariablePathFlags knownFlags) { if (string.IsNullOrEmpty(path)) { throw PSTraceSource.NewArgumentException("path"); } this._userPath = path; this._flags = knownFlags; string str = null; string str2 = null; VariablePathFlags unqualified = VariablePathFlags.Unqualified; int startIndex = 0; int index = -1; Label_0036: switch (path[0]) { case 'P': case 'p': str = "rivate"; str2 = "RIVATE"; unqualified = VariablePathFlags.Private; break; case 'S': case 's': str = "cript"; str2 = "CRIPT"; unqualified = VariablePathFlags.Script; break; case 'V': case 'v': if (knownFlags == VariablePathFlags.None) { str = "ariable"; str2 = "ARIABLE"; unqualified = VariablePathFlags.Variable; } break; case 'G': case 'g': str = "lobal"; str2 = "LOBAL"; unqualified = VariablePathFlags.Global; break; case 'L': case 'l': str = "ocal"; str2 = "OCAL"; unqualified = VariablePathFlags.Local; break; } if (str != null) { startIndex++; int num3 = 0; while ((startIndex < path.Length) && (num3 < str.Length)) { if ((path[startIndex] != str[num3]) && (path[startIndex] != str2[num3])) { break; } num3++; startIndex++; } if (((num3 == str.Length) && (startIndex < path.Length)) && (path[startIndex] == ':')) { if (this._flags == VariablePathFlags.None) { this._flags = VariablePathFlags.Variable; } this._flags |= unqualified; index = startIndex; startIndex++; if (unqualified == VariablePathFlags.Variable) { knownFlags = VariablePathFlags.Variable; str = (string)(str2 = null); unqualified = VariablePathFlags.None; goto Label_0036; } } } if (this._flags == VariablePathFlags.None) { index = path.IndexOf(':', startIndex); if (index > 0) { this._flags = VariablePathFlags.DriveQualified; } } if (index == -1) { this._unqualifiedPath = this._userPath; } else { this._unqualifiedPath = this._userPath.Substring(index + 1); } if (this._flags == VariablePathFlags.None) { this._flags = VariablePathFlags.Unqualified | VariablePathFlags.Variable; } }
/// <summary> /// Constructor for the ProviderInfo class. /// </summary> /// /// <param name="sessionState"> /// The instance of session state that the provider is being added to. /// </param> /// /// <param name="implementingType"> /// The type that implements the provider /// </param> /// /// <param name="name"> /// The alternate name to use for the provider instead of the one specified /// in the .cmdletprovider file. /// </param> /// /// <param name="description"> /// The description of the provider. /// </param> /// /// <param name="home"> /// The home path for the provider. This must be an MSH path. /// </param> /// /// <param name="helpFile"> /// The help file for the provider. /// </param> /// /// <param name="psSnapIn"> /// The Snap-In for the provider. /// </param> /// /// <exception cref="ArgumentNullException"> /// If <paramref name="implementingType"/> or <paramref name="sessionState"/> is null. /// </exception> /// /// <exception cref="ArgumentException"> /// If <paramref name="name"/> is null or empty. /// </exception> /// internal ProviderInfo( SessionState sessionState, Type implementingType, string name, string description, string home, string helpFile, PSSnapInInfo psSnapIn) { // Verify parameters if (sessionState == null) { throw PSTraceSource.NewArgumentNullException("sessionState"); } if (implementingType == null) { throw PSTraceSource.NewArgumentNullException("implementingType"); } if (String.IsNullOrEmpty(name)) { throw PSTraceSource.NewArgumentException("name"); } if (String.IsNullOrEmpty(name)) { throw PSTraceSource.NewArgumentException("name"); } _sessionState = sessionState; Name = name; Description = description; Home = home; ImplementingType = implementingType; HelpFile = helpFile; PSSnapIn = psSnapIn; #if SUPPORTS_CMDLETPROVIDER_FILE LoadProviderFromPath(path); #endif // Create the hidden drive. The name doesn't really // matter since we are not adding this drive to a scope. _hiddenDrive = new PSDriveInfo( this.FullName, this, "", "", null); _hiddenDrive.Hidden = true; // TODO:PSL // this is probably not right here if (implementingType == typeof(Microsoft.PowerShell.Commands.FileSystemProvider) && !Platform.IsWindows) { VolumeSeparatedByColon = false; } }