Beispiel #1
0
        private void HandleStartEvent(object sender, PSEventArgs args)
        {
            ServerSteppablePipelineDriverEventArg sourceEventArgs = args.SourceEventArgs as ServerSteppablePipelineDriverEventArg;
            ServerSteppablePipelineDriver         steppableDriver = sourceEventArgs.SteppableDriver;
            Exception reason = null;

            try
            {
                using (ExecutionContextForStepping.PrepareExecutionContext(steppableDriver.LocalPowerShell.GetContextFromTLS(), steppableDriver.LocalPowerShell.InformationalBuffers, steppableDriver.RemoteHost))
                {
                    steppableDriver.SteppablePipeline = steppableDriver.LocalPowerShell.GetSteppablePipeline();
                    steppableDriver.SteppablePipeline.Begin(!steppableDriver.NoInput);
                }
                if (steppableDriver.NoInput)
                {
                    steppableDriver.HandleInputEndReceived(this, EventArgs.Empty);
                }
            }
            catch (Exception exception2)
            {
                reason = exception2;
            }
            if (reason != null)
            {
                steppableDriver.SetState(PSInvocationState.Failed, reason);
            }
        }
 internal void FireStartSteppablePipeline(ServerSteppablePipelineDriver driver)
 {
     lock (this.syncObject)
     {
         if (this.eventManager != null)
         {
             this.eventManager.GenerateEvent(this.startSubscriber.SourceIdentifier, this, new object[] { new ServerSteppablePipelineDriverEventArg(driver) }, null, true, false);
         }
     }
 }
Beispiel #3
0
 internal void FireStartSteppablePipeline(ServerSteppablePipelineDriver driver)
 {
     lock (this.syncObject)
     {
         if (this.eventManager != null)
         {
             this.eventManager.GenerateEvent(this.startSubscriber.SourceIdentifier, this, new object[] { new ServerSteppablePipelineDriverEventArg(driver) }, null, true, false);
         }
     }
 }
 /// <summary>
 /// Fires the process record event
 /// </summary>
 /// <param name="driver">steppable pipeline driver</param>
 internal void FireHandleProcessRecord(ServerSteppablePipelineDriver driver)
 {
     lock (_syncObject)
     {
         if (_eventManager != null)
         {
             _eventManager.GenerateEvent(_processSubscriber.SourceIdentifier, this,
                                         new object[1] {
                 new ServerSteppablePipelineDriverEventArg(driver)
             }, null, true, false);
         }
     }
 }
Beispiel #5
0
 internal void SubscribeEvents(ServerSteppablePipelineDriver driver)
 {
     lock (this.syncObject)
     {
         if (!this.initialized)
         {
             this.eventManager = driver.LocalPowerShell.Runspace.Events as PSLocalEventManager;
             if (this.eventManager != null)
             {
                 this.startSubscriber   = this.eventManager.SubscribeEvent(this, "StartSteppablePipeline", Guid.NewGuid().ToString(), null, new PSEventReceivedEventHandler(this.HandleStartEvent), true, false, true, 0);
                 this.processSubscriber = this.eventManager.SubscribeEvent(this, "RunProcessRecord", Guid.NewGuid().ToString(), null, new PSEventReceivedEventHandler(this.HandleProcessRecord), true, false, true, 0);
             }
             this.initialized = true;
         }
     }
 }
        internal void SubscribeEvents(ServerSteppablePipelineDriver driver)
        {
            lock (_syncObject)
            {
                if (!_initialized)
                {
                    _eventManager = (object)driver.LocalPowerShell.Runspace.Events as PSLocalEventManager;

                    if (_eventManager != null)
                    {
                        _startSubscriber = _eventManager.SubscribeEvent(this, "StartSteppablePipeline", Guid.NewGuid().ToString(), null,
                            new PSEventReceivedEventHandler(this.HandleStartEvent), true, false, true);

                        _processSubscriber = _eventManager.SubscribeEvent(this, "RunProcessRecord", Guid.NewGuid().ToString(), null,
                            new PSEventReceivedEventHandler(this.HandleProcessRecord), true, false, true);
                    }
                    _initialized = true;
                }
            }
        }
        /// <summary>
        /// Handles the start pipeline event, this is called by the event manager
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void HandleStartEvent(object sender, PSEventArgs args)
        {
            ServerSteppablePipelineDriverEventArg driverArg = (object)args.SourceEventArgs as ServerSteppablePipelineDriverEventArg;
            ServerSteppablePipelineDriver         driver    = driverArg.SteppableDriver;

            Exception exceptionOccurred = null;

            try
            {
                using (ExecutionContextForStepping ctxt =
                           ExecutionContextForStepping.PrepareExecutionContext(
                               driver.LocalPowerShell.GetContextFromTLS(),
                               driver.LocalPowerShell.InformationalBuffers,
                               driver.RemoteHost))
                {
                    driver.SteppablePipeline = driver.LocalPowerShell.GetSteppablePipeline();
                    driver.SteppablePipeline.Begin(!driver.NoInput);
                }

                if (driver.NoInput)
                {
                    driver.HandleInputEndReceived(this, EventArgs.Empty);
                }
            }
            catch (Exception e)
            {
                // We need to catch this so that we can set the pipeline execution;
                // state to "failed" and send the exception as an error to the user.
                // Otherwise, the event manager will swallow this exception and
                // cause the client to hang.
                exceptionOccurred = e;
            }

            if (exceptionOccurred != null)
            {
                driver.SetState(PSInvocationState.Failed, exceptionOccurred);
            }
        }
 internal ServerSteppablePipelineDriverEventArg(ServerSteppablePipelineDriver driver)
 {
     this.SteppableDriver = driver;
 }
        /// <summary>
        /// Handles process record event
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void HandleProcessRecord(object sender, PSEventArgs args)
        {
            ServerSteppablePipelineDriverEventArg driverArg = (object)args.SourceEventArgs as ServerSteppablePipelineDriverEventArg;
            ServerSteppablePipelineDriver         driver    = driverArg.SteppableDriver;

            lock (driver.SyncObject)
            {
                // Make sure start event handler was called
                if (driver.SteppablePipeline == null)
                {
                    return;
                }

                // make sure only one thread does the processing
                if (driver.ProcessingInput)
                {
                    return;
                }
                driver.ProcessingInput = true;
                driver.Pulsed          = false;
            }

            bool      shouldDoComplete  = false;
            Exception exceptionOccurred = null;

            try
            {
                using (ExecutionContextForStepping ctxt =
                           ExecutionContextForStepping.PrepareExecutionContext(
                               driver.LocalPowerShell.GetContextFromTLS(),
                               driver.LocalPowerShell.InformationalBuffers,
                               driver.RemoteHost))
                {
                    bool isProcessCalled = false;
                    while (true)
                    {
                        if (driver.PipelineState != PSInvocationState.Running)
                        {
                            driver.SetState(driver.PipelineState, null);
                            return;
                        }

                        if (!driver.InputEnumerator.MoveNext())
                        {
                            shouldDoComplete = true;
                            if (!driver.NoInput || isProcessCalled)
                            {
                                // if there is noInput then we
                                // need to call process atleast once
                                break;
                            }
                        }

                        isProcessCalled = true;
                        Array output;
                        if (driver.NoInput)
                        {
                            output = driver.SteppablePipeline.Process();
                        }
                        else
                        {
                            output = driver.SteppablePipeline.Process(driver.InputEnumerator.Current);
                        }
                        foreach (object o in output)
                        {
                            if (driver.PipelineState != PSInvocationState.Running)
                            {
                                driver.SetState(driver.PipelineState, null);
                                return;
                            }

                            // send the output data to the client
                            driver.DataStructureHandler.SendOutputDataToClient(PSObject.AsPSObject(o));
                        }

                        lock (driver.SyncObject)
                        {
                            driver.TotalObjectsProcessed++;
                            if (driver.TotalObjectsProcessed >= driver.Input.Count)
                            {
                                break;
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                exceptionOccurred = e;
            }
            finally
            {
                lock (driver.SyncObject)
                {
                    driver.ProcessingInput = false;
                    driver.CheckAndPulseForProcessing(false);
                }
                // Check if should perform stop
                if (driver.PipelineState == PSInvocationState.Stopping)
                {
                    driver.PerformStop();
                }
            }

            if (shouldDoComplete)
            {
                try
                {
                    using (ExecutionContextForStepping ctxt =
                               ExecutionContextForStepping.PrepareExecutionContext(
                                   driver.LocalPowerShell.GetContextFromTLS(),
                                   driver.LocalPowerShell.InformationalBuffers,
                                   driver.RemoteHost))
                    {
                        Array output = driver.SteppablePipeline.End();
                        foreach (object o in output)
                        {
                            if (driver.PipelineState != PSInvocationState.Running)
                            {
                                driver.SetState(driver.PipelineState, null);
                                return;
                            }

                            // send the output data to the client
                            driver.DataStructureHandler.SendOutputDataToClient(PSObject.AsPSObject(o));
                        }

                        driver.SetState(PSInvocationState.Completed, null);
                        return;
                    }
                }
                catch (Exception e)
                {
                    exceptionOccurred = e;
                }
                finally
                {
                    // Check if should perform stop
                    if (driver.PipelineState == PSInvocationState.Stopping)
                    {
                        driver.PerformStop();
                    }
                }
            }

            if (exceptionOccurred != null)
            {
                driver.SetState(PSInvocationState.Failed, exceptionOccurred);
            }
        }
        /// <summary>
        /// Handle the invocation of powershell
        /// </summary>
        /// <param name="sender">sender of this event, unused</param>
        /// <param name="eventArgs">arguments describing this event</param>
        private void HandleCreateAndInvokePowerShell(object sender, RemoteDataEventArgs<RemoteDataObject<PSObject>> eventArgs)
        {
            RemoteDataObject<PSObject> data = eventArgs.Data;

            // it is sufficient to just construct the powershell
            // driver, the local powershell on server side is
            // invoked from within the driver
            HostInfo hostInfo = RemotingDecoder.GetHostInfo(data.Data);

#if !CORECLR // No ApartmentState In CoreCLR
            ApartmentState apartmentState = RemotingDecoder.GetApartmentState(data.Data);
#endif

            RemoteStreamOptions streamOptions = RemotingDecoder.GetRemoteStreamOptions(data.Data);
            PowerShell powershell = RemotingDecoder.GetPowerShell(data.Data);
            bool noInput = RemotingDecoder.GetNoInput(data.Data);
            bool addToHistory = RemotingDecoder.GetAddToHistory(data.Data);
            bool isNested = false;

            // The server would've dropped the protocol version of an older client was connecting
            if (_serverCapability.ProtocolVersion >= RemotingConstants.ProtocolVersionWin8RTM)
            {
                isNested = RemotingDecoder.GetIsNested(data.Data);
            }

            // Perform pre-processing of command for over the wire debugging commands.
            if (_serverRemoteDebugger != null)
            {
                DebuggerCommandArgument commandArgument;
                bool terminateImmediate = false;
                var result = PreProcessDebuggerCommand(powershell.Commands, _serverRemoteDebugger.IsActive, _serverRemoteDebugger.IsRemote, out commandArgument);

                switch (result)
                {
                    case PreProcessCommandResult.SetDebuggerAction:
                        // Run this directly on the debugger and terminate the remote command.
                        _serverRemoteDebugger.SetDebuggerAction(commandArgument.ResumeAction.Value);
                        terminateImmediate = true;
                        break;

                    case PreProcessCommandResult.SetDebugMode:
                        // Set debug mode directly and terminate remote command.
                        _serverRemoteDebugger.SetDebugMode(commandArgument.Mode.Value);
                        terminateImmediate = true;
                        break;

                    case PreProcessCommandResult.SetDebuggerStepMode:
                        // Enable debugger and set to step action, then terminate remote command.
                        _serverRemoteDebugger.SetDebuggerStepMode(commandArgument.DebuggerStepEnabled.Value);
                        terminateImmediate = true;
                        break;

                    case PreProcessCommandResult.SetPreserveUnhandledBreakpointMode:
                        _serverRemoteDebugger.UnhandledBreakpointMode = commandArgument.UnhandledBreakpointMode.Value;
                        terminateImmediate = true;
                        break;

                    case PreProcessCommandResult.ValidNotProcessed:
                        terminateImmediate = true;
                        break;
                }

                // If we don't want to run or queue a command to run in the server session then
                // terminate the command here by making it a No Op.
                if (terminateImmediate)
                {
                    ServerPowerShellDriver noOpDriver = new ServerPowerShellDriver(
                        powershell,
                        null,
                        noInput,
                        data.PowerShellId,
                        data.RunspacePoolId,
                        this,
#if !CORECLR // No ApartmentState In CoreCLR
                        apartmentState,
#endif
                        hostInfo,
                        streamOptions,
                        addToHistory,
                        null);

                    noOpDriver.RunNoOpCommand();
                    return;
                }
            }

            if (_remoteHost.IsRunspacePushed)
            {
                // If we have a pushed runspace then execute there.  
                // Ensure debugger is enabled to the original mode it was set to.
                if (_serverRemoteDebugger != null)
                {
                    _serverRemoteDebugger.CheckDebuggerState();
                }

                StartPowerShellCommandOnPushedRunspace(
                    powershell,
                    null,
                    data.PowerShellId,
                    data.RunspacePoolId,
                    hostInfo,
                    streamOptions,
                    noInput,
                    addToHistory);

                return;
            }
            else if (isNested)
            {
                if (RunspacePool.GetMaxRunspaces() == 1)
                {
                    if (_driverNestedInvoker != null && _driverNestedInvoker.IsActive)
                    {
                        if (_driverNestedInvoker.IsAvailable == false)
                        {
                            // A nested command is already running.
                            throw new PSInvalidOperationException(
                                StringUtil.Format(RemotingErrorIdStrings.CannotInvokeNestedCommandNestedCommandRunning));
                        }

                        // Handle as nested pipeline invocation.
                        powershell.SetIsNested(true);

                        // Always invoke PowerShell commands on pipeline worker thread
                        // for single runspace case, to support nested invocation requests (debugging scenario).
                        ServerPowerShellDriver srdriver = new ServerPowerShellDriver(
                            powershell,
                            null,
                            noInput,
                            data.PowerShellId,
                            data.RunspacePoolId,
                            this,
#if !CORECLR // No ApartmentState In CoreCLR
                            apartmentState,
#endif
                            hostInfo,
                            streamOptions,
                            addToHistory,
                            _rsToUseForSteppablePipeline);

                        _inputCollection = srdriver.InputCollection;
                        _driverNestedInvoker.InvokeDriverAsync(srdriver);
                        return;
                    }
                    else if (_serverRemoteDebugger != null &&
                             _serverRemoteDebugger.InBreakpoint &&
                             _serverRemoteDebugger.IsPushed)
                    {
                        _serverRemoteDebugger.StartPowerShellCommand(
                            powershell,
                            data.PowerShellId,
                            data.RunspacePoolId,
                            this,
#if !CORECLR // No ApartmentState In CoreCLR
                            apartmentState,
#endif
                            _remoteHost,
                            hostInfo,
                            streamOptions,
                            addToHistory);

                        return;
                    }
                    else if (powershell.Commands.Commands.Count == 1 &&
                             !powershell.Commands.Commands[0].IsScript &&
                             ((powershell.Commands.Commands[0].CommandText.IndexOf("Get-PSDebuggerStopArgs", StringComparison.OrdinalIgnoreCase) != -1) ||
                              (powershell.Commands.Commands[0].CommandText.IndexOf("Set-PSDebuggerAction", StringComparison.OrdinalIgnoreCase) != -1)))
                    {
                        // We do not want to invoke debugger commands in the steppable pipeline.
                        // Consider adding IsSteppable message to PSRP to handle this.
                        // This will be caught on the client.
                        throw new PSInvalidOperationException();
                    }

                    ServerPowerShellDataStructureHandler psHandler = DataStructureHandler.GetPowerShellDataStructureHandler();
                    if (psHandler != null)
                    {
                        // Have steppable invocation request.
                        powershell.SetIsNested(false);
                        // Execute command concurrently
                        ServerSteppablePipelineDriver spDriver = new ServerSteppablePipelineDriver(
                            powershell,
                            noInput,
                            data.PowerShellId,
                            data.RunspacePoolId,
                            this,
#if !CORECLR // No ApartmentState In CoreCLR
                            apartmentState,
#endif
                            hostInfo,
                            streamOptions,
                            addToHistory,
                            _rsToUseForSteppablePipeline,
                            _eventSubscriber,
                            _inputCollection);

                        spDriver.Start();
                        return;
                    }
                }

                // Allow command to run as non-nested and non-stepping.
                powershell.SetIsNested(false);
            }

            // Invoke command normally.  Ensure debugger is enabled to the 
            // original mode it was set to.
            if (_serverRemoteDebugger != null)
            {
                _serverRemoteDebugger.CheckDebuggerState();
            }

            // Invoke PowerShell on driver runspace pool.
            ServerPowerShellDriver driver = new ServerPowerShellDriver(
                powershell,
                null,
                noInput,
                data.PowerShellId,
                data.RunspacePoolId,
                this,
#if !CORECLR // No ApartmentState In CoreCLR
                apartmentState,
#endif
                hostInfo,
                streamOptions,
                addToHistory,
                null);

            _inputCollection = driver.InputCollection;
            driver.Start();
        }
 internal ServerSteppablePipelineDriverEventArg(ServerSteppablePipelineDriver driver)
 {
     this.SteppableDriver = driver;
 }
Beispiel #12
0
        private void HandleProcessRecord(object sender, PSEventArgs args)
        {
            ServerSteppablePipelineDriverEventArg sourceEventArgs = args.SourceEventArgs as ServerSteppablePipelineDriverEventArg;
            ServerSteppablePipelineDriver         steppableDriver = sourceEventArgs.SteppableDriver;

            lock (steppableDriver.SyncObject)
            {
                if ((steppableDriver.SteppablePipeline == null) || steppableDriver.ProcessingInput)
                {
                    return;
                }
                steppableDriver.ProcessingInput = true;
                steppableDriver.Pulsed          = false;
            }
            bool      flag   = false;
            Exception reason = null;

            try
            {
                using (ExecutionContextForStepping.PrepareExecutionContext(steppableDriver.LocalPowerShell.GetContextFromTLS(), steppableDriver.LocalPowerShell.InformationalBuffers, steppableDriver.RemoteHost))
                {
                    bool flag2 = false;
Label_0086:
                    if (steppableDriver.PipelineState != PSInvocationState.Running)
                    {
                        steppableDriver.SetState(steppableDriver.PipelineState, null);
                        return;
                    }
                    if (!steppableDriver.InputEnumerator.MoveNext())
                    {
                        flag = true;
                        if (!steppableDriver.NoInput || flag2)
                        {
                            goto Label_0203;
                        }
                    }
                    flag2 = true;
                    Array array = new int[0];
                    if (steppableDriver.NoInput)
                    {
                        array = steppableDriver.SteppablePipeline.Process();
                    }
                    else
                    {
                        array = steppableDriver.SteppablePipeline.Process(steppableDriver.InputEnumerator.Current);
                    }
                    foreach (object obj2 in array)
                    {
                        if (steppableDriver.PipelineState != PSInvocationState.Running)
                        {
                            steppableDriver.SetState(steppableDriver.PipelineState, null);
                            return;
                        }
                        steppableDriver.DataStructureHandler.SendOutputDataToClient(PSObject.AsPSObject(obj2));
                    }
                    lock (steppableDriver.SyncObject)
                    {
                        steppableDriver.TotalObjectsProcessed++;
                        if (steppableDriver.TotalObjectsProcessed < steppableDriver.Input.Count)
                        {
                            goto Label_0086;
                        }
                    }
                }
            }
            catch (Exception exception2)
            {
                CommandProcessorBase.CheckForSevereException(exception2);
                reason = exception2;
            }
            finally
            {
                lock (steppableDriver.SyncObject)
                {
                    steppableDriver.ProcessingInput = false;
                    steppableDriver.CheckAndPulseForProcessing(false);
                }
                if (steppableDriver.PipelineState == PSInvocationState.Stopping)
                {
                    steppableDriver.PerformStop();
                }
            }
Label_0203:
            if (flag)
            {
                try
                {
                    using (ExecutionContextForStepping.PrepareExecutionContext(steppableDriver.LocalPowerShell.GetContextFromTLS(), steppableDriver.LocalPowerShell.InformationalBuffers, steppableDriver.RemoteHost))
                    {
                        foreach (object obj3 in steppableDriver.SteppablePipeline.End())
                        {
                            if (steppableDriver.PipelineState != PSInvocationState.Running)
                            {
                                steppableDriver.SetState(steppableDriver.PipelineState, null);
                                return;
                            }
                            steppableDriver.DataStructureHandler.SendOutputDataToClient(PSObject.AsPSObject(obj3));
                        }
                        steppableDriver.SetState(PSInvocationState.Completed, null);
                        return;
                    }
                }
                catch (Exception exception3)
                {
                    CommandProcessorBase.CheckForSevereException(exception3);
                    reason = exception3;
                }
                finally
                {
                    if (steppableDriver.PipelineState == PSInvocationState.Stopping)
                    {
                        steppableDriver.PerformStop();
                    }
                }
            }
            if (reason != null)
            {
                steppableDriver.SetState(PSInvocationState.Failed, reason);
            }
        }
 /// <summary>
 /// Fires the process record event
 /// </summary>
 /// <param name="driver">steppable pipeline driver</param>
 internal void FireHandleProcessRecord(ServerSteppablePipelineDriver driver)
 {
     lock (_syncObject)
     {
         if (_eventManager != null)
         {
             _eventManager.GenerateEvent(_processSubscriber.SourceIdentifier, this,
                 new object[1] { new ServerSteppablePipelineDriverEventArg(driver) }, null, true, false);
         }
     }
 }