Exemplo n.º 1
0
        protected void Start(string initialCommand, PSRemotingCryptoHelperServer cryptoHelper, string configurationName = null)
        {
            _initialCommand = initialCommand;

            sessionTM = CreateSessionTransportManager(configurationName, cryptoHelper);

            try
            {
                do
                {
                    string data = originalStdIn.ReadLine();
                    lock (_syncObject)
                    {
                        if (sessionTM == null)
                        {
                            sessionTM = CreateSessionTransportManager(configurationName, cryptoHelper);
                        }
                    }
                    if (string.IsNullOrEmpty(data))
                    {
                        lock (_syncObject)
                        {
                            // give a chance to runspace/pipelines to close (as it looks like the client died
                            // interminently)
                            sessionTM.Close(null);
                            sessionTM = null;
                        }
                        throw new PSRemotingTransportException(PSRemotingErrorId.IPCUnknownElementReceived,
                                                               RemotingErrorIdStrings.IPCUnknownElementReceived, string.Empty);
                    }

                    // process data in a thread pool thread..this way Runspace, Command
                    // data can be processed concurrently.
#if CORECLR
                    ThreadPool.QueueUserWorkItem(new WaitCallback(ProcessingThreadStart), data);
#else
                    Utils.QueueWorkItemWithImpersonation(
                        _windowsIdentityToImpersonate,
                        new WaitCallback(ProcessingThreadStart),
                        data);
#endif
                } while (true);
            }
            catch (Exception e)
            {
                CommandProcessorBase.CheckForSevereException(e);

                PSEtwLog.LogOperationalError(
                    PSEventId.TransportError, PSOpcode.Open, PSTask.None,
                    PSKeyword.UseAlwaysOperational,
                    Guid.Empty.ToString(),
                    Guid.Empty.ToString(),
                    OutOfProcessUtils.EXITCODE_UNHANDLED_EXCEPTION,
                    e.Message,
                    e.StackTrace);

                PSEtwLog.LogAnalyticError(
                    PSEventId.TransportError_Analytic, PSOpcode.Open, PSTask.None,
                    PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic,
                    Guid.Empty.ToString(),
                    Guid.Empty.ToString(),
                    OutOfProcessUtils.EXITCODE_UNHANDLED_EXCEPTION,
                    e.Message,
                    e.StackTrace);

                if (_exitProcessOnError)
                {
                    // notify the remote client of any errors and fail gracefully
                    originalStdErr.WriteLine(e.Message);

                    Environment.Exit(OutOfProcessUtils.EXITCODE_UNHANDLED_EXCEPTION);
                }
            }
        }
Exemplo n.º 2
0
 /// <summary>
 /// Log an error message.
 /// </summary>
 private static void LogError(PSEventId eventId, params object[] args)
 {
     PSEtwLog.LogOperationalError(eventId, PSOpcode.Constructor, PSTask.ExperimentalFeature, PSKeyword.UseAlwaysOperational, args);
 }
Exemplo n.º 3
0
        private void ProcessListeningThread(object state)
        {
            string processId     = System.Diagnostics.Process.GetCurrentProcess().Id.ToString(CultureInfo.InvariantCulture);
            string appDomainName = NamedPipeUtils.GetCurrentAppDomainName();

            // Logging.
            _tracer.WriteMessage("RemoteSessionNamedPipeServer", "StartListening", Guid.Empty,
                                 "Listener thread started on Process {0} in AppDomainName {1}.", processId, appDomainName);
            PSEtwLog.LogOperationalInformation(
                PSEventId.NamedPipeIPC_ServerListenerStarted, PSOpcode.Open, PSTask.NamedPipe,
                PSKeyword.UseAlwaysOperational,
                processId, appDomainName);

            Exception ex       = null;
            string    userName = string.Empty;
            bool      restartListenerThread = true;

            // Wait for connection.
            try
            {
                // Begin listening for a client connect.
                this.WaitForConnection();

                try
                {
                    userName = WindowsIdentity.GetCurrent().Name;
                }
                catch (System.Security.SecurityException) { }

                // Logging.
                _tracer.WriteMessage("RemoteSessionNamedPipeServer", "StartListening", Guid.Empty,
                                     "Client connection started on Process {0} in AppDomainName {1} for User {2}.", processId, appDomainName, userName);
                PSEtwLog.LogOperationalInformation(
                    PSEventId.NamedPipeIPC_ServerConnect, PSOpcode.Connect, PSTask.NamedPipe,
                    PSKeyword.UseAlwaysOperational,
                    processId, appDomainName, userName);

                // Create reader/writer streams.
                TextReader           = new StreamReader(Stream);
                TextWriter           = new StreamWriter(Stream);
                TextWriter.AutoFlush = true;
            }
            catch (Exception e)
            {
                CommandProcessorBase.CheckForSevereException(e);
                ex = e;
            }
            if (ex != null)
            {
                // Error during connection handling.  Don't try to restart listening thread.
                string errorMessage = !string.IsNullOrEmpty(ex.Message) ? ex.Message : string.Empty;
                _tracer.WriteMessage("RemoteSessionNamedPipeServer", "StartListening", Guid.Empty,
                                     "Unexpected error in listener thread on process {0} in AppDomainName {1}.  Error Message: {2}", processId, appDomainName, errorMessage);
                PSEtwLog.LogOperationalError(PSEventId.NamedPipeIPC_ServerListenerError, PSOpcode.Exception, PSTask.NamedPipe,
                                             PSKeyword.UseAlwaysOperational,
                                             processId, appDomainName, errorMessage);

                Dispose();
                return;
            }

            // Start server session on new connection.
            ex = null;
            try
            {
                Action <RemoteSessionNamedPipeServer> clientConnectCallback = state as Action <RemoteSessionNamedPipeServer>;
                Dbg.Assert(clientConnectCallback != null, "Client callback should never be null.");

                // Handle a new client connect by making the callback.
                // The callback must handle all exceptions except
                // for a named pipe disposed or disconnected exception
                // which propagates up to the thread listener loop.
                clientConnectCallback(this);
            }
            catch (IOException)
            {
                // Expected connection terminated.
            }
            catch (ObjectDisposedException)
            {
                // Expected from PS transport close/dispose.
            }
            catch (Exception e)
            {
                CommandProcessorBase.CheckForSevereException(e);
                ex = e;
                restartListenerThread = false;
            }

            // Logging.
            _tracer.WriteMessage("RemoteSessionNamedPipeServer", "StartListening", Guid.Empty,
                                 "Client connection ended on process {0} in AppDomainName {1} for User {2}.", processId, appDomainName, userName);
            PSEtwLog.LogOperationalInformation(
                PSEventId.NamedPipeIPC_ServerDisconnect, PSOpcode.Close, PSTask.NamedPipe,
                PSKeyword.UseAlwaysOperational,
                processId, appDomainName, userName);

            if (ex == null)
            {
                // Normal listener exit.
                _tracer.WriteMessage("RemoteSessionNamedPipeServer", "StartListening", Guid.Empty,
                                     "Listener thread ended on process {0} in AppDomainName {1}.", processId, appDomainName);
                PSEtwLog.LogOperationalInformation(PSEventId.NamedPipeIPC_ServerListenerEnded, PSOpcode.Close, PSTask.NamedPipe,
                                                   PSKeyword.UseAlwaysOperational,
                                                   processId, appDomainName);
            }
            else
            {
                // Unexpected error.
                string errorMessage = !string.IsNullOrEmpty(ex.Message) ? ex.Message : string.Empty;
                _tracer.WriteMessage("RemoteSessionNamedPipeServer", "StartListening", Guid.Empty,
                                     "Unexpected error in listener thread on process {0} in AppDomainName {1}.  Error Message: {2}", processId, appDomainName, errorMessage);
                PSEtwLog.LogOperationalError(PSEventId.NamedPipeIPC_ServerListenerError, PSOpcode.Exception, PSTask.NamedPipe,
                                             PSKeyword.UseAlwaysOperational,
                                             processId, appDomainName, errorMessage);
            }

            lock (_syncObject)
            {
                IsListenerRunning = false;
            }

            // Ensure this named pipe server object is disposed.
            Dispose();

            ListenerEnded.SafeInvoke(
                this,
                new ListenerEndedEventArgs(ex, restartListenerThread));
        }