private static void OnRemoteCmdSendCompleted(IntPtr operationContext,
            int flags,
            IntPtr error,
            IntPtr shellOperationHandle,
            IntPtr commandOperationHandle,
            IntPtr operationHandle,
            IntPtr data)
        {
            tracer.WriteLine("SendComplete callback received");

            long cmdContextId = 0;
            WSManClientCommandTransportManager cmdTM = null;
            if (!TryGetCmdTransportManager(operationContext, out cmdTM, out cmdContextId))
            {
                // We dont have the command TM handle..just return.
                tracer.WriteLine("Unable to find a transport manager for the command context {0}.", cmdContextId);
                return;
            }

            cmdTM._isSendingInput = false;

            // do the logging for this send
            PSEtwLog.LogAnalyticInformational(PSEventId.WSManSendShellInputExCallbackReceived,
                PSOpcode.Connect, PSTask.None, PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic,
                cmdTM.RunspacePoolInstanceId.ToString(), cmdTM.powershellInstanceId.ToString());

            if ((!shellOperationHandle.Equals(cmdTM._wsManShellOperationHandle)) ||
                (!commandOperationHandle.Equals(cmdTM._wsManCmdOperationHandle)))
            {
                tracer.WriteLine("SendShellInputEx callback: ShellOperationHandles are not the same as the Send is initiated with");
                // WSMan returned data from a wrong shell..notify the caller
                // about the same.
                PSRemotingTransportException e = new PSRemotingTransportException(RemotingErrorIdStrings.CommandSendExFailed);
                TransportErrorOccuredEventArgs eventargs =
                    new TransportErrorOccuredEventArgs(e, TransportMethodEnum.CommandInputEx);
                cmdTM.ProcessWSManTransportError(eventargs);

                return;
            }

            // release the resources related to send
            cmdTM.ClearReceiveOrSendResources(flags, true);

            // if the transport manager is already closed..ignore the errors and return           
            if (cmdTM.isClosed)
            {
                tracer.WriteLine("Client Command TM: Transport manager is closed. So returning");

                if (cmdTM._isDisconnectPending)
                {
                    cmdTM.RaiseReadyForDisconnect();
                }

                return;
            }

            if (IntPtr.Zero != error)
            {
                WSManNativeApi.WSManError errorStruct = WSManNativeApi.WSManError.UnMarshal(error);
                // Ignore Command aborted error. Command aborted is raised by WSMan to 
                // notify command operation complete. PowerShell protocol has its own
                // way of notifying the same using state change events.
                if ((errorStruct.errorCode != 0) && (errorStruct.errorCode != 995))
                {
                    tracer.WriteLine("CmdSend callback: WSMan reported an error: {0}", errorStruct.errorDetail);

                    TransportErrorOccuredEventArgs eventargs = WSManTransportManagerUtils.ConstructTransportErrorEventArgs(
                        cmdTM._sessnTm.WSManAPIData.WSManAPIHandle,
                        null,
                        errorStruct,
                        TransportMethodEnum.CommandInputEx,
                        RemotingErrorIdStrings.CommandSendExCallBackError,
                        new object[] { WSManTransportManagerUtils.ParseEscapeWSManErrorMessage(errorStruct.errorDetail) });
                    cmdTM.ProcessWSManTransportError(eventargs);

                    return;
                }
            }

            // Send the next item, if available
            cmdTM.SendOneItem();
        }
        private static void OnRemoteCmdDataReceived(IntPtr operationContext,
            int flags,
            IntPtr error,
            IntPtr shellOperationHandle,
            IntPtr commandOperationHandle,
            IntPtr operationHandle,
            IntPtr data)
        {
            tracer.WriteLine("Remote Command DataReceived callback.");

            long cmdContextId = 0;
            WSManClientCommandTransportManager cmdTM = null;
            if (!TryGetCmdTransportManager(operationContext, out cmdTM, out cmdContextId))
            {
                // We dont have the command TM handle..just return.
                tracer.WriteLine("Unable to find a transport manager for the given command context {0}.", cmdContextId);
                return;
            }

            if ((!shellOperationHandle.Equals(cmdTM._wsManShellOperationHandle)) ||
                (!commandOperationHandle.Equals(cmdTM._wsManCmdOperationHandle)))
            {
                // WSMan returned data from a wrong shell..notify the caller
                // about the same.
                tracer.WriteLine("CmdReceive callback: ShellOperationHandles are not the same as the Receive is initiated with");
                PSRemotingTransportException e = new PSRemotingTransportException(RemotingErrorIdStrings.CommandReceiveExFailed);
                TransportErrorOccuredEventArgs eventargs =
                    new TransportErrorOccuredEventArgs(e, TransportMethodEnum.ReceiveCommandOutputEx);
                cmdTM.ProcessWSManTransportError(eventargs);

                return;
            }

            // release the resources related to receive
            cmdTM.ClearReceiveOrSendResources(flags, false);

            // if the transport manager is already closed..ignore the errors and return            
            if (cmdTM.isClosed)
            {
                tracer.WriteLine("Client Command TM: Transport manager is closed. So returning");
                return;
            }

            if (IntPtr.Zero != error)
            {
                WSManNativeApi.WSManError errorStruct = WSManNativeApi.WSManError.UnMarshal(error);
                if (errorStruct.errorCode != 0)
                {
                    tracer.WriteLine("CmdReceive callback: WSMan reported an error: {0}", errorStruct.errorDetail);

                    TransportErrorOccuredEventArgs eventargs = WSManTransportManagerUtils.ConstructTransportErrorEventArgs(
                        cmdTM._sessnTm.WSManAPIData.WSManAPIHandle,
                        null,
                        errorStruct,
                        TransportMethodEnum.ReceiveCommandOutputEx,
                        RemotingErrorIdStrings.CommandReceiveExCallBackError,
                        new object[] { errorStruct.errorDetail });
                    cmdTM.ProcessWSManTransportError(eventargs);

                    return;
                }
            }

            if (flags == (int)WSManNativeApi.WSManCallbackFlags.WSMAN_FLAG_RECEIVE_DELAY_STREAM_REQUEST_PROCESSED)
            {
                cmdTM._isDisconnectedOnInvoke = true;
                cmdTM.RaiseDelayStreamProcessedEvent();
                return;
            }

            WSManNativeApi.WSManReceiveDataResult dataReceived = WSManNativeApi.WSManReceiveDataResult.UnMarshal(data);
            if (null != dataReceived.data)
            {
                tracer.WriteLine("Cmd Received Data : {0}", dataReceived.data.Length);
                PSEtwLog.LogAnalyticInformational(
                    PSEventId.WSManReceiveShellOutputExCallbackReceived, PSOpcode.Receive, PSTask.None,
                    PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic,
                    cmdTM.RunspacePoolInstanceId.ToString(),
                    cmdTM.powershellInstanceId.ToString(),
                    dataReceived.data.Length.ToString(CultureInfo.InvariantCulture));
                cmdTM.ProcessRawData(dataReceived.data, dataReceived.stream);
            }
        }
        /// <summary>
        /// </summary>
        /// <exception cref="PSRemotingTransportException">
        /// WSManConnectShellCommandEx failed.
        /// </exception>
        internal override void ConnectAsync()
        {
            Dbg.Assert(!isClosed, "object already disposed");
            ReceivedDataCollection.PrepareForStreamConnect();

            // Empty the serializedPipeline data that contains PowerShell command information created in the 
            // constructor.  We are connecting to an existing command on the server and don't want to send
            // information on a new command.
            serializedPipeline.Read();

            // create cmdContextId
            _cmdContextId = GetNextCmdTMHandleId();
            AddCmdTransportManager(_cmdContextId, this);

            // Create Callback
            _connectCmdCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(_cmdContextId), s_cmdConnectCallback);
            _reconnectCmdCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(_cmdContextId), s_cmdReconnectCallback);
            lock (syncObject)
            {
                if (isClosed)
                {
                    // the transport is already closed..so no need to create a connection
                    // anymore.
                    return;
                }

                WSManNativeApi.WSManConnectShellCommandEx(_wsManShellOperationHandle,
                    0,
                    PowershellInstanceId.ToString().ToUpperInvariant(),
                    IntPtr.Zero,
                    IntPtr.Zero,
                    _connectCmdCompleted,
                    ref _wsManCmdOperationHandle);
            }

            if (_wsManCmdOperationHandle == IntPtr.Zero)
            {
                PSRemotingTransportException e = new PSRemotingTransportException(RemotingErrorIdStrings.RunShellCommandExFailed);
                TransportErrorOccuredEventArgs eventargs =
                    new TransportErrorOccuredEventArgs(e, TransportMethodEnum.ConnectShellCommandEx);
                ProcessWSManTransportError(eventargs);
                return;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <exception cref="PSRemotingTransportException">
        /// WSManRunShellCommandEx failed.
        /// </exception>
        internal override void CreateAsync()
        {
            byte[] cmdPart1 = serializedPipeline.ReadOrRegisterCallback(null);
            if (null != cmdPart1)
            {
                #region SHIM: Redirection code for command code send.

                bool sendContinue = true;

                if (s_commandCodeSendRedirect != null)
                {
                    object[] arguments = new object[2] { null, cmdPart1 };
                    sendContinue = (bool)s_commandCodeSendRedirect.DynamicInvoke(arguments);
                    cmdPart1 = (byte[])arguments[0];
                }

                if (!sendContinue)
                    return;

                #endregion

                WSManNativeApi.WSManCommandArgSet argSet = new WSManNativeApi.WSManCommandArgSet(cmdPart1);

                // create cmdContextId
                _cmdContextId = GetNextCmdTMHandleId();
                AddCmdTransportManager(_cmdContextId, this);

                PSEtwLog.LogAnalyticInformational(PSEventId.WSManCreateCommand, PSOpcode.Connect,
                                PSTask.CreateRunspace, PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic,
                                RunspacePoolInstanceId.ToString(), powershellInstanceId.ToString());

                _createCmdCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(_cmdContextId), s_cmdCreateCallback);
                _createCmdCompletedGCHandle = GCHandle.Alloc(_createCmdCompleted);
                _reconnectCmdCompleted = new WSManNativeApi.WSManShellAsync(new IntPtr(_cmdContextId), s_cmdReconnectCallback);

                using (argSet)
                {
                    lock (syncObject)
                    {
                        if (!isClosed)
                        {
                            WSManNativeApi.WSManRunShellCommandEx(_wsManShellOperationHandle,
                                0,
                                PowershellInstanceId.ToString().ToUpperInvariant(),
                                // WSManRunsShellCommand doesn't accept empty string "".
                                (_cmdLine == null || _cmdLine.Length == 0) ? " " : (_cmdLine.Length <= 256 ? _cmdLine : _cmdLine.Substring(0, 255)),
                                argSet,
                                IntPtr.Zero,
                                _createCmdCompleted,
                                ref _wsManCmdOperationHandle);

                            tracer.WriteLine("Started cmd with command context : {0} Operation context: {1}", _cmdContextId, _wsManCmdOperationHandle);
                        }
                    }
                }
            }

            if (_wsManCmdOperationHandle == IntPtr.Zero)
            {
                PSRemotingTransportException e = new PSRemotingTransportException(RemotingErrorIdStrings.RunShellCommandExFailed);
                TransportErrorOccuredEventArgs eventargs =
                    new TransportErrorOccuredEventArgs(e, TransportMethodEnum.RunShellCommandEx);
                ProcessWSManTransportError(eventargs);
                return;
            }
        }
        private static void OnRemoteSessionSendCompleted(IntPtr operationContext,
            int flags,
            IntPtr error,
            IntPtr shellOperationHandle,
            IntPtr commandOperationHandle,
            IntPtr operationHandle,
            IntPtr data)
        {
            tracer.WriteLine("Client Session TM: SendComplete callback received");

            long sessionTMHandle = 0;
            WSManClientSessionTransportManager sessionTM = null;
            if (!TryGetSessionTransportManager(operationContext, out sessionTM, out sessionTMHandle))
            {
                // We dont have the session TM handle..just return.
                tracer.WriteLine("Unable to find a transport manager for context {0}.", sessionTMHandle);
                return;
            }

            // do the logging for this send
            PSEtwLog.LogAnalyticInformational(PSEventId.WSManSendShellInputExCallbackReceived,
                PSOpcode.Connect, PSTask.None, PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic,
                sessionTM.RunspacePoolInstanceId.ToString(), Guid.Empty.ToString());

            if (!shellOperationHandle.Equals(sessionTM._wsManShellOperationHandle))
            {
                // WSMan returned data from a wrong shell..notify the caller
                // about the same.
                PSRemotingTransportException e = new PSRemotingTransportException(
                    PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.SendExFailed, sessionTM.ConnectionInfo.ComputerName));
                TransportErrorOccuredEventArgs eventargs =
                    new TransportErrorOccuredEventArgs(e, TransportMethodEnum.SendShellInputEx);
                sessionTM.ProcessWSManTransportError(eventargs);

                return;
            }

            sessionTM.ClearReceiveOrSendResources(flags, true);

            // if the session is already closed ignore the errors and return.
            if (sessionTM.isClosed)
            {
                tracer.WriteLine("Client Session TM: Transport manager is closed. So returning");
                return;
            }

            if (IntPtr.Zero != error)
            {
                WSManNativeApi.WSManError errorStruct = WSManNativeApi.WSManError.UnMarshal(error);

                // Ignore operation aborted error. operation aborted is raised by WSMan to 
                // notify operation complete. PowerShell protocol has its own
                // way of notifying the same using state change events.
                if ((errorStruct.errorCode != 0) && (errorStruct.errorCode != 995))
                {
                    tracer.WriteLine("Got error with error code {0}. Message {1}", errorStruct.errorCode, errorStruct.errorDetail);

                    TransportErrorOccuredEventArgs eventargs = WSManTransportManagerUtils.ConstructTransportErrorEventArgs(
                        sessionTM.WSManAPIData.WSManAPIHandle,
                        sessionTM,
                        errorStruct,
                        TransportMethodEnum.SendShellInputEx,
                        RemotingErrorIdStrings.SendExCallBackError,
                        new object[] { sessionTM.ConnectionInfo.ComputerName, WSManTransportManagerUtils.ParseEscapeWSManErrorMessage(errorStruct.errorDetail) });
                    sessionTM.ProcessWSManTransportError(eventargs);

                    return;
                }
            }

            // Send the next item, if available
            sessionTM.SendOneItem();
        }
        // WSMan will make sure this callback is synchronously called ie., if 1 callback
        // is active, the callback will not be called from a different thread.
        private static void OnRemoteSessionDataReceived(IntPtr operationContext,
            int flags,
            IntPtr error,
            IntPtr shellOperationHandle,
            IntPtr commandOperationHandle,
            IntPtr operationHandle,
            IntPtr data)
        {
            tracer.WriteLine("Client Session TM: OnRemoteDataReceived callback.");

            long sessionTMHandle = 0;
            WSManClientSessionTransportManager sessionTM = null;
            if (!TryGetSessionTransportManager(operationContext, out sessionTM, out sessionTMHandle))
            {
                // We dont have the session TM handle..just return.
                tracer.WriteLine("Unable to find a transport manager for context {0}.", sessionTMHandle);
                return;
            }

            sessionTM.ClearReceiveOrSendResources(flags, false);

            if (sessionTM.isClosed)
            {
                tracer.WriteLine("Client Session TM: Transport manager is closed. So returning");
                return;
            }

            if (!shellOperationHandle.Equals(sessionTM._wsManShellOperationHandle))
            {
                // WSMan returned data from a wrong shell..notify the caller
                // about the same.
                PSRemotingTransportException e = new PSRemotingTransportException(
                    PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.ReceiveExFailed, sessionTM.ConnectionInfo.ComputerName));
                TransportErrorOccuredEventArgs eventargs =
                    new TransportErrorOccuredEventArgs(e, TransportMethodEnum.ReceiveShellOutputEx);
                sessionTM.ProcessWSManTransportError(eventargs);

                return;
            }

            if (IntPtr.Zero != error)
            {
                WSManNativeApi.WSManError errorStruct = WSManNativeApi.WSManError.UnMarshal(error);

                if (errorStruct.errorCode != 0)
                {
                    tracer.WriteLine("Got error with error code {0}. Message {1}", errorStruct.errorCode, errorStruct.errorDetail);

                    TransportErrorOccuredEventArgs eventargs = WSManTransportManagerUtils.ConstructTransportErrorEventArgs(
                        sessionTM.WSManAPIData.WSManAPIHandle,
                        sessionTM,
                        errorStruct,
                        TransportMethodEnum.ReceiveShellOutputEx,
                        RemotingErrorIdStrings.ReceiveExCallBackError,
                        new object[] { sessionTM.ConnectionInfo.ComputerName, WSManTransportManagerUtils.ParseEscapeWSManErrorMessage(errorStruct.errorDetail) });
                    sessionTM.ProcessWSManTransportError(eventargs);

                    return;
                }
            }

            WSManNativeApi.WSManReceiveDataResult dataReceived = WSManNativeApi.WSManReceiveDataResult.UnMarshal(data);
            if (null != dataReceived.data)
            {
                tracer.WriteLine("Session Received Data : {0}", dataReceived.data.Length);
                PSEtwLog.LogAnalyticInformational(
                    PSEventId.WSManReceiveShellOutputExCallbackReceived, PSOpcode.Receive, PSTask.None,
                    PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic,
                    sessionTM.RunspacePoolInstanceId.ToString(),
                    Guid.Empty.ToString(),
                    dataReceived.data.Length.ToString(CultureInfo.InvariantCulture));
                sessionTM.ProcessRawData(dataReceived.data, dataReceived.stream);
            }
        }
        /// <summary>
        /// Launch a new Process (PowerShell.exe -s) to perform remoting. This is used by *-Job cmdlets
        /// to support background jobs without depending on WinRM (WinRM has complex requirements like
        /// elevation to support local machine remoting)
        /// </summary>
        /// <exception cref="System.InvalidOperationException">
        /// </exception>
        /// <exception cref="System.ComponentModel.Win32Exception">
        /// 1. There was an error in opening the associated file. 
        /// </exception>
        internal override void CreateAsync()
        {
            if (null != _connectionInfo)
            {
                _processInstance = _connectionInfo.Process ?? new PowerShellProcessInstance(_connectionInfo.PSVersion,
                                                                                           _connectionInfo.Credential,
                                                                                           _connectionInfo.InitializationScript,
                                                                                           _connectionInfo.RunAs32);
                if (_connectionInfo.Process != null)
                {
                    _processCreated = false;
                }
                // _processInstance.Start();
            }

            PSEtwLog.LogAnalyticInformational(PSEventId.WSManCreateShell, PSOpcode.Connect,
                            PSTask.CreateRunspace, PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic,
                            RunspacePoolInstanceId.ToString());

            try
            {
                lock (syncObject)
                {
                    if (isClosed)
                    {
                        return;
                    }

                    // Attach handlers and start the process
                    _serverProcess = _processInstance.Process;

                    if (_processInstance.RunspacePool != null)
                    {
                        _processInstance.RunspacePool.Close();
                        _processInstance.RunspacePool.Dispose();
                    }

                    stdInWriter = _processInstance.StdInWriter;
                    //if (stdInWriter == null)
                    {
                        _serverProcess.OutputDataReceived += new DataReceivedEventHandler(OnOutputDataReceived);
                        _serverProcess.ErrorDataReceived += new DataReceivedEventHandler(OnErrorDataReceived);
                    }
                    _serverProcess.Exited += new EventHandler(OnExited);

                    //serverProcess.Start();
                    _processInstance.Start();

                    if (stdInWriter != null)
                    {
                        _serverProcess.CancelErrorRead();
                        _serverProcess.CancelOutputRead();
                    }

                    // Start asynchronous reading of output/errors
                    _serverProcess.BeginOutputReadLine();
                    _serverProcess.BeginErrorReadLine();

                    stdInWriter = new OutOfProcessTextWriter(_serverProcess.StandardInput);
                    _processInstance.StdInWriter = stdInWriter;
                }
            }
            catch (System.ComponentModel.Win32Exception w32e)
            {
                PSRemotingTransportException psrte = new PSRemotingTransportException(w32e, RemotingErrorIdStrings.IPCExceptionLaunchingProcess,
                    w32e.Message);
                psrte.ErrorCode = w32e.HResult;
                TransportErrorOccuredEventArgs eventargs = new TransportErrorOccuredEventArgs(psrte, TransportMethodEnum.CreateShellEx);
                RaiseErrorHandler(eventargs);
                return;
            }
            catch (Exception e)
            {
                CommandProcessorBase.CheckForSevereException(e);

                PSRemotingTransportException psrte = new PSRemotingTransportException(PSRemotingErrorId.IPCExceptionLaunchingProcess,
                RemotingErrorIdStrings.IPCExceptionLaunchingProcess,
                    e.Message);
                TransportErrorOccuredEventArgs eventargs = new TransportErrorOccuredEventArgs(psrte, TransportMethodEnum.CreateShellEx);
                RaiseErrorHandler(eventargs);
                return;
            }

            // Send one fragment
            SendOneItem();
        }
        private void ProcessReaderThread(object state)
        {
            try
            {
                StreamReader reader = state as StreamReader;
                Dbg.Assert(reader != null, "Reader cannot be null.");

                // Send one fragment.
                SendOneItem();

                // Start reader loop.
                while (true)
                {
                    string data = reader.ReadLine();
                    if (data == null)
                    {
                        // End of stream indicates the target process was lost.
                        // Raise transport exception to invalidate the client remote runspace.
                        PSRemotingTransportException psrte = new PSRemotingTransportException(
                            PSRemotingErrorId.IPCServerProcessReportedError,
                            RemotingErrorIdStrings.IPCServerProcessReportedError,
                            RemotingErrorIdStrings.NamedPipeTransportProcessEnded);
                        RaiseErrorHandler(new TransportErrorOccuredEventArgs(psrte, TransportMethodEnum.ReceiveShellOutputEx));
                        break;
                    }

                    if (data.StartsWith(System.Management.Automation.Remoting.Server.NamedPipeErrorTextWriter.ErrorPrepend, StringComparison.OrdinalIgnoreCase))
                    {
                        // Error message from the server.
                        string errorData = data.Substring(System.Management.Automation.Remoting.Server.NamedPipeErrorTextWriter.ErrorPrepend.Length);
                        HandleErrorDataReceived(errorData);
                    }
                    else
                    {
                        // Normal output data.
                        HandleOutputDataReceived(data);
                    }
                }
            }
            catch (ObjectDisposedException)
            {
                // Normal reader thread end.
            }
            catch (Exception e)
            {
                CommandProcessorBase.CheckForSevereException(e);

                if (e is ArgumentOutOfRangeException)
                {
                    Dbg.Assert(false, "Need to adjust transport fragmentor to accomodate read buffer size.");
                }

                string errorMsg = (e.Message != null) ? e.Message : string.Empty;
                _tracer.WriteMessage("NamedPipeClientSessionTransportManager", "StartReaderThread", Guid.Empty,
                    "Transport manager reader thread ended with error: {0}", errorMsg);
            }
        }
        protected void OnExited(object sender, EventArgs e)
        {
            TransportMethodEnum transportMethod = TransportMethodEnum.Unknown;
            lock (syncObject)
            {
                // There is no need to return when IsClosed==true here as in a legitimate case process exits
                // after Close is called..In that legitimate case, Exit handler is removed before
                // calling Exit..So, this Exit must have been called abnormally.
                if (isClosed)
                {
                    transportMethod = TransportMethodEnum.CloseShellOperationEx;
                }

                // dont let the writer write new data as the process is exited.
                // Not assigning null to stdInWriter to fix the race condition between OnExited() and CloseAsync() methods.
                // 
                stdInWriter.StopWriting();
            }
            PSRemotingTransportException psrte = new PSRemotingTransportException(PSRemotingErrorId.IPCServerProcessExited,
                                RemotingErrorIdStrings.IPCServerProcessExited);
            RaiseErrorHandler(new TransportErrorOccuredEventArgs(psrte, transportMethod));
        }
 internal void OnCloseTimeOutTimerElapsed(object source)
 {
     PSRemotingTransportException psrte = new PSRemotingTransportException(PSRemotingErrorId.IPCCloseTimedOut, RemotingErrorIdStrings.IPCCloseTimedOut);
     RaiseErrorHandler(new TransportErrorOccuredEventArgs(psrte, TransportMethodEnum.CloseShellOperationEx));
 }
        protected void HandleErrorDataReceived(string data)
        {
            lock (syncObject)
            {
                if (isClosed)
                {
                    return;
                }
            }

            PSRemotingTransportException psrte = new PSRemotingTransportException(PSRemotingErrorId.IPCServerProcessReportedError,
                RemotingErrorIdStrings.IPCServerProcessReportedError,
                data);
            RaiseErrorHandler(new TransportErrorOccuredEventArgs(psrte, TransportMethodEnum.Unknown));
        }
        protected void HandleOutputDataReceived(string data)
        {
            try
            {
                OutOfProcessUtils.ProcessData(data, _dataProcessingCallbacks);
            }
            catch (Exception exception)
            {
                CommandProcessorBase.CheckForSevereException(exception);

                PSRemotingTransportException psrte =
                    new PSRemotingTransportException(PSRemotingErrorId.IPCErrorProcessingServerData,
                        RemotingErrorIdStrings.IPCErrorProcessingServerData,
                        exception.Message);
                RaiseErrorHandler(new TransportErrorOccuredEventArgs(psrte, TransportMethodEnum.ReceiveShellOutputEx));
            }
        }
        internal void OnSignalTimeOutTimerElapsed(object source)
        {
            //Signal timer is triggered only once

            if (isClosed)
            {
                return;
            }

            PSRemotingTransportException psrte = new PSRemotingTransportException(RemotingErrorIdStrings.IPCSignalTimedOut);
            RaiseErrorHandler(new TransportErrorOccuredEventArgs(psrte, TransportMethodEnum.ReceiveShellOutputEx));
        }
        private static void OnReconnectCmdCompleted(IntPtr operationContext,
            int flags,
            IntPtr error,
            IntPtr shellOperationHandle,
            IntPtr commandOperationHandle,
            IntPtr operationHandle,
            IntPtr data)
        {
            long cmdContextId = 0;
            WSManClientCommandTransportManager cmdTM = null;
            if (!TryGetCmdTransportManager(operationContext, out cmdTM, out cmdContextId))
            {
                // We dont have the command TM handle..just return.
                tracer.WriteLine("Unable to find a transport manager for the given command context {0}.", cmdContextId);
                return;
            }

            if ((!shellOperationHandle.Equals(cmdTM._wsManShellOperationHandle)) ||
               (!commandOperationHandle.Equals(cmdTM._wsManCmdOperationHandle)))
            {
                // WSMan returned data from a wrong shell..notify the caller
                // about the same.
                tracer.WriteLine("Cmd Signal callback: ShellOperationHandles are not the same as the signal is initiated with");
                PSRemotingTransportException e = new PSRemotingTransportException(RemotingErrorIdStrings.ReconnectShellCommandExCallBackError);
                TransportErrorOccuredEventArgs eventargs =
                    new TransportErrorOccuredEventArgs(e, TransportMethodEnum.ReconnectShellCommandEx);
                cmdTM.ProcessWSManTransportError(eventargs);

                return;
            }

            if (IntPtr.Zero != error)
            {
                WSManNativeApi.WSManError errorStruct = WSManNativeApi.WSManError.UnMarshal(error);
                if (errorStruct.errorCode != 0)
                {
                    tracer.WriteLine("OnReconnectCmdCompleted callback: WSMan reported an error: {0}", errorStruct.errorDetail);

                    TransportErrorOccuredEventArgs eventargs = WSManTransportManagerUtils.ConstructTransportErrorEventArgs(
                        cmdTM._sessnTm.WSManAPIData.WSManAPIHandle,
                        null,
                        errorStruct,
                        TransportMethodEnum.ReconnectShellCommandEx,
                        RemotingErrorIdStrings.ReconnectShellCommandExCallBackError,
                         new object[] { WSManTransportManagerUtils.ParseEscapeWSManErrorMessage(errorStruct.errorDetail) });
                    cmdTM.ProcessWSManTransportError(eventargs);

                    return;
                }
            }

            // The command may have been disconnected before all input was read or 
            // the returned command data started to be received.
            cmdTM._shouldStartReceivingData = true;
            cmdTM.SendOneItem();

            cmdTM.RaiseReconnectCompleted();
        }
        /// <summary>
        /// Constructs a WSManTransportErrorOccuredEventArgs instance from the supplied data
        /// </summary>
        /// <param name="wsmanAPIHandle">
        /// WSMan API handle to use to get error messages from WSMan error id(s)
        /// </param>
        /// <param name="wsmanSessionTM">
        /// Session Transportmanager to use to get error messages (for redirect)
        /// </param>
        /// <param name="errorStruct">
        /// Error structure supplied by callbacks from WSMan API
        /// </param>
        /// <param name="transportMethodReportingError">
        /// The transport method call that reported this error.
        /// </param>
        /// <param name="resourceString">
        /// resource string that holds the message.
        /// </param>
        /// <param name="resourceArgs">
        /// Arguments to pass to the resource
        /// </param>
        /// <returns>
        /// An instance of WSManTransportErrorOccuredEventArgs
        /// </returns>
        internal static TransportErrorOccuredEventArgs ConstructTransportErrorEventArgs(IntPtr wsmanAPIHandle,
            WSManClientSessionTransportManager wsmanSessionTM,
            WSManNativeApi.WSManError errorStruct,
            TransportMethodEnum transportMethodReportingError,
            string resourceString,
            params object[] resourceArgs)
        {
            PSRemotingTransportException e;

            //For the first two special error conditions, it is remotely possible that the wsmanSessionTM is null when the failures are returned 
            //as part of command TM operations (could be returned because of RC retries under the hood)
            //Not worth to handle these cases separately as there are very corner scenarios, but need to make sure wsmanSessionTM is not referenced


            // Destination server is reporting that URI redirect is required for this user.
            if ((errorStruct.errorCode == WSManNativeApi.ERROR_WSMAN_REDIRECT_REQUESTED) && (wsmanSessionTM != null))
            {
                IntPtr wsmanSessionHandle = wsmanSessionTM.SessionHandle;
                // populate the transport message with the redirection uri..this will
                // allow caller to make a new connection.
                string redirectLocation = WSManNativeApi.WSManGetSessionOptionAsString(wsmanSessionHandle,
                    WSManNativeApi.WSManSessionOption.WSMAN_OPTION_REDIRECT_LOCATION);
                string winrmMessage = ParseEscapeWSManErrorMessage(
                    WSManNativeApi.WSManGetErrorMessage(wsmanAPIHandle, errorStruct.errorCode)).Trim();

                e = new PSRemotingTransportRedirectException(redirectLocation,
                    PSRemotingErrorId.URIEndPointNotResolved,
                    RemotingErrorIdStrings.URIEndPointNotResolved,
                    winrmMessage,
                    redirectLocation);
            }
            else if ((errorStruct.errorCode == WSManNativeApi.ERROR_WSMAN_INVALID_RESOURCE_URI) && (wsmanSessionTM != null))
            {
                string configurationName =
                    wsmanSessionTM.ConnectionInfo.ShellUri.Replace(Remoting.Client.WSManNativeApi.ResourceURIPrefix, string.Empty);
                string errorMessage = PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.InvalidConfigurationName,
                                                   configurationName,
                                                   wsmanSessionTM.ConnectionInfo.ComputerName);

                e = new PSRemotingTransportException(PSRemotingErrorId.InvalidConfigurationName,
                                                   RemotingErrorIdStrings.ConnectExCallBackError, wsmanSessionTM.ConnectionInfo.ComputerName, errorMessage);

                e.TransportMessage = ParseEscapeWSManErrorMessage(
                   WSManNativeApi.WSManGetErrorMessage(wsmanAPIHandle, errorStruct.errorCode));
            }
            else
            {
                // Construct specific error message and then append this message pointing to our own
                // help topic. PowerShell's about help topic "about_Remote_Troubleshooting" should
                // contain all the trouble shooting information.
                string wsManErrorMessage = PSRemotingErrorInvariants.FormatResourceString(resourceString, resourceArgs);
                e = new PSRemotingTransportException(PSRemotingErrorId.TroubleShootingHelpTopic,
                    RemotingErrorIdStrings.TroubleShootingHelpTopic,
                    wsManErrorMessage);

                e.TransportMessage = ParseEscapeWSManErrorMessage(
                    WSManNativeApi.WSManGetErrorMessage(wsmanAPIHandle, errorStruct.errorCode));
            }

            e.ErrorCode = errorStruct.errorCode;
            TransportErrorOccuredEventArgs eventargs =
                new TransportErrorOccuredEventArgs(e, transportMethodReportingError);
            return eventargs;
        }
        private static void OnRemoteCmdSignalCompleted(IntPtr operationContext,
            int flags,
            IntPtr error,
            IntPtr shellOperationHandle,
            IntPtr commandOperationHandle,
            IntPtr operationHandle,
            IntPtr data)
        {
            tracer.WriteLine("Signal Completed callback received.");

            long cmdContextId = 0;
            WSManClientCommandTransportManager cmdTM = null;
            if (!TryGetCmdTransportManager(operationContext, out cmdTM, out cmdContextId))
            {
                // We dont have the command TM handle..just return.
                tracer.WriteLine("Unable to find a transport manager for the given command context {0}.", cmdContextId);
                return;
            }

            // log the callback received event.
            PSEtwLog.LogAnalyticInformational(PSEventId.WSManSignalCallbackReceived,
                PSOpcode.Disconnect, PSTask.None, PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic,
                cmdTM.RunspacePoolInstanceId.ToString(), cmdTM.powershellInstanceId.ToString());

            if ((!shellOperationHandle.Equals(cmdTM._wsManShellOperationHandle)) ||
                (!commandOperationHandle.Equals(cmdTM._wsManCmdOperationHandle)))
            {
                // WSMan returned data from a wrong shell..notify the caller
                // about the same.
                tracer.WriteLine("Cmd Signal callback: ShellOperationHandles are not the same as the signal is initiated with");
                PSRemotingTransportException e = new PSRemotingTransportException(RemotingErrorIdStrings.CommandSendExFailed);
                TransportErrorOccuredEventArgs eventargs =
                    new TransportErrorOccuredEventArgs(e, TransportMethodEnum.CommandInputEx);
                cmdTM.ProcessWSManTransportError(eventargs);

                return;
            }

            // release the resources related to signal
            if (IntPtr.Zero != cmdTM._cmdSignalOperationHandle)
            {
                WSManNativeApi.WSManCloseOperation(cmdTM._cmdSignalOperationHandle, 0);
                cmdTM._cmdSignalOperationHandle = IntPtr.Zero;
            }

            if (null != cmdTM._signalCmdCompleted)
            {
                cmdTM._signalCmdCompleted.Dispose();
                cmdTM._signalCmdCompleted = null;
            }

            // if the transport manager is already closed..ignore the errors and return            
            if (cmdTM.isClosed)
            {
                tracer.WriteLine("Client Command TM: Transport manager is closed. So returning");
                return;
            }

            if (IntPtr.Zero != error)
            {
                WSManNativeApi.WSManError errorStruct = WSManNativeApi.WSManError.UnMarshal(error);
                if (errorStruct.errorCode != 0)
                {
                    tracer.WriteLine("Cmd Signal callback: WSMan reported an error: {0}", errorStruct.errorDetail);

                    TransportErrorOccuredEventArgs eventargs = WSManTransportManagerUtils.ConstructTransportErrorEventArgs(
                        cmdTM._sessnTm.WSManAPIData.WSManAPIHandle,
                        null,
                        errorStruct,
                        TransportMethodEnum.CommandInputEx,
                        RemotingErrorIdStrings.CommandSendExCallBackError,
                        new object[] { WSManTransportManagerUtils.ParseEscapeWSManErrorMessage(errorStruct.errorDetail) });
                    cmdTM.ProcessWSManTransportError(eventargs);
                    return;
                }
            }

            cmdTM.EnqueueAndStartProcessingThread(null, null, true);
        }
        private void ProcessErrorThread(object state)
        {
            try
            {
                StreamReader reader = state as StreamReader;
                Dbg.Assert(reader != null, "Reader cannot be null.");

                while (true)
                {
                    string error = reader.ReadLine();
                    if (!string.IsNullOrEmpty(error) && (error.IndexOf("WARNING:", StringComparison.OrdinalIgnoreCase) < 0))
                    {
                        // Any SSH client error results in a broken session.
                        PSRemotingTransportException psrte = new PSRemotingTransportException(
                            PSRemotingErrorId.IPCServerProcessReportedError,
                            RemotingErrorIdStrings.IPCServerProcessReportedError,
                            error);
                        RaiseErrorHandler(new TransportErrorOccuredEventArgs(psrte, TransportMethodEnum.CloseShellOperationEx));
                        CloseConnection();
                    }
                }
            }
            catch (ObjectDisposedException) { }
            catch (Exception e)
            {
                CommandProcessorBase.CheckForSevereException(e);

                string errorMsg = (e.Message != null) ? e.Message : string.Empty;
                _tracer.WriteMessage("SSHClientSessionTransportManager", "ProcessErrorThread", Guid.Empty,
                    "Transport manager error thread ended with error: {0}", errorMsg);
            }
        }