/// <summary> /// Gets the fragment or if no fragment is available registers the callback which /// gets called once a fragment is available. These 2 steps are performed in a /// synchronized way. /// /// While getting a fragment the following algorithm is used: /// 1. If this is the first time or if the last fragment read is an EndFragment, /// then a new set of fragments is chosen based on the implicit priority. /// PromptResponse is higher in priority order than default. /// 2. If last fragment read is not an EndFragment, then next fragment is chosen from /// the priority collection as the last fragment. This will ensure fragments /// are sent in order. /// </summary> /// <param name="callback"> /// Callback to call once data is available. (This will be used if no data is currently /// available). /// </param> /// <param name="priorityType"> /// Priority stream to which the returned object belongs to, if any. /// If the call does not return any data, the value of this "out" parameter /// is undefined. /// </param> /// <returns> /// A FragmentRemoteObject if available, otherwise null. /// </returns> internal byte[] ReadOrRegisterCallback(OnDataAvailableCallback callback, out DataPriorityType priorityType) { lock (_readSyncObject) { priorityType = DataPriorityType.Default; // Send data from which ever stream that has data directly. byte[] result = null; SerializedDataStream promptDataToBeSent = _dataToBeSent[(int)DataPriorityType.PromptResponse]; if (promptDataToBeSent is not null) { result = promptDataToBeSent.ReadOrRegisterCallback(_onSendCollectionDataAvailable); priorityType = DataPriorityType.PromptResponse; } if (result == null) { SerializedDataStream defaultDataToBeSent = _dataToBeSent[(int)DataPriorityType.Default]; if (defaultDataToBeSent is not null) { result = defaultDataToBeSent.ReadOrRegisterCallback(_onSendCollectionDataAvailable); priorityType = DataPriorityType.Default; } } // No data to return..so register the callback. if (result == null) { // Register callback. _onDataAvailableCallback = callback; } return(result); } }
protected BaseClientCommandTransportManager(ClientRemotePowerShell shell, PSRemotingCryptoHelper cryptoHelper, BaseClientSessionTransportManager sessnTM) : base(sessnTM.RunspacePoolInstanceId, cryptoHelper) { RemoteDataObject obj2; base.Fragmentor.FragmentSize = sessnTM.Fragmentor.FragmentSize; base.Fragmentor.TypeTable = sessnTM.Fragmentor.TypeTable; base.dataToBeSent.Fragmentor = base.Fragmentor; this.powershellInstanceId = shell.PowerShell.InstanceId; this.cmdText = new StringBuilder(); foreach (Command command in shell.PowerShell.Commands.Commands) { this.cmdText.Append(command.CommandText); this.cmdText.Append(" | "); } this.cmdText.Remove(this.cmdText.Length - 3, 3); if (shell.PowerShell.IsGetCommandMetadataSpecialPipeline) { obj2 = RemotingEncoder.GenerateGetCommandMetadata(shell); } else { obj2 = RemotingEncoder.GenerateCreatePowerShell(shell); } this.serializedPipeline = new SerializedDataStream(base.Fragmentor.FragmentSize); base.Fragmentor.Fragment<object>(obj2, this.serializedPipeline); }
internal void Enter() { this.isEntered = true; this.fragmentId = 0L; this.currentFragment.ObjectId = SerializedDataStream.GetObjectId(); this.currentFragment.FragmentId = this.fragmentId; this.currentFragment.IsStartFragment = true; this.currentFragment.BlobLength = 0; this.currentFragment.Blob = new byte[this.fragmentSize]; }
internal void Fragment <T>(RemoteDataObject <T> obj, SerializedDataStream dataToBeSent) { dataToBeSent.Enter(); try { obj.Serialize(dataToBeSent, this); } finally { dataToBeSent.Exit(); } }
/// <summary> /// The method performs the fragmentation operation. /// All fragments of the same object have the same ObjectId. /// All fragments of the same object have the same ObjectId. /// Each fragment has its own Fragment Id. Fragment Id always starts from zero (0), /// and increments sequentially with an increment of 1. /// The last fragment is indicated by an End of Fragment marker. /// </summary> /// <param name="obj"> /// The object to be fragmented. Caller should make sure this is not null. /// </param> /// <param name="dataToBeSent"> /// Caller specified dataToStore to which the fragments are added /// one-by-one /// </param> internal void Fragment <T>(RemoteDataObject <T> obj, SerializedDataStream dataToBeSent) { Dbg.Assert(obj != null, "Cannot fragment a null object"); Dbg.Assert(dataToBeSent != null, "SendDataCollection cannot be null"); dataToBeSent.Enter(); try { obj.Serialize(dataToBeSent, this); } finally { dataToBeSent.Exit(); } }
/// <summary> /// ExecutesConnect. expects client capability and connect_runspacepool PSRP /// messages in connectData. /// If negotiation is successful and max and min runspaces in connect_runspacepool /// match the associated runspace pool parameters, it builds up server capability /// and runspace_initinfo in connectResponseData. /// This is a version of Connect that executes the whole connect algorithm in one single /// hop. /// This algorithm is being executed synchronously without associating with state machine. /// </summary> /// <param name="connectData"></param> /// <param name="connectResponseData"></param> /// The operation is being outside the statemachine because of multiple reasons associated with design simplicity /// - Support automatic disconnect and let wsman server stack take care of connection state /// - The response data should not travel in transports output stream but as part of connect response /// - We want this operation to be synchronous internal void ExecuteConnect(byte[] connectData, out byte[] connectResponseData) { connectResponseData = null; Fragmentor fragmentor = new Fragmentor(int.MaxValue, null); Fragmentor defragmentor = fragmentor; int totalDataLen = connectData.Length; if (totalDataLen < FragmentedRemoteObject.HeaderLength) { //raise exception throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } //TODO: Follow up on comment from Krishna regarding having the serialization/deserialization separate for this // operation. This could be integrated as helper functions in fragmentor/serializer components long fragmentId = FragmentedRemoteObject.GetFragmentId(connectData, 0); bool sFlag = FragmentedRemoteObject.GetIsStartFragment(connectData, 0); bool eFlag = FragmentedRemoteObject.GetIsEndFragment(connectData, 0); int blobLength = FragmentedRemoteObject.GetBlobLength(connectData, 0); if (blobLength > totalDataLen - FragmentedRemoteObject.HeaderLength) { //raise exception throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } if (!sFlag || !eFlag) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } //if session is not in expected state RemoteSessionState currentState = SessionDataStructureHandler.StateMachine.State; if (currentState != RemoteSessionState.Established && currentState != RemoteSessionState.EstablishedAndKeyExchanged) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnServerStateValidation); } //process first message MemoryStream serializedStream = new MemoryStream(); serializedStream.Write(connectData, FragmentedRemoteObject.HeaderLength, blobLength); serializedStream.Seek(0, SeekOrigin.Begin); RemoteDataObject<PSObject> capabilityObject = RemoteDataObject<PSObject>.CreateFrom(serializedStream, defragmentor); if (capabilityObject == null) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } if ((capabilityObject.Destination != RemotingDestination.Server) || (capabilityObject.DataType != RemotingDataType.SessionCapability)) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } //process second message int secondFragmentLength = totalDataLen - FragmentedRemoteObject.HeaderLength - blobLength; if (secondFragmentLength < FragmentedRemoteObject.HeaderLength) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } byte[] secondFragment = new byte[secondFragmentLength]; Array.Copy(connectData, FragmentedRemoteObject.HeaderLength + blobLength, secondFragment, 0, secondFragmentLength); fragmentId = FragmentedRemoteObject.GetFragmentId(secondFragment, 0); sFlag = FragmentedRemoteObject.GetIsStartFragment(secondFragment, 0); eFlag = FragmentedRemoteObject.GetIsEndFragment(secondFragment, 0); blobLength = FragmentedRemoteObject.GetBlobLength(secondFragment, 0); if (blobLength != secondFragmentLength - FragmentedRemoteObject.HeaderLength) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } if (!sFlag || !eFlag) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } //process second message serializedStream = new MemoryStream(); serializedStream.Write(secondFragment, FragmentedRemoteObject.HeaderLength, blobLength); serializedStream.Seek(0, SeekOrigin.Begin); RemoteDataObject<PSObject> connectRunspacePoolObject = RemoteDataObject<PSObject>.CreateFrom(serializedStream, defragmentor); if (connectRunspacePoolObject == null) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnServerStateValidation); } if ((connectRunspacePoolObject.Destination != RemotingDestination.Server) || (connectRunspacePoolObject.DataType != RemotingDataType.ConnectRunspacePool)) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } //We have the two objects required for validating the connect operation RemoteSessionCapability clientCapability; try { clientCapability = RemotingDecoder.GetSessionCapability(capabilityObject.Data); } catch (PSRemotingDataStructureException) { // this will happen if expected properties are not // received for session capability throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } try { RunServerNegotiationAlgorithm(clientCapability, true); } catch (PSRemotingDataStructureException ex) { throw ex; } //validate client connect_runspacepool request int clientRequestedMinRunspaces = -1; int clientRequestedMaxRunspaces = -1; bool clientRequestedRunspaceCount = false; if (connectRunspacePoolObject.Data.Properties[RemoteDataNameStrings.MinRunspaces] != null && connectRunspacePoolObject.Data.Properties[RemoteDataNameStrings.MinRunspaces] != null) { try { clientRequestedMinRunspaces = RemotingDecoder.GetMinRunspaces(connectRunspacePoolObject.Data); clientRequestedMaxRunspaces = RemotingDecoder.GetMaxRunspaces(connectRunspacePoolObject.Data); clientRequestedRunspaceCount = true; } catch (PSRemotingDataStructureException) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } } //these should be positive and max should be greater than min if (clientRequestedRunspaceCount && (clientRequestedMinRunspaces == -1 || clientRequestedMaxRunspaces == -1 || clientRequestedMinRunspaces > clientRequestedMaxRunspaces)) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } if (_runspacePoolDriver == null) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnServerStateValidation); } //currently only one runspace pool per session is allowed. make sure this ID in connect message is the same if (connectRunspacePoolObject.RunspacePoolId != _runspacePoolDriver.InstanceId) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } //we currently dont support adjusting runspace count on a connect operation. //there is a potential race here where in the runspace pool driver is still yet to process a queued //setMax or setMinrunspaces request. //TODO: resolve this race.. probably by letting the runspace pool consume all messages before we execute this. if (clientRequestedRunspaceCount && (_runspacePoolDriver.RunspacePool.GetMaxRunspaces() != clientRequestedMaxRunspaces) && (_runspacePoolDriver.RunspacePool.GetMinRunspaces() != clientRequestedMinRunspaces)) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnMismatchedRunspacePoolProperties); } // all client messages are validated // now build up the server capabilities and connect response messages to be piggybacked on connect response RemoteDataObject capability = RemotingEncoder.GenerateServerSessionCapability(Context.ServerCapability, _runspacePoolDriver.InstanceId); RemoteDataObject runspacepoolInitData = RemotingEncoder.GenerateRunspacePoolInitData(_runspacePoolDriver.InstanceId, _runspacePoolDriver.RunspacePool.GetMaxRunspaces(), _runspacePoolDriver.RunspacePool.GetMinRunspaces()); //having this stream operating separately will result in out of sync fragment Ids. but this is still OK //as this is executed only when connecting from a new client that does not have any previous fragments context. //no problem even if fragment Ids in this response and the sessiontransport stream clash (interfere) and its guaranteed // that the fragments in connect response are always complete (enclose a complete object). SerializedDataStream stream = new SerializedDataStream(4 * 1024);//Each message with fragment headers cannot cross 4k stream.Enter(); capability.Serialize(stream, fragmentor); stream.Exit(); stream.Enter(); runspacepoolInitData.Serialize(stream, fragmentor); stream.Exit(); byte[] outbuffer = stream.Read(); Dbg.Assert(outbuffer != null, "connet response data should be serialized"); stream.Dispose(); //we are done connectResponseData = outbuffer; //enqueue a connect event in state machine to let session do any other post-connect operation // Do this outside of the synchronous connect operation, as otherwise connect can easily get deadlocked ThreadPool.QueueUserWorkItem(new WaitCallback( delegate (object state) { RemoteSessionStateMachineEventArgs startEventArg = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.ConnectSession); SessionDataStructureHandler.StateMachine.RaiseEvent(startEventArg); })); _runspacePoolDriver.DataStructureHandler.ProcessConnect(); return; }
internal void ExecuteConnect(byte[] connectData, out byte[] connectResponseData) { RemoteSessionCapability sessionCapability; connectResponseData = null; Fragmentor fragmentor = new Fragmentor(0x7fffffff, null); Fragmentor defragmentor = fragmentor; int length = connectData.Length; if (length < 0x15) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } FragmentedRemoteObject.GetFragmentId(connectData, 0); bool isStartFragment = FragmentedRemoteObject.GetIsStartFragment(connectData, 0); bool isEndFragment = FragmentedRemoteObject.GetIsEndFragment(connectData, 0); int blobLength = FragmentedRemoteObject.GetBlobLength(connectData, 0); if (blobLength > (length - 0x15)) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } if (!isStartFragment || !isEndFragment) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } RemoteSessionState state = this.SessionDataStructureHandler.StateMachine.State; if ((state != RemoteSessionState.Established) && (state != RemoteSessionState.EstablishedAndKeyExchanged)) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnServerStateValidation); } MemoryStream serializedDataStream = new MemoryStream(); serializedDataStream.Write(connectData, 0x15, blobLength); serializedDataStream.Seek(0L, SeekOrigin.Begin); RemoteDataObject<PSObject> obj2 = RemoteDataObject<PSObject>.CreateFrom(serializedDataStream, defragmentor); if (obj2 == null) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } if ((obj2.Destination != (RemotingDestination.InvalidDestination | RemotingDestination.Server)) || (obj2.DataType != RemotingDataType.SessionCapability)) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } int num3 = (length - 0x15) - blobLength; if (num3 < 0x15) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } byte[] destinationArray = new byte[num3]; Array.Copy(connectData, 0x15 + blobLength, destinationArray, 0, num3); FragmentedRemoteObject.GetFragmentId(destinationArray, 0); isStartFragment = FragmentedRemoteObject.GetIsStartFragment(destinationArray, 0); isEndFragment = FragmentedRemoteObject.GetIsEndFragment(destinationArray, 0); blobLength = FragmentedRemoteObject.GetBlobLength(destinationArray, 0); if (blobLength != (num3 - 0x15)) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } if (!isStartFragment || !isEndFragment) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } serializedDataStream = new MemoryStream(); serializedDataStream.Write(destinationArray, 0x15, blobLength); serializedDataStream.Seek(0L, SeekOrigin.Begin); RemoteDataObject<PSObject> obj3 = RemoteDataObject<PSObject>.CreateFrom(serializedDataStream, defragmentor); if (obj3 == null) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnServerStateValidation); } if ((obj3.Destination != (RemotingDestination.InvalidDestination | RemotingDestination.Server)) || (obj3.DataType != RemotingDataType.ConnectRunspacePool)) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } try { sessionCapability = RemotingDecoder.GetSessionCapability(obj2.Data); } catch (PSRemotingDataStructureException) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } try { this.RunServerNegotiationAlgorithm(sessionCapability, true); } catch (PSRemotingDataStructureException exception) { throw exception; } int minRunspaces = -1; int maxRunspaces = -1; bool flag3 = false; if ((obj3.Data.Properties["MinRunspaces"] != null) && (obj3.Data.Properties["MinRunspaces"] != null)) { try { minRunspaces = RemotingDecoder.GetMinRunspaces(obj3.Data); maxRunspaces = RemotingDecoder.GetMaxRunspaces(obj3.Data); flag3 = true; } catch (PSRemotingDataStructureException) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } } if (flag3 && (((minRunspaces == -1) || (maxRunspaces == -1)) || (minRunspaces > maxRunspaces))) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } if (this._runspacePoolDriver == null) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnServerStateValidation); } if (obj3.RunspacePoolId != this._runspacePoolDriver.InstanceId) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } if ((flag3 && (this._runspacePoolDriver.RunspacePool.GetMaxRunspaces() != maxRunspaces)) && (this._runspacePoolDriver.RunspacePool.GetMinRunspaces() != minRunspaces)) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnMismatchedRunspacePoolProperties); } RemoteDataObject obj4 = RemotingEncoder.GenerateServerSessionCapability(this._context.ServerCapability, this._runspacePoolDriver.InstanceId); RemoteDataObject obj5 = RemotingEncoder.GenerateRunspacePoolInitData(this._runspacePoolDriver.InstanceId, this._runspacePoolDriver.RunspacePool.GetMaxRunspaces(), this._runspacePoolDriver.RunspacePool.GetMinRunspaces()); SerializedDataStream streamToWriteTo = new SerializedDataStream(0x1000); streamToWriteTo.Enter(); obj4.Serialize(streamToWriteTo, fragmentor); streamToWriteTo.Exit(); streamToWriteTo.Enter(); obj5.Serialize(streamToWriteTo, fragmentor); streamToWriteTo.Exit(); byte[] buffer2 = streamToWriteTo.Read(); streamToWriteTo.Dispose(); connectResponseData = buffer2; ThreadPool.QueueUserWorkItem(new WaitCallback(delegate (object s) { RemoteSessionStateMachineEventArgs fsmEventArg = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.ConnectSession); this._sessionDSHandler.StateMachine.RaiseEvent(fsmEventArg); })); this._runspacePoolDriver.DataStructureHandler.ProcessConnect(); }
internal void ExecuteConnect(byte[] connectData, out byte[] connectResponseData) { RemoteSessionCapability sessionCapability; connectResponseData = null; Fragmentor fragmentor = new Fragmentor(0x7fffffff, null); Fragmentor defragmentor = fragmentor; int length = connectData.Length; if (length < 0x15) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } FragmentedRemoteObject.GetFragmentId(connectData, 0); bool isStartFragment = FragmentedRemoteObject.GetIsStartFragment(connectData, 0); bool isEndFragment = FragmentedRemoteObject.GetIsEndFragment(connectData, 0); int blobLength = FragmentedRemoteObject.GetBlobLength(connectData, 0); if (blobLength > (length - 0x15)) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } if (!isStartFragment || !isEndFragment) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } RemoteSessionState state = this.SessionDataStructureHandler.StateMachine.State; if ((state != RemoteSessionState.Established) && (state != RemoteSessionState.EstablishedAndKeyExchanged)) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnServerStateValidation); } MemoryStream serializedDataStream = new MemoryStream(); serializedDataStream.Write(connectData, 0x15, blobLength); serializedDataStream.Seek(0L, SeekOrigin.Begin); RemoteDataObject <PSObject> obj2 = RemoteDataObject <PSObject> .CreateFrom(serializedDataStream, defragmentor); if (obj2 == null) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } if ((obj2.Destination != (RemotingDestination.InvalidDestination | RemotingDestination.Server)) || (obj2.DataType != RemotingDataType.SessionCapability)) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } int num3 = (length - 0x15) - blobLength; if (num3 < 0x15) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } byte[] destinationArray = new byte[num3]; Array.Copy(connectData, 0x15 + blobLength, destinationArray, 0, num3); FragmentedRemoteObject.GetFragmentId(destinationArray, 0); isStartFragment = FragmentedRemoteObject.GetIsStartFragment(destinationArray, 0); isEndFragment = FragmentedRemoteObject.GetIsEndFragment(destinationArray, 0); blobLength = FragmentedRemoteObject.GetBlobLength(destinationArray, 0); if (blobLength != (num3 - 0x15)) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } if (!isStartFragment || !isEndFragment) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } serializedDataStream = new MemoryStream(); serializedDataStream.Write(destinationArray, 0x15, blobLength); serializedDataStream.Seek(0L, SeekOrigin.Begin); RemoteDataObject <PSObject> obj3 = RemoteDataObject <PSObject> .CreateFrom(serializedDataStream, defragmentor); if (obj3 == null) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnServerStateValidation); } if ((obj3.Destination != (RemotingDestination.InvalidDestination | RemotingDestination.Server)) || (obj3.DataType != RemotingDataType.ConnectRunspacePool)) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } try { sessionCapability = RemotingDecoder.GetSessionCapability(obj2.Data); } catch (PSRemotingDataStructureException) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } try { this.RunServerNegotiationAlgorithm(sessionCapability, true); } catch (PSRemotingDataStructureException exception) { throw exception; } int minRunspaces = -1; int maxRunspaces = -1; bool flag3 = false; if ((obj3.Data.Properties["MinRunspaces"] != null) && (obj3.Data.Properties["MinRunspaces"] != null)) { try { minRunspaces = RemotingDecoder.GetMinRunspaces(obj3.Data); maxRunspaces = RemotingDecoder.GetMaxRunspaces(obj3.Data); flag3 = true; } catch (PSRemotingDataStructureException) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } } if (flag3 && (((minRunspaces == -1) || (maxRunspaces == -1)) || (minRunspaces > maxRunspaces))) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } if (this._runspacePoolDriver == null) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnServerStateValidation); } if (obj3.RunspacePoolId != this._runspacePoolDriver.InstanceId) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnInputValidation); } if ((flag3 && (this._runspacePoolDriver.RunspacePool.GetMaxRunspaces() != maxRunspaces)) && (this._runspacePoolDriver.RunspacePool.GetMinRunspaces() != minRunspaces)) { throw new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnMismatchedRunspacePoolProperties); } RemoteDataObject obj4 = RemotingEncoder.GenerateServerSessionCapability(this._context.ServerCapability, this._runspacePoolDriver.InstanceId); RemoteDataObject obj5 = RemotingEncoder.GenerateRunspacePoolInitData(this._runspacePoolDriver.InstanceId, this._runspacePoolDriver.RunspacePool.GetMaxRunspaces(), this._runspacePoolDriver.RunspacePool.GetMinRunspaces()); SerializedDataStream streamToWriteTo = new SerializedDataStream(0x1000); streamToWriteTo.Enter(); obj4.Serialize(streamToWriteTo, fragmentor); streamToWriteTo.Exit(); streamToWriteTo.Enter(); obj5.Serialize(streamToWriteTo, fragmentor); streamToWriteTo.Exit(); byte[] buffer2 = streamToWriteTo.Read(); streamToWriteTo.Dispose(); connectResponseData = buffer2; ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object s) { RemoteSessionStateMachineEventArgs fsmEventArg = new RemoteSessionStateMachineEventArgs(RemoteSessionEvent.ConnectSession); this._sessionDSHandler.StateMachine.RaiseEvent(fsmEventArg); })); this._runspacePoolDriver.DataStructureHandler.ProcessConnect(); }