internal WSManClientSessionTransportManager(Guid runspacePoolInstanceId, WSManConnectionInfo connectionInfo, PSRemotingCryptoHelper cryptoHelper, string sessionName) : base(runspacePoolInstanceId, cryptoHelper)
 {
     this.startMode = WSManTransportManagerUtils.tmStartModes.None;
     base.CryptoHelper = cryptoHelper;
     base.dataToBeSent.Fragmentor = base.Fragmentor;
     this.sessionName = sessionName;
     base.ReceivedDataCollection.MaximumReceivedDataSize = null;
     base.ReceivedDataCollection.MaximumReceivedObjectSize = connectionInfo.MaximumReceivedObjectSize;
     this.onDataAvailableToSendCallback = new System.Management.Automation.Remoting.PrioritySendDataCollection.OnDataAvailableCallback(this.OnDataAvailableCallback);
     this.Initialize(connectionInfo.ConnectionUri, connectionInfo);
 }
        /// <summary>
        /// Starts connecting to an existing remote session. This will result in a WSManConnectShellEx WSMan
        /// async call. Piggy backs available data in input stream as openXml in connect SOAP.
        /// DSHandler will push negotiation related messages through the open content
        /// </summary>
        /// <exception cref="PSRemotingTransportException">
        /// WSManConnectShellEx failed.
        /// </exception>
        internal override void ConnectAsync()
        {
            Dbg.Assert(!isClosed, "object already disposed");
            Dbg.Assert(!String.IsNullOrEmpty(ConnectionInfo.ShellUri), "shell uri cannot be null or empty.");

            ReceivedDataCollection.PrepareForStreamConnect();
            // additional content with connect shell call. Negotiation and connect related messages
            // should be included in payload
            if (null == _openContent)
            {
                DataPriorityType additionalDataType;
                byte[] additionalData = dataToBeSent.ReadOrRegisterCallback(null, out additionalDataType);

                if (null != additionalData)
                {
                    // WSMan expects the data to be in XML format (which is text + xml tags)
                    // so convert byte[] into base64 encoded format
                    string base64EncodedDataInXml = string.Format(CultureInfo.InvariantCulture, "<{0} xmlns=\"{1}\">{2}</{0}>",
                        WSManNativeApi.PS_CONNECT_XML_TAG,
                        WSManNativeApi.PS_XML_NAMESPACE,
                        Convert.ToBase64String(additionalData));
                    _openContent = new WSManNativeApi.WSManData_ManToUn(base64EncodedDataInXml);
                }

                //THERE SHOULD BE NO ADDITIONAL DATA. If there is, it means we are not able to push all initial negotiation related data
                // as part of Connect SOAP. The connect algorithm is based on this assumption. So bail out.
                additionalData = dataToBeSent.ReadOrRegisterCallback(null, out additionalDataType);
                if (additionalData != null)
                {
                    //Negotiation payload does not fit in ConnectShell. bail out. 
                    //Assert for now. should be replaced with raising an exception so upper layers can catch.
                    Dbg.Assert(false, "Negotiation payload does not fit in ConnectShell");
                    return;
                }
            }

            // Create and store context for this shell operation. This context is used from various callbacks
            _sessionContextID = GetNextSessionTMHandleId();
            AddSessionTransportManager(_sessionContextID, this);

            //session is implicitly assumed to support disconnect
            SupportsDisconnect = true;

            // Create Callback
            _connectSessionCallback = new WSManNativeApi.WSManShellAsync(new IntPtr(_sessionContextID), s_sessionConnectCallback);
            lock (syncObject)
            {
                if (isClosed)
                {
                    // the transport is already closed..so no need to connect
                    // anymore.
                    return;
                }

                Dbg.Assert(_startMode == WSManTransportManagerUtils.tmStartModes.None, "startMode is not in expected state");
                _startMode = WSManTransportManagerUtils.tmStartModes.Connect;

                int flags = 0;
                flags |= (ConnectionInfo.OutputBufferingMode == Runspaces.OutputBufferingMode.Block) ?
                                (int)WSManNativeApi.WSManShellFlag.WSMAN_FLAG_SERVER_BUFFERING_MODE_BLOCK : 0;
                flags |= (ConnectionInfo.OutputBufferingMode == Runspaces.OutputBufferingMode.Drop) ?
                                (int)WSManNativeApi.WSManShellFlag.WSMAN_FLAG_SERVER_BUFFERING_MODE_DROP : 0;

                WSManNativeApi.WSManConnectShellEx(_wsManSessionHandle,
                    flags,
                    ConnectionInfo.ShellUri,
                    RunspacePoolInstanceId.ToString().ToUpperInvariant(),  //wsman is case sensitive wrt shellId. so consistently using upper case
                    IntPtr.Zero,
                    _openContent,
                    _connectSessionCallback,
                    ref _wsManShellOperationHandle);
            }

            if (_wsManShellOperationHandle == IntPtr.Zero)
            {
                TransportErrorOccuredEventArgs eventargs = WSManTransportManagerUtils.ConstructTransportErrorEventArgs(WSManAPIData.WSManAPIHandle,
                    this,
                    new WSManNativeApi.WSManError(),
                    TransportMethodEnum.ConnectShellEx,
                    RemotingErrorIdStrings.ConnectExFailed, this.ConnectionInfo.ComputerName);
                ProcessWSManTransportError(eventargs);
                return;
            }
        }
 private void StartCreateRetry(object state)
 {
     // Begin new session create attempt.
     _startMode = WSManTransportManagerUtils.tmStartModes.None;
     CreateAsync();
 }
 /// <summary>
 /// Redirect the transport manager to point to a new URI.
 /// </summary>
 /// <param name="newUri">
 /// Redirect Uri to connect to.
 /// </param>
 /// <param name="connectionInfo">
 /// Connection info object used for retrieving credential, auth. mechanism etc.
 /// </param>
 /// <exception cref="PSInvalidOperationException">
 /// 1. Create Session failed with a non-zero error code.
 /// </exception>
 internal override void Redirect(Uri newUri, RunspaceConnectionInfo connectionInfo)
 {
     CloseSessionAndClearResources();
     tracer.WriteLine("Redirecting to URI: {0}", newUri);
     PSEtwLog.LogAnalyticInformational(PSEventId.URIRedirection,
         PSOpcode.Connect, PSTask.None, PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic,
         RunspacePoolInstanceId.ToString(), newUri.ToString());
     Initialize(newUri, (WSManConnectionInfo)connectionInfo);
     //reset startmode
     _startMode = WSManTransportManagerUtils.tmStartModes.None;
     CreateAsync();
 }
        /// <summary>
        /// Starts connecting to remote end asynchronously. This will result in a WSManCreateShellEx WSMan
        /// async call. By the time this call returns, we will have a valid handle, if the operation
        /// succeeds. Make sure other methods are called only after this method returns. Thread
        /// synchronization is left to the caller.
        /// </summary>
        /// <exception cref="PSRemotingTransportException">
        /// WSManCreateShellEx failed.
        /// </exception>
        internal override void CreateAsync()
        {
            Dbg.Assert(!isClosed, "object already disposed");
            Dbg.Assert(!String.IsNullOrEmpty(ConnectionInfo.ShellUri), "shell uri cannot be null or empty.");
            Dbg.Assert(WSManAPIData != null, "WSManApiData should always be created before session creation.");

            List<WSManNativeApi.WSManOption> shellOptions = new List<WSManNativeApi.WSManOption>(WSManAPIData.CommonOptionSet);

            #region SHIM: Redirection code for protocol version

            if (s_protocolVersionRedirect != null)
            {
                string newProtocolVersion = (string)s_protocolVersionRedirect.DynamicInvoke();
                shellOptions.Clear();
                WSManNativeApi.WSManOption newPrtVOption = new WSManNativeApi.WSManOption();
                newPrtVOption.name = RemoteDataNameStrings.PS_STARTUP_PROTOCOL_VERSION_NAME;
                newPrtVOption.value = newProtocolVersion;
                newPrtVOption.mustComply = true;
                shellOptions.Add(newPrtVOption);
            }

            #endregion

            // Pass the WSManConnectionInfo object IdleTimeout value if it is
            // valid.  Otherwise pass the default value that instructs the server
            // to use its default IdleTimeout value.
            uint uIdleTimeout = (ConnectionInfo.IdleTimeout > 0) ?
                (uint)ConnectionInfo.IdleTimeout : UseServerDefaultIdleTimeoutUInt;

            // startup info           
            WSManNativeApi.WSManShellStartupInfo_ManToUn startupInfo =
                new WSManNativeApi.WSManShellStartupInfo_ManToUn(WSManAPIData.InputStreamSet,
                WSManAPIData.OutputStreamSet,
                uIdleTimeout,
                _sessionName);

            // additional content with create shell call. Piggy back first fragment from
            // the dataToBeSent buffer.
            if (null == _openContent)
            {
                DataPriorityType additionalDataType;
                byte[] additionalData = dataToBeSent.ReadOrRegisterCallback(null, out additionalDataType);

                #region SHIM: Redirection code for session data send.

                bool sendContinue = true;

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

                if (!sendContinue)
                    return;

                #endregion

                if (null != additionalData)
                {
                    // WSMan expects the data to be in XML format (which is text + xml tags)
                    // so convert byte[] into base64 encoded format
                    string base64EncodedDataInXml = string.Format(CultureInfo.InvariantCulture, "<{0} xmlns=\"{1}\">{2}</{0}>",
                        WSManNativeApi.PS_CREATION_XML_TAG,
                        WSManNativeApi.PS_XML_NAMESPACE,
                        Convert.ToBase64String(additionalData));
                    _openContent = new WSManNativeApi.WSManData_ManToUn(base64EncodedDataInXml);
                }
            }

            // Create the session context information only once.  CreateAsync() can be called multiple
            // times by RetrySessionCreation for flaky networks.
            if (_sessionContextID == 0)
            {
                // Create and store context for this shell operation. This context is used from various callbacks
                _sessionContextID = GetNextSessionTMHandleId();
                AddSessionTransportManager(_sessionContextID, this);

                // Create Callback
                _createSessionCallback = new WSManNativeApi.WSManShellAsync(new IntPtr(_sessionContextID), s_sessionCreateCallback);
                _createSessionCallbackGCHandle = GCHandle.Alloc(_createSessionCallback);
            }

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

            try
            {
                lock (syncObject)
                {
                    if (isClosed)
                    {
                        // the transport is already closed..so no need to create a connection
                        // anymore.
                        return;
                    }

                    Dbg.Assert(_startMode == WSManTransportManagerUtils.tmStartModes.None, "startMode is not in expected state");
                    _startMode = WSManTransportManagerUtils.tmStartModes.Create;

                    if (_noMachineProfile)
                    {
                        WSManNativeApi.WSManOption noProfile = new WSManNativeApi.WSManOption();
                        noProfile.name = WSManNativeApi.NoProfile;
                        noProfile.mustComply = true;
                        noProfile.value = "1";
                        shellOptions.Add(noProfile);
                    }

                    int flags = _noCompression ? (int)WSManNativeApi.WSManShellFlag.WSMAN_FLAG_NO_COMPRESSION : 0;
                    flags |= (ConnectionInfo.OutputBufferingMode == Runspaces.OutputBufferingMode.Block) ?
                                    (int)WSManNativeApi.WSManShellFlag.WSMAN_FLAG_SERVER_BUFFERING_MODE_BLOCK : 0;
                    flags |= (ConnectionInfo.OutputBufferingMode == Runspaces.OutputBufferingMode.Drop) ?
                                    (int)WSManNativeApi.WSManShellFlag.WSMAN_FLAG_SERVER_BUFFERING_MODE_DROP : 0;

                    using (WSManNativeApi.WSManOptionSet optionSet = new WSManNativeApi.WSManOptionSet(shellOptions.ToArray()))
                    {
                        WSManNativeApi.WSManCreateShellEx(_wsManSessionHandle,
                            flags,
                            ConnectionInfo.ShellUri,
                            RunspacePoolInstanceId.ToString().ToUpperInvariant(),
                            startupInfo,
                            optionSet,
                            _openContent,
                            _createSessionCallback,
                            ref _wsManShellOperationHandle);
                    }
                }

                if (_wsManShellOperationHandle == IntPtr.Zero)
                {
                    TransportErrorOccuredEventArgs eventargs = WSManTransportManagerUtils.ConstructTransportErrorEventArgs(WSManAPIData.WSManAPIHandle,
                        this,
                        new WSManNativeApi.WSManError(),
                        TransportMethodEnum.CreateShellEx,
                        RemotingErrorIdStrings.ConnectExFailed,
                        this.ConnectionInfo.ComputerName);
                    ProcessWSManTransportError(eventargs);
                    return;
                }
            }
            finally
            {
                startupInfo.Dispose();
            }
        }
 internal override void CreateAsync()
 {
     List<WSManNativeApi.WSManOption> list = new List<WSManNativeApi.WSManOption>(wsManApiStaticData.CommonOptionSet);
     if (protocolVersionRedirect != null)
     {
         string str = (string) protocolVersionRedirect.DynamicInvoke(new object[0]);
         list.Clear();
         WSManNativeApi.WSManOption item = new WSManNativeApi.WSManOption {
             name = "protocolversion",
             value = str,
             mustComply = true
         };
         list.Add(item);
     }
     int serverIdleTimeOut = (this._connectionInfo.IdleTimeout > 0) ? ((int) this._connectionInfo.IdleTimeout) : int.MaxValue;
     WSManNativeApi.WSManShellStartupInfo startupInfo = new WSManNativeApi.WSManShellStartupInfo(wsManApiStaticData.InputStreamSet, wsManApiStaticData.OutputStreamSet, serverIdleTimeOut, this.sessionName);
     if (this.openContent == null)
     {
         DataPriorityType type;
         byte[] inArray = base.dataToBeSent.ReadOrRegisterCallback(null, out type);
         bool flag = true;
         if (sessionSendRedirect != null)
         {
             object[] objArray2 = new object[2];
             objArray2[1] = inArray;
             object[] objArray = objArray2;
             flag = (bool) sessionSendRedirect.DynamicInvoke(objArray);
             inArray = (byte[]) objArray[0];
         }
         if (!flag)
         {
             return;
         }
         if (inArray != null)
         {
             string data = string.Format(CultureInfo.InvariantCulture, "<{0} xmlns=\"{1}\">{2}</{0}>", new object[] { "creationXml", "http://schemas.microsoft.com/powershell", Convert.ToBase64String(inArray, Base64FormattingOptions.None) });
             this.openContent = new WSManNativeApi.WSManData(data);
         }
     }
     this.sessionContextID = GetNextSessionTMHandleId();
     AddSessionTransportManager(this.sessionContextID, this);
     PSEtwLog.LogAnalyticInformational(PSEventId.WSManCreateShell, PSOpcode.Connect, PSTask.CreateRunspace, PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic, new object[] { base.RunspacePoolInstanceId.ToString() });
     this.createSessionCallback = new WSManNativeApi.WSManShellAsync(new IntPtr(this.sessionContextID), sessionCreateCallback);
     this.createSessionCallbackGCHandle = GCHandle.Alloc(this.createSessionCallback);
     try
     {
         lock (base.syncObject)
         {
             if (base.isClosed)
             {
                 return;
             }
             this.startMode = WSManTransportManagerUtils.tmStartModes.Create;
             if (this.noMachineProfile)
             {
                 WSManNativeApi.WSManOption option2 = new WSManNativeApi.WSManOption {
                     name = "WINRS_NOPROFILE",
                     mustComply = true,
                     value = "1"
                 };
                 list.Add(option2);
             }
             int flags = this.noCompression ? 1 : 0;
             flags |= (this._connectionInfo.OutputBufferingMode == OutputBufferingMode.Block) ? 8 : 0;
             flags |= (this._connectionInfo.OutputBufferingMode == OutputBufferingMode.Drop) ? 4 : 0;
             using (WSManNativeApi.WSManOptionSet set = new WSManNativeApi.WSManOptionSet(list.ToArray()))
             {
                 WSManNativeApi.WSManCreateShellEx(this.wsManSessionHandle, flags, this._connectionInfo.ShellUri, base.RunspacePoolInstanceId.ToString().ToUpper(CultureInfo.InvariantCulture), startupInfo, set, this.openContent, (IntPtr) this.createSessionCallback, ref this.wsManShellOperationHandle);
             }
         }
         if (this.wsManShellOperationHandle == IntPtr.Zero)
         {
             TransportErrorOccuredEventArgs eventArgs = WSManTransportManagerUtils.ConstructTransportErrorEventArgs(wsManApiStaticData.WSManAPIHandle, this, new WSManNativeApi.WSManError(), TransportMethodEnum.CreateShellEx, RemotingErrorIdStrings.ConnectExFailed, new object[] { this.ConnectionInfo.ComputerName });
             this.ProcessWSManTransportError(eventArgs);
         }
     }
     finally
     {
         startupInfo.Dispose();
     }
 }
 internal override void ConnectAsync()
 {
     base.ReceivedDataCollection.PrepareForStreamConnect();
     if (this.openContent == null)
     {
         DataPriorityType type;
         byte[] inArray = base.dataToBeSent.ReadOrRegisterCallback(null, out type);
         if (inArray != null)
         {
             string data = string.Format(CultureInfo.InvariantCulture, "<{0} xmlns=\"{1}\">{2}</{0}>", new object[] { "connectXml", "http://schemas.microsoft.com/powershell", Convert.ToBase64String(inArray, Base64FormattingOptions.None) });
             this.openContent = new WSManNativeApi.WSManData(data);
         }
         if (base.dataToBeSent.ReadOrRegisterCallback(null, out type) != null)
         {
             return;
         }
     }
     this.sessionContextID = GetNextSessionTMHandleId();
     AddSessionTransportManager(this.sessionContextID, this);
     this.supportsDisconnect = true;
     this.connectSessionCallback = new WSManNativeApi.WSManShellAsync(new IntPtr(this.sessionContextID), sessionConnectCallback);
     lock (base.syncObject)
     {
         if (base.isClosed)
         {
             return;
         }
         this.startMode = WSManTransportManagerUtils.tmStartModes.Connect;
         int flags = 0;
         flags |= (this._connectionInfo.OutputBufferingMode == OutputBufferingMode.Block) ? 8 : 0;
         flags |= (this._connectionInfo.OutputBufferingMode == OutputBufferingMode.Drop) ? 4 : 0;
         WSManNativeApi.WSManConnectShellEx(this.wsManSessionHandle, flags, this._connectionInfo.ShellUri, base.RunspacePoolInstanceId.ToString().ToUpper(CultureInfo.InvariantCulture), IntPtr.Zero, (IntPtr) this.openContent, (IntPtr) this.connectSessionCallback, ref this.wsManShellOperationHandle);
     }
     if (this.wsManShellOperationHandle == IntPtr.Zero)
     {
         TransportErrorOccuredEventArgs eventArgs = WSManTransportManagerUtils.ConstructTransportErrorEventArgs(wsManApiStaticData.WSManAPIHandle, this, new WSManNativeApi.WSManError(), TransportMethodEnum.ConnectShellEx, RemotingErrorIdStrings.ConnectExFailed, new object[] { this.ConnectionInfo.ComputerName });
         this.ProcessWSManTransportError(eventArgs);
     }
 }