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; } } } }
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(); }
private bool TryProcessLoginAck(TdsParserStateObject stateObj, out SqlLoginAck sqlLoginAck) { SqlLoginAck a = new SqlLoginAck(); sqlLoginAck = null; // read past interface type and version if (!stateObj.TrySkipBytes(1)) { return false; } byte[] b = new byte[TdsEnums.VERSION_SIZE]; if (!stateObj.TryReadByteArray(b, 0, b.Length)) { return false; } a.tdsVersion = (UInt32)((((((b[0] << 8) | b[1]) << 8) | b[2]) << 8) | b[3]); // bytes are in motorola order (high byte first) UInt32 majorMinor = a.tdsVersion & 0xff00ffff; UInt32 increment = (a.tdsVersion >> 16) & 0xff; // Server responds: // 0x07000000 -> Sphinx // Notice server response format is different for bwd compat // 0x07010000 -> Shiloh RTM // Notice server response format is different for bwd compat // 0x71000001 -> Shiloh SP1 // 0x72xx0002 -> Yukon RTM // information provided by S. Ashwin switch (majorMinor) { case TdsEnums.YUKON_MAJOR << 24 | TdsEnums.YUKON_RTM_MINOR: // Yukon if (increment != TdsEnums.YUKON_INCREMENT) { throw SQL.InvalidTDSVersion(); } break; case TdsEnums.KATMAI_MAJOR << 24 | TdsEnums.KATMAI_MINOR: if (increment != TdsEnums.KATMAI_INCREMENT) { throw SQL.InvalidTDSVersion(); } _isKatmai = true; break; case TdsEnums.DENALI_MAJOR << 24 | TdsEnums.DENALI_MINOR: if (increment != TdsEnums.DENALI_INCREMENT) { throw SQL.InvalidTDSVersion(); } _isDenali = true; break; default: throw SQL.InvalidTDSVersion(); } _isKatmai |= _isDenali; stateObj._outBytesUsed = stateObj._outputHeaderLen; byte len; if (!stateObj.TryReadByte(out len)) { return false; } if (!stateObj.TrySkipBytes(len * ADP.CharSize)) { return false; } if (!stateObj.TryReadByte(out a.majorVersion)) { return false; } if (!stateObj.TryReadByte(out a.minorVersion)) { return false; } byte buildNumHi, buildNumLo; if (!stateObj.TryReadByte(out buildNumHi)) { return false; } if (!stateObj.TryReadByte(out buildNumLo)) { return false; } a.buildNum = (short)((buildNumHi << 8) + buildNumLo); Debug.Assert(_state == TdsParserState.OpenNotLoggedIn, "ProcessLoginAck called with state not TdsParserState.OpenNotLoggedIn"); _state = TdsParserState.OpenLoggedIn; { if (_fMARS) { _resetConnectionEvent = new AutoResetEvent(true); } } // Fail if SSE UserInstance and we have not received this info. if (_connHandler.ConnectionOptions.UserInstance && ADP.IsEmpty(_connHandler.InstanceName)) { stateObj.AddError(new SqlError(0, 0, TdsEnums.FATAL_ERROR_CLASS, Server, SQLMessage.UserInstanceFailure(), "", 0)); ThrowExceptionAndWarning(stateObj); } sqlLoginAck = a; return true; }
override public void Dispose() { if (Bid.AdvancedOn) { Bid.Trace("<sc.SqlInternalConnectionTds.Dispose|ADV> %d# disposing\n", base.ObjectID); } try { TdsParser parser = Interlocked.Exchange(ref _parser, null); // guard against multiple concurrent dispose calls -- Delegated Transactions might cause this. Debug.Assert(parser != null && _fConnectionOpen || parser == null && !_fConnectionOpen, "Unexpected state on dispose"); if (null != parser) { parser.Disconnect(); } } finally { // UNDONE: MDAC 77928 // close will always close, even if exception is thrown // remember to null out any object references _loginAck = null; _fConnectionOpen = false; // mark internal connection as closed } base.Dispose(); }
internal void OnLoginAck(SqlLoginAck rec) { _loginAck = rec; // if (_recoverySessionData != null) { if (_recoverySessionData._tdsVersion != rec.tdsVersion) { throw SQL.CR_TDSVersionNotPreserved(this); } } if (_currentSessionData != null) { _currentSessionData._tdsVersion = rec.tdsVersion; } }
internal void OnLoginAck(SqlLoginAck rec) { this._loginAck = rec; }
public void OnLoginAck(SqlLoginAck rec) { _loginAck = rec; // UNDONE: throw an error if this is not 7.0 or 7.1[5]. }
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(); }
private SqlLoginAck ProcessLoginAck(TdsParserStateObject stateObj) { SqlLoginAck ack = new SqlLoginAck(); this.SkipBytes(1, stateObj); byte[] buff = new byte[4]; stateObj.ReadByteArray(buff, 0, buff.Length); uint num3 = (uint) ((((((buff[0] << 8) | buff[1]) << 8) | buff[2]) << 8) | buff[3]); uint num6 = num3 & 0xff00ffff; uint num2 = (num3 >> 0x10) & 0xff; switch (num6) { case 0x72000002: if (num2 != 9) { throw SQL.InvalidTDSVersion(); } this._isYukon = true; break; case 0x73000003: if (num2 != 10) { throw SQL.InvalidTDSVersion(); } this._isKatmai = true; break; case 0x7000000: switch (num2) { case 1: this._isShiloh = true; goto Label_00DF; } throw SQL.InvalidTDSVersion(); case 0x71000001: if (num2 != 0) { throw SQL.InvalidTDSVersion(); } this._isShilohSP1 = true; break; default: throw SQL.InvalidTDSVersion(); } Label_00DF: this._isYukon |= this._isKatmai; this._isShilohSP1 |= this._isYukon; this._isShiloh |= this._isShilohSP1; ack.isVersion8 = this._isShiloh; stateObj._outBytesUsed = stateObj._outputHeaderLen; byte length = stateObj.ReadByte(); ack.programName = stateObj.ReadString(length); ack.majorVersion = stateObj.ReadByte(); ack.minorVersion = stateObj.ReadByte(); ack.buildNum = (short) ((stateObj.ReadByte() << 8) + stateObj.ReadByte()); this._state = TdsParserState.OpenLoggedIn; if ((this._isYukon && this._fAsync) && this._fMARS) { this._resetConnectionEvent = new AutoResetEvent(true); } if (this._connHandler.ConnectionOptions.UserInstance && ADP.IsEmpty(this._connHandler.InstanceName)) { this.Errors.Add(new SqlError(0, 0, 20, this.Server, SQLMessage.UserInstanceFailure(), "", 0)); this.ThrowExceptionAndWarning(); } return ack; }