internal bool TryProcessReturnValue(int length, TdsParserStateObject stateObj, out SqlReturnValue returnValue) { returnValue = null; SqlReturnValue rec = new SqlReturnValue(); rec.length = length; // In Yukon this length is -1 ushort parameterIndex; if (!stateObj.TryReadUInt16(out parameterIndex)) { return false; } byte len; if (!stateObj.TryReadByte(out len)) { // Length of parameter name return false; } if (len > 0) { if (!stateObj.TryReadString(len, out rec.parameter)) { return false; } } // read status and ignore byte ignored; if (!stateObj.TryReadByte(out ignored)) { return false; } UInt32 userType; // read user type - 4 bytes Yukon, 2 backwards if (!stateObj.TryReadUInt32(out userType)) { return false; } // read off the flags ushort ignoredFlags; if (!stateObj.TryReadUInt16(out ignoredFlags)) { return false; } // read the type byte tdsType; if (!stateObj.TryReadByte(out tdsType)) { return false; } // read the MaxLen // For xml datatpyes, there is no tokenLength int tdsLen; if (tdsType == TdsEnums.SQLXMLTYPE) { tdsLen = TdsEnums.SQL_USHORTVARMAXLEN; } else if (IsVarTimeTds(tdsType)) tdsLen = 0; // placeholder until we read the scale, just make sure it's not SQL_USHORTVARMAXLEN else if (tdsType == TdsEnums.SQLDATE) { tdsLen = 3; } else { if (!TryGetTokenLength(tdsType, stateObj, out tdsLen)) { return false; } } rec.metaType = MetaType.GetSqlDataType(tdsType, userType, tdsLen); rec.type = rec.metaType.SqlDbType; // always use the nullable type for parameters if Shiloh or later // Sphinx sometimes sends fixed length return values rec.tdsType = rec.metaType.NullableType; rec.isNullable = true; if (tdsLen == TdsEnums.SQL_USHORTVARMAXLEN) { rec.metaType = MetaType.GetMaxMetaTypeFromMetaType(rec.metaType); } if (rec.type == SqlDbType.Decimal) { if (!stateObj.TryReadByte(out rec.precision)) { return false; } if (!stateObj.TryReadByte(out rec.scale)) { return false; } } if (rec.metaType.IsVarTime) { if (!stateObj.TryReadByte(out rec.scale)) { return false; } } if (tdsType == TdsEnums.SQLUDT) { throw SQL.UnsupportedFeatureAndToken(_connHandler, SqlDbType.Udt.ToString()); } if (rec.type == SqlDbType.Xml) { // Read schema info byte schemapresent; if (!stateObj.TryReadByte(out schemapresent)) { return false; } if ((schemapresent & 1) != 0) { if (!stateObj.TryReadByte(out len)) { return false; } if (len != 0) { if (!stateObj.TryReadString(len, out rec.xmlSchemaCollectionDatabase)) { return false; } } if (!stateObj.TryReadByte(out len)) { return false; } if (len != 0) { if (!stateObj.TryReadString(len, out rec.xmlSchemaCollectionOwningSchema)) { return false; } } short slen; if (!stateObj.TryReadInt16(out slen)) { return false; } if (slen != 0) { if (!stateObj.TryReadString(slen, out rec.xmlSchemaCollectionName)) { return false; } } } } else if (rec.metaType.IsCharType) { // read the collation for 8.x servers if (!TryProcessCollation(stateObj, out rec.collation)) { return false; } int codePage = GetCodePage(rec.collation, stateObj); // if the column lcid is the same as the default, use the default encoder if (codePage == _defaultCodePage) { rec.codePage = _defaultCodePage; rec.encoding = _defaultEncoding; } else { rec.codePage = codePage; rec.encoding = System.Text.Encoding.GetEncoding(rec.codePage); } } // for now we coerce return values into a SQLVariant, not good... bool isNull = false; ulong valLen; if (!TryProcessColumnHeaderNoNBC(rec, stateObj, out isNull, out valLen)) { return false; } // always read as sql types Debug.Assert(valLen < (ulong)(Int32.MaxValue), "ProcessReturnValue received data size > 2Gb"); int intlen = valLen > (ulong)(Int32.MaxValue) ? Int32.MaxValue : (int)valLen; if (rec.metaType.IsPlp) { intlen = Int32.MaxValue; // If plp data, read it all } if (isNull) { GetNullSqlValue(rec.value, rec); } else { if (!TryReadSqlValue(rec.value, rec, intlen, stateObj)) { return false; } } returnValue = rec; return true; }
internal bool TryProcessReturnValue(int length, TdsParserStateObject stateObj, out SqlReturnValue returnValue, SqlCommandColumnEncryptionSetting columnEncryptionSetting) { returnValue = null; SqlReturnValue rec = new SqlReturnValue(); rec.length = length; // In Yukon this length is -1 if (_isYukon) { if (!stateObj.TryReadUInt16(out rec.parmIndex)) { return false; } } byte len; if (!stateObj.TryReadByte(out len)) { // Length of parameter name return false; } rec.parameter = null; if (len > 0) { if (!stateObj.TryReadString(len, out rec.parameter)) { return false; } } // read status and ignore byte ignored; if (!stateObj.TryReadByte(out ignored)) { return false; } UInt32 userType; // read user type - 4 bytes Yukon, 2 backwards if (IsYukonOrNewer) { if (!stateObj.TryReadUInt32(out userType)) { return false; } } else { ushort userTypeShort; if (!stateObj.TryReadUInt16(out userTypeShort)) { return false; } userType = userTypeShort; } // Read off the flags. // The first byte is ignored since it doesn't contain any interesting information. byte flags; if (!stateObj.TryReadByte(out flags)) { return false; } if (!stateObj.TryReadByte(out flags)) { return false; } // Check if the column is encrypted. if (_serverSupportsColumnEncryption) { rec.isEncrypted = (TdsEnums.IsEncrypted == (flags & TdsEnums.IsEncrypted)); } // read the type byte tdsType; if (!stateObj.TryReadByte(out tdsType)) { return false; } // read the MaxLen // For xml datatpyes, there is no tokenLength int tdsLen; if (tdsType == TdsEnums.SQLXMLTYPE) { tdsLen = TdsEnums.SQL_USHORTVARMAXLEN; } else if (IsVarTimeTds(tdsType)) tdsLen = 0; // placeholder until we read the scale, just make sure it's not SQL_USHORTVARMAXLEN else if (tdsType == TdsEnums.SQLDATE) { tdsLen = 3; } else { if (!TryGetTokenLength(tdsType, stateObj, out tdsLen)) { return false; } } rec.metaType = MetaType.GetSqlDataType(tdsType, userType, tdsLen); rec.type = rec.metaType.SqlDbType; // always use the nullable type for parameters if Shiloh or later // Sphinx sometimes sends fixed length return values if (_isShiloh) { rec.tdsType = rec.metaType.NullableType; rec.isNullable = true; if (tdsLen == TdsEnums.SQL_USHORTVARMAXLEN) { Debug.Assert(_isYukon, "plp data from pre-Yukon server"); rec.metaType = MetaType.GetMaxMetaTypeFromMetaType(rec.metaType); } } else { // For sphinx, keep the fixed type if that is what is returned if (rec.metaType.NullableType == tdsType) rec.isNullable = true; rec.tdsType = (byte)tdsType; } if (rec.type == SqlDbType.Decimal) { if (!stateObj.TryReadByte(out rec.precision)) { return false; } if (!stateObj.TryReadByte(out rec.scale)) { return false; } } if (rec.metaType.IsVarTime) { if (!stateObj.TryReadByte(out rec.scale)) { return false; } } if (tdsType == TdsEnums.SQLUDT) { if (!TryProcessUDTMetaData((SqlMetaDataPriv) rec, stateObj)) { return false; } } if (rec.type == SqlDbType.Xml) { // Read schema info byte schemapresent; if (!stateObj.TryReadByte(out schemapresent)) { return false; } if ((schemapresent & 1) != 0) { if (!stateObj.TryReadByte(out len)) { return false; } if (len != 0) { if (!stateObj.TryReadString(len, out rec.xmlSchemaCollectionDatabase)) { return false; } } if (!stateObj.TryReadByte(out len)) { return false; } if (len != 0) { if (!stateObj.TryReadString(len, out rec.xmlSchemaCollectionOwningSchema)) { return false; } } short slen; if (!stateObj.TryReadInt16(out slen)) { return false; } if (slen != 0) { if (!stateObj.TryReadString(slen, out rec.xmlSchemaCollectionName)) { return false; } } } } else if (_isShiloh && rec.metaType.IsCharType) { // read the collation for 8.x servers if (!TryProcessCollation(stateObj, out rec.collation)) { return false; } int codePage = GetCodePage(rec.collation, stateObj); // if the column lcid is the same as the default, use the default encoder if (codePage == _defaultCodePage) { rec.codePage = _defaultCodePage; rec.encoding = _defaultEncoding; } else { rec.codePage = codePage; rec.encoding = System.Text.Encoding.GetEncoding(rec.codePage); } } // For encrypted parameters, read the unencrypted type and encryption information. if (_serverSupportsColumnEncryption && rec.isEncrypted) { if (!TryProcessTceCryptoMetadata(stateObj, rec, cipherTable: null, columnEncryptionSetting: columnEncryptionSetting, isReturnValue: true)) { return false; } } // for now we coerce return values into a SQLVariant, not good... bool isNull = false; ulong valLen; if (!TryProcessColumnHeaderNoNBC(rec, stateObj, out isNull, out valLen)) { return false; } // always read as sql types Debug.Assert(valLen < (ulong)(Int32.MaxValue), "ProcessReturnValue received data size > 2Gb"); int intlen = valLen > (ulong)(Int32.MaxValue) ? Int32.MaxValue : (int)valLen; if (rec.metaType.IsPlp) { intlen = Int32.MaxValue; // If plp data, read it all } if (isNull) { GetNullSqlValue(rec.value, rec, SqlCommandColumnEncryptionSetting.Disabled, _connHandler); } else { // We should never do any decryption here, so pass disabled as the command encryption override. // We only read the binary value and decryption will be performed by OnReturnValue(). if (!TryReadSqlValue(rec.value, rec, intlen, stateObj, SqlCommandColumnEncryptionSetting.Disabled, columnName:null /*Not used*/)) { return false; } } returnValue = rec; return true; }
internal void OnReturnValue(SqlReturnValue rec) { if (this._inPrepare) { if (!rec.value.IsNull) { this._prepareHandle = rec.value.Int32; } this._inPrepare = false; } else { SqlParameterCollection currentParameterCollection = this.GetCurrentParameterCollection(); int parameterCount = this.GetParameterCount(currentParameterCollection); SqlParameter parameter = this.GetParameterForOutputValueExtraction(currentParameterCollection, rec.parameter, parameterCount); if (parameter != null) { object obj1 = parameter.Value; if (SqlDbType.Udt == parameter.SqlDbType) { object byteArray = null; try { SqlConnection.CheckGetExtendedUDTInfo(rec, true); if (rec.value.IsNull) { byteArray = DBNull.Value; } else { byteArray = rec.value.ByteArray; } parameter.Value = this.Connection.GetUdtValue(byteArray, rec, false); } catch (FileNotFoundException exception2) { parameter.SetUdtLoadError(exception2); } catch (FileLoadException exception) { parameter.SetUdtLoadError(exception); } } else { parameter.SetSqlBuffer(rec.value); MetaType metaTypeFromSqlDbType = MetaType.GetMetaTypeFromSqlDbType(rec.type, rec.isMultiValued); if (rec.type == SqlDbType.Decimal) { parameter.ScaleInternal = rec.scale; parameter.PrecisionInternal = rec.precision; } else if (metaTypeFromSqlDbType.IsVarTime) { parameter.ScaleInternal = rec.scale; } else if (rec.type == SqlDbType.Xml) { SqlCachedBuffer buffer = parameter.Value as SqlCachedBuffer; if (buffer != null) { parameter.Value = buffer.ToString(); } } if (rec.collation != null) { parameter.Collation = rec.collation; } } } } }
internal SqlReturnValue ProcessReturnValue(int length, TdsParserStateObject stateObj) { int tokenLength; uint num8; SqlReturnValue metaData = new SqlReturnValue { length = length }; if (this._isYukon) { metaData.parmIndex = stateObj.ReadUInt16(); } byte num2 = stateObj.ReadByte(); if (num2 > 0) { metaData.parameter = stateObj.ReadString(num2); } stateObj.ReadByte(); if (this.IsYukonOrNewer) { num8 = stateObj.ReadUInt32(); } else { num8 = stateObj.ReadUInt16(); } stateObj.ReadUInt16(); byte tdsType = stateObj.ReadByte(); if (tdsType == 0xf1) { tokenLength = 0xffff; } else if (this.IsVarTimeTds(tdsType)) { tokenLength = 0; } else if (tdsType == 40) { tokenLength = 3; } else { tokenLength = this.GetTokenLength(tdsType, stateObj); } metaData.metaType = MetaType.GetSqlDataType(tdsType, num8, tokenLength); metaData.type = metaData.metaType.SqlDbType; if (this._isShiloh) { metaData.tdsType = metaData.metaType.NullableType; metaData.isNullable = true; if (tokenLength == 0xffff) { metaData.metaType = MetaType.GetMaxMetaTypeFromMetaType(metaData.metaType); } } else { if (metaData.metaType.NullableType == tdsType) { metaData.isNullable = true; } metaData.tdsType = tdsType; } if (metaData.type == SqlDbType.Decimal) { metaData.precision = stateObj.ReadByte(); metaData.scale = stateObj.ReadByte(); } if (metaData.metaType.IsVarTime) { metaData.scale = stateObj.ReadByte(); } if (tdsType == 240) { this.ProcessUDTMetaData(metaData, stateObj); } if (metaData.type == SqlDbType.Xml) { if ((stateObj.ReadByte() & 1) != 0) { num2 = stateObj.ReadByte(); if (num2 != 0) { metaData.xmlSchemaCollectionDatabase = stateObj.ReadString(num2); } num2 = stateObj.ReadByte(); if (num2 != 0) { metaData.xmlSchemaCollectionOwningSchema = stateObj.ReadString(num2); } short num7 = stateObj.ReadInt16(); if (num7 != 0) { metaData.xmlSchemaCollectionName = stateObj.ReadString(num7); } } } else if (this._isShiloh && metaData.metaType.IsCharType) { metaData.collation = this.ProcessCollation(stateObj); int codePage = this.GetCodePage(metaData.collation, stateObj); if (codePage == this._defaultCodePage) { metaData.codePage = this._defaultCodePage; metaData.encoding = this._defaultEncoding; } else { metaData.codePage = codePage; metaData.encoding = Encoding.GetEncoding(metaData.codePage); } } bool isNull = false; ulong num5 = this.ProcessColumnHeader(metaData, stateObj, out isNull); int num4 = (num5 > 0x7fffffffL) ? 0x7fffffff : ((int) num5); if (metaData.metaType.IsPlp) { num4 = 0x7fffffff; } if (isNull) { this.GetNullSqlValue(metaData.value, metaData); return metaData; } this.ReadSqlValue(metaData.value, metaData, num4, stateObj); return metaData; }