private void RunClause(Action <FunctionContext> clause, object dollarUnderbar, object inputToProcess)
        {
            ExecutionContext.CheckStackDepth();

            _anyClauseExecuted = true;
            Pipe oldErrorOutputPipe = this.Context.ShellFunctionErrorOutputPipe;

            // If the script block has a different language mode than the current,
            // change the language mode.
            PSLanguageMode?oldLanguageMode = null;
            PSLanguageMode?newLanguageMode = null;

            if ((_scriptBlock.LanguageMode.HasValue) &&
                (_scriptBlock.LanguageMode != Context.LanguageMode))
            {
                oldLanguageMode = Context.LanguageMode;
                newLanguageMode = _scriptBlock.LanguageMode;
            }

            try
            {
                var oldScopeOrigin = this.Context.EngineSessionState.CurrentScope.ScopeOrigin;

                try
                {
                    this.Context.EngineSessionState.CurrentScope.ScopeOrigin =
                        this._dontUseScopeCommandOrigin ? CommandOrigin.Internal : this.Command.CommandOrigin;

                    // Set the language mode. We do this before EnterScope(), so that the language
                    // mode is appropriately applied for evaluation parameter defaults.
                    if (newLanguageMode.HasValue)
                    {
                        Context.LanguageMode = newLanguageMode.Value;
                    }

                    bool?oldLangModeTransitionStatus = null;
                    try
                    {
                        // If it's from ConstrainedLanguage to FullLanguage, indicate the transition before parameter binding takes place.
                        if (oldLanguageMode == PSLanguageMode.ConstrainedLanguage && newLanguageMode == PSLanguageMode.FullLanguage)
                        {
                            oldLangModeTransitionStatus = Context.LanguageModeTransitionInParameterBinding;
                            Context.LanguageModeTransitionInParameterBinding = true;
                        }

                        EnterScope();
                    }
                    finally
                    {
                        if (oldLangModeTransitionStatus.HasValue)
                        {
                            // Revert the transition state to old value after doing the parameter binding
                            Context.LanguageModeTransitionInParameterBinding = oldLangModeTransitionStatus.Value;
                        }
                    }

                    if (commandRuntime.ErrorMergeTo == MshCommandRuntime.MergeDataStream.Output)
                    {
                        Context.RedirectErrorPipe(commandRuntime.OutputPipe);
                    }
                    else if (commandRuntime.ErrorOutputPipe.IsRedirected)
                    {
                        Context.RedirectErrorPipe(commandRuntime.ErrorOutputPipe);
                    }

                    if (dollarUnderbar != AutomationNull.Value)
                    {
                        _localsTuple.SetAutomaticVariable(AutomaticVariable.Underbar, dollarUnderbar, _context);
                    }
                    else if (_dollarUnderbar != AutomationNull.Value)
                    {
                        _localsTuple.SetAutomaticVariable(AutomaticVariable.Underbar, _dollarUnderbar, _context);
                    }

                    if (inputToProcess != AutomationNull.Value)
                    {
                        if (inputToProcess == null)
                        {
                            inputToProcess = MshCommandRuntime.StaticEmptyArray.GetEnumerator();
                        }
                        else
                        {
                            IList list = inputToProcess as IList;
                            inputToProcess = (list != null)
                                                 ? list.GetEnumerator()
                                                 : LanguagePrimitives.GetEnumerator(inputToProcess);
                        }

                        _localsTuple.SetAutomaticVariable(AutomaticVariable.Input, inputToProcess, _context);
                    }

                    clause(_functionContext);
                }
                catch (TargetInvocationException tie)
                {
                    // DynamicInvoke wraps exceptions, unwrap them here.
                    throw tie.InnerException;
                }
                finally
                {
                    Context.ShellFunctionErrorOutputPipe = oldErrorOutputPipe;

                    if (oldLanguageMode.HasValue)
                    {
                        Context.LanguageMode = oldLanguageMode.Value;
                    }

                    Context.EngineSessionState.CurrentScope.ScopeOrigin = oldScopeOrigin;
                }
            }
            catch (ExitException ee)
            {
                if (!this.FromScriptFile || _rethrowExitException)
                {
                    throw;
                }

                this._exitWasCalled = true;

                int exitCode = (int)ee.Argument;
                this.Command.Context.SetVariable(SpecialVariables.LastExitCodeVarPath, exitCode);

                if (exitCode != 0)
                {
                    this.commandRuntime.PipelineProcessor.ExecutionFailed = true;
                }
            }
            catch (FlowControlException)
            {
                throw;
            }
            catch (RuntimeException e)
            {
                // This method always throws.
                ManageScriptException(e);
            }
            catch (Exception e)
            {
                // This cmdlet threw an exception, so wrap it and bubble it up.
                throw ManageInvocationException(e);
            }
        }
        internal static Uri GetUriFromCommandPSObject(PSObject commandFullHelp)
        {
            // this object knows Maml format...
            // So retrieve Uri information as per the format..
            if ((commandFullHelp is null) ||
                (commandFullHelp.Properties["relatedLinks"] is null) ||
                (commandFullHelp.Properties["relatedLinks"].Value is null))
            {
                // return the default..
                return(null);
            }

            PSObject relatedLinks = PSObject.AsPSObject(commandFullHelp.Properties["relatedLinks"].Value);

            if (relatedLinks.Properties["navigationLink"] is null)
            {
                return(null);
            }

            object[] navigationLinks = (object[])LanguagePrimitives.ConvertTo(
                relatedLinks.Properties["navigationLink"].Value,
                typeof(object[]),
                CultureInfo.InvariantCulture);
            foreach (object navigationLinkAsObject in navigationLinks)
            {
                if (navigationLinkAsObject is null)
                {
                    continue;
                }

                PSObject       navigationLink = PSObject.AsPSObject(navigationLinkAsObject);
                PSNoteProperty uriNP          = navigationLink.Properties["uri"] as PSNoteProperty;
                if (uriNP != null)
                {
                    string uriString = string.Empty;
                    LanguagePrimitives.TryConvertTo <string>(uriNP.Value, CultureInfo.InvariantCulture, out uriString);
                    if (!string.IsNullOrEmpty(uriString))
                    {
                        if (!System.Uri.IsWellFormedUriString(uriString, UriKind.RelativeOrAbsolute))
                        {
                            // WinBlue: 545315 Online help links are broken with localized help
                            // Example: https://go.microsoft.com/fwlink/?LinkID=113324 (moglicherwei se auf Englisch)
                            // Split the string based on <s> (space). We decided to go with this approach as
                            // UX localization authors use spaces. Correctly extracting only the wellformed URI
                            // is out-of-scope for this fix.
                            string[] tempUriSplitArray = uriString.Split(Utils.Separators.Space);
                            uriString = tempUriSplitArray[0];
                        }

                        try
                        {
                            return(new System.Uri(uriString));
                            // return only the first Uri (ignore other uris)
                        }
                        catch (UriFormatException)
                        {
                            throw PSTraceSource.NewInvalidOperationException(HelpErrors.InvalidURI, uriString);
                        }
                    }
                }
            }

            return(null);
        }
        private void ConvertCommand(CommandAst commandAst, bool isTrustedInput)
        {
            // First need command name.
            var commandName = GetCommandName(commandAst.CommandElements[0], isTrustedInput);

            var command = new Command(commandName, isScript: false, useLocalScope: _createLocalScope);

            // Handle redirections, if any (there can really be just 0 or 1).
            if (commandAst.Redirections.Count > 0)
            {
                Diagnostics.Assert(commandAst.Redirections.Count == 1, "only 1 kind of redirection is supported");
                Diagnostics.Assert(commandAst.Redirections[0] is MergingRedirectionAst, "unexpected redirection type");

                PipelineResultTypes toType = PipelineResultTypes.Output;
                PipelineResultTypes fromType;
                switch (commandAst.Redirections[0].FromStream)
                {
                case RedirectionStream.Error:
                    fromType = PipelineResultTypes.Error;
                    break;

                case RedirectionStream.Warning:
                    fromType = PipelineResultTypes.Warning;
                    break;

                case RedirectionStream.Verbose:
                    fromType = PipelineResultTypes.Verbose;
                    break;

                case RedirectionStream.Debug:
                    fromType = PipelineResultTypes.Debug;
                    break;

                case RedirectionStream.Information:
                    fromType = PipelineResultTypes.Information;
                    break;

                case RedirectionStream.All:
                    fromType = PipelineResultTypes.All;
                    break;

                default:
                    // Default to Error->Output to be compatible with V2.
                    fromType = PipelineResultTypes.Error;
                    break;
                }

                command.MergeMyResults(fromType, toType);
            }

            _powershell.AddCommand(command);

            // Now the parameters and arguments.
            foreach (var ast in commandAst.CommandElements.Skip(1))
            {
                var exprAst = ast as ExpressionAst;
                if (exprAst != null)
                {
                    VariableExpressionAst variableAst = null;

                    var usingExprAst = ast as UsingExpressionAst;
                    if (usingExprAst != null)
                    {
                        string usingAstKey = PsUtils.GetUsingExpressionKey(usingExprAst);
                        object usingValue  = _usingValueMap[usingAstKey];
                        variableAst = usingExprAst.SubExpression as VariableExpressionAst;
                        if (variableAst != null && variableAst.Splatted)
                        {
                            // Support the splatting of a dictionary
                            var parameters = usingValue as System.Collections.IDictionary;
                            if (parameters != null)
                            {
                                _powershell.AddParameters(parameters);
                            }
                            else
                            {
                                // Support the splatting of an array
                                var arguments = usingValue as System.Collections.IEnumerable;
                                if (arguments != null)
                                {
                                    foreach (object argument in arguments)
                                    {
                                        _powershell.AddArgument(argument);
                                    }
                                }
                                else
                                {
                                    // Splat the object directly.
                                    _powershell.AddArgument(usingValue);
                                }
                            }
                        }
                        else
                        {
                            _powershell.AddArgument(usingValue);
                        }

                        continue;
                    }

                    variableAst = ast as VariableExpressionAst;
                    if (variableAst != null && variableAst.Splatted)
                    {
                        GetSplattedVariable(variableAst);
                    }
                    else
                    {
                        var    constantExprAst = ast as ConstantExpressionAst;
                        object argument;
                        if (constantExprAst != null &&
                            (LanguagePrimitives.IsNumeric(LanguagePrimitives.GetTypeCode(constantExprAst.StaticType)) ||
                             constantExprAst.StaticType == typeof(System.Numerics.BigInteger)))
                        {
                            var commandArgumentText = constantExprAst.Extent.Text;
                            argument = constantExprAst.Value;
                            if (!commandArgumentText.Equals(constantExprAst.Value.ToString(), StringComparison.Ordinal))
                            {
                                // The wrapped number will actually return a PSObject which could end holding a reference to
                                // a typetable, making the object runspace specific.  We should find a better way to avoid
                                // any possibility of sharing problems, though this is unlikely to cause problems.
                                argument = ParserOps.WrappedNumber(argument, commandArgumentText);
                            }
                        }
                        else
                        {
                            if (!isTrustedInput)
                            {
                                try
                                {
                                    argument = GetSafeValueVisitor.GetSafeValue(exprAst, _context, GetSafeValueVisitor.SafeValueContext.GetPowerShell);
                                }
                                catch (System.Exception)
                                {
                                    throw new ScriptBlockToPowerShellNotSupportedException(
                                              "CantConvertWithDynamicExpression",
                                              null,
                                              AutomationExceptions.CantConvertWithDynamicExpression,
                                              exprAst.Extent.Text);
                                }
                            }
                            else
                            {
                                argument = GetExpressionValue(exprAst, isTrustedInput);
                            }
                        }

                        _powershell.AddArgument(argument);
                    }
                }
                else
                {
                    AddParameter((CommandParameterAst)ast, isTrustedInput);
                }
            }
        }
        /// <summary>
        /// Read the 'Zone.Identifier' alternate data stream to determin SecurityZone of the file.
        /// </summary>
        private static SecurityZone ReadFromZoneIdentifierDataStream(string filePath)
        {
            try
            {
                FileStream zoneDataSteam = AlternateDataStreamUtilities.CreateFileStream(
                    filePath, "Zone.Identifier", FileMode.Open,
                    FileAccess.Read, FileShare.Read);

                // If we successfully get the zone data stream, try to read the ZoneId information
                using (StreamReader zoneDataReader = new StreamReader(zoneDataSteam, GetDefaultEncoding()))
                {
                    string line = null;
                    bool   zoneTransferMatched = false;

                    // After a lot experiments with Zone.CreateFromUrl/Zone.SecurityZone, the way it handles the alternate
                    // data stream 'Zone.Identifier' is observed as follows:
                    //    1. Read content of the data stream line by line. Each line is trimmed.
                    //    2. Try to match the current line with '^\[ZoneTransfer\]'.
                    //           - if matching, then do step #3 starting from the next line
                    //           - if not matching, then continue to do step #2 with the next line.
                    //    3. Try to match the current line with '^ZoneId\s*=\s*(.*)'
                    //           - if matching, check if the ZoneId is valid. Then return the corresponding SecurityZone if valid, or 'NoZone' if invalid.
                    //           - if not matching, then continue to do step #3 with the next line.
                    //    4. Reach EOF, then return 'NoZone'.
                    while ((line = zoneDataReader.ReadLine()) != null)
                    {
                        line = line.Trim();
                        if (!zoneTransferMatched)
                        {
                            zoneTransferMatched = Regex.IsMatch(line, @"^\[ZoneTransfer\]", RegexOptions.IgnoreCase);
                        }
                        else
                        {
                            Match match = Regex.Match(line, @"^ZoneId\s*=\s*(.*)", RegexOptions.IgnoreCase);
                            if (!match.Success)
                            {
                                continue;
                            }

                            // Match found. Validate ZoneId value.
                            string zoneIdRawValue = match.Groups[1].Value;
                            match = Regex.Match(zoneIdRawValue, @"^[+-]?\d+", RegexOptions.IgnoreCase);
                            if (!match.Success)
                            {
                                return(SecurityZone.NoZone);
                            }

                            string       zoneId = match.Groups[0].Value;
                            SecurityZone result;
                            return(LanguagePrimitives.TryConvertTo(zoneId, out result) ? result : SecurityZone.NoZone);
                        }
                    }
                }
            }
            catch (FileNotFoundException)
            {
                // FileNotFoundException may be thrown by AlternateDataStreamUtilities.CreateFileStream when the data stream 'Zone.Identifier'
                // does not exist, or when the underlying file system doesn't support alternate data stream.
            }

            return(SecurityZone.NoZone);
        }
Exemple #5
0
        private Collection <PSObject> InvokeScript(ScriptBlock sb, bool useNewScope,
                                                   PipelineResultTypes writeToPipeline, IList input, params object[] args)
        {
            if (_cmdlet != null)
            {
                _cmdlet.ThrowIfStopping();
            }

            Cmdlet cmdletToUse = null;

            ScriptBlock.ErrorHandlingBehavior errorHandlingBehavior = ScriptBlock.ErrorHandlingBehavior.WriteToExternalErrorPipe;

            // Check if they want output
            if ((writeToPipeline & PipelineResultTypes.Output) == PipelineResultTypes.Output)
            {
                cmdletToUse      = _cmdlet;
                writeToPipeline &= (~PipelineResultTypes.Output);
            }

            // Check if they want error
            if ((writeToPipeline & PipelineResultTypes.Error) == PipelineResultTypes.Error)
            {
                errorHandlingBehavior = ScriptBlock.ErrorHandlingBehavior.WriteToCurrentErrorPipe;
                writeToPipeline      &= (~PipelineResultTypes.Error);
            }

            if (writeToPipeline != PipelineResultTypes.None)
            {
                // The only output types are Output and Error.
                throw PSTraceSource.NewNotImplementedException();
            }

            // If the cmdletToUse is not null, then the result of the evaluation will be
            // streamed out the output pipe of the cmdlet.
            object rawResult;

            if (cmdletToUse != null)
            {
                sb.InvokeUsingCmdlet(
                    contextCmdlet: cmdletToUse,
                    useLocalScope: useNewScope,
                    errorHandlingBehavior: errorHandlingBehavior,
                    dollarUnder: AutomationNull.Value,
                    input: input,
                    scriptThis: AutomationNull.Value,
                    args: args);
                rawResult = AutomationNull.Value;
            }
            else
            {
                rawResult = sb.DoInvokeReturnAsIs(
                    useLocalScope: useNewScope,
                    errorHandlingBehavior: errorHandlingBehavior,
                    dollarUnder: AutomationNull.Value,
                    input: input,
                    scriptThis: AutomationNull.Value,
                    args: args);
            }

            if (rawResult == AutomationNull.Value)
            {
                return(new Collection <PSObject>());
            }

            // If the result is already a collection of PSObjects, just return it...
            Collection <PSObject> result = rawResult as Collection <PSObject>;

            if (result != null)
            {
                return(result);
            }

            result = new Collection <PSObject>();

            IEnumerator list = null;

            list = LanguagePrimitives.GetEnumerator(rawResult);

            if (list != null)
            {
                while (list.MoveNext())
                {
                    object val = list.Current;

                    result.Add(LanguagePrimitives.AsPSObjectOrNull(val));
                }
            }
            else
            {
                result.Add(LanguagePrimitives.AsPSObjectOrNull(rawResult));
            }

            return(result);
        }
Exemple #6
0
        internal static object GetMDArrayValueOrSlice(Array array, object indexes)
        {
            Exception whyFailed = null;

            int[] indexArray = null;
            try
            {
                indexArray = (int[])LanguagePrimitives.ConvertTo(indexes, typeof(int[]), NumberFormatInfo.InvariantInfo);
            }
            catch (InvalidCastException ice)
            {
                // Ignore an exception here as we may actually be looking at an array of arrays
                // which could still be ok. Save the exception as we may use it later...
                whyFailed = ice;
            }

            if (indexArray != null)
            {
                if (indexArray.Length != array.Rank)
                {
                    // rank failed to match so error...
                    ReportIndexingError(array, indexes, null);
                }

                return(GetMDArrayValue(array, indexArray, false));
            }

            var indexList = new List <int[]>();

            var ie = LanguagePrimitives.GetEnumerator(indexes);

            while (EnumerableOps.MoveNext(null, ie))
            {
                var currentIndex = EnumerableOps.Current(ie);
                try
                {
                    indexArray = LanguagePrimitives.ConvertTo <int[]>(currentIndex);
                }
                catch (InvalidCastException)
                {
                    indexArray = null;
                }

                if (indexArray == null || indexArray.Length != array.Rank)
                {
                    if (whyFailed != null)
                    {
                        // If the first fails, report the original exception and all indices
                        ReportIndexingError(array, indexes, whyFailed);
                        Diagnostics.Assert(false, "ReportIndexingError must throw");
                    }
                    // If the second or subsequent index fails, report the failure for just that index
                    ReportIndexingError(array, currentIndex, null);
                    Diagnostics.Assert(false, "ReportIndexingError must throw");
                }

                // Only use whyFailed the first time through, otherwise
                whyFailed = null;
                indexList.Add(indexArray);
            }

            // Optimistically assume all indices are valid so the result array is the same size.
            // If that turns out to be wrong, we'll just copy the elements produced.
            var result = new object[indexList.Count];
            int j      = 0;

            foreach (var i in indexList)
            {
                var value = GetMDArrayValue(array, i, true);
                if (value != AutomationNull.Value)
                {
                    result[j++] = value;
                }
            }

            if (j != indexList.Count)
            {
                var shortResult = new object[j];
                Array.Copy(result, shortResult, j);
                return(shortResult);
            }

            return(result);
        }
Exemple #7
0
 internal static bool IsNumeric(this Type type)
 {
     return(LanguagePrimitives.IsNumeric(LanguagePrimitives.GetTypeCode(type)));
 }
Exemple #8
0
 internal static bool IsNumericOrPrimitive(this Type type)
 {
     return(type.GetTypeInfo().IsPrimitive || LanguagePrimitives.IsNumeric(LanguagePrimitives.GetTypeCode(type)));
 }
Exemple #9
0
 internal static bool IsFloating(this Type type)
 {
     return(LanguagePrimitives.IsFloating(LanguagePrimitives.GetTypeCode(type)));
 }
Exemple #10
0
        internal static object GetMDArrayValueOrSlice(Array array, object indexes)
        {
            Exception reason = null;

            int[] numArray = null;
            try
            {
                numArray = (int[])LanguagePrimitives.ConvertTo(indexes, typeof(int[]), NumberFormatInfo.InvariantInfo);
            }
            catch (InvalidCastException exception2)
            {
                reason = exception2;
            }
            if (numArray != null)
            {
                if (numArray.Length != array.Rank)
                {
                    ReportIndexingError(array, indexes, null);
                }
                return(GetMDArrayValue(array, numArray, false));
            }
            List <int[]> list       = new List <int[]>();
            IEnumerator  enumerator = LanguagePrimitives.GetEnumerator(indexes);

            while (EnumerableOps.MoveNext(null, enumerator))
            {
                object valueToConvert = EnumerableOps.Current(enumerator);
                try
                {
                    numArray = LanguagePrimitives.ConvertTo <int[]>(valueToConvert);
                }
                catch (InvalidCastException)
                {
                    numArray = null;
                }
                if ((numArray == null) || (numArray.Length != array.Rank))
                {
                    if (reason != null)
                    {
                        ReportIndexingError(array, indexes, reason);
                    }
                    ReportIndexingError(array, valueToConvert, null);
                }
                reason = null;
                list.Add(numArray);
            }
            object[] sourceArray = new object[list.Count];
            int      length      = 0;

            foreach (int[] numArray2 in list)
            {
                object obj3 = GetMDArrayValue(array, numArray2, true);
                if (obj3 != AutomationNull.Value)
                {
                    sourceArray[length++] = obj3;
                }
            }
            if (length != list.Count)
            {
                object[] destinationArray = new object[length];
                Array.Copy(sourceArray, destinationArray, length);
                return(destinationArray);
            }
            return(sourceArray);
        }
Exemple #11
0
        /// <summary>
        /// Evaluate a given flag enum value against the expression.
        /// </summary>
        /// <param name="value">
        /// The flag enum value to be evaluated.
        /// </param>
        /// <returns>
        /// Whether the enum value satisfy the expression.
        /// </returns>
        public bool Evaluate(T value)
        {
            object val = LanguagePrimitives.ConvertTo(value, _underType, CultureInfo.InvariantCulture);

            return(Root.Eval(val));
        }
Exemple #12
0
        /// <summary>
        /// Stringize a non-IEnum argument to a native command, adding quotes
        /// and trailing spaces as appropriate. An array gets added as multiple arguments
        /// each of which will be stringized.
        /// </summary>
        /// <param name="context">Execution context instance.</param>
        /// <param name="parameter">The parameter associated with the operation.</param>
        /// <param name="obj">The object to append.</param>
        /// <param name="argArrayAst">If the argument was an array literal, the Ast, otherwise null.</param>
        /// <param name="sawVerbatimArgumentMarker">True if the argument occurs after --%.</param>
        /// <param name="stringConstantType">Bare, SingleQuoted, or DoubleQuoted.</param>
        private void AppendOneNativeArgument(ExecutionContext context, CommandParameterInternal parameter, object obj, ArrayLiteralAst argArrayAst, bool sawVerbatimArgumentMarker, StringConstantType stringConstantType)
        {
            IEnumerator list = LanguagePrimitives.GetEnumerator(obj);

            Diagnostics.Assert((argArrayAst == null) || (obj is object[] && ((object[])obj).Length == argArrayAst.Elements.Count), "array argument and ArrayLiteralAst differ in number of elements");

            int    currentElement = -1;
            string separator      = string.Empty;

            do
            {
                string arg;
                object currentObj;
                if (list == null)
                {
                    arg        = PSObject.ToStringParser(context, obj);
                    currentObj = obj;
                }
                else
                {
                    if (!ParserOps.MoveNext(context, null, list))
                    {
                        break;
                    }

                    currentObj = ParserOps.Current(null, list);
                    arg        = PSObject.ToStringParser(context, currentObj);

                    currentElement += 1;
                    if (currentElement != 0)
                    {
                        separator = GetEnumerableArgSeparator(argArrayAst, currentElement);
                    }
                }

                if (!string.IsNullOrEmpty(arg))
                {
                    // Only add the separator to the argument string rather than adding a separator to the ArgumentList.
                    _arguments.Append(separator);

                    if (sawVerbatimArgumentMarker)
                    {
                        arg = Environment.ExpandEnvironmentVariables(arg);
                        _arguments.Append(arg);

                        // we need to split the argument on spaces
                        _argumentList.AddRange(arg.Split(' ', StringSplitOptions.RemoveEmptyEntries));
                    }
                    else
                    {
                        // We need to add quotes if the argument has unquoted spaces.  The
                        // quotes could appear anywhere inside the string, not just at the start,
                        // e.g.
                        //    $a = 'a"b c"d'
                        //    echoargs $a 'a"b c"d' a"b c"d
                        //
                        // The above should see 3 identical arguments in argv (the command line will
                        // actually have quotes in different places, but the Win32 command line=>argv parser
                        // erases those differences.
                        //
                        // We need to check quotes that the win32 argument parser checks which is currently
                        // just the normal double quotes, no other special quotes.  Also note that mismatched
                        // quotes are supported
                        if (NeedQuotes(arg))
                        {
                            _arguments.Append('"');

                            if (stringConstantType == StringConstantType.DoubleQuoted)
                            {
                                _arguments.Append(ResolvePath(arg, Context));
                                AddToArgumentList(parameter, ResolvePath(arg, Context));
                            }
                            else
                            {
                                _arguments.Append(arg);
                                AddToArgumentList(parameter, arg);
                            }

                            // need to escape all trailing backslashes so the native command receives it correctly
                            // according to http://www.daviddeley.com/autohotkey/parameters/parameters.htm#WINCRULESDOC
                            for (int i = arg.Length - 1; i >= 0 && arg[i] == '\\'; i--)
                            {
                                _arguments.Append('\\');
                            }

                            _arguments.Append('"');
                        }
                        else
                        {
                            if (argArrayAst != null && ArgumentPassingStyle == NativeArgumentPassingStyle.Standard)
                            {
                                // We have a literal array, so take the extent, break it on spaces and add them to the argument list.
                                foreach (string element in argArrayAst.Extent.Text.Split(' ', StringSplitOptions.RemoveEmptyEntries))
                                {
                                    PossiblyGlobArg(element, parameter, stringConstantType);
                                }

                                break;
                            }
                            else
                            {
                                PossiblyGlobArg(arg, parameter, stringConstantType);
                            }
                        }
                    }
                }
                else if (ArgumentPassingStyle == NativeArgumentPassingStyle.Standard && currentObj != null)
                {
                    // add empty strings to arglist, but not nulls
                    AddToArgumentList(parameter, arg);
                }
            }while (list != null);
        }
        internal static ArrayList GetSuggestion(HistoryInfo lastHistory, Object lastError, ArrayList errorList)
        {
            ArrayList returnSuggestions = new ArrayList();

            PSModuleInfo invocationModule = new PSModuleInfo(true);

            invocationModule.SessionState.PSVariable.Set("lastHistory", lastHistory);
            invocationModule.SessionState.PSVariable.Set("lastError", lastError);

            int initialErrorCount = 0;

            // Go through all of the suggestions
            foreach (Hashtable suggestion in s_suggestions)
            {
                initialErrorCount = errorList.Count;

                // Make sure the rule is enabled
                if (!LanguagePrimitives.IsTrue(suggestion["Enabled"]))
                {
                    continue;
                }

                SuggestionMatchType matchType = (SuggestionMatchType)LanguagePrimitives.ConvertTo(
                    suggestion["MatchType"],
                    typeof(SuggestionMatchType),
                    CultureInfo.InvariantCulture);

                // If this is a dynamic match, evaluate the ScriptBlock
                if (matchType == SuggestionMatchType.Dynamic)
                {
                    object result = null;

                    ScriptBlock evaluator = suggestion["Rule"] as ScriptBlock;
                    if (evaluator == null)
                    {
                        suggestion["Enabled"] = false;

                        throw new ArgumentException(
                                  SuggestionStrings.RuleMustBeScriptBlock, "Rule");
                    }

                    try
                    {
                        result = invocationModule.Invoke(evaluator, null);
                    }
                    catch (Exception)
                    {
                        // Catch-all OK. This is a third-party call-out.
                        suggestion["Enabled"] = false;
                        continue;
                    }

                    // If it returned results, evaluate its suggestion
                    if (LanguagePrimitives.IsTrue(result))
                    {
                        string suggestionText = GetSuggestionText(suggestion["Suggestion"], (object[])suggestion["SuggestionArgs"], invocationModule);

                        if (!String.IsNullOrEmpty(suggestionText))
                        {
                            string returnString = String.Format(
                                CultureInfo.CurrentCulture,
                                "Suggestion [{0},{1}]: {2}",
                                (int)suggestion["Id"],
                                (string)suggestion["Category"],
                                suggestionText);

                            returnSuggestions.Add(returnString);
                        }
                    }
                }
                else
                {
                    string matchText = String.Empty;

                    // Otherwise, this is a Regex match against the
                    // command or error
                    if (matchType == SuggestionMatchType.Command)
                    {
                        matchText = lastHistory.CommandLine;
                    }
                    else if (matchType == SuggestionMatchType.Error)
                    {
                        if (lastError != null)
                        {
                            Exception lastException = lastError as Exception;
                            if (lastException != null)
                            {
                                matchText = lastException.Message;
                            }
                            else
                            {
                                matchText = lastError.ToString();
                            }
                        }
                    }
                    else
                    {
                        suggestion["Enabled"] = false;

                        throw new ArgumentException(
                                  SuggestionStrings.InvalidMatchType,
                                  "MatchType");
                    }

                    // If the text matches, evaluate the suggestion
                    if (Regex.IsMatch(matchText, (string)suggestion["Rule"], RegexOptions.IgnoreCase))
                    {
                        string suggestionText = GetSuggestionText(suggestion["Suggestion"], (object[])suggestion["SuggestionArgs"], invocationModule);

                        if (!String.IsNullOrEmpty(suggestionText))
                        {
                            string returnString = String.Format(
                                CultureInfo.CurrentCulture,
                                "Suggestion [{0},{1}]: {2}",
                                (int)suggestion["Id"],
                                (string)suggestion["Category"],
                                suggestionText);

                            returnSuggestions.Add(returnString);
                        }
                    }
                }

                // If the rule generated an error, disable it
                if (errorList.Count != initialErrorCount)
                {
                    suggestion["Enabled"] = false;
                }
            }

            return(returnSuggestions);
        }
Exemple #14
0
        /// <summary>
        /// Sets the value of a property coming from a previous call to GetMember
        /// </summary>
        /// <param name="property">PSProperty coming from a previous call to GetMember</param>
        /// <param name="setValue">value to set the property with</param>
        /// <param name="convertIfPossible">instructs the adapter to convert before setting, if the adapter supports conversion</param>
        protected override void PropertySet(PSProperty property, object setValue, bool convertIfPossible)
        {
            PropertyValueCollection values = property.adapterData as PropertyValueCollection;

            if (null != values)
            {
                // This means GetMember returned PropertyValueCollection
                try
                {
                    values.Clear();
                }
                catch (System.Runtime.InteropServices.COMException e)
                {
                    if (e.ErrorCode != unchecked ((int)0x80004005) || (setValue == null))
                    {
                        // When clear is called, DirectoryEntry calls PutEx on AD object with Clear option and Null Value
                        // WinNT provider throws E_FAIL when null value is specified though actually ADS_PROPERTY_CLEAR option is used,
                        // we need to catch this exception here.
                        // But at the same time we don't want to catch the exception if user explicitly sets the value to null.
                        throw;
                    }
                }

                IEnumerable enumValues = LanguagePrimitives.GetEnumerable(setValue);

                if (enumValues == null)
                {
                    values.Add(setValue);
                }
                else
                {
                    foreach (object objValue in enumValues)
                    {
                        values.Add(objValue);
                    }
                }
            }
            else
            {
                // This means GetMember returned the value from InvokeGet..So set the value using InvokeSet.
                DirectoryEntry entry = (DirectoryEntry)property.baseObject;
                Diagnostics.Assert(entry != null, "Object should be of type DirectoryEntry in DirectoryEntry adapter.");

                List <object> setValues  = new List <object>();
                IEnumerable   enumValues = LanguagePrimitives.GetEnumerable(setValue);

                if (enumValues == null)
                {
                    setValues.Add(setValue);
                }
                else
                {
                    foreach (object objValue in enumValues)
                    {
                        setValues.Add(objValue);
                    }
                }

                entry.InvokeSet(property.name, setValues.ToArray());
            }

            return;
        }
Exemple #15
0
        /// <summary>
        /// Override - Modify Parameters element in maml1 using the Parameters element from maml2.
        /// This will copy parameters from maml2 that are not present in maml1.
        /// </summary>
        internal static void OverrideParameters(PSObject maml1, PSObject maml2)
        {
            string[] parametersPath = new string[] { "Parameters", "Parameter" };
            // Final collection of PSObjects.
            List <object> maml2items = new List <object>();

            // Add maml2 first since we are prepending.

            // For maml2: Add as collection or single item. No-op if
            PSPropertyInfo propertyInfo2 = GetPropertyInfo(maml2, parametersPath);
            var            array         = propertyInfo2.Value as Array;

            if (array != null)
            {
                maml2items.AddRange(array as IEnumerable <object>);
            }
            else
            {
                maml2items.Add(PSObject.AsPSObject(propertyInfo2.Value));
            }

            // Extend maml1 to make sure the property-path exists - since we'll be modifying it soon.
            EnsurePropertyInfoPathExists(maml1, parametersPath);
            // For maml1: Add as collection or single item. Do nothing if null or some other type.
            PSPropertyInfo propertyInfo1 = GetPropertyInfo(maml1, parametersPath);
            List <object>  maml1items    = new List <object>();

            array = propertyInfo1.Value as Array;
            if (array != null)
            {
                maml1items.AddRange(array as IEnumerable <object>);
            }
            else
            {
                maml1items.Add(PSObject.AsPSObject(propertyInfo1.Value));
            }

            // copy parameters from maml2 that are not present in maml1
            for (int index = 0; index < maml2items.Count; index++)
            {
                PSObject       m2paramObj     = PSObject.AsPSObject(maml2items[index]);
                string         param2Name     = "";
                PSPropertyInfo m2propertyInfo = m2paramObj.Properties["Name"];

                if (null != m2propertyInfo)
                {
                    if (!LanguagePrimitives.TryConvertTo <string>(m2propertyInfo.Value, out param2Name))
                    {
                        continue;
                    }
                }

                bool isParamFoundInMaml1 = false;
                foreach (PSObject m1ParamObj in maml1items)
                {
                    string         param1Name     = "";
                    PSPropertyInfo m1PropertyInfo = m1ParamObj.Properties["Name"];

                    if (null != m1PropertyInfo)
                    {
                        if (!LanguagePrimitives.TryConvertTo <string>(m1PropertyInfo.Value, out param1Name))
                        {
                            continue;
                        }
                    }

                    if (param1Name.Equals(param2Name, StringComparison.OrdinalIgnoreCase))
                    {
                        isParamFoundInMaml1 = true;
                    }
                }

                if (!isParamFoundInMaml1)
                {
                    maml1items.Add(maml2items[index]);
                }
            }

            // Now replace in maml1. If items.Count == 0 do nothing since Value is already null.
            if (maml1items.Count == 1)
            {
                propertyInfo1.Value = maml1items[0];
            }
            else if (maml1items.Count >= 2)
            {
                propertyInfo1.Value = maml1items.ToArray();
            }
        }
Exemple #16
0
 internal static bool IsInteger(this Type type)
 {
     return(LanguagePrimitives.IsInteger(LanguagePrimitives.GetTypeCode(type)));
 }
        internal Uri LookupUriFromCommandInfo()
        {
            CommandTypes cmdTypesToLookFor = CommandTypes.Cmdlet;

            switch (this.HelpCategory)
            {
            case Automation.HelpCategory.Cmdlet:
                cmdTypesToLookFor = CommandTypes.Cmdlet;
                break;

            case Automation.HelpCategory.Function:
                cmdTypesToLookFor = CommandTypes.Function;
                break;

            case Automation.HelpCategory.ScriptCommand:
                cmdTypesToLookFor = CommandTypes.Script;
                break;

            case Automation.HelpCategory.ExternalScript:
                cmdTypesToLookFor = CommandTypes.ExternalScript;
                break;

            case Automation.HelpCategory.Filter:
                cmdTypesToLookFor = CommandTypes.Filter;
                break;

            case Automation.HelpCategory.Configuration:
                cmdTypesToLookFor = CommandTypes.Configuration;
                break;

            default:
                return(null);
            }

            string commandName = this.Name;
            string moduleName  = string.Empty;

            if (this.FullHelp.Properties["ModuleName"] != null)
            {
                PSNoteProperty moduleNameNP = this.FullHelp.Properties["ModuleName"] as PSNoteProperty;
                if (moduleNameNP != null)
                {
                    LanguagePrimitives.TryConvertTo <string>(moduleNameNP.Value, CultureInfo.InvariantCulture,
                                                             out moduleName);
                }
            }

            string commandToSearch = commandName;

            if (!string.IsNullOrEmpty(moduleName))
            {
                commandToSearch = string.Format(CultureInfo.InvariantCulture,
                                                "{0}\\{1}", moduleName, commandName);
            }

            ExecutionContext context = LocalPipeline.GetExecutionContextFromTLS();

            if (context == null)
            {
                return(null);
            }

            try
            {
                CommandInfo cmdInfo = null;

                if (cmdTypesToLookFor == CommandTypes.Cmdlet)
                {
                    cmdInfo = context.SessionState.InvokeCommand.GetCmdlet(commandToSearch);
                }
                else
                {
                    cmdInfo = context.SessionState.InvokeCommand.GetCommands(commandToSearch, cmdTypesToLookFor, false).FirstOrDefault();
                }

                if ((cmdInfo == null) || (cmdInfo.CommandMetadata == null))
                {
                    return(null);
                }

                string uriString = cmdInfo.CommandMetadata.HelpUri;
                if (!string.IsNullOrEmpty(uriString))
                {
                    if (!System.Uri.IsWellFormedUriString(uriString, UriKind.RelativeOrAbsolute))
                    {
                        // WinBlue: 545315 Online help links are broken with localized help
                        // Example: https://go.microsoft.com/fwlink/?LinkID=113324 (moglicherwei se auf Englisch)
                        // Split the string based on <s> (space). We decided to go with this approach as
                        // UX localization authors use spaces. Correctly extracting only the wellformed URI
                        // is out-of-scope for this fix.
                        string[] tempUriSplitArray = uriString.Split(Utils.Separators.Space);
                        uriString = tempUriSplitArray[0];
                    }

                    try
                    {
                        return(new System.Uri(uriString));
                        // return only the first Uri (ignore other uris)
                    }
                    catch (UriFormatException)
                    {
                        throw PSTraceSource.NewInvalidOperationException(HelpErrors.InvalidURI,
                                                                         cmdInfo.CommandMetadata.HelpUri);
                    }
                }
            }
            catch (CommandNotFoundException)
            {
            }

            return(null);
        }
        /// <summary>
        /// Stringize a non-IEnum argument to a native command, adding quotes
        /// and trailing spaces as appropriate. An array gets added as multiple arguments
        /// each of which will be stringized.
        /// </summary>
        /// <param name="context">Execution context instance</param>
        /// <param name="obj">The object to append</param>
        /// <param name="argArrayAst">If the argument was an array literal, the Ast, otherwise null</param>
        /// <param name="sawVerbatimArgumentMarker">true if the argument occurs after --%</param>
        /// <param name="usedQuotes">True if the argument was a quoted string (single or double)</param>
        private void appendOneNativeArgument(ExecutionContext context, object obj, ArrayLiteralAst argArrayAst, bool sawVerbatimArgumentMarker, bool usedQuotes)
        {
            IEnumerator list = LanguagePrimitives.GetEnumerator(obj);

            Diagnostics.Assert(argArrayAst == null ||
                               obj is object[] && ((object[])obj).Length == argArrayAst.Elements.Count,
                               "array argument and ArrayLiteralAst differ in number of elements");

            int    currentElement = -1;
            string separator      = "";

            do
            {
                string arg;
                if (list == null)
                {
                    arg = PSObject.ToStringParser(context, obj);
                }
                else
                {
                    if (!ParserOps.MoveNext(context, null, list))
                    {
                        break;
                    }
                    arg = PSObject.ToStringParser(context, ParserOps.Current(null, list));

                    currentElement += 1;
                    if (currentElement != 0)
                    {
                        separator = GetEnumerableArgSeparator(argArrayAst, currentElement);
                    }
                }

                if (!String.IsNullOrEmpty(arg))
                {
                    _arguments.Append(separator);

                    if (sawVerbatimArgumentMarker)
                    {
                        arg = Environment.ExpandEnvironmentVariables(arg);
                        _arguments.Append(arg);
                    }
                    else
                    {
                        // We need to add quotes if the argument has unquoted spaces.  The
                        // quotes could appear anywhere inside the string, not just at the start,
                        // e.g.
                        //    $a = 'a"b c"d'
                        //    echoargs $a 'a"b c"d' a"b c"d
                        //
                        // The above should see 3 identical arguments in argv (the command line will
                        // actually have quotes in different places, but the Win32 command line=>argv parser
                        // erases those differences.
                        //
                        // We need to check quotes that the win32 argument parser checks which is currently
                        // just the normal double quotes, no other special quotes.  Also note that mismatched
                        // quotes are supported
                        if (NeedQuotes(arg))
                        {
                            _arguments.Append('"');
                            // need to escape all trailing backslashes so the native command receives it correctly
                            // according to http://www.daviddeley.com/autohotkey/parameters/parameters.htm#WINCRULESDOC
                            _arguments.Append(arg);
                            for (int i = arg.Length - 1; i >= 0 && arg[i] == '\\'; i--)
                            {
                                _arguments.Append('\\');
                            }
                            _arguments.Append('"');
                        }
                        else
                        {
                            PossiblyGlobArg(arg, usedQuotes);
                        }
                    }
                }
            } while (list != null);
        }