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(); }
_isYukon = true;
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;
_isYukon |= _isKatmai;
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 &&
string.IsNullOrEmpty(_connHandler.InstanceName))
{
stateObj.AddError(new SqlError(0, 0, TdsEnums.FATAL_ERROR_CLASS, Server, SQLMessage.UserInstanceFailure(), "", 0));
ThrowExceptionAndWarning(stateObj);
}
sqlLoginAck = a;
return true;
}