Beispiel #1
0
 internal SerializedDataStream(int fragmentSize)
 {
     SerializedDataStream._trace.WriteLine("Creating SerializedDataStream with fragmentsize : {0}", (object)fragmentSize);
     this.syncObject      = new object();
     this.currentFragment = new FragmentedRemoteObject();
     this.queuedStreams   = new Queue <MemoryStream>();
     this.fragmentSize    = fragmentSize;
 }
Beispiel #2
0
 /// <summary>
 /// Creates a stream to hold serialized data.
 /// </summary>
 /// <param name="fragmentSize">
 /// fragmentSize to be used while creating fragment boundaries.
 /// </param>
 internal SerializedDataStream(int fragmentSize)
 {
     s_trace.WriteLine("Creating SerializedDataStream with fragmentsize : {0}", fragmentSize);
     Dbg.Assert(fragmentSize > 0, "fragmentsize should be greater than 0.");
     _syncObject      = new object();
     _currentFragment = new FragmentedRemoteObject();
     _queuedStreams   = new Queue <MemoryStream>();
     _fragmentSize    = fragmentSize;
 }
Beispiel #3
0
        internal SerializedDataStream (int fragmentSize)
		{
			if (fragmentSize == 0) {
				_trace.WriteLine("Error: SerializedDataStream with fragmentsize : {0}", new object[] { fragmentSize });
			}
            _trace.WriteLine("Creating SerializedDataStream with fragmentsize : {0}", new object[] { fragmentSize });
            this.syncObject = new object();
            this.currentFragment = new FragmentedRemoteObject();
            this.queuedStreams = new Queue<MemoryStream>();
            this.fragmentSize = fragmentSize;
        }
Beispiel #4
0
 internal SerializedDataStream(int fragmentSize)
 {
     if (fragmentSize == 0)
     {
         _trace.WriteLine("Error: SerializedDataStream with fragmentsize : {0}", new object[] { fragmentSize });
     }
     _trace.WriteLine("Creating SerializedDataStream with fragmentsize : {0}", new object[] { fragmentSize });
     this.syncObject      = new object();
     this.currentFragment = new FragmentedRemoteObject();
     this.queuedStreams   = new Queue <MemoryStream>();
     this.fragmentSize    = fragmentSize;
 }
Beispiel #5
0
        /// <summary>
        /// Process data coming from the transport. This method analyses the data
        /// and if an object can be created, it creates one and calls the
        /// <paramref name="callback"/> with the deserialized object. This method
        /// does not assume all fragments to be available. So if not enough fragments are
        /// available it will simply return..
        /// </summary>
        /// <param name="data">
        /// Data to process.
        /// </param>
        /// <param name="callback">
        /// Callback to call once a complete deserialized object is available.
        /// </param>
        /// <returns>
        /// Defragmented Object if any, otherwise null.
        /// </returns>
        /// <exception cref="PSRemotingTransportException">
        /// 1. Fragment Ids not in sequence
        /// 2. Object Ids does not match
        /// 3. The current deserialized object size of the received data exceeded
        /// allowed maximum object size. The current deserialized object size is {0}.
        /// Allowed maximum object size is {1}.
        /// </exception>
        /// <remarks>
        /// Might throw other exceptions as the deserialized object is handled here.
        /// </remarks>
        internal void ProcessRawData(byte[] data, OnDataAvailableCallback callback)
        {
            Dbg.Assert(data != null, "Cannot process null data");
            Dbg.Assert(callback != null, "Callback cannot be null");

            lock (_syncObject)
            {
                if (_isDisposed)
                {
                    return;
                }

                _numberOfThreadsProcessing++;
                if (_numberOfThreadsProcessing > _maxNumberOfThreadsToAllowForProcessing)
                {
                    Dbg.Assert(false, "Multiple threads are not allowed in ProcessRawData.");
                }
            }

            try
            {
                _pendingDataStream.Write(data, 0, data.Length);

                // this do loop will process one deserialized object.
                // using a loop allows to process multiple objects within
                // the same packet
                while (true)
                {
                    if (_pendingDataStream.Length <= FragmentedRemoteObject.HeaderLength)
                    {
                        // there is not enough data to be processed.
                        s_baseTracer.WriteLine("Not enough data to process. Data is less than header length. Data length is {0}. Header Length {1}.",
                                               _pendingDataStream.Length, FragmentedRemoteObject.HeaderLength);
                        return;
                    }

                    byte[] dataRead = _pendingDataStream.ToArray();

                    // there is enough data to process here. get the fragment header
                    long objectId = FragmentedRemoteObject.GetObjectId(dataRead, 0);
                    if (objectId <= 0)
                    {
                        throw new PSRemotingTransportException(RemotingErrorIdStrings.ObjectIdCannotBeLessThanZero);
                    }

                    long fragmentId = FragmentedRemoteObject.GetFragmentId(dataRead, 0);
                    bool sFlag      = FragmentedRemoteObject.GetIsStartFragment(dataRead, 0);
                    bool eFlag      = FragmentedRemoteObject.GetIsEndFragment(dataRead, 0);
                    int  blobLength = FragmentedRemoteObject.GetBlobLength(dataRead, 0);

                    if ((s_baseTracer.Options & PSTraceSourceOptions.WriteLine) != PSTraceSourceOptions.None)
                    {
                        s_baseTracer.WriteLine("Object Id: {0}", objectId);
                        s_baseTracer.WriteLine("Fragment Id: {0}", fragmentId);
                        s_baseTracer.WriteLine("Start Flag: {0}", sFlag);
                        s_baseTracer.WriteLine("End Flag: {0}", eFlag);
                        s_baseTracer.WriteLine("Blob Length: {0}", blobLength);
                    }

                    int totalLengthOfFragment = 0;

                    try
                    {
                        totalLengthOfFragment = checked (FragmentedRemoteObject.HeaderLength + blobLength);
                    }
                    catch (System.OverflowException)
                    {
                        s_baseTracer.WriteLine("Fragment too big.");
                        ResetReceiveData();
                        PSRemotingTransportException e = new PSRemotingTransportException(RemotingErrorIdStrings.ObjectIsTooBig);
                        throw e;
                    }

                    if (_pendingDataStream.Length < totalLengthOfFragment)
                    {
                        s_baseTracer.WriteLine("Not enough data to process packet. Data is less than expected blob length. Data length {0}. Expected Length {1}.",
                                               _pendingDataStream.Length, totalLengthOfFragment);
                        return;
                    }

                    // ensure object size limit is not reached
                    if (_maxReceivedObjectSize.HasValue)
                    {
                        _totalReceivedObjectSizeSoFar = unchecked (_totalReceivedObjectSizeSoFar + totalLengthOfFragment);
                        if ((_totalReceivedObjectSizeSoFar < 0) || (_totalReceivedObjectSizeSoFar > _maxReceivedObjectSize.Value))
                        {
                            s_baseTracer.WriteLine("ObjectSize > MaxReceivedObjectSize. ObjectSize is {0}. MaxReceivedObjectSize is {1}",
                                                   _totalReceivedObjectSizeSoFar, _maxReceivedObjectSize);
                            PSRemotingTransportException e = null;

                            if (_isCreateByClientTM)
                            {
                                e = new PSRemotingTransportException(PSRemotingErrorId.ReceivedObjectSizeExceededMaximumClient,
                                                                     RemotingErrorIdStrings.ReceivedObjectSizeExceededMaximumClient,
                                                                     _totalReceivedObjectSizeSoFar, _maxReceivedObjectSize);
                            }
                            else
                            {
                                e = new PSRemotingTransportException(PSRemotingErrorId.ReceivedObjectSizeExceededMaximumServer,
                                                                     RemotingErrorIdStrings.ReceivedObjectSizeExceededMaximumServer,
                                                                     _totalReceivedObjectSizeSoFar, _maxReceivedObjectSize);
                            }

                            ResetReceiveData();
                            throw e;
                        }
                    }

                    // appears like stream doesn't have individual position marker for read and write
                    // since we are going to read from now...
                    _pendingDataStream.Seek(0, SeekOrigin.Begin);

                    // we have enough data to process..so read the data from the stream and process.
                    byte[] oneFragment = new byte[totalLengthOfFragment];
                    // this will change position back to totalLengthOfFragment
                    int dataCount = _pendingDataStream.Read(oneFragment, 0, totalLengthOfFragment);
                    Dbg.Assert(dataCount == totalLengthOfFragment, "Unable to read enough data from the stream. Read failed");

                    PSEtwLog.LogAnalyticVerbose(
                        PSEventId.ReceivedRemotingFragment, PSOpcode.Receive, PSTask.None,
                        PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic,
                        (Int64)objectId,
                        (Int64)fragmentId,
                        sFlag ? 1 : 0,
                        eFlag ? 1 : 0,
                        (UInt32)blobLength,
                        new PSETWBinaryBlob(oneFragment, FragmentedRemoteObject.HeaderLength, blobLength));

                    byte[] extraData = null;
                    if (totalLengthOfFragment < _pendingDataStream.Length)
                    {
                        // there is more data in the stream than fragment size..so save that data
                        extraData = new byte[_pendingDataStream.Length - totalLengthOfFragment];
                        _pendingDataStream.Read(extraData, 0, (int)(_pendingDataStream.Length - totalLengthOfFragment));
                    }

                    // reset incoming stream.
                    _pendingDataStream.Dispose();
                    _pendingDataStream = new MemoryStream();
                    if (extraData != null)
                    {
                        _pendingDataStream.Write(extraData, 0, extraData.Length);
                    }

                    if (sFlag)
                    {
                        _canIgnoreOffSyncFragments = false; // reset this upon receiving a start fragment of a fresh object
                        _currentObjectId           = objectId;
                        // Memory streams created with an unsigned byte array provide a non-resizable stream view
                        // of the data, and can only be written to. When using a byte array, you can neither append
                        // to nor shrink the stream, although you might be able to modify the existing contents
                        // depending on the parameters passed into the constructor. Empty memory streams are
                        // resizable, and can be written to and read from.
                        _dataToProcessStream = new MemoryStream();
                    }
                    else
                    {
                        // check if the data belongs to the same object as the start fragment
                        if (objectId != _currentObjectId)
                        {
                            s_baseTracer.WriteLine("ObjectId != CurrentObjectId");
                            // TODO - drop an ETW event
                            ResetReceiveData();
                            if (!_canIgnoreOffSyncFragments)
                            {
                                PSRemotingTransportException e = new PSRemotingTransportException(RemotingErrorIdStrings.ObjectIdsNotMatching);
                                throw e;
                            }
                            else
                            {
                                s_baseTracer.WriteLine("Ignoring ObjectId != CurrentObjectId");
                                continue;
                            }
                        }

                        if (fragmentId != (_currentFrgId + 1))
                        {
                            s_baseTracer.WriteLine("Fragment Id is not in sequence.");
                            // TODO - drop an ETW event
                            ResetReceiveData();
                            if (!_canIgnoreOffSyncFragments)
                            {
                                PSRemotingTransportException e = new PSRemotingTransportException(RemotingErrorIdStrings.FragmentIdsNotInSequence);
                                throw e;
                            }
                            else
                            {
                                s_baseTracer.WriteLine("Ignoring Fragment Id is not in sequence.");
                                continue;
                            }
                        }
                    }

                    // make fragment id from this packet as the current fragment id
                    _currentFrgId = fragmentId;
                    // store the blob in a separate stream
                    _dataToProcessStream.Write(oneFragment, FragmentedRemoteObject.HeaderLength, blobLength);

                    if (eFlag)
                    {
                        try
                        {
                            // appears like stream doesn't individual position marker for read and write
                            // since we are going to read from now..i am resetting position to 0.
                            _dataToProcessStream.Seek(0, SeekOrigin.Begin);
                            RemoteDataObject <PSObject> remoteObject = RemoteDataObject <PSObject> .CreateFrom(_dataToProcessStream, _defragmentor);

                            s_baseTracer.WriteLine("Runspace Id: {0}", remoteObject.RunspacePoolId);
                            s_baseTracer.WriteLine("PowerShell Id: {0}", remoteObject.PowerShellId);
                            // notify the caller that a deserialized object is available.
                            callback(remoteObject);
                        }
                        finally
                        {
                            // Reset the receive data buffers and start the process again.
                            ResetReceiveData();
                        }

                        if (_isDisposed)
                        {
                            break;
                        }
                    }
                }
            }
            finally
            {
                lock (_syncObject)
                {
                    if (_isDisposed && (_numberOfThreadsProcessing == 1))
                    {
                        ReleaseResources();
                    }

                    _numberOfThreadsProcessing--;
                }
            }
        }
Beispiel #6
0
        internal void ProcessRawData(byte[] data, OnDataAvailableCallback callback)
        {
            lock (this.syncObject)
            {
                if (this.isDisposed)
                {
                    return;
                }
                this.numberOfThreadsProcessing++;
                int maxNumberOfThreadsToAllowForProcessing = this.maxNumberOfThreadsToAllowForProcessing;
                int numberOfThreadsProcessing = this.numberOfThreadsProcessing;
            }
            try
            {
                this.pendingDataStream.Write(data, 0, data.Length);
Label_005A:
                if (this.pendingDataStream.Length <= 0x15L)
                {
                    baseTracer.WriteLine(string.Format(CultureInfo.InvariantCulture, "Not enough data to process. Data is less than header length. Data length is {0}. Header Length {1}.", new object[] { this.pendingDataStream.Length, 0x15 }), new object[0]);
                }
                else
                {
                    byte[] fragmentBytes = this.pendingDataStream.GetBuffer();
                    long   objectId      = FragmentedRemoteObject.GetObjectId(fragmentBytes, 0);
                    if (objectId <= 0L)
                    {
                        throw new PSRemotingTransportException(RemotingErrorIdStrings.ObjectIdCannotBeLessThanZero);
                    }
                    long fragmentId      = FragmentedRemoteObject.GetFragmentId(fragmentBytes, 0);
                    bool isStartFragment = FragmentedRemoteObject.GetIsStartFragment(fragmentBytes, 0);
                    bool isEndFragment   = FragmentedRemoteObject.GetIsEndFragment(fragmentBytes, 0);
                    int  blobLength      = FragmentedRemoteObject.GetBlobLength(fragmentBytes, 0);
                    baseTracer.WriteLine(string.Format(CultureInfo.InvariantCulture, "Object Id: {0}", new object[] { objectId }), new object[0]);
                    baseTracer.WriteLine(string.Format(CultureInfo.InvariantCulture, "Fragment Id: {0}", new object[] { fragmentId }), new object[0]);
                    baseTracer.WriteLine(string.Format(CultureInfo.InvariantCulture, "Start Flag: {0}", new object[] { isStartFragment }), new object[0]);
                    baseTracer.WriteLine(string.Format(CultureInfo.InvariantCulture, "End Flag: {0}", new object[] { isEndFragment }), new object[0]);
                    baseTracer.WriteLine(string.Format(CultureInfo.InvariantCulture, "Blob Length: {0}", new object[] { blobLength }), new object[0]);
                    int count = 0;
                    try
                    {
                        count = 0x15 + blobLength;
                    }
                    catch (OverflowException)
                    {
                        baseTracer.WriteLine("Fragement too big.", new object[0]);
                        this.ResetRecieveData();
                        PSRemotingTransportException exception = new PSRemotingTransportException(RemotingErrorIdStrings.ObjectIsTooBig);
                        throw exception;
                    }
                    if (this.pendingDataStream.Length < count)
                    {
                        baseTracer.WriteLine(string.Format(CultureInfo.InvariantCulture, "Not enough data to process packet. Data is less than expected blob length. Data length {0}. Expected Length {1}.", new object[] { this.pendingDataStream.Length, count }), new object[0]);
                    }
                    else
                    {
                        if (this.maxReceivedObjectSize.HasValue)
                        {
                            this.totalReceivedObjectSizeSoFar += count;
                            if ((this.totalReceivedObjectSizeSoFar < 0) || (this.totalReceivedObjectSizeSoFar > this.maxReceivedObjectSize.Value))
                            {
                                baseTracer.WriteLine("ObjectSize > MaxReceivedObjectSize. ObjectSize is {0}. MaxReceivedObjectSize is {1}", new object[] { this.totalReceivedObjectSizeSoFar, this.maxReceivedObjectSize });
                                PSRemotingTransportException exception2 = null;
                                if (this.isCreateByClientTM)
                                {
                                    exception2 = new PSRemotingTransportException(PSRemotingErrorId.ReceivedObjectSizeExceededMaximumClient, RemotingErrorIdStrings.ReceivedObjectSizeExceededMaximumClient, new object[] { this.totalReceivedObjectSizeSoFar, this.maxReceivedObjectSize });
                                }
                                else
                                {
                                    exception2 = new PSRemotingTransportException(PSRemotingErrorId.ReceivedObjectSizeExceededMaximumServer, RemotingErrorIdStrings.ReceivedObjectSizeExceededMaximumServer, new object[] { this.totalReceivedObjectSizeSoFar, this.maxReceivedObjectSize });
                                }
                                this.ResetRecieveData();
                                throw exception2;
                            }
                        }
                        this.pendingDataStream.Seek(0L, SeekOrigin.Begin);
                        byte[] buffer = new byte[count];
                        this.pendingDataStream.Read(buffer, 0, count);
                        PSEtwLog.LogAnalyticVerbose(PSEventId.ReceivedRemotingFragment, PSOpcode.Receive, PSTask.None, PSKeyword.Transport | PSKeyword.UseAlwaysAnalytic, objectId, fragmentId, isStartFragment ? 1 : 0, isEndFragment ? 1 : 0, (int)blobLength, new PSETWBinaryBlob(buffer, 0x15, blobLength));
                        byte[] buffer3 = null;
                        if (count < this.pendingDataStream.Length)
                        {
                            buffer3 = new byte[this.pendingDataStream.Length - count];
                            this.pendingDataStream.Read(buffer3, 0, ((int)this.pendingDataStream.Length) - count);
                        }
                        this.pendingDataStream.Close();
                        this.pendingDataStream = new MemoryStream();
                        if (buffer3 != null)
                        {
                            this.pendingDataStream.Write(buffer3, 0, buffer3.Length);
                        }
                        if (isStartFragment)
                        {
                            this.canIgnoreOffSyncFragments = false;
                            this.currentObjectId           = objectId;
                            this.dataToProcessStream       = new MemoryStream();
                        }
                        else
                        {
                            if (objectId != this.currentObjectId)
                            {
                                baseTracer.WriteLine("ObjectId != CurrentObjectId", new object[0]);
                                this.ResetRecieveData();
                                if (!this.canIgnoreOffSyncFragments)
                                {
                                    PSRemotingTransportException exception3 = new PSRemotingTransportException(RemotingErrorIdStrings.ObjectIdsNotMatching);
                                    throw exception3;
                                }
                                baseTracer.WriteLine("Ignoring ObjectId != CurrentObjectId", new object[0]);
                                goto Label_005A;
                            }
                            if (fragmentId != (this.currentFrgId + 1L))
                            {
                                baseTracer.WriteLine("Fragment Id is not in sequence.", new object[0]);
                                this.ResetRecieveData();
                                if (!this.canIgnoreOffSyncFragments)
                                {
                                    PSRemotingTransportException exception4 = new PSRemotingTransportException(RemotingErrorIdStrings.FragmetIdsNotInSequence);
                                    throw exception4;
                                }
                                baseTracer.WriteLine("Ignoring Fragment Id is not in sequence.", new object[0]);
                                goto Label_005A;
                            }
                        }
                        this.currentFrgId = fragmentId;
                        this.dataToProcessStream.Write(buffer, 0x15, blobLength);
                        if (!isEndFragment)
                        {
                            goto Label_005A;
                        }
                        try
                        {
                            this.dataToProcessStream.Seek(0L, SeekOrigin.Begin);
                            RemoteDataObject <PSObject> obj2 = RemoteDataObject <PSObject> .CreateFrom(this.dataToProcessStream, this.defragmentor);

                            baseTracer.WriteLine(string.Format(CultureInfo.InvariantCulture, "Runspace Id: {0}", new object[] { obj2.RunspacePoolId }), new object[0]);
                            baseTracer.WriteLine(string.Format(CultureInfo.InvariantCulture, "PowerShell Id: {0}", new object[] { obj2.PowerShellId }), new object[0]);
                            callback(obj2);
                        }
                        finally
                        {
                            this.ResetRecieveData();
                        }
                        if (!this.isDisposed && this.pendingDataStream.Length > 0x15L)
                        {
                            goto Label_005A;
                        }
                    }
                }
            }
            finally
            {
                lock (this.syncObject)
                {
                    if (this.isDisposed && (this.numberOfThreadsProcessing == 1))
                    {
                        this.ReleaseResources();
                    }
                    this.numberOfThreadsProcessing--;
                }
            }
        }
        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();
        }