//////////////////////////////////////////////////////////////////////// #region Private Methods #region Pseudo-Plugin Helper Methods private static _Cmdlets.Script GetScriptCmdlet( IClientData clientData, ref Result error ) { if (clientData == null) { error = "invalid clientData"; return(null); } _Cmdlets.Script result = null; object data = null; /* IGNORED */ clientData = _Public.ClientData.UnwrapOrReturn( clientData, ref data); result = data as _Cmdlets.Script; if (result == null) { error = "clientData does not contain script cmdlet"; return(null); } if (result.Disposed) { error = "script cmdlet is disposed"; return(null); } return(result); }
/////////////////////////////////////////////////////////////////////// #region Private Methods private static ReturnCode GetCmdlet( Interpreter interpreter, ref _Cmdlets.Script script, ref Result error ) { if (interpreter == null) { error = "invalid interpreter"; return(ReturnCode.Error); } IObject @object = null; if (interpreter.GetObject( _Cmdlets.Script.CmdletObjectName, LookupFlags.Default, ref @object) == ReturnCode.Ok) { script = @object.Value as _Cmdlets.Script; if (script != null) { return(ReturnCode.Ok); } else { error = "cmdlet object is not a script"; } } else { // // BUGBUG: This is potentially a bad idea since the property // used here (i.e. PolicyObject) could, in theory, // be in-use by another policy; however, this impact // of this is mitigated by the fact that the property // is only relied upon while the interpreter is being // created and initialized. // script = interpreter.PolicyObject as _Cmdlets.Script; if (script != null) { return(ReturnCode.Ok); } else { error = "policy object is not a script"; } } return(ReturnCode.Error); }
//////////////////////////////////////////////////////////////////////// #region IExecute Members public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Result result ) { if (interpreter == null) { result = "invalid interpreter"; return(ReturnCode.Error); } _Cmdlets.Script script = GetScriptCmdlet(clientData, ref result); if (script == null) { return(ReturnCode.Error); } if (arguments == null) { result = "invalid argument list"; return(ReturnCode.Error); } if (arguments.Count < 2) { result = String.Format( "wrong # args: should be \"{0} option ?arg ...?\"", this.Name); return(ReturnCode.Error); } ReturnCode code = ReturnCode.Ok; string subCommand = arguments[1]; bool tried = false; code = Utility.TryExecuteSubCommandFromEnsemble( interpreter, this, clientData, arguments, true, false, ref subCommand, ref tried, ref result); if ((code == ReturnCode.Ok) && !tried) { switch (subCommand) { case "about": { if (arguments.Count == 2) { IPlugin plugin = this.Plugin; if (plugin != null) { code = plugin.About( interpreter, ref result); } else { result = "invalid command plugin"; code = ReturnCode.Error; } } else { result = String.Format( "wrong # args: should be \"{0} {1}\"", this.Name, subCommand); code = ReturnCode.Error; } break; } case "debug": { if (arguments.Count == 3) { try { script.WriteDebug(arguments[2]); /* throw */ result = String.Empty; } catch (Exception e) { Engine.SetExceptionErrorCode(interpreter, e); result = e; code = ReturnCode.Error; } } else { result = String.Format( "wrong # args: should be \"{0} {1} text\"", this.Name, subCommand); code = ReturnCode.Error; } break; } case "error": { if (arguments.Count == 4) { object enumValue = Utility.TryParseEnum( typeof(ReturnCode), arguments[2], true, true, ref result); if (enumValue is ReturnCode) { try { script.WriteErrorRecord( (ReturnCode)enumValue, arguments[3]); /* throw */ result = String.Empty; } catch (Exception e) { Engine.SetExceptionErrorCode(interpreter, e); result = e; code = ReturnCode.Error; } } else { code = ReturnCode.Error; } } else { result = String.Format( "wrong # args: should be \"{0} {1} code result\"", this.Name, subCommand); code = ReturnCode.Error; } break; } case "invoke": { if (arguments.Count >= 3) { OptionDictionary options = new OptionDictionary( new IOption[] { new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-addtohistory", null) }, Utility.GetFixupReturnValueOptions().Values); int argumentIndex = Index.Invalid; code = interpreter.GetOptions(options, arguments, 0, 2, Index.Invalid, true, ref argumentIndex, ref result); if (code == ReturnCode.Ok) { if ((argumentIndex != Index.Invalid) && ((argumentIndex + 1) == arguments.Count)) { Type returnType; ObjectFlags objectFlags; string objectName; string interpName; bool create; bool dispose; bool alias; bool aliasRaw; bool aliasAll; bool aliasReference; bool toString; Utility.ProcessFixupReturnValueOptions( options, null, out returnType, out objectFlags, out objectName, out interpName, out create, out dispose, out alias, out aliasRaw, out aliasAll, out aliasReference, out toString); bool addToHistory = false; if (options.IsPresent("-addtohistory")) { addToHistory = true; } Collection <PSObject> returnValue = null; try { code = InvokePipeline( arguments[argumentIndex], addToHistory, ref returnValue, ref result); } catch (Exception e) { Engine.SetExceptionErrorCode(interpreter, e); result = e; code = ReturnCode.Error; } if (code == ReturnCode.Ok) { ObjectOptionType objectOptionType = Utility.GetOptionType(aliasRaw, aliasAll); code = Utility.FixupReturnValue(interpreter, GetBinder(interpreter, this.Plugin), interpreter.CultureInfo, returnType, objectFlags, Utility.GetInvokeOptions( objectOptionType), objectOptionType, objectName, interpName, returnValue, create, dispose, alias, aliasReference, toString, ref result); } } else { if ((argumentIndex != Index.Invalid) && Option.LooksLikeOption(arguments[argumentIndex])) { result = OptionDictionary.BadOption( options, arguments[argumentIndex]); } else { result = String.Format( "wrong # args: should be \"{0} {1} ?options? script\"", this.Name, subCommand); } code = ReturnCode.Error; } } } else { result = String.Format( "wrong # args: should be \"{0} {1} ?options? script\"", this.Name, subCommand); code = ReturnCode.Error; } break; } case "options": { if (arguments.Count == 2) { IPlugin plugin = this.Plugin; if (plugin != null) { code = plugin.Options( interpreter, ref result); } else { // // NOTE: There is (normally) no plugin // context for this library. // code = GetDefineConstants(ref result); } } else { result = String.Format( "wrong # args: should be \"{0} {1}\"", this.Name, subCommand); code = ReturnCode.Error; } break; } case "progress": { if (arguments.Count >= 5) { OptionDictionary options = new OptionDictionary( new IOption[] { new Option(null, OptionFlags.MustHaveValue | OptionFlags.NoCase, Index.Invalid, Index.Invalid, "-currentOperation", null), new Option(null, OptionFlags.MustHaveIntegerValue | OptionFlags.NoCase, Index.Invalid, Index.Invalid, "-parentActivityId", null), new Option(null, OptionFlags.MustHaveIntegerValue | OptionFlags.NoCase, Index.Invalid, Index.Invalid, "-percentComplete", null), new Option(typeof(ProgressRecordType), OptionFlags.MustHaveIntegerValue | OptionFlags.NoCase, Index.Invalid, Index.Invalid, "-recordType", new Variant((ProgressRecordType)(-1))), new Option(null, OptionFlags.MustHaveIntegerValue | OptionFlags.NoCase, Index.Invalid, Index.Invalid, "-secondsRemaining", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null) }); int argumentIndex = Index.Invalid; code = interpreter.GetOptions(options, arguments, 0, 2, Index.Invalid, true, ref argumentIndex, ref result); if (code == ReturnCode.Ok) { if ((argumentIndex != Index.Invalid) && ((argumentIndex + 3) == arguments.Count)) { Variant value = null; string currentOperation = null; if (options.IsPresent("-currentOperation", true, ref value)) { currentOperation = value.ToString(); } int parentActivityId = Identifier.Invalid; if (options.IsPresent("-parentActivityId", true, ref value)) { parentActivityId = (int)value.Value; } int percentComplete = Percent.Invalid; if (options.IsPresent("-percentComplete", true, ref value)) { percentComplete = (int)value.Value; } ProgressRecordType recordType = (ProgressRecordType)(-1); if (options.IsPresent("-recordType", true, ref value)) { recordType = (ProgressRecordType)value.Value; } int secondsRemaining = Count.Invalid; if (options.IsPresent("-secondsRemaining", true, ref value)) { secondsRemaining = (int)value.Value; } int activityId = Identifier.Invalid; code = Value.GetInteger2( (IGetValue)arguments[argumentIndex], ValueFlags.AnyInteger, interpreter.CultureInfo, ref activityId, ref result); if (code == ReturnCode.Ok) { try { ProgressRecord progressRecord = new ProgressRecord( activityId, arguments[argumentIndex + 1], arguments[argumentIndex + 2]); /* throw */ if (currentOperation != null) { progressRecord.CurrentOperation = currentOperation; } if (parentActivityId != Identifier.Invalid) { progressRecord.ParentActivityId = parentActivityId; /* throw */ } if (percentComplete != Percent.Invalid) { progressRecord.PercentComplete = percentComplete; /* throw */ } if (recordType != (ProgressRecordType)(-1)) { progressRecord.RecordType = recordType; /* throw */ } if (secondsRemaining != Count.Invalid) { progressRecord.SecondsRemaining = secondsRemaining; } script.WriteProgress(progressRecord); /* throw */ result = String.Empty; } catch (Exception e) { Engine.SetExceptionErrorCode(interpreter, e); result = e; code = ReturnCode.Error; } } } else { if ((argumentIndex != Index.Invalid) && Option.LooksLikeOption(arguments[argumentIndex])) { result = OptionDictionary.BadOption( options, arguments[argumentIndex]); } else { result = String.Format( "wrong # args: should be \"{0} {1} ?options? activityId activity statusDescription\"", this.Name, subCommand); } code = ReturnCode.Error; } } } else { result = String.Format( "wrong # args: should be \"{0} {1} ?options? activityId activity statusDescription\"", this.Name, subCommand); code = ReturnCode.Error; } break; } case "remove": { if (arguments.Count == 2) { code = script.RemoveMetaCommand(interpreter, ref result); if (code == ReturnCode.Ok) { result = String.Empty; } } else { result = String.Format( "wrong # args: should be \"{0} {1}\"", this.Name, subCommand); code = ReturnCode.Error; } break; } case "status": { if (arguments.Count == 2) { result = StringList.MakeList( "Disposed", script.Disposed, /* PEDANTIC */ "FlagsCallback", script.FlagsCallback, "StateCallback", script.StateCallback, "ParameterCallback", script.ParameterCallback, "Listener", script.Listener, "PreInitialize", script.PreInitialize, "CreateFlags", script.CreateFlags, "EngineFlags", script.EngineFlags, "SubstitutionFlags", script.SubstitutionFlags, "EventFlags", script.EventFlags, "ExpressionFlags", script.ExpressionFlags, "Console", script.Console, "Unsafe", script.Unsafe, "Standard", script.Standard, "Force", script.Force, "Exceptions", script.Exceptions, "Policies", script.Policies, "Deny", script.Deny, "MetaCommand", script.MetaCommand, "Text", script.Text, "Interpreter", script.Interpreter, "Tokens", script.Tokens, "CommandRuntime", script.CommandRuntime, "Stopping", script.Stopping); /* throw */ } else { result = String.Format( "wrong # args: should be \"{0} {1}\"", this.Name, subCommand); code = ReturnCode.Error; } break; } case "verbose": { if (arguments.Count == 3) { try { script.WriteVerbose(arguments[2]); /* throw */ result = String.Empty; } catch (Exception e) { Engine.SetExceptionErrorCode(interpreter, e); result = e; code = ReturnCode.Error; } } else { result = String.Format( "wrong # args: should be \"{0} {1} text\"", this.Name, subCommand); code = ReturnCode.Error; } break; } default: { result = Utility.BadSubCommand( interpreter, null, null, subCommand, this, null, null); code = ReturnCode.Error; break; } } } return(code); }
public static ReturnCode PolicyCallback( /* POLICY */ Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Result result ) { IPolicyContext policyContext = null; bool match = false; if (Utility.ExtractPolicyContextAndCommand( interpreter, clientData, null, 0, ref policyContext, ref match, ref result) == ReturnCode.Ok) { if (match) { // // NOTE: Fetch the reference to the Cmdlet itself that we // smuggled in via the named opaque object handle // that was prearranged with the base cmdlet itself. // _Cmdlets.Script script = null; if (GetCmdlet(interpreter, ref script, ref result) == ReturnCode.Ok) { // // NOTE: Grab the interpreter host, if any. // IInteractiveHost interactiveHost = interpreter.Host; // // NOTE: If the interpreter host is available, use the // title as the caption; otherwise, we will use // the hard-coded default. // string processCaption = (interactiveHost != null) ? interactiveHost.Title : null; // // NOTE: If the caption is null or empty, use the // hard-coded default. // if (String.IsNullOrEmpty(processCaption)) { processCaption = _Constants.Policy.ProcessCaption; } // // NOTE: Build the description of the operation for // "What-If" and "Verbose" modes. // string verboseDescription = String.Format( _Constants.Policy.VerboseDescription, arguments); // // NOTE: Grab the command name from the argument list // because we need to present it to the user in // the confirmation query. // string commandName = (arguments.Count > 0) ? arguments[0] : null; // // NOTE: Build the confirmation query to present to // the user. // string verboseWarning = String.Format( _Constants.Policy.VerboseWarning, commandName, arguments); // // TODO: *TEST* Verify that this works correctly and // has the expected semantics. // if (ShouldProcess(script, verboseDescription, verboseWarning, processCaption)) { // // NOTE: If the interpreter host is available, use // the title as the caption; otherwise, we // will use the hard-coded default. // string continueCaption = (interactiveHost != null) ? interactiveHost.Title : null; // // NOTE: If the caption is null or empty, use the // hard-coded default. // if (String.IsNullOrEmpty(continueCaption)) { continueCaption = _Constants.Policy.ContinueCaption; } // // NOTE: Build the re-confirmation query to present // to the user. // string query = String.Format( _Constants.Policy.Query, verboseWarning); // // NOTE: If we are in "force" mode or the user // allows us to continue then do so; // otherwise, do nothing and the command will // be allowed/denied based on the other // policies, if any. In the event that there // are no other policies present, the command // will not be allowed to execute. // // BUGFIX: Cannot ask user when not interactive. // if (script.Force || ShouldContinue(script, query, continueCaption, ref yesToAll, ref noToAll)) { // // NOTE: The user has explicitly approved the // command execution. // policyContext.Approved(); } else if (script.Deny) { // // BUGFIX: Must explicitly deny to override the // built-in policies (e.g. for [info], // [object], etc). // policyContext.Denied(); } } else if (script.Deny) { // // BUGFIX: Must explicitly deny to override the // built-in policies (e.g. for [info], // [object], etc). // policyContext.Denied(); } // // NOTE: The policy checking has been successful; // however, this does not necessarily mean // that we allow the command to be executed. // return(ReturnCode.Ok); } } else { result = "policyContext does not contain a command object"; } } return(ReturnCode.Error); }