internal void Bind(TdsParserStateObject stateObj)
 {
     stateObj.Owner = this;
     this._stateObj = stateObj;
     this._parser = stateObj.Parser;
     this._defaultLCID = this._parser.DefaultLCID;
 }
Beispiel #2
0
        public void Close()
        {
            // this method will actually close the internal connection and dipose it, this
            // should only be called by a non-pooled sqlconnection, or by the object pooler
            // when it deems an object should be destroyed

            // it's possible to have a connection finalizer, internal connection finalizer,
            // and the object pool destructor calling this method at the same time, so
            // we need to provide some synchronization
            if (_fConnectionOpen)
            {
                if (Interlocked.CompareExchange(ref _lock, 1, 0) == 0)
                {
                    if (_fConnectionOpen)
                    {
                        if (_fIsPooled)
                        {
                            // PerfCounters - on close of pooled connection, decrement count
                            SQL.DecrementPooledConnectionCount();
                        }

                        try {
                            try {
                                _parser.Disconnect();

                                // UNDONE: GC.SuppressFinalize causes a permission demand?
                                //GC.SuppressFinalize(_parser);
                            }
                            finally { // _connectionWeakRef=
                                // close will always close, even if exception is thrown
                                // remember to null out any object references
                                _connectionWeakRef = null;
                                _connectionOptions = null;
                                _parser            = null;
                                _loginAck          = null;
                                _fConnectionOpen   = false;  // mark internal connection as closed
                                _fUsableState      = false;  // mark internal connection as unusable
                                _pool              = null;
                                _dtcAddress        = null;
                                _transactionGuid   = Guid.Empty;
                                _transactionExport = null;

                                // always release the lock
                                //Interlocked.CompareExchange(ref _lock, 0, 1);
                                _lock = 0;
                            }
                        }
                        catch { // MDAC 80973
                            throw;
                        }
                    }
                    else
                    {
                        // release lock in case where connection already closed
                        //Interlocked.CompareExchange(ref _lock, 0, 1);
                        _lock = 0;
                    }
                }
            }
        }
        private int _freeStateObjectCount;                   // Number of available free sessions

        internal TdsParserSessionPool(TdsParser parser)
        {
            _parser               = parser;
            _cache                = new List <TdsParserStateObject>();
            _freeStateObjects     = new TdsParserStateObject[MaxInactiveCount];
            _freeStateObjectCount = 0;
        }
        internal SqlCachedBuffer(SqlMetaDataPriv metadata, TdsParser parser, TdsParserStateObject stateObj)
        {
            int len = 0;

            this._cachedBytes = new ArrayList();
            ulong num = parser.PlpBytesLeft(stateObj);

            do
            {
                if (num == 0L)
                {
                    return;
                }
                do
                {
                    len = (num > 0x800L) ? 0x800 : ((int)num);
                    byte[] buff = new byte[len];
                    len = stateObj.ReadPlpBytes(ref buff, 0, len);
                    if (this._cachedBytes.Count == 0)
                    {
                        this.AddByteOrderMark(buff);
                    }
                    this._cachedBytes.Add(buff);
                    num -= len;
                }while (num > 0L);
                num = parser.PlpBytesLeft(stateObj);
            }while (num > 0L);
        }
 internal SqlCachedBuffer(SqlMetaDataPriv metadata, TdsParser parser, TdsParserStateObject stateObj)
 {
     int len = 0;
     this._cachedBytes = new ArrayList();
     ulong num = parser.PlpBytesLeft(stateObj);
     do
     {
         if (num == 0L)
         {
             return;
         }
         do
         {
             len = (num > 0x800L) ? 0x800 : ((int) num);
             byte[] buff = new byte[len];
             len = stateObj.ReadPlpBytes(ref buff, 0, len);
             if (this._cachedBytes.Count == 0)
             {
                 this.AddByteOrderMark(buff);
             }
             this._cachedBytes.Add(buff);
             num -= len;
         }
         while (num > 0L);
         num = parser.PlpBytesLeft(stateObj);
     }
     while (num > 0L);
 }
        private int _freeStateObjectCount; // Number of available free sessions

        internal TdsParserSessionPool(TdsParser parser)
        {
            _parser = parser;
            _cache = new List<TdsParserStateObject>();
            _freeStateObjects = new TdsParserStateObject[MaxInactiveCount];
            _freeStateObjectCount = 0;
        }
Beispiel #7
0
        private void OpenAndLogin()
        {
            // Open the connection and Login
            try {
                int timeout = _connectionOptions.ConnectTimeout;

                _parser = new TdsParser();
                timeout = _parser.Connect(_connectionOptions.DataSource,
                                          _connectionOptions.NetworkLibrary,
                                          this,
                                          timeout,
                                          _connectionOptions.Encrypt);

                this.Login(timeout);

                _fConnectionOpen = true; // mark connection as open
            }
            catch (Exception e) {
                ADP.TraceException(e);

                // If the parser was allocated and we failed, then we must have failed on
                // either the Connect or Login, either way we should call Disconnect.
                // Disconnect can be called if the connection is already closed - becomes
                // no-op, so no issues there.
                if (_parser != null)
                {
                    _parser.Disconnect();
                }

                throw e;
            }
        }
Beispiel #8
0
 static internal void BestEffortCleanup(TdsParser target)
 {
     if (null != target)
     {
         target.BestEffortCleanup();
     }
 }
        ////////////////////////////////////////////////////////////////////////////////////////
        // PUBLIC METHODS
        ////////////////////////////////////////////////////////////////////////////////////////

        override public void Commit()
        {
            SqlConnection.ExecutePermission.Demand(); // MDAC 81476

            ZombieCheck();

            SqlStatistics statistics = null;
            IntPtr        hscp;

            Bid.ScopeEnter(out hscp, "<sc.SqlTransaction.Commit|API> %d#", ObjectID);
            Bid.CorrelationTrace("<sc.SqlTransaction.Commit|API|Correlation> ObjectID%d#, ActivityID %ls", ObjectID);

            TdsParser bestEffortCleanupTarget = null;

            RuntimeHelpers.PrepareConstrainedRegions();
            try {
#if DEBUG
                TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection();

                RuntimeHelpers.PrepareConstrainedRegions();
                try {
                    tdsReliabilitySection.Start();
#else
                {
#endif //DEBUG
                    bestEffortCleanupTarget = SqlInternalConnection.GetBestEffortCleanupTarget(_connection);
                    statistics = SqlStatistics.StartTimer(Statistics);

                    _isFromAPI = true;

                    _internalTransaction.Commit();
                }
#if DEBUG
                finally {
                    tdsReliabilitySection.Stop();
                }
#endif //DEBUG
            }
            catch (System.OutOfMemoryException e) {
                _connection.Abort(e);
                throw;
            }
            catch (System.StackOverflowException e) {
                _connection.Abort(e);
                throw;
            }
            catch (System.Threading.ThreadAbortException e)  {
                _connection.Abort(e);
                SqlInternalConnection.BestEffortCleanup(bestEffortCleanupTarget);
                throw;
            }
            finally {
                _isFromAPI = false;

                SqlStatistics.StopTimer(statistics);
                Bid.ScopeLeave(ref hscp);
            }
        }
Beispiel #10
0
        internal override void DisconnectTransaction(SqlInternalTransaction internalTransaction)
        {
            TdsParser parser = this.Parser;

            if (parser != null)
            {
                parser.DisconnectTransaction(internalTransaction);
            }
        }
 private int                                 _freeStateObjectCount; // Number of available free sessions
 
 internal TdsParserSessionPool(TdsParser parser) {
     _parser = parser;
     _cache  = new List<TdsParserStateObject>();
     _freeStateObjects = new TdsParserStateObject[MaxInactiveCount];
     _freeStateObjectCount = 0;
     if (Bid.AdvancedOn) {
         Bid.Trace("<sc.TdsParserSessionPool.ctor|ADV> %d# created session pool for parser %d\n", ObjectID, parser.ObjectID);
     }
 }
 internal TdsParserSessionPool(TdsParser parser)
 {
     this._parser = parser;
     this._cache = new List<TdsParserStateObject>();
     this._freeStack = new TdsParserStateObjectListStack();
     if (Bid.AdvancedOn)
     {
         Bid.Trace("<sc.TdsParserSessionPool.ctor|ADV> %d# created session pool for parser %d\n", this.ObjectID, parser.ObjectID);
     }
 }
 internal TdsParserSessionPool(TdsParser parser)
 {
     this._parser    = parser;
     this._cache     = new List <TdsParserStateObject>();
     this._freeStack = new TdsParserStateObjectListStack();
     if (Bid.AdvancedOn)
     {
         Bid.Trace("<sc.TdsParserSessionPool.ctor|ADV> %d# created session pool for parser %d\n", this.ObjectID, parser.ObjectID);
     }
 }
Beispiel #14
0
 internal TdsParserStateObject CreateSessionObject(TdsParser tdsParser, TdsParserStateObject _pMarsPhysicalConObj, bool v)
 {
     if (TdsParserStateObjectFactory.UseManagedSNI)
     {
         return(new TdsParserStateObjectManaged(tdsParser, _pMarsPhysicalConObj, true));
     }
     else
     {
         return(new TdsParserStateObjectNative(tdsParser, _pMarsPhysicalConObj, true));
     }
 }
Beispiel #15
0
 public TdsParserStateObject CreateTdsParserStateObject(TdsParser parser)
 {
     if (UseManagedSNI)
     {
         return(new TdsParserStateObjectManaged(parser));
     }
     else
     {
         return(new TdsParserStateObjectNative(parser));
     }
 }
        private int _freeStateObjectCount;                             // Number of available free sessions

        internal TdsParserSessionPool(TdsParser parser)
        {
            _parser               = parser;
            _cache                = new List <TdsParserStateObject>();
            _freeStateObjects     = new TdsParserStateObject[MaxInactiveCount];
            _freeStateObjectCount = 0;
            if (Bid.AdvancedOn)
            {
                Bid.Trace("<sc.TdsParserSessionPool.ctor|ADV> %d# created session pool for parser %d\n", ObjectID, parser.ObjectID);
            }
        }
Beispiel #17
0
        static public void DeriveParameters(SqlCommand command)   // MDAC 65927\
        {
            SqlConnection.ExecutePermission.Demand();

            if (null == command)
            {
                throw ADP.ArgumentNull("command");
            }
            TdsParser bestEffortCleanupTarget = null;

            RuntimeHelpers.PrepareConstrainedRegions();
            try {
#if DEBUG
                TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection();

                RuntimeHelpers.PrepareConstrainedRegions();
                try {
                    tdsReliabilitySection.Start();
#else
                {
#endif
                    bestEffortCleanupTarget = SqlInternalConnection.GetBestEffortCleanupTarget(command.Connection);
                    command.DeriveParameters();
                }
#if DEBUG
                finally {
                    tdsReliabilitySection.Stop();
                }
#endif
            }
            catch (System.OutOfMemoryException e) {
                if (null != command && null != command.Connection)
                {
                    command.Connection.Abort(e);
                }
                throw;
            }
            catch (System.StackOverflowException e) {
                if (null != command && null != command.Connection)
                {
                    command.Connection.Abort(e);
                }
                throw;
            }
            catch (System.Threading.ThreadAbortException e)  {
                if (null != command && null != command.Connection)
                {
                    command.Connection.Abort(e);
                }
                SqlInternalConnection.BestEffortCleanup(bestEffortCleanupTarget);
                throw;
            }
        }
 internal TdsParserStateObject(TdsParser parser)
 {
     this._objectID = Interlocked.Increment(ref _objectTypeCount);
     this._owner = new WeakReference(null);
     this._inputHeaderLen = 8;
     this._outputHeaderLen = 8;
     this._outBytesUsed = 8;
     this._outputPacketNumber = 1;
     this._bTmp = new byte[12];
     this._parser = parser;
     this.SetPacketSize(0x1000);
     this.IncrementPendingCallbacks();
 }
Beispiel #19
0
        // Reads off from the network buffer and caches bytes. Only reads one column value in the current row.
        internal static bool TryCreate(SqlMetaDataPriv metadata, TdsParser parser, TdsParserStateObject stateObj, out SqlCachedBuffer buffer)
        {
            int   cb = 0;
            ulong plplength;

            byte[] byteArr;

            List <byte[]> cachedBytes = new List <byte[]>();

            buffer = null;

            // the very first length is already read.
            if (!parser.TryPlpBytesLeft(stateObj, out plplength))
            {
                return(false);
            }
            // For now we  only handle Plp data from the parser directly.
            Debug.Assert(metadata.metaType.IsPlp, "SqlCachedBuffer call on a non-plp data");
            do
            {
                if (plplength == 0)
                {
                    break;
                }
                do
                {
                    cb      = (plplength > (ulong)_maxChunkSize) ? _maxChunkSize : (int)plplength;
                    byteArr = new byte[cb];
                    if (!stateObj.TryReadPlpBytes(ref byteArr, 0, cb, out cb))
                    {
                        return(false);
                    }
                    Debug.Assert(cb == byteArr.Length);
                    if (cachedBytes.Count == 0)
                    {
                        // Add the Byte order mark if needed if we read the first array
                        AddByteOrderMark(byteArr, cachedBytes);
                    }
                    cachedBytes.Add(byteArr);
                    plplength -= (ulong)cb;
                } while (plplength > 0);
                if (!parser.TryPlpBytesLeft(stateObj, out plplength))
                {
                    return(false);
                }
            } while (plplength > 0);
            Debug.Assert(stateObj._longlen == 0 && stateObj._longlenleft == 0);

            buffer = new SqlCachedBuffer(cachedBytes);
            return(true);
        }
 internal static SNIHandle GetBestEffortCleanupTarget(SqlConnection connection)
 {
     if (connection != null)
     {
         SqlInternalConnectionTds innerConnection = connection.InnerConnection as SqlInternalConnectionTds;
         if (innerConnection != null)
         {
             TdsParser parser = innerConnection.Parser;
             if (parser != null)
             {
                 return(parser.GetBestEffortCleanupTarget());
             }
         }
     }
     return(null);
 }
Beispiel #21
0
        // Reads off from the network buffer and caches bytes. Only reads one column value in the current row.
        static internal bool TryCreate(SqlMetaDataPriv metadata, TdsParser parser, TdsParserStateObject stateObj, out SqlCachedBuffer buffer)
        {
            int cb = 0;
            ulong plplength;
            byte[] byteArr;

            List<byte[]> cachedBytes = new List<byte[]>();
            buffer = null;

            // the very first length is already read.
            if (!parser.TryPlpBytesLeft(stateObj, out plplength))
            {
                return false;
            }
            // For now we  only handle Plp data from the parser directly.
            Debug.Assert(metadata.metaType.IsPlp, "SqlCachedBuffer call on a non-plp data");
            do
            {
                if (plplength == 0)
                    break;
                do
                {
                    cb = (plplength > (ulong)_maxChunkSize) ? _maxChunkSize : (int)plplength;
                    byteArr = new byte[cb];
                    if (!stateObj.TryReadPlpBytes(ref byteArr, 0, cb, out cb))
                    {
                        return false;
                    }
                    Debug.Assert(cb == byteArr.Length);
                    if (cachedBytes.Count == 0)
                    {
                        // Add the Byte order mark if needed if we read the first array
                        AddByteOrderMark(byteArr, cachedBytes);
                    }
                    cachedBytes.Add(byteArr);
                    plplength -= (ulong)cb;
                } while (plplength > 0);
                if (!parser.TryPlpBytesLeft(stateObj, out plplength))
                {
                    return false;
                }
            } while (plplength > 0);
            Debug.Assert(stateObj._longlen == 0 && stateObj._longlenleft == 0);

            buffer = new SqlCachedBuffer(cachedBytes);
            return true;
        }
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                TdsParser bestEffortCleanupTarget = null;
                RuntimeHelpers.PrepareConstrainedRegions();
                try {
#if DEBUG
                    TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection();

                    RuntimeHelpers.PrepareConstrainedRegions();
                    try {
                        tdsReliabilitySection.Start();
#else
                    {
#endif //DEBUG
                        bestEffortCleanupTarget = SqlInternalConnection.GetBestEffortCleanupTarget(_connection);
                        if (!IsZombied && !IsYukonPartialZombie)
                        {
                            _internalTransaction.Dispose();
                        }
                    }
#if DEBUG
                    finally {
                        tdsReliabilitySection.Stop();
                    }
#endif //DEBUG
                }
                catch (System.OutOfMemoryException e) {
                    _connection.Abort(e);
                    throw;
                }
                catch (System.StackOverflowException e) {
                    _connection.Abort(e);
                    throw;
                }
                catch (System.Threading.ThreadAbortException e)  {
                    _connection.Abort(e);
                    SqlInternalConnection.BestEffortCleanup(bestEffortCleanupTarget);
                    throw;
                }
            }
            base.Dispose(disposing);
        }
Beispiel #23
0
 public override void Dispose()
 {
     if (Bid.AdvancedOn)
     {
         Bid.Trace("<sc.SqlInternalConnectionTds.Dispose|ADV> %d# disposing\n", base.ObjectID);
     }
     try
     {
         TdsParser parser = Interlocked.Exchange <TdsParser>(ref this._parser, null);
         if (parser != null)
         {
             parser.Disconnect();
         }
     }
     finally
     {
         this._loginAck        = null;
         this._fConnectionOpen = false;
     }
     base.Dispose();
 }
 internal TdsParserStateObject(TdsParser parser, SNIHandle physicalConnection, bool async)
 {
     this._objectID = Interlocked.Increment(ref _objectTypeCount);
     this._owner = new WeakReference(null);
     this._inputHeaderLen = 8;
     this._outputHeaderLen = 8;
     this._outBytesUsed = 8;
     this._outputPacketNumber = 1;
     this._bTmp = new byte[12];
     this._parser = parser;
     this.SniContext = System.Data.SqlClient.SniContext.Snix_GetMarsSession;
     this.SetPacketSize(this._parser._physicalStateObj._outBuff.Length);
     SNINativeMethodWrapper.ConsumerInfo myInfo = this.CreateConsumerInfo(async);
     this._sessionHandle = new SNIHandle(myInfo, "session:", physicalConnection);
     if (this._sessionHandle.Status != 0)
     {
         parser.Errors.Add(parser.ProcessSNIError(this));
         parser.ThrowExceptionAndWarning();
     }
     this.IncrementPendingCallbacks();
 }
 private void Dispose(bool disposing)
 {
     if (disposing)
     {
         this._columnMappings = null;
         this._parser         = null;
         try
         {
             if (this._internalTransaction != null)
             {
                 this._internalTransaction.Rollback();
                 this._internalTransaction.Dispose();
                 this._internalTransaction = null;
             }
         }
         catch (Exception exception)
         {
             if (!ADP.IsCatchableExceptionType(exception))
             {
                 throw;
             }
             ADP.TraceExceptionWithoutRethrow(exception);
         }
         finally
         {
             if (this._connection != null)
             {
                 if (this._ownConnection)
                 {
                     this._connection.Dispose();
                 }
                 this._connection = null;
             }
         }
     }
 }
        override public void Rollback()
        {
            if (IsYukonPartialZombie)
            {
                // Put something in the trace in case a customer has an issue
                if (Bid.AdvancedOn)
                {
                    Bid.Trace("<sc.SqlTransaction.Rollback|ADV> %d# partial zombie no rollback required\n", ObjectID);
                }
                _internalTransaction = null; // yukon zombification
            }
            else
            {
                ZombieCheck();

                SqlStatistics statistics = null;
                IntPtr        hscp;
                Bid.ScopeEnter(out hscp, "<sc.SqlTransaction.Rollback|API> %d#", ObjectID);
                Bid.CorrelationTrace("<sc.SqlTransaction.Rollback|API|Correlation> ObjectID%d#, ActivityID %ls\n", ObjectID);

                TdsParser bestEffortCleanupTarget = null;
                RuntimeHelpers.PrepareConstrainedRegions();
                try {
#if DEBUG
                    TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection();

                    RuntimeHelpers.PrepareConstrainedRegions();
                    try {
                        tdsReliabilitySection.Start();
#else
                    {
#endif //DEBUG
                        bestEffortCleanupTarget = SqlInternalConnection.GetBestEffortCleanupTarget(_connection);
                        statistics = SqlStatistics.StartTimer(Statistics);

                        _isFromAPI = true;

                        _internalTransaction.Rollback();
                    }
#if DEBUG
                    finally {
                        tdsReliabilitySection.Stop();
                    }
#endif //DEBUG
                }
                catch (System.OutOfMemoryException e) {
                    _connection.Abort(e);
                    throw;
                }
                catch (System.StackOverflowException e) {
                    _connection.Abort(e);
                    throw;
                }
                catch (System.Threading.ThreadAbortException e)  {
                    _connection.Abort(e);
                    SqlInternalConnection.BestEffortCleanup(bestEffortCleanupTarget);
                    throw;
                }
                finally {
                    _isFromAPI = false;

                    SqlStatistics.StopTimer(statistics);
                    Bid.ScopeLeave(ref hscp);
                }
            }
        }
Beispiel #27
0
        internal void ExecuteTransactionYukon(SqlInternalConnection.TransactionRequest transactionRequest, string transactionName, System.Data.IsolationLevel iso, SqlInternalTransaction internalTransaction, bool isDelegateControlRequest)
        {
            TdsEnums.TransactionManagerRequestType    begin         = TdsEnums.TransactionManagerRequestType.Begin;
            TdsEnums.TransactionManagerIsolationLevel readCommitted = TdsEnums.TransactionManagerIsolationLevel.ReadCommitted;
            switch (iso)
            {
            case System.Data.IsolationLevel.Unspecified:
                readCommitted = TdsEnums.TransactionManagerIsolationLevel.Unspecified;
                break;

            case System.Data.IsolationLevel.Chaos:
                throw SQL.NotSupportedIsolationLevel(iso);

            case System.Data.IsolationLevel.ReadUncommitted:
                readCommitted = TdsEnums.TransactionManagerIsolationLevel.ReadUncommitted;
                break;

            case System.Data.IsolationLevel.Serializable:
                readCommitted = TdsEnums.TransactionManagerIsolationLevel.Serializable;
                break;

            case System.Data.IsolationLevel.Snapshot:
                readCommitted = TdsEnums.TransactionManagerIsolationLevel.Snapshot;
                break;

            case System.Data.IsolationLevel.ReadCommitted:
                readCommitted = TdsEnums.TransactionManagerIsolationLevel.ReadCommitted;
                break;

            case System.Data.IsolationLevel.RepeatableRead:
                readCommitted = TdsEnums.TransactionManagerIsolationLevel.RepeatableRead;
                break;

            default:
                throw ADP.InvalidIsolationLevel(iso);
            }
            TdsParserStateObject session = this._parser._physicalStateObj;
            TdsParser            parser  = this._parser;
            bool flag      = false;
            bool lockTaken = false;

            try
            {
                switch (transactionRequest)
                {
                case SqlInternalConnection.TransactionRequest.Begin:
                    begin = TdsEnums.TransactionManagerRequestType.Begin;
                    break;

                case SqlInternalConnection.TransactionRequest.Promote:
                    begin = TdsEnums.TransactionManagerRequestType.Promote;
                    break;

                case SqlInternalConnection.TransactionRequest.Commit:
                    begin = TdsEnums.TransactionManagerRequestType.Commit;
                    break;

                case SqlInternalConnection.TransactionRequest.Rollback:
                case SqlInternalConnection.TransactionRequest.IfRollback:
                    begin = TdsEnums.TransactionManagerRequestType.Rollback;
                    break;

                case SqlInternalConnection.TransactionRequest.Save:
                    begin = TdsEnums.TransactionManagerRequestType.Save;
                    break;
                }
                if ((internalTransaction != null) && internalTransaction.IsDelegated)
                {
                    if (!this._parser.MARSOn)
                    {
                        if (internalTransaction.OpenResultsCount != 0)
                        {
                            throw SQL.CannotCompleteDelegatedTransactionWithOpenResults();
                        }
                        Monitor.Enter(session, ref lockTaken);
                        if (internalTransaction.OpenResultsCount != 0)
                        {
                            throw SQL.CannotCompleteDelegatedTransactionWithOpenResults();
                        }
                    }
                    else
                    {
                        session = this._parser.GetSession(this);
                        flag    = true;
                    }
                }
                this._parser.TdsExecuteTransactionManagerRequest(null, begin, transactionName, readCommitted, base.ConnectionOptions.ConnectTimeout, internalTransaction, session, isDelegateControlRequest);
            }
            finally
            {
                if (flag)
                {
                    parser.PutSession(session);
                }
                if (lockTaken)
                {
                    Monitor.Exit(session);
                }
            }
        }
        private readonly Dictionary <IntPtr, SNIPacket> _pendingWritePackets = new Dictionary <IntPtr, SNIPacket>(); // Stores write packets that have been sent to SNI, but have not yet finished writing (i.e. we are waiting for SNI's callback)

        internal TdsParserStateObjectNative(TdsParser parser, TdsParserStateObject physicalConnection, bool async) :
            base(parser, physicalConnection, async)
        {
        }
Beispiel #29
0
 public TdsOutputStream(TdsParser parser, TdsParserStateObject stateObj, byte[] preambleToStrip)
 {
     _parser = parser;
     _stateObj = stateObj;
     _preambleToStrip = preambleToStrip;
 }
 internal TdsParserStateObject CreateSessionObject(TdsParser tdsParser, TdsParserStateObject _pMarsPhysicalConObj, bool v)
 {
     return(new TdsParserStateObjectManaged(tdsParser, _pMarsPhysicalConObj, true));
 }
Beispiel #31
0
#pragma warning restore 0649
#endif

        //////////////////
        // Constructors //
        //////////////////

        internal TdsParserStateObject(TdsParser parser)
        {
            // Construct a physical connection
            Debug.Assert(null != parser, "no parser?");
            _parser = parser;

            // For physical connection, initialize to default login packet size.
            SetPacketSize(TdsEnums.DEFAULT_LOGIN_PACKET_SIZE);

            // we post a callback that represents the call to dispose; once the
            // object is disposed, the next callback will cause the GC Handle to
            // be released.
            IncrementPendingCallbacks();
            _lastSuccessfulIOTimer = new LastIOTimer();
        }
    // Attempt to login to a host that does not have a failover partner
    //
    //  Will repeatedly attempt to connect, but back off between each attempt so as not to clog the network.
    //  Back off period increases for first few failures: 100ms, 200ms, 400ms, 800ms, then 1000ms for subsequent attempts
    //
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    //  DEVNOTE: The logic in this method is paralleled by the logic in LoginWithFailover.
    //           Changes to either one should be examined to see if they need to be reflected in the other
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    private void LoginNoFailover(ServerInfo serverInfo, string newPassword, SecureString newSecurePassword, bool redirectedUserInstance, 
                SqlConnectionString connectionOptions, SqlCredential credential, TimeoutTimer timeout) {

        Debug.Assert(object.ReferenceEquals(connectionOptions, this.ConnectionOptions), "ConnectionOptions argument and property must be the same"); // consider removing the argument
        int routingAttempts = 0;
        ServerInfo originalServerInfo = serverInfo; // serverInfo may end up pointing to new object due to routing, original object is used to set CurrentDatasource

        if (Bid.AdvancedOn) {
            Bid.Trace("<sc.SqlInternalConnectionTds.LoginNoFailover|ADV> %d#, host=%ls\n", ObjectID, serverInfo.UserServerName);
        }
        int  sleepInterval = 100;  //milliseconds to sleep (back off) between attempts.

        ResolveExtendedServerName(serverInfo, !redirectedUserInstance, connectionOptions);

        long timeoutUnitInterval = 0;
        Boolean isParallel = connectionOptions.MultiSubnetFailover || connectionOptions.TransparentNetworkIPResolution;

        if(isParallel) {
            // Determine unit interval
            if (timeout.IsInfinite) {
                timeoutUnitInterval = checked((long)(ADP.FailoverTimeoutStep * (1000L * ADP.DefaultConnectionTimeout)));
            }
            else {
                timeoutUnitInterval = checked((long)(ADP.FailoverTimeoutStep * timeout.MillisecondsRemaining));
            }
        }
        // Only three ways out of this loop:
        //  1) Successfully connected
        //  2) Parser threw exception while main timer was expired
        //  3) Parser threw logon failure-related exception 
        //  4) Parser threw exception in post-initial connect code,
        //      such as pre-login handshake or during actual logon. (parser state != Closed)
        //
        //  Of these methods, only #1 exits normally. This preserves the call stack on the exception 
        //  back into the parser for the error cases.
        int attemptNumber = 0;
        TimeoutTimer intervalTimer = null;
        TimeoutTimer firstTransparentAttemptTimeout = TimeoutTimer.StartMillisecondsTimeout(ADP.FirstTransparentAttemptTimeout);
        TimeoutTimer attemptOneLoginTimeout = timeout;
        while(true) {

            if(isParallel) {
                attemptNumber++;
                // Set timeout for this attempt, but don't exceed original timer                
                long nextTimeoutInterval = checked(timeoutUnitInterval * attemptNumber);
                long milliseconds = timeout.MillisecondsRemaining;
                if (nextTimeoutInterval > milliseconds) {
                    nextTimeoutInterval = milliseconds;
                }
                intervalTimer = TimeoutTimer.StartMillisecondsTimeout(nextTimeoutInterval);
            }

            // Re-allocate parser each time to make sure state is known
            // RFC 50002652 - if parser was created by previous attempt, dispose it to properly close the socket, if created
            if (_parser != null)
                _parser.Disconnect();
 
            _parser = new TdsParser(ConnectionOptions.MARS, ConnectionOptions.Asynchronous);
            Debug.Assert(SniContext.Undefined== Parser._physicalStateObj.SniContext, String.Format((IFormatProvider)null, "SniContext should be Undefined; actual Value: {0}", Parser._physicalStateObj.SniContext));

            try {
                // 


                Boolean isFirstTransparentAttempt =  connectionOptions.TransparentNetworkIPResolution && attemptNumber == 1;

                if(isFirstTransparentAttempt) {
                    attemptOneLoginTimeout = firstTransparentAttemptTimeout;
                }
                else {
                    if(isParallel) {
                        attemptOneLoginTimeout = intervalTimer;
                    }
                }
                
                AttemptOneLogin(    serverInfo, 
                                    newPassword,
                                    newSecurePassword,
                                    !isParallel,    // ignore timeout for SniOpen call unless MSF , and TNIR
                                    attemptOneLoginTimeout,
                                    isFirstTransparentAttempt:isFirstTransparentAttempt);
                
                if (connectionOptions.MultiSubnetFailover && null != ServerProvidedFailOverPartner) {
                    // connection succeeded: trigger exception if server sends failover partner and MultiSubnetFailover is used.
                    throw SQL.MultiSubnetFailoverWithFailoverPartner(serverProvidedFailoverPartner: true, internalConnection: this);
                }

                if (_routingInfo != null) {
                    Bid.Trace("<sc.SqlInternalConnectionTds.LoginNoFailover> Routed to %ls", serverInfo.ExtendedServerName);

                    if (routingAttempts > 0) {
                        throw SQL.ROR_RecursiveRoutingNotSupported(this);
                    }

                    if (timeout.IsExpired) {
                        throw SQL.ROR_TimeoutAfterRoutingInfo(this);
                    }                    

                    serverInfo = new ServerInfo(ConnectionOptions, _routingInfo, serverInfo.ResolvedServerName);
                    timeoutErrorInternal.SetInternalSourceType(SqlConnectionInternalSourceType.RoutingDestination);
                    _originalClientConnectionId = _clientConnectionId;
                    _routingDestination = serverInfo.UserServerName;

                    // restore properties that could be changed by the environment tokens
                    _currentPacketSize = ConnectionOptions.PacketSize;
                    _currentLanguage = _originalLanguage = ConnectionOptions.CurrentLanguage;
                    CurrentDatabase = _originalDatabase = ConnectionOptions.InitialCatalog;
                    _currentFailoverPartner = null;
                    _instanceName = String.Empty;

                    routingAttempts++;

                    continue; // repeat the loop, but skip code reserved for failed connections (after the catch)
                }
                else {
                    break; // leave the while loop -- we've successfully connected
                }
            }
            catch (SqlException sqlex) {
                if (null == _parser
                    || TdsParserState.Closed != _parser.State
                    || IsDoNotRetryConnectError(sqlex)
                    || timeout.IsExpired) {       // no more time to try again
                    throw;  // Caller will call LoginFailure()
                }

                // Check sleep interval to make sure we won't exceed the timeout
                //  Do this in the catch block so we can re-throw the current exception
                if (timeout.MillisecondsRemaining <= sleepInterval) {
                    throw;
                }

                // 
            }

            // We only get here when we failed to connect, but are going to re-try

            // Switch to failover logic if the server provided a partner
            if (null != ServerProvidedFailOverPartner) {
                if (connectionOptions.MultiSubnetFailover) {
                    // connection failed: do not allow failover to server-provided failover partner if MultiSubnetFailover is set
                    throw SQL.MultiSubnetFailoverWithFailoverPartner(serverProvidedFailoverPartner: true, internalConnection: this);
                }
                Debug.Assert(ConnectionOptions.ApplicationIntent != ApplicationIntent.ReadOnly, "FAILOVER+AppIntent=RO: Should already fail (at LOGSHIPNODE in OnEnvChange)");

                timeoutErrorInternal.ResetAndRestartPhase();
                timeoutErrorInternal.SetAndBeginPhase(SqlConnectionTimeoutErrorPhase.PreLoginBegin);
                timeoutErrorInternal.SetInternalSourceType(SqlConnectionInternalSourceType.Failover);
                timeoutErrorInternal.SetFailoverScenario(true); // this is a failover scenario
                LoginWithFailover(
                            true,   // start by using failover partner, since we already failed to connect to the primary
                            serverInfo,
                            ServerProvidedFailOverPartner,
                            newPassword,
                            newSecurePassword,
                            redirectedUserInstance,
                            connectionOptions,
                            credential,
                            timeout);
                return; // LoginWithFailover successfully connected and handled entire connection setup
            }

            // Sleep for a bit to prevent clogging the network with requests, 
            //  then update sleep interval for next iteration (max 1 second interval)
            if (Bid.AdvancedOn) {
                Bid.Trace("<sc.SqlInternalConnectionTds.LoginNoFailover|ADV> %d#, sleeping %d{milisec}\n", ObjectID, sleepInterval);
            }
            Thread.Sleep(sleepInterval);
            sleepInterval = (sleepInterval < 500) ? sleepInterval * 2 : 1000;
        }

        if (null != PoolGroupProviderInfo) {
            // We must wait for CompleteLogin to finish for to have the
            // env change from the server to know its designated failover 
            // partner; save this information in _currentFailoverPartner.
            PoolGroupProviderInfo.FailoverCheck(this, false, connectionOptions, ServerProvidedFailOverPartner);
        }
        CurrentDataSource = originalServerInfo.UserServerName;
    }
Beispiel #33
0
        override protected void Deactivate()
        {
            if (Bid.AdvancedOn)
            {
                Bid.Trace("<sc.SqlInternalConnection.Deactivate|ADV> %d# deactivating\n", base.ObjectID);
            }
            TdsParser bestEffortCleanupTarget = null;

            RuntimeHelpers.PrepareConstrainedRegions();
            try {
#if DEBUG
                TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection();

                RuntimeHelpers.PrepareConstrainedRegions();
                try {
                    tdsReliabilitySection.Start();
#else
                {
#endif //DEBUG
                    bestEffortCleanupTarget = SqlInternalConnection.GetBestEffortCleanupTarget(Connection);
                    SqlReferenceCollection referenceCollection = (SqlReferenceCollection)ReferenceCollection;
                    if (null != referenceCollection)
                    {
                        referenceCollection.Deactivate();
                    }

                    // Invoke subclass-specific deactivation logic
                    InternalDeactivate();
                }
#if DEBUG
                finally {
                    tdsReliabilitySection.Stop();
                }
#endif //DEBUG
            }
            catch (System.OutOfMemoryException) {
                DoomThisConnection();
                throw;
            }
            catch (System.StackOverflowException) {
                DoomThisConnection();
                throw;
            }
            catch (System.Threading.ThreadAbortException) {
                DoomThisConnection();
                SqlInternalConnection.BestEffortCleanup(bestEffortCleanupTarget);
                throw;
            }
            catch (Exception e) {
                //
                if (!ADP.IsCatchableExceptionType(e))
                {
                    throw;
                }

                // if an exception occurred, the inner connection will be
                // marked as unusable and destroyed upon returning to the
                // pool
                DoomThisConnection();

                ADP.TraceExceptionWithoutRethrow(e);
            }
        }
Beispiel #34
0
        private void EnlistNonNull(SysTx.Transaction tx)
        {
            Debug.Assert(null != tx, "null transaction?");

            if (Bid.AdvancedOn)
            {
                Bid.Trace("<sc.SqlInternalConnection.EnlistNonNull|ADV> %d#, transaction %d#.\n", base.ObjectID, tx.GetHashCode());
            }

            bool hasDelegatedTransaction = false;

            if (IsYukonOrNewer)
            {
                if (Bid.AdvancedOn)
                {
                    Bid.Trace("<sc.SqlInternalConnection.EnlistNonNull|ADV> %d#, attempting to delegate\n", base.ObjectID);
                }

                // Promotable transactions are only supported on Yukon
                // servers or newer.
                SqlDelegatedTransaction delegatedTransaction = new SqlDelegatedTransaction(this, tx);

                try {
                    // NOTE: System.Transactions claims to resolve all
                    // potential race conditions between multiple delegate
                    // requests of the same transaction to different
                    // connections in their code, such that only one
                    // attempt to delegate will succeed.

                    // NOTE: PromotableSinglePhaseEnlist will eventually
                    // make a round trip to the server; doing this inside
                    // a lock is not the best choice.  We presume that you
                    // aren't trying to enlist concurrently on two threads
                    // and leave it at that -- We don't claim any thread
                    // safety with regard to multiple concurrent requests
                    // to enlist the same connection in different
                    // transactions, which is good, because we don't have
                    // it anyway.

                    // PromotableSinglePhaseEnlist may not actually promote
                    // the transaction when it is already delegated (this is
                    // the way they resolve the race condition when two
                    // threads attempt to delegate the same Lightweight
                    // Transaction)  In that case, we can safely ignore
                    // our delegated transaction, and proceed to enlist
                    // in the promoted one.

                    if (tx.EnlistPromotableSinglePhase(delegatedTransaction))
                    {
                        hasDelegatedTransaction = true;

                        this.DelegatedTransaction = delegatedTransaction;

                        if (Bid.AdvancedOn)
                        {
                            long transactionId       = SqlInternalTransaction.NullTransactionId;
                            int  transactionObjectID = 0;
                            if (null != CurrentTransaction)
                            {
                                transactionId       = CurrentTransaction.TransactionId;
                                transactionObjectID = CurrentTransaction.ObjectID;
                            }
                            Bid.Trace("<sc.SqlInternalConnection.EnlistNonNull|ADV> %d#, delegated to transaction %d# with transactionId=0x%I64x\n", base.ObjectID, transactionObjectID, transactionId);
                        }
                    }
                }
                catch (SqlException e) {
                    // we do not want to eat the error if it is a fatal one
                    if (e.Class >= TdsEnums.FATAL_ERROR_CLASS)
                    {
                        throw;
                    }

                    // if the parser is null or its state is not openloggedin, the connection is no longer good.
                    SqlInternalConnectionTds tdsConnection = this as SqlInternalConnectionTds;
                    if (tdsConnection != null)
                    {
                        TdsParser parser = tdsConnection.Parser;
                        if (parser == null || parser.State != TdsParserState.OpenLoggedIn)
                        {
                            throw;
                        }
                    }

                    ADP.TraceExceptionWithoutRethrow(e);

                    // In this case, SqlDelegatedTransaction.Initialize
                    // failed and we don't necessarily want to reject
                    // things -- there may have been a legitimate reason
                    // for the failure.
                }
            }

            if (!hasDelegatedTransaction)
            {
                if (Bid.AdvancedOn)
                {
                    Bid.Trace("<sc.SqlInternalConnection.EnlistNonNull|ADV> %d#, delegation not possible, enlisting.\n", base.ObjectID);
                }

                byte[] cookie = null;

                if (null == _whereAbouts)
                {
                    byte[] dtcAddress = GetDTCAddress();

                    if (null == dtcAddress)
                    {
                        throw SQL.CannotGetDTCAddress();
                    }
                    _whereAbouts = dtcAddress;
                }

                cookie = GetTransactionCookie(tx, _whereAbouts);

                // send cookie to server to finish enlistment
                PropagateTransactionCookie(cookie);

                _isEnlistedInTransaction = true;

                if (Bid.AdvancedOn)
                {
                    long transactionId       = SqlInternalTransaction.NullTransactionId;
                    int  transactionObjectID = 0;
                    if (null != CurrentTransaction)
                    {
                        transactionId       = CurrentTransaction.TransactionId;
                        transactionObjectID = CurrentTransaction.ObjectID;
                    }
                    Bid.Trace("<sc.SqlInternalConnection.EnlistNonNull|ADV> %d#, enlisted with transaction %d# with transactionId=0x%I64x\n", base.ObjectID, transactionObjectID, transactionId);
                }
            }

            EnlistedTransaction = tx; // Tell the base class about our enlistment


            // If we're on a Yukon or newer server, and we we delegate the
            // transaction successfully, we will have done a begin transaction,
            // which produces a transaction id that we should execute all requests
            // on.  The TdsParser or SmiEventSink will store this information as
            // the current transaction.
            //
            // Likewise, propagating a transaction to a Yukon or newer server will
            // produce a transaction id that The TdsParser or SmiEventSink will
            // store as the current transaction.
            //
            // In either case, when we're working with a Yukon or newer server
            // we better have a current transaction by now.

            Debug.Assert(!IsYukonOrNewer || null != CurrentTransaction, "delegated/enlisted transaction with null current transaction?");
        }
 private void CloseInternal(bool closeReader)
 {
     TdsParser parser = this._parser;
     TdsParserStateObject stateObj = this._stateObj;
     bool flag2 = this.IsCommandBehavior(CommandBehavior.CloseConnection);
     this._parser = null;
     bool flag = false;
     RuntimeHelpers.PrepareConstrainedRegions();
     try
     {
         if (((parser != null) && (stateObj != null)) && (stateObj._pendingData && (parser.State == TdsParserState.OpenLoggedIn)))
         {
             if (this._altRowStatus == ALTROWSTATUS.AltRow)
             {
                 this._dataReady = true;
             }
             if (this._dataReady)
             {
                 this.CleanPartialRead();
             }
             parser.Run(RunBehavior.Clean, this._command, this, null, stateObj);
         }
         this.RestoreServerSettings(parser, stateObj);
     }
     catch (OutOfMemoryException exception6)
     {
         this._isClosed = true;
         flag = true;
         if (this._connection != null)
         {
             this._connection.Abort(exception6);
         }
         throw;
     }
     catch (StackOverflowException exception5)
     {
         this._isClosed = true;
         flag = true;
         if (this._connection != null)
         {
             this._connection.Abort(exception5);
         }
         throw;
     }
     catch (ThreadAbortException exception4)
     {
         this._isClosed = true;
         flag = true;
         if (this._connection != null)
         {
             this._connection.Abort(exception4);
         }
         throw;
     }
     finally
     {
         if (flag)
         {
             this._isClosed = true;
             this._command = null;
             this._connection = null;
             this._statistics = null;
         }
         else if (closeReader)
         {
             this._stateObj = null;
             this._data = null;
             if (this.Connection != null)
             {
                 this.Connection.RemoveWeakReference(this);
             }
             RuntimeHelpers.PrepareConstrainedRegions();
             try
             {
                 if ((this._command != null) && (stateObj != null))
                 {
                     stateObj.CloseSession();
                 }
             }
             catch (OutOfMemoryException exception3)
             {
                 this._isClosed = true;
                 flag = true;
                 if (this._connection != null)
                 {
                     this._connection.Abort(exception3);
                 }
                 throw;
             }
             catch (StackOverflowException exception2)
             {
                 this._isClosed = true;
                 flag = true;
                 if (this._connection != null)
                 {
                     this._connection.Abort(exception2);
                 }
                 throw;
             }
             catch (ThreadAbortException exception)
             {
                 this._isClosed = true;
                 flag = true;
                 if (this._connection != null)
                 {
                     this._connection.Abort(exception);
                 }
                 throw;
             }
             this.SetMetaData(null, false);
             this._dataReady = false;
             this._isClosed = true;
             this._fieldNameLookup = null;
             if (flag2 && (this.Connection != null))
             {
                 this.Connection.Close();
             }
             if (this._command != null)
             {
                 this._recordsAffected = this._command.InternalRecordsAffected;
             }
             this._command = null;
             this._connection = null;
             this._statistics = null;
         }
     }
 }
Beispiel #36
0
        virtual internal SqlTransaction BeginSqlTransaction(IsolationLevel iso, string transactionName, bool shouldReconnect)
        {
            SqlStatistics statistics = null;
            TdsParser     bestEffortCleanupTarget = null;

            RuntimeHelpers.PrepareConstrainedRegions();
            try {
#if DEBUG
                TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection();

                RuntimeHelpers.PrepareConstrainedRegions();
                try {
                    tdsReliabilitySection.Start();
#else
                {
#endif //DEBUG
                    bestEffortCleanupTarget = SqlInternalConnection.GetBestEffortCleanupTarget(Connection);
                    statistics = SqlStatistics.StartTimer(Connection.Statistics);

                    SqlConnection.ExecutePermission.Demand(); // MDAC 81476

                    ValidateConnectionForExecute(null);

                    if (HasLocalTransactionFromAPI)
                    {
                        throw ADP.ParallelTransactionsNotSupported(Connection);
                    }

                    if (iso == IsolationLevel.Unspecified)
                    {
                        iso = IsolationLevel.ReadCommitted; // Default to ReadCommitted if unspecified.
                    }

                    SqlTransaction transaction = new SqlTransaction(this, Connection, iso, AvailableInternalTransaction);
                    transaction.InternalTransaction.RestoreBrokenConnection = shouldReconnect;
                    ExecuteTransaction(TransactionRequest.Begin, transactionName, iso, transaction.InternalTransaction, false);
                    transaction.InternalTransaction.RestoreBrokenConnection = false;
                    return(transaction);
                }
#if DEBUG
                finally {
                    tdsReliabilitySection.Stop();
                }
#endif //DEBUG
            }
            catch (System.OutOfMemoryException e) {
                Connection.Abort(e);
                throw;
            }
            catch (System.StackOverflowException e) {
                Connection.Abort(e);
                throw;
            }
            catch (System.Threading.ThreadAbortException e) {
                Connection.Abort(e);
                SqlInternalConnection.BestEffortCleanup(bestEffortCleanupTarget);
                throw;
            }
            finally {
                SqlStatistics.StopTimer(statistics);
            }
        }
 private void Dispose(bool disposing)
 {
     if (disposing)
     {
         this._columnMappings = null;
         this._parser = null;
         try
         {
             if (this._internalTransaction != null)
             {
                 this._internalTransaction.Rollback();
                 this._internalTransaction.Dispose();
                 this._internalTransaction = null;
             }
         }
         catch (Exception exception)
         {
             if (!ADP.IsCatchableExceptionType(exception))
             {
                 throw;
             }
             ADP.TraceExceptionWithoutRethrow(exception);
         }
         finally
         {
             if (this._connection != null)
             {
                 if (this._ownConnection)
                 {
                     this._connection.Dispose();
                 }
                 this._connection = null;
             }
         }
     }
 }
Beispiel #38
0
        private void LoginWithFailover(bool useFailoverHost, ServerInfo primaryServerInfo, string failoverHost, string newPassword, bool redirectedUserInstance, SqlConnection owningObject, SqlConnectionString connectionOptions, TimeoutTimer timeout)
        {
            long num5;

            if (Bid.AdvancedOn)
            {
                Bid.Trace("<sc.SqlInternalConnectionTds.LoginWithFailover|ADV> %d#, useFailover=%d{bool}, primary=", base.ObjectID, useFailoverHost);
                Bid.PutStr(primaryServerInfo.UserServerName);
                Bid.PutStr(", failover=");
                Bid.PutStr(failoverHost);
                Bid.PutStr("\n");
            }
            int        num            = 100;
            string     networkLibrary = base.ConnectionOptions.NetworkLibrary;
            ServerInfo serverInfo     = new ServerInfo(connectionOptions, failoverHost);

            this.ResolveExtendedServerName(primaryServerInfo, !redirectedUserInstance, owningObject);
            if (this.ServerProvidedFailOverPartner == null)
            {
                this.ResolveExtendedServerName(serverInfo, !redirectedUserInstance && (failoverHost != primaryServerInfo.UserServerName), owningObject);
            }
            if (timeout.IsInfinite)
            {
                ADP.TimerFromSeconds(15);
                num5 = 0L;
            }
            else
            {
                num5 = (long)(0.08f * timeout.MillisecondsRemaining);
            }
            bool flag = false;
            int  num2 = 0;

            while (true)
            {
                ServerInfo info2;
                long       milliseconds          = num5 * ((num2 / 2) + 1);
                long       millisecondsRemaining = timeout.MillisecondsRemaining;
                if (milliseconds > millisecondsRemaining)
                {
                    milliseconds = millisecondsRemaining;
                }
                TimeoutTimer timer = TimeoutTimer.StartMillisecondsTimeout(milliseconds);
                if (this._parser != null)
                {
                    this._parser.Disconnect();
                }
                this._parser = new TdsParser(base.ConnectionOptions.MARS, base.ConnectionOptions.Asynchronous);
                if (useFailoverHost)
                {
                    if (!flag)
                    {
                        this.FailoverPermissionDemand();
                        flag = true;
                    }
                    if ((this.ServerProvidedFailOverPartner != null) && (serverInfo.ResolvedServerName != this.ServerProvidedFailOverPartner))
                    {
                        if (Bid.AdvancedOn)
                        {
                            Bid.Trace("<sc.SqlInternalConnectionTds.LoginWithFailover|ADV> %d#, new failover partner=%ls\n", base.ObjectID, this.ServerProvidedFailOverPartner);
                        }
                        serverInfo.SetDerivedNames(networkLibrary, this.ServerProvidedFailOverPartner);
                    }
                    info2 = serverInfo;
                }
                else
                {
                    info2 = primaryServerInfo;
                }
                try
                {
                    this.AttemptOneLogin(info2, newPassword, false, timer, owningObject);
                    if (this._routingInfo != null)
                    {
                        Bid.Trace("<sc.SqlInternalConnectionTds.LoginWithFailover> Routed to %ls", this._routingInfo.ServerName);
                        throw SQL.ROR_UnexpectedRoutingInfo();
                    }
                    break;
                }
                catch (SqlException exception)
                {
                    if (this.IsDoNotRetryConnectError(exception) || timeout.IsExpired)
                    {
                        throw;
                    }
                    if (base.IsConnectionDoomed)
                    {
                        throw;
                    }
                    if ((1 == (num2 % 2)) && (timeout.MillisecondsRemaining <= num))
                    {
                        throw;
                    }
                }
                if (1 == (num2 % 2))
                {
                    if (Bid.AdvancedOn)
                    {
                        Bid.Trace("<sc.SqlInternalConnectionTds.LoginWithFailover|ADV> %d#, sleeping %d{milisec}\n", base.ObjectID, num);
                    }
                    Thread.Sleep(num);
                    num = (num < 500) ? (num * 2) : 0x3e8;
                }
                num2++;
                useFailoverHost = !useFailoverHost;
            }
            if (useFailoverHost && (this.ServerProvidedFailOverPartner == null))
            {
                throw SQL.InvalidPartnerConfiguration(failoverHost, base.CurrentDatabase);
            }
            if (this.PoolGroupProviderInfo != null)
            {
                this.PoolGroupProviderInfo.FailoverCheck(this, useFailoverHost, connectionOptions, this.ServerProvidedFailOverPartner);
            }
            base.CurrentDataSource = useFailoverHost ? failoverHost : primaryServerInfo.UserServerName;
        }
Beispiel #39
0
        private void LoginNoFailover(ServerInfo serverInfo, string newPassword, bool redirectedUserInstance, SqlConnection owningObject, SqlConnectionString connectionOptions, TimeoutTimer timeout)
        {
            int        num2 = 0;
            ServerInfo info = serverInfo;

            if (Bid.AdvancedOn)
            {
                Bid.Trace("<sc.SqlInternalConnectionTds.LoginNoFailover|ADV> %d#, host=%ls\n", base.ObjectID, serverInfo.UserServerName);
            }
            int num = 100;

            this.ResolveExtendedServerName(serverInfo, !redirectedUserInstance, owningObject);
Label_0032:
            if (this._parser != null)
            {
                this._parser.Disconnect();
            }
            this._parser = new TdsParser(base.ConnectionOptions.MARS, base.ConnectionOptions.Asynchronous);
            try
            {
                this.AttemptOneLogin(serverInfo, newPassword, true, timeout, owningObject);
                if (connectionOptions.MultiSubnetFailover && (this.ServerProvidedFailOverPartner != null))
                {
                    bool serverProvidedFailoverPartner = true;
                    throw SQL.MultiSubnetFailoverWithFailoverPartner(serverProvidedFailoverPartner);
                }
                if (this._routingInfo == null)
                {
                    if (this.PoolGroupProviderInfo != null)
                    {
                        this.PoolGroupProviderInfo.FailoverCheck(this, false, connectionOptions, this.ServerProvidedFailOverPartner);
                    }
                    base.CurrentDataSource = info.UserServerName;
                    return;
                }
                Bid.Trace("<sc.SqlInternalConnectionTds.LoginNoFailover> Routed to %ls", serverInfo.ExtendedServerName);
                if (num2 > 0)
                {
                    throw SQL.ROR_RecursiveRoutingNotSupported();
                }
                if (timeout.IsExpired)
                {
                    throw SQL.ROR_TimeoutAfterRoutingInfo();
                }
                serverInfo = new ServerInfo(base.ConnectionOptions, this._routingInfo, serverInfo.ResolvedServerName);
                this._currentPacketSize      = base.ConnectionOptions.PacketSize;
                this._currentLanguage        = this._originalLanguage = base.ConnectionOptions.CurrentLanguage;
                base.CurrentDatabase         = this._originalDatabase = base.ConnectionOptions.InitialCatalog;
                this._currentFailoverPartner = null;
                this._instanceName           = string.Empty;
                num2++;
                goto Label_0032;
            }
            catch (SqlException exception)
            {
                if (((this._parser == null) || (this._parser.State != TdsParserState.Closed)) || (this.IsDoNotRetryConnectError(exception) || timeout.IsExpired))
                {
                    throw;
                }
                if (timeout.MillisecondsRemaining <= num)
                {
                    throw;
                }
            }
            if (this.ServerProvidedFailOverPartner != null)
            {
                if (connectionOptions.MultiSubnetFailover)
                {
                    bool flag = true;
                    throw SQL.MultiSubnetFailoverWithFailoverPartner(flag);
                }
                this.LoginWithFailover(true, serverInfo, this.ServerProvidedFailOverPartner, newPassword, redirectedUserInstance, owningObject, connectionOptions, timeout);
            }
            else
            {
                if (Bid.AdvancedOn)
                {
                    Bid.Trace("<sc.SqlInternalConnectionTds.LoginNoFailover|ADV> %d#, sleeping %d{milisec}\n", base.ObjectID, num);
                }
                Thread.Sleep(num);
                num = (num < 500) ? (num * 2) : 0x3e8;
                goto Label_0032;
            }
        }
 private void LoginWithFailover(bool useFailoverHost, ServerInfo primaryServerInfo, string failoverHost, string newPassword, bool redirectedUserInstance, SqlConnection owningObject, SqlConnectionString connectionOptions, TimeoutTimer timeout)
 {
     long num5;
     if (Bid.AdvancedOn)
     {
         Bid.Trace("<sc.SqlInternalConnectionTds.LoginWithFailover|ADV> %d#, useFailover=%d{bool}, primary=", base.ObjectID, useFailoverHost);
         Bid.PutStr(primaryServerInfo.UserServerName);
         Bid.PutStr(", failover=");
         Bid.PutStr(failoverHost);
         Bid.PutStr("\n");
     }
     int num = 100;
     string networkLibrary = base.ConnectionOptions.NetworkLibrary;
     ServerInfo serverInfo = new ServerInfo(connectionOptions, failoverHost);
     this.ResolveExtendedServerName(primaryServerInfo, !redirectedUserInstance, owningObject);
     if (this.ServerProvidedFailOverPartner == null)
     {
         this.ResolveExtendedServerName(serverInfo, !redirectedUserInstance && (failoverHost != primaryServerInfo.UserServerName), owningObject);
     }
     if (timeout.IsInfinite)
     {
         ADP.TimerFromSeconds(15);
         num5 = 0L;
     }
     else
     {
         num5 = (long) (0.08f * timeout.MillisecondsRemaining);
     }
     bool flag = false;
     int num2 = 0;
     while (true)
     {
         ServerInfo info2;
         long milliseconds = num5 * ((num2 / 2) + 1);
         long millisecondsRemaining = timeout.MillisecondsRemaining;
         if (milliseconds > millisecondsRemaining)
         {
             milliseconds = millisecondsRemaining;
         }
         TimeoutTimer timer = TimeoutTimer.StartMillisecondsTimeout(milliseconds);
         if (this._parser != null)
         {
             this._parser.Disconnect();
         }
         this._parser = new TdsParser(base.ConnectionOptions.MARS, base.ConnectionOptions.Asynchronous);
         if (useFailoverHost)
         {
             if (!flag)
             {
                 this.FailoverPermissionDemand();
                 flag = true;
             }
             if ((this.ServerProvidedFailOverPartner != null) && (serverInfo.ResolvedServerName != this.ServerProvidedFailOverPartner))
             {
                 if (Bid.AdvancedOn)
                 {
                     Bid.Trace("<sc.SqlInternalConnectionTds.LoginWithFailover|ADV> %d#, new failover partner=%ls\n", base.ObjectID, this.ServerProvidedFailOverPartner);
                 }
                 serverInfo.SetDerivedNames(networkLibrary, this.ServerProvidedFailOverPartner);
             }
             info2 = serverInfo;
         }
         else
         {
             info2 = primaryServerInfo;
         }
         try
         {
             this.AttemptOneLogin(info2, newPassword, false, timer, owningObject);
             if (this._routingInfo != null)
             {
                 Bid.Trace("<sc.SqlInternalConnectionTds.LoginWithFailover> Routed to %ls", this._routingInfo.ServerName);
                 throw SQL.ROR_UnexpectedRoutingInfo();
             }
             break;
         }
         catch (SqlException exception)
         {
             if (this.IsDoNotRetryConnectError(exception) || timeout.IsExpired)
             {
                 throw;
             }
             if (base.IsConnectionDoomed)
             {
                 throw;
             }
             if ((1 == (num2 % 2)) && (timeout.MillisecondsRemaining <= num))
             {
                 throw;
             }
         }
         if (1 == (num2 % 2))
         {
             if (Bid.AdvancedOn)
             {
                 Bid.Trace("<sc.SqlInternalConnectionTds.LoginWithFailover|ADV> %d#, sleeping %d{milisec}\n", base.ObjectID, num);
             }
             Thread.Sleep(num);
             num = (num < 500) ? (num * 2) : 0x3e8;
         }
         num2++;
         useFailoverHost = !useFailoverHost;
     }
     if (useFailoverHost && (this.ServerProvidedFailOverPartner == null))
     {
         throw SQL.InvalidPartnerConfiguration(failoverHost, base.CurrentDatabase);
     }
     if (this.PoolGroupProviderInfo != null)
     {
         this.PoolGroupProviderInfo.FailoverCheck(this, useFailoverHost, connectionOptions, this.ServerProvidedFailOverPartner);
     }
     base.CurrentDataSource = useFailoverHost ? failoverHost : primaryServerInfo.UserServerName;
 }
Beispiel #41
0
        override public void EnlistTransaction(SysTx.Transaction transaction)
        {
            SqlConnection.VerifyExecutePermission();

            ValidateConnectionForExecute(null);

            // If a connection has a local transaction outstanding and you try
            // to enlist in a DTC transaction, SQL Server will rollback the
            // local transaction and then do the enlist (7.0 and 2000).  So, if
            // the user tries to do this, throw.
            if (HasLocalTransaction)
            {
                throw ADP.LocalTransactionPresent();
            }

            if (null != transaction && transaction.Equals(EnlistedTransaction))
            {
                // No-op if this is the current transaction
                return;
            }

            // If a connection is already enlisted in a DTC transaction and you
            // try to enlist in another one, in 7.0 the existing DTC transaction
            // would roll back and then the connection would enlist in the new
            // one. In SQL 2000 & Yukon, when you enlist in a DTC transaction
            // while the connection is already enlisted in a DTC transaction,
            // the connection simply switches enlistments.  Regardless, simply
            // enlist in the user specified distributed transaction.  This
            // behavior matches OLEDB and ODBC.

            TdsParser bestEffortCleanupTarget = null;

            RuntimeHelpers.PrepareConstrainedRegions();
            try {
#if DEBUG
                TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection();

                RuntimeHelpers.PrepareConstrainedRegions();
                try {
                    tdsReliabilitySection.Start();
#else
                {
#endif //DEBUG
                    bestEffortCleanupTarget = SqlInternalConnection.GetBestEffortCleanupTarget(Connection);
                    Enlist(transaction);
                }
#if DEBUG
                finally {
                    tdsReliabilitySection.Stop();
                }
#endif //DEBUG
            }
            catch (System.OutOfMemoryException e) {
                Connection.Abort(e);
                throw;
            }
            catch (System.StackOverflowException e) {
                Connection.Abort(e);
                throw;
            }
            catch (System.Threading.ThreadAbortException e) {
                Connection.Abort(e);
                SqlInternalConnection.BestEffortCleanup(bestEffortCleanupTarget);
                throw;
            }
        }
 private void LoginNoFailover(ServerInfo serverInfo, string newPassword, bool redirectedUserInstance, SqlConnection owningObject, SqlConnectionString connectionOptions, TimeoutTimer timeout)
 {
     int num2 = 0;
     ServerInfo info = serverInfo;
     if (Bid.AdvancedOn)
     {
         Bid.Trace("<sc.SqlInternalConnectionTds.LoginNoFailover|ADV> %d#, host=%ls\n", base.ObjectID, serverInfo.UserServerName);
     }
     int num = 100;
     this.ResolveExtendedServerName(serverInfo, !redirectedUserInstance, owningObject);
 Label_0032:
     if (this._parser != null)
     {
         this._parser.Disconnect();
     }
     this._parser = new TdsParser(base.ConnectionOptions.MARS, base.ConnectionOptions.Asynchronous);
     try
     {
         this.AttemptOneLogin(serverInfo, newPassword, true, timeout, owningObject);
         if (connectionOptions.MultiSubnetFailover && (this.ServerProvidedFailOverPartner != null))
         {
             bool serverProvidedFailoverPartner = true;
             throw SQL.MultiSubnetFailoverWithFailoverPartner(serverProvidedFailoverPartner);
         }
         if (this._routingInfo == null)
         {
             if (this.PoolGroupProviderInfo != null)
             {
                 this.PoolGroupProviderInfo.FailoverCheck(this, false, connectionOptions, this.ServerProvidedFailOverPartner);
             }
             base.CurrentDataSource = info.UserServerName;
             return;
         }
         Bid.Trace("<sc.SqlInternalConnectionTds.LoginNoFailover> Routed to %ls", serverInfo.ExtendedServerName);
         if (num2 > 0)
         {
             throw SQL.ROR_RecursiveRoutingNotSupported();
         }
         if (timeout.IsExpired)
         {
             throw SQL.ROR_TimeoutAfterRoutingInfo();
         }
         serverInfo = new ServerInfo(base.ConnectionOptions, this._routingInfo, serverInfo.ResolvedServerName);
         this._currentPacketSize = base.ConnectionOptions.PacketSize;
         this._currentLanguage = this._originalLanguage = base.ConnectionOptions.CurrentLanguage;
         base.CurrentDatabase = this._originalDatabase = base.ConnectionOptions.InitialCatalog;
         this._currentFailoverPartner = null;
         this._instanceName = string.Empty;
         num2++;
         goto Label_0032;
     }
     catch (SqlException exception)
     {
         if (((this._parser == null) || (this._parser.State != TdsParserState.Closed)) || (this.IsDoNotRetryConnectError(exception) || timeout.IsExpired))
         {
             throw;
         }
         if (timeout.MillisecondsRemaining <= num)
         {
             throw;
         }
     }
     if (this.ServerProvidedFailOverPartner != null)
     {
         if (connectionOptions.MultiSubnetFailover)
         {
             bool flag = true;
             throw SQL.MultiSubnetFailoverWithFailoverPartner(flag);
         }
         this.LoginWithFailover(true, serverInfo, this.ServerProvidedFailOverPartner, newPassword, redirectedUserInstance, owningObject, connectionOptions, timeout);
     }
     else
     {
         if (Bid.AdvancedOn)
         {
             Bid.Trace("<sc.SqlInternalConnectionTds.LoginNoFailover|ADV> %d#, sleeping %d{milisec}\n", base.ObjectID, num);
         }
         Thread.Sleep(num);
         num = (num < 500) ? (num * 2) : 0x3e8;
         goto Label_0032;
     }
 }
 private void RestoreServerSettings(TdsParser parser, TdsParserStateObject stateObj)
 {
     if ((parser != null) && (this._resetOptionsString != null))
     {
         if (parser.State == TdsParserState.OpenLoggedIn)
         {
             parser.TdsExecuteSQLBatch(this._resetOptionsString, (this._command != null) ? this._command.CommandTimeout : 0, null, stateObj);
             parser.Run(RunBehavior.UntilDone, this._command, this, null, stateObj);
         }
         this._resetOptionsString = null;
     }
 }
Beispiel #44
0
        internal TdsParserStateObject(TdsParser parser, SNIHandle physicalConnection, bool async)
        {
            // Construct a MARS session
            Debug.Assert(null != parser, "no parser?");
            _parser = parser;
            SniContext = SniContext.Snix_GetMarsSession;

            Debug.Assert(null != _parser._physicalStateObj, "no physical session?");
            Debug.Assert(null != _parser._physicalStateObj._inBuff, "no in buffer?");
            Debug.Assert(null != _parser._physicalStateObj._outBuff, "no out buffer?");
            Debug.Assert(_parser._physicalStateObj._outBuff.Length ==
                         _parser._physicalStateObj._inBuff.Length, "Unexpected unequal buffers.");

            // Determine packet size based on physical connection buffer lengths.
            SetPacketSize(_parser._physicalStateObj._outBuff.Length);

            SNINativeMethodWrapper.ConsumerInfo myInfo = CreateConsumerInfo(async);
            _sessionHandle = new SNIHandle(myInfo, physicalConnection);

            if (_sessionHandle.Status != TdsEnums.SNI_SUCCESS)
            {
                AddError(parser.ProcessSNIError(this));
                ThrowExceptionAndWarning();
            }

            // we post a callback that represents the call to dispose; once the
            // object is disposed, the next callback will cause the GC Handle to
            // be released.
            IncrementPendingCallbacks();
            _lastSuccessfulIOTimer = parser._physicalStateObj._lastSuccessfulIOTimer;
        }
 internal string BuildParamList(TdsParser parser, SqlParameterCollection parameters)
 {
     StringBuilder builder = new StringBuilder();
     bool flag = false;
     bool isYukonOrNewer = parser.IsYukonOrNewer;
     int count = 0;
     count = parameters.Count;
     for (int i = 0; i < count; i++)
     {
         SqlParameter p = parameters[i];
         p.Validate(i, System.Data.CommandType.StoredProcedure == this.CommandType);
         if (ShouldSendParameter(p))
         {
             if (flag)
             {
                 builder.Append(',');
             }
             builder.Append(p.ParameterNameFixed);
             MetaType internalMetaType = p.InternalMetaType;
             builder.Append(" ");
             if (internalMetaType.SqlDbType == SqlDbType.Udt)
             {
                 string udtTypeName = p.UdtTypeName;
                 if (ADP.IsEmpty(udtTypeName))
                 {
                     throw SQL.MustSetUdtTypeNameForUdtParams();
                 }
                 builder.Append(this.ParseAndQuoteIdentifier(udtTypeName, true));
             }
             else if (internalMetaType.SqlDbType == SqlDbType.Structured)
             {
                 string typeName = p.TypeName;
                 if (ADP.IsEmpty(typeName))
                 {
                     throw SQL.MustSetTypeNameForParam(internalMetaType.TypeName, p.ParameterNameFixed);
                 }
                 builder.Append(this.ParseAndQuoteIdentifier(typeName, false));
                 builder.Append(" READONLY");
             }
             else
             {
                 internalMetaType = p.ValidateTypeLengths(isYukonOrNewer);
                 builder.Append(internalMetaType.TypeName);
             }
             flag = true;
             if (internalMetaType.SqlDbType == SqlDbType.Decimal)
             {
                 byte actualPrecision = p.GetActualPrecision();
                 byte actualScale = p.GetActualScale();
                 builder.Append('(');
                 if (actualPrecision == 0)
                 {
                     if (this.IsShiloh)
                     {
                         actualPrecision = 0x1d;
                     }
                     else
                     {
                         actualPrecision = 0x1c;
                     }
                 }
                 builder.Append(actualPrecision);
                 builder.Append(',');
                 builder.Append(actualScale);
                 builder.Append(')');
             }
             else if (internalMetaType.IsVarTime)
             {
                 byte num6 = p.GetActualScale();
                 builder.Append('(');
                 builder.Append(num6);
                 builder.Append(')');
             }
             else if (((!internalMetaType.IsFixed && !internalMetaType.IsLong) && ((internalMetaType.SqlDbType != SqlDbType.Timestamp) && (internalMetaType.SqlDbType != SqlDbType.Udt))) && (SqlDbType.Structured != internalMetaType.SqlDbType))
             {
                 int size = p.Size;
                 builder.Append('(');
                 if (internalMetaType.IsAnsiType)
                 {
                     object coercedValue = p.GetCoercedValue();
                     string str = null;
                     if ((coercedValue != null) && (DBNull.Value != coercedValue))
                     {
                         str = coercedValue as string;
                         if (str == null)
                         {
                             SqlString str4 = (coercedValue is SqlString) ? ((SqlString) coercedValue) : SqlString.Null;
                             if (!str4.IsNull)
                             {
                                 str = str4.Value;
                             }
                         }
                     }
                     if (str != null)
                     {
                         int num4 = parser.GetEncodingCharLength(str, p.GetActualSize(), p.Offset, null);
                         if (num4 > size)
                         {
                             size = num4;
                         }
                     }
                 }
                 if (size == 0)
                 {
                     size = internalMetaType.IsSizeInCharacters ? 0xfa0 : 0x1f40;
                 }
                 builder.Append(size);
                 builder.Append(')');
             }
             else if ((internalMetaType.IsPlp && (internalMetaType.SqlDbType != SqlDbType.Xml)) && (internalMetaType.SqlDbType != SqlDbType.Udt))
             {
                 builder.Append("(max) ");
             }
             if (p.Direction != ParameterDirection.Input)
             {
                 builder.Append(" output");
             }
         }
     }
     return builder.ToString();
 }
    // Attempt to login to a host that has a failover partner
    //
    // Connection & timeout sequence is
    //      First target, timeout = interval * 1
    //      second target, timeout = interval * 1
    //      sleep for 100ms
    //      First target, timeout = interval * 2
    //      Second target, timeout = interval * 2
    //      sleep for 200ms
    //      First Target, timeout = interval * 3
    //      etc.
    //
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    //  DEVNOTE: The logic in this method is paralleled by the logic in LoginNoFailover.
    //           Changes to either one should be examined to see if they need to be reflected in the other
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    private void LoginWithFailover(
            bool                useFailoverHost, 
            ServerInfo          primaryServerInfo, 
            string              failoverHost, 
            string              newPassword,
            SecureString        newSecurePassword,
            bool                redirectedUserInstance, 
            SqlConnectionString connectionOptions,
            SqlCredential       credential,
            TimeoutTimer        timeout
        ) {

        Debug.Assert(!connectionOptions.MultiSubnetFailover, "MultiSubnetFailover should not be set if failover partner is used");

        if (Bid.AdvancedOn) {
            Bid.Trace("<sc.SqlInternalConnectionTds.LoginWithFailover|ADV> %d#, useFailover=%d{bool}, primary=", ObjectID, useFailoverHost);
            Bid.PutStr(primaryServerInfo.UserServerName);
            Bid.PutStr(", failover=");
            Bid.PutStr(failoverHost);
            Bid.PutStr("\n");
        }
        int  sleepInterval = 100;  //milliseconds to sleep (back off) between attempts.
        long timeoutUnitInterval;

        string     protocol = ConnectionOptions.NetworkLibrary;
        ServerInfo failoverServerInfo = new ServerInfo(connectionOptions, failoverHost);

        ResolveExtendedServerName(primaryServerInfo, !redirectedUserInstance, connectionOptions);
        if (null == ServerProvidedFailOverPartner) {// No point in resolving the failover partner when we're going to override it below
            // Don't resolve aliases if failover == primary // 
            ResolveExtendedServerName(failoverServerInfo, !redirectedUserInstance && failoverHost != primaryServerInfo.UserServerName, connectionOptions);
        }

        // Determine unit interval
        if (timeout.IsInfinite) {
            timeoutUnitInterval = checked((long) ADP.FailoverTimeoutStep * ADP.TimerFromSeconds(ADP.DefaultConnectionTimeout));
        }
        else {
            timeoutUnitInterval = checked((long) (ADP.FailoverTimeoutStep * timeout.MillisecondsRemaining));
        }

        // Initialize loop variables
        bool failoverDemandDone = false; // have we demanded for partner information yet (as necessary)?
        int attemptNumber = 0;

        // Only three ways out of this loop:
        //  1) Successfully connected
        //  2) Parser threw exception while main timer was expired
        //  3) Parser threw logon failure-related exception (LOGON_FAILED, PASSWORD_EXPIRED, etc)
        //
        //  Of these methods, only #1 exits normally. This preserves the call stack on the exception 
        //  back into the parser for the error cases.
        while (true) {
            // Set timeout for this attempt, but don't exceed original timer
            long nextTimeoutInterval = checked(timeoutUnitInterval * ((attemptNumber / 2) + 1));
            long milliseconds = timeout.MillisecondsRemaining;
            if (nextTimeoutInterval > milliseconds) {
                nextTimeoutInterval = milliseconds;
            }

            TimeoutTimer intervalTimer = TimeoutTimer.StartMillisecondsTimeout(nextTimeoutInterval);

            // Re-allocate parser each time to make sure state is known
            // RFC 50002652 - if parser was created by previous attempt, dispose it to properly close the socket, if created
            if (_parser != null)
                _parser.Disconnect();

            _parser = new TdsParser(ConnectionOptions.MARS, ConnectionOptions.Asynchronous);
            Debug.Assert(SniContext.Undefined== Parser._physicalStateObj.SniContext, String.Format((IFormatProvider)null, "SniContext should be Undefined; actual Value: {0}", Parser._physicalStateObj.SniContext));

            ServerInfo currentServerInfo;
            if (useFailoverHost) {
                if (!failoverDemandDone) {
                    FailoverPermissionDemand();
                    failoverDemandDone = true;
                }

                // Primary server may give us a different failover partner than the connection string indicates.  Update it
                if (null != ServerProvidedFailOverPartner && failoverServerInfo.ResolvedServerName != ServerProvidedFailOverPartner) {
                    if (Bid.AdvancedOn) {
                        Bid.Trace("<sc.SqlInternalConnectionTds.LoginWithFailover|ADV> %d#, new failover partner=%ls\n", ObjectID, ServerProvidedFailOverPartner);
                    }
                    failoverServerInfo.SetDerivedNames(protocol, ServerProvidedFailOverPartner);
                }
                currentServerInfo = failoverServerInfo;
                timeoutErrorInternal.SetInternalSourceType(SqlConnectionInternalSourceType.Failover);
            }
            else {
                currentServerInfo = primaryServerInfo;
                timeoutErrorInternal.SetInternalSourceType(SqlConnectionInternalSourceType.Principle);
            }

            try {
                // Attempt login.  Use timerInterval for attempt timeout unless infinite timeout was requested.
                AttemptOneLogin(
                        currentServerInfo,
                        newPassword,
                        newSecurePassword,
                        false,          // Use timeout in SniOpen
                        intervalTimer,
                        withFailover:true
                        );

                if (_routingInfo != null) {
                    // We are in login with failover scenation and server sent routing information
                    // If it is read-only routing - we did not supply AppIntent=RO (it should be checked before)
                    // If it is something else, not known yet (future server) - this client is not designed to support this.                    
                    // In any case, server should not have sent the routing info.
                    Bid.Trace("<sc.SqlInternalConnectionTds.LoginWithFailover> Routed to %ls", _routingInfo.ServerName);
                    throw SQL.ROR_UnexpectedRoutingInfo(this);
                }

                break; // leave the while loop -- we've successfully connected
            }
            catch (SqlException sqlex) {
                if (IsDoNotRetryConnectError(sqlex)
                        || timeout.IsExpired) 
                {       // no more time to try again
                    throw;  // Caller will call LoginFailure()
                }

                if (IsConnectionDoomed) {
                    throw;
                }

                if (1 == attemptNumber % 2) {
                    // Check sleep interval to make sure we won't exceed the original timeout
                    //  Do this in the catch block so we can re-throw the current exception
                    if (timeout.MillisecondsRemaining <= sleepInterval) {
                        throw;
                    }
                }

                // 
            }

            // We only get here when we failed to connect, but are going to re-try

            // After trying to connect to both servers fails, sleep for a bit to prevent clogging 
            //  the network with requests, then update sleep interval for next iteration (max 1 second interval)
            if (1 == attemptNumber % 2) {
                if (Bid.AdvancedOn) {
                    Bid.Trace("<sc.SqlInternalConnectionTds.LoginWithFailover|ADV> %d#, sleeping %d{milisec}\n", ObjectID, sleepInterval);
                }
                Thread.Sleep(sleepInterval);
                sleepInterval = (sleepInterval < 500) ? sleepInterval * 2 : 1000;
            }

            // Update attempt number and target host
            attemptNumber++;
            useFailoverHost = !useFailoverHost;
        }

        // If we get here, connection/login succeeded!  Just a few more checks & record-keeping

        // if connected to failover host, but said host doesn't have DbMirroring set up, throw an error
        if (useFailoverHost && null == ServerProvidedFailOverPartner) {
            throw SQL.InvalidPartnerConfiguration(failoverHost, CurrentDatabase);
        }

        if (null != PoolGroupProviderInfo) {
            // We must wait for CompleteLogin to finish for to have the
            // env change from the server to know its designated failover 
            // partner; save this information in _currentFailoverPartner.
            PoolGroupProviderInfo.FailoverCheck(this, useFailoverHost, connectionOptions, ServerProvidedFailOverPartner);
        }
        CurrentDataSource = (useFailoverHost ? failoverHost : primaryServerInfo.UserServerName);
    }
 static internal void BestEffortCleanup(TdsParser target) {
     if (null != target) {
         target.BestEffortCleanup();
     }
 }
 public TdsParserStateObject CreateTdsParserStateObject(TdsParser parser)
 {
     return(new TdsParserStateObjectManaged(parser));
 }
        private readonly WritePacketCache _writePacketCache = new WritePacketCache(); // Store write packets that are ready to be re-used

        public TdsParserStateObjectNative(TdsParser parser) : base(parser)
        {
        }
Beispiel #50
0
        private void EnlistNonNull(Transaction tx)
        {
            Debug.Assert(null != tx, "null transaction?");

            bool hasDelegatedTransaction = false;

            // Promotable transactions are only supported on Yukon
            // servers or newer.
            SqlDelegatedTransaction delegatedTransaction = new SqlDelegatedTransaction(this, tx);

            try
            {
                // NOTE: System.Transactions claims to resolve all
                // potential race conditions between multiple delegate
                // requests of the same transaction to different
                // connections in their code, such that only one
                // attempt to delegate will succeed.

                // NOTE: PromotableSinglePhaseEnlist will eventually
                // make a round trip to the server; doing this inside
                // a lock is not the best choice.  We presume that you
                // aren't trying to enlist concurrently on two threads
                // and leave it at that -- We don't claim any thread
                // safety with regard to multiple concurrent requests
                // to enlist the same connection in different
                // transactions, which is good, because we don't have
                // it anyway.

                // PromotableSinglePhaseEnlist may not actually promote
                // the transaction when it is already delegated (this is
                // the way they resolve the race condition when two
                // threads attempt to delegate the same Lightweight
                // Transaction)  In that case, we can safely ignore
                // our delegated transaction, and proceed to enlist
                // in the promoted one.

                // NOTE: Global Transactions is an Azure SQL DB only
                // feature where the Transaction Manager (TM) is not
                // MS-DTC. Sys.Tx added APIs to support Non MS-DTC
                // promoter types/TM in .NET 4.6.1. Following directions
                // from .NETFX shiproom, to avoid a "hard-dependency"
                // (compile time) on Sys.Tx, we use reflection to invoke
                // the new APIs. Further, the _isGlobalTransaction flag
                // indicates that this is an Azure SQL DB Transaction
                // that could be promoted to a Global Transaction (it's
                // always false for on-prem Sql Server). The Promote()
                // call in SqlDelegatedTransaction makes sure that the
                // right Sys.Tx.dll is loaded and that Global Transactions
                // are actually allowed for this Azure SQL DB.

                if (_isGlobalTransaction)
                {
                    if (SysTxForGlobalTransactions.EnlistPromotableSinglePhase == null)
                    {
                        // This could be a local Azure SQL DB transaction.
                        hasDelegatedTransaction = tx.EnlistPromotableSinglePhase(delegatedTransaction);
                    }
                    else
                    {
                        hasDelegatedTransaction = (bool)SysTxForGlobalTransactions.EnlistPromotableSinglePhase.Invoke(tx, new object[] { delegatedTransaction, _globalTransactionTMID });
                    }
                }
                else
                {
                    // This is an MS-DTC distributed transaction
                    hasDelegatedTransaction = tx.EnlistPromotableSinglePhase(delegatedTransaction);
                }

                if (hasDelegatedTransaction)
                {
                    this.DelegatedTransaction = delegatedTransaction;
                }
            }
            catch (SqlException e)
            {
                // we do not want to eat the error if it is a fatal one
                if (e.Class >= TdsEnums.FATAL_ERROR_CLASS)
                {
                    throw;
                }

                // if the parser is null or its state is not openloggedin, the connection is no longer good.
                SqlInternalConnectionTds tdsConnection = this as SqlInternalConnectionTds;
                if (tdsConnection != null)
                {
                    TdsParser parser = tdsConnection.Parser;
                    if (parser == null || parser.State != TdsParserState.OpenLoggedIn)
                    {
                        throw;
                    }
                }

                // In this case, SqlDelegatedTransaction.Initialize
                // failed and we don't necessarily want to reject
                // things -- there may have been a legitimate reason
                // for the failure.
            }

            if (!hasDelegatedTransaction)
            {
                byte[] cookie = null;

                if (_isGlobalTransaction)
                {
                    if (SysTxForGlobalTransactions.GetPromotedToken == null)
                    {
                        throw SQL.UnsupportedSysTxForGlobalTransactions();
                    }

                    cookie = (byte[])SysTxForGlobalTransactions.GetPromotedToken.Invoke(tx, null);
                }
                else
                {
                    if (null == _whereAbouts)
                    {
                        byte[] dtcAddress = GetDTCAddress();

                        if (null == dtcAddress)
                        {
                            throw SQL.CannotGetDTCAddress();
                        }
                        _whereAbouts = dtcAddress;
                    }
                    cookie = GetTransactionCookie(tx, _whereAbouts);
                }

                // send cookie to server to finish enlistment
                PropagateTransactionCookie(cookie);

                _isEnlistedInTransaction = true;
            }

            EnlistedTransaction = tx; // Tell the base class about our enlistment


            // If we're on a Yukon or newer server, and we delegate the
            // transaction successfully, we will have done a begin transaction,
            // which produces a transaction id that we should execute all requests
            // on.  The TdsParser or SmiEventSink will store this information as
            // the current transaction.
            //
            // Likewise, propagating a transaction to a Yukon or newer server will
            // produce a transaction id that The TdsParser or SmiEventSink will
            // store as the current transaction.
            //
            // In either case, when we're working with a Yukon or newer server
            // we better have a current transaction by now.

            Debug.Assert(null != CurrentTransaction, "delegated/enlisted transaction with null current transaction?");
        }
 private void WriteToServerInternal()
 {
     string tDSCommand = null;
     bool flag3 = false;
     bool flag2 = false;
     int[] useSqlValue = null;
     int num5 = this._batchSize;
     bool flag4 = false;
     if (this._batchSize > 0)
     {
         flag4 = true;
     }
     Exception inner = null;
     this._rowsCopied = 0;
     if (this._destinationTableName == null)
     {
         throw SQL.BulkLoadMissingDestinationTable();
     }
     if (this.ReadFromRowSource())
     {
         RuntimeHelpers.PrepareConstrainedRegions();
         try
         {
             bool flag = true;
             this._parser = this._connection.Parser;
             this._stateObj = this._parser.GetSession(this);
             this._stateObj._bulkCopyOpperationInProgress = true;
             try
             {
                 BulkCopySimpleResultSet set;
                 this._stateObj.StartSession(this.ObjectID);
                 try
                 {
                     set = this.CreateAndExecuteInitialQuery();
                 }
                 catch (SqlException exception5)
                 {
                     throw SQL.BulkLoadInvalidDestinationTable(this._destinationTableName, exception5);
                 }
                 this._rowsUntilNotification = this._notifyAfter;
                 tDSCommand = this.AnalyzeTargetAndCreateUpdateBulkCommand(set);
                 if (this._sortedColumnMappings.Count == 0)
                 {
                     return;
                 }
                 this._stateObj.SniContext = SniContext.Snix_SendRows;
             Label_00DD:
                 if (this.IsCopyOption(SqlBulkCopyOptions.UseInternalTransaction))
                 {
                     this._internalTransaction = this._connection.BeginTransaction();
                 }
                 this.SubmitUpdateBulkCommand(set, tDSCommand);
                 try
                 {
                     this.WriteMetaData(set);
                     object[] objArray = new object[this._sortedColumnMappings.Count];
                     if (useSqlValue == null)
                     {
                         useSqlValue = new int[objArray.Length];
                     }
                     int num3 = num5;
                     do
                     {
                         for (int i = 0; i < objArray.Length; i++)
                         {
                             _ColumnMapping mapping = (_ColumnMapping) this._sortedColumnMappings[i];
                             _SqlMetaData metadata = mapping._metadata;
                             object obj2 = this.GetValueFromSourceRow(mapping._sourceColumnOrdinal, metadata, useSqlValue, i);
                             objArray[i] = this.ConvertValue(obj2, metadata);
                         }
                         this._parser.WriteByte(0xd1, this._stateObj);
                         for (int j = 0; j < objArray.Length; j++)
                         {
                             _ColumnMapping mapping2 = (_ColumnMapping) this._sortedColumnMappings[j];
                             _SqlMetaData data = mapping2._metadata;
                             if (data.type != SqlDbType.Variant)
                             {
                                 this._parser.WriteBulkCopyValue(objArray[j], data, this._stateObj);
                             }
                             else
                             {
                                 this._parser.WriteSqlVariantDataRowValue(objArray[j], this._stateObj);
                             }
                         }
                         this._rowsCopied++;
                         if (((this._notifyAfter > 0) && (this._rowsUntilNotification > 0)) && (--this._rowsUntilNotification == 0))
                         {
                             try
                             {
                                 this._stateObj.BcpLock = true;
                                 flag2 = this.FireRowsCopiedEvent((long) this._rowsCopied);
                                 Bid.Trace("<sc.SqlBulkCopy.WriteToServerInternal|INFO> \n");
                                 if (ConnectionState.Open != this._connection.State)
                                 {
                                     goto Label_02F7;
                                 }
                             }
                             catch (Exception exception2)
                             {
                                 if (!ADP.IsCatchableExceptionType(exception2))
                                 {
                                     throw;
                                 }
                                 inner = OperationAbortedException.Aborted(exception2);
                                 goto Label_02F7;
                             }
                             finally
                             {
                                 this._stateObj.BcpLock = false;
                             }
                             if (flag2)
                             {
                                 goto Label_02F7;
                             }
                             this._rowsUntilNotification = this._notifyAfter;
                         }
                         if (this._rowsUntilNotification > this._notifyAfter)
                         {
                             this._rowsUntilNotification = this._notifyAfter;
                         }
                         flag3 = this.ReadFromRowSource();
                         if (flag4)
                         {
                             num3--;
                             if (num3 == 0)
                             {
                                 goto Label_02F7;
                             }
                         }
                     }
                     while (flag3);
                 }
                 catch (NullReferenceException)
                 {
                     this._stateObj.CancelRequest();
                     throw;
                 }
                 catch (Exception exception4)
                 {
                     if (ADP.IsCatchableExceptionType(exception4))
                     {
                         this._stateObj.CancelRequest();
                     }
                     throw;
                 }
             Label_02F7:
                 if (ConnectionState.Open != this._connection.State)
                 {
                     throw ADP.OpenConnectionRequired("WriteToServer", this._connection.State);
                 }
                 this._parser.WriteBulkCopyDone(this._stateObj);
                 this._parser.Run(RunBehavior.UntilDone, null, null, null, this._stateObj);
                 if (flag2 || (inner != null))
                 {
                     throw OperationAbortedException.Aborted(inner);
                 }
                 if (this._internalTransaction != null)
                 {
                     this._internalTransaction.Commit();
                     this._internalTransaction = null;
                 }
                 if (flag3)
                 {
                     goto Label_00DD;
                 }
                 this._localColumnMappings = null;
             }
             catch (Exception exception3)
             {
                 flag = ADP.IsCatchableExceptionType(exception3);
                 if (flag)
                 {
                     this._stateObj._internalTimeout = false;
                     if (this._internalTransaction != null)
                     {
                         if (!this._internalTransaction.IsZombied)
                         {
                             this._internalTransaction.Rollback();
                         }
                         this._internalTransaction = null;
                     }
                 }
                 throw;
             }
             finally
             {
                 if (flag && (this._stateObj != null))
                 {
                     this._stateObj.CloseSession();
                 }
             }
         }
         finally
         {
             if (this._stateObj != null)
             {
                 this._stateObj._bulkCopyOpperationInProgress = false;
                 this._stateObj = null;
             }
         }
     }
 }