/// <summary> /// Inflate the token /// </summary> /// <param name="source">Stream to inflate the token from</param> /// <returns>TRUE if inflation is complete</returns> public virtual bool Inflate(Stream source) { // Read protocol value Protocol = (TDSRoutingEnvChangeTokenValueType)source.ReadByte(); // Based on the protocol type read the rest of the token switch (Protocol) { case TDSRoutingEnvChangeTokenValueType.TCP: { // Read port ProtocolProperty = TDSUtilities.ReadUShort(source); // Read alternate server name of the length AlternateServer = TDSUtilities.ReadString(source, (ushort)(TDSUtilities.ReadUShort(source) * 2)); break; } default: { throw new Exception("Unrecognized routing protocol"); } } // Inflation is complete return(true); }
public override bool Inflate(Stream source) { AllHeaders = new TDSAllHeadersToken(); // Inflate all headers if (!AllHeaders.Inflate(source)) { // Failed to inflate headers throw new ArgumentException("Failed to inflate all headers"); } RequestType = (TDSTransMgrReqRequestType)TDSUtilities.ReadUShort(source); switch (RequestType) { case TDSTransMgrReqRequestType.TM_GET_DTC_ADDRESS: case TDSTransMgrReqRequestType.TM_PROPAGATE_XACT: var lenPayload = TDSUtilities.ReadUShort(source); byte[] arrayPayload = new byte[lenPayload]; source.Read(arrayPayload, 0, lenPayload); RequestPayload = arrayPayload; break; case TDSTransMgrReqRequestType.TM_BEGIN_XACT: TransactionIsolationLevel = (TransactionIsolationLevelType)source.ReadByte(); var len = source.ReadByte(); byte[] array = new byte[len]; source.Read(array, 0, len); XactName = array; break; } return(true); }
/// <summary> /// Inflate the token /// NOTE: This operation is not continuable and assumes that the entire token is available in the stream /// </summary> /// <param name="source">Stream to inflate the token from</param> /// <returns>TRUE if inflation is complete</returns> public override bool Inflate(Stream source) { AllHeaders = new TDSAllHeadersToken(); // Inflate all headers if (!AllHeaders.Inflate(source)) { // Failed to inflate headers throw new ArgumentException("Failed to inflate all headers"); } var lengthProcName = TDSUtilities.ReadUShort(source); if (lengthProcName == 65535) { ProcID = (TDSRPCRequestTokenProcID)TDSUtilities.ReadUShort(source); } else { ProcName = TDSUtilities.ReadString(source, (ushort)(lengthProcName * 2)); } OptionFlags = new TDSRPCRequestOptionFlags((byte)TDSUtilities.ReadUShort(source)); TDSRPCRequestParameter p = new TDSRPCRequestParameter(); while (p.Inflate(source)) { Parameters.Add(p); p = new TDSRPCRequestParameter(); } return(true); }
/// <summary> /// Inflate the token /// NOTE: This operation is not continuable and assumes that the entire token is available in the stream /// </summary> /// <param name="source">Stream to inflate the token from</param> /// <returns>TRUE if inflation is complete</returns> public override bool Inflate(Stream source) { // Re-prepare collection Columns = new List <TDSColumnProperty>(); // Read the length of the data ushort length = TDSUtilities.ReadUShort(source); // Current offset in the stream ushort offset = 0; // Inflate each property while (offset < length) { // Allocate a new property TDSColumnProperty newColumn = new TDSColumnProperty(); // Inflate newColumn.Inflate(source); // Register with the collection Columns.Add(newColumn); // Update offset with the size of the last inflated property offset += (ushort)newColumn.InflationSize; } return(true); }
/// <summary> /// Inflate the token /// NOTE: This operation is not continuable and assumes that the entire token is available in the stream /// </summary> /// <param name="source">Stream to inflate the token from</param> /// <returns>TRUE if inflation is complete</returns> public override bool Inflate(Stream source) { // Read column count ushort count = TDSUtilities.ReadUShort(source); // Check if count indicates that no columns are available if (count == 0xFFFF) { // We're done return(true); } // Allocate new collection Columns = new List <TDSColumnData>(); // Inflate each column for (ushort usIndex = 0; usIndex < count; usIndex++) { // Create a new column data TDSColumnData data = new TDSColumnData(); // Inflate data.Inflate(source); // Register data with the collection Columns.Add(data); } return(true); }
/// <summary> /// Inflate the token /// NOTE: This operation is not continuable and assumes that the entire token is available in the stream /// </summary> /// <param name="source">Stream to inflate the token from</param> /// <returns>TRUE if inflation is complete</returns> public override bool Inflate(Stream source) { // Read status Status = (TDSDoneTokenStatusType)TDSUtilities.ReadUShort(source); // Read command Command = (TDSDoneTokenCommandType)TDSUtilities.ReadUShort(source); // Read row count RowCount = TDSUtilities.ReadULong(source); return(true); }
/// <summary> /// Inflate the token /// </summary> /// <param name="source">Stream to inflate the token from</param> /// <returns>TRUE if inflation is complete</returns> public override bool Inflate(Stream source) { // Read the payload length ushort length = TDSUtilities.ReadUShort(source); // Allocate buffer Payload = new byte[length]; // Read payload source.Read(Payload, 0, Payload.Length); return(true); }
/// <summary> /// Inflate the token /// NOTE: This operation is not continuable and assumes that the entire token is available in the stream /// </summary> /// <param name="source">Stream to inflate the token from</param> /// <returns>TRUE if inflation is complete</returns> public override bool Inflate(Stream source) { // Read the stream length ushort length = TDSUtilities.ReadUShort(source); // Check if there's enough space for a short if (length < sizeof(ushort)) { return(false); } // Read return value Number = TDSUtilities.ReadUShort(source); return(true); }
/// <summary> /// Inflate the token /// NOTE: This operation is not continuable and assumes that the entire token is available in the stream /// </summary> /// <param name="source">Stream to inflate the token from</param> public override bool Inflate(Stream source) { // Read the length of the notification ID ushort length = TDSUtilities.ReadUShort(source); // Read notification ID string NotifyID = TDSUtilities.ReadString(source, length); // Read the length of the service broker deployment length = TDSUtilities.ReadUShort(source); // Read service broker deployment string SerciceBrokerDeployment = TDSUtilities.ReadString(source, length); // Read query notification timeout Timeout = TDSUtilities.ReadUInt(source); return(true); }
/// <summary> /// Inflate the token /// NOTE: This operation is not continuable and assumes that the entire token is available in the stream /// </summary> /// <param name="source">Stream to inflate the token from</param> /// <returns>TRUE if inflation is complete</returns> public override bool Inflate(Stream source) { // We skip the token identifier because it is read by token factory // Read token length ushort tokenLength = TDSUtilities.ReadUShort(source); // Read the number Number = TDSUtilities.ReadUInt(source); // Read state State = (byte)source.ReadByte(); // Read class Class = (byte)source.ReadByte(); // Read the message text length ushort textLength = TDSUtilities.ReadUShort(source); // Read the message itself Message = TDSUtilities.ReadString(source, (ushort)(textLength * 2)); // Read server name length textLength = (byte)source.ReadByte(); // Read server name ServerName = TDSUtilities.ReadString(source, (ushort)(textLength * 2)); // Read procedure name length textLength = (byte)source.ReadByte(); // Read procedure name ProcedureName = TDSUtilities.ReadString(source, (ushort)(textLength * 2)); // Read the line number Line = TDSUtilities.ReadUInt(source); return(true); }
public static object InflateColumnData(Stream source, TDSDataType column, Object dataTypeSpecific) { // Dispatch further reading based on the type switch (column) { case TDSDataType.Null: { // No data associated with it return(null); } case TDSDataType.DateTime: { int daypart = TDSUtilities.ReadInt(source); uint timepart = TDSUtilities.ReadUInt(source); return(null); } case TDSDataType.DateTime2N: { var length = (byte)source.ReadByte(); var rawDate = new byte[length]; source.Read(rawDate, 0, length); uint secondIncrements = 0; for (int i = 0; i < length - 3; i++) { secondIncrements += (uint)(rawDate[i] << (8 * i)); } var days = (uint)rawDate[length - 3] + (uint)(rawDate[length - 2] << 8) + (uint)(rawDate[length - 1] << 16); var date = new DateTime(1, 1, 1).AddDays(days).AddSeconds(secondIncrements * Math.Pow(10, -1 * 5)); return(date); } case TDSDataType.Bit: case TDSDataType.Int1: { // Bit, 1 byte data representation return((byte)source.ReadByte()); } case TDSDataType.Int2: { // SmallInt, 2 byte data representation return(unchecked ((short)TDSUtilities.ReadUShort(source))); } case TDSDataType.Int4: { // Int, 4 byte data representation return(unchecked ((int)TDSUtilities.ReadUInt(source))); } case TDSDataType.Float8: { // Float (8 byte data representation) return(BitConverter.ToDouble(BitConverter.GetBytes(TDSUtilities.ReadULong(source)), 0)); } case TDSDataType.Int8: { // BigInt (8 byte data representation) return(unchecked ((long)TDSUtilities.ReadULong(source))); } case TDSDataType.BitN: { // Read length byte length = (byte)source.ReadByte(); // Check if null if (length == 0) { // No data return(null); } // Bit, 1 byte data representation return((byte)source.ReadByte()); } case TDSDataType.IntN: { // Read length byte length = (byte)source.ReadByte(); // Check integer length switch (length) { case 0: { // No data return(null); } case 1: { // Bit data return((byte)source.ReadByte()); } case 2: { // Short data return(unchecked ((short)TDSUtilities.ReadUShort(source))); } case 4: { // Integer data return(unchecked ((int)TDSUtilities.ReadUInt(source))); } case 8: { // Integer data return(unchecked ((long)TDSUtilities.ReadULong(source))); } default: { // We don't know how to inflate this integer throw new InvalidDataException(string.Format("Unable to inflate integer of {0} bytes", length)); } } } case TDSDataType.NumericN: { // Read length byte length = (byte)source.ReadByte(); // Check if null if (length == 0) { // No data return(null); } // Allocate value container byte[] guidBytes = new byte[length]; // Read value source.Read(guidBytes, 0, guidBytes.Length); // Instantiate type return(guidBytes); } case TDSDataType.Guid: { // Read the length byte length = (byte)source.ReadByte(); // Check if we have any data if (length == 0x0000) { // No data return(null); } // Allocate value container byte[] guidBytes = new byte[length]; // Read value source.Read(guidBytes, 0, guidBytes.Length); // Convert to type return(new Guid(guidBytes)); } case TDSDataType.BigVarChar: case TDSDataType.BigChar: { // Read length ushort length = TDSUtilities.ReadUShort(source); // Check if we have any data if (length == 0xFFFF) { // No data return(null); } // Allocate value container byte[] textBytes = new byte[length]; // Read value source.Read(textBytes, 0, textBytes.Length); // Convert to type return(Encoding.ASCII.GetString(textBytes)); } case TDSDataType.NVarChar: { // Check if MAX type if ((dataTypeSpecific as TDSShilohVarCharColumnSpecific).Length == 0xFFFF) { // Read the length of partialy length-prefixed type ulong length = TDSUtilities.ReadULong(source); // Check the value if (length == 0xFFFFFFFFFFFFFFFF) { // There's no data return(null); } else if (length == 0xFFFFFFFFFFFFFFFE) { throw new NotImplementedException("UNKNOWN_PLP_LEN is not implemented yet"); } else { // Allocate a memory stream MemoryStream chunks = new MemoryStream(); // Size of the last chunk uint chunkLength = 0; // Iterate until we read the whole data do { // Read the length of the chunk chunkLength = TDSUtilities.ReadUInt(source); // Allocate chunk container byte[] chunk = new byte[chunkLength]; // Read value source.Read(chunk, 0, chunk.Length); // Append into the stream chunks.Write(chunk, 0, chunk.Length); }while (chunkLength > 0); // Convert to byte array byte[] byteString = chunks.ToArray(); // Serialize the data into the string return(Encoding.Unicode.GetString(byteString, 0, byteString.Length)); } } else { // Read length ushort length = TDSUtilities.ReadUShort(source); // Check if we have any data if (length == 0xFFFF) { // No data return(null); } // Read the whole string at once return(TDSUtilities.ReadString(source, (ushort)length)); } } case TDSDataType.BigVarBinary: { byte[] bytes = null; // Check if MAX type if ((ushort)dataTypeSpecific == 0xFFFF) { // Read the length of partialy length-prefixed type ulong length = TDSUtilities.ReadULong(source); // Check the value if (length == 0xFFFFFFFFFFFFFFFF) { // There's no data return(null); } else if (length == 0xFFFFFFFFFFFFFFFE) { throw new NotImplementedException("UNKNOWN_PLP_LEN is not implemented yet"); } else { // Allocate a memory stream MemoryStream chunks = new MemoryStream(); // Size of the last chunk uint chunkLength = 0; // Iterate until we read the whole data do { // Read the length of the chunk chunkLength = TDSUtilities.ReadUInt(source); // Allocate chunk container byte[] chunk = new byte[chunkLength]; // Read value source.Read(chunk, 0, chunk.Length); // Append into the stream chunks.Write(chunk, 0, chunk.Length); }while (chunkLength > 0); // Serialize to byte array bytes = chunks.ToArray(); } } else { // Read length ushort length = TDSUtilities.ReadUShort(source); // Check if we have any data if (length == 0xFFFF) { // No data return(null); } // Allocate value container bytes = new byte[length]; // Read value source.Read(bytes, 0, bytes.Length); } // Convert to type return(bytes); } case TDSDataType.BigBinary: { // Read length ushort length = TDSUtilities.ReadUShort(source); // Check if we have any data if (length == 0xFFFF) { // No data return(null); } // Allocate value container byte[] bytes = new byte[length]; // Read value source.Read(bytes, 0, bytes.Length); // Convert to type return(bytes); } default: { // We don't know this type throw new NotImplementedException(string.Format("Unrecognized data type {0} for inflation", column)); } } }
/// <summary> /// Inflate the token /// NOTE: This operation is not continuable and assumes that the entire token is available in the stream /// </summary> /// <param name="source">Stream to inflate the token from</param> /// <returns>TRUE if inflation is complete</returns> public override bool Inflate(Stream source) { // Read packet length uint length = TDSUtilities.ReadUInt(source); // Read TDS version string tdsVersion = string.Format("{0:X}", TDSUtilities.ReadUInt(source)); // Consturct TDS version TDSVersion = new Version(int.Parse(tdsVersion.Substring(0, 1)), int.Parse(tdsVersion.Substring(1, 1)), Convert.ToInt32(tdsVersion.Substring(2, 2), 16), Convert.ToInt32(tdsVersion.Substring(4, 4), 16)); // Read packet length PacketSize = TDSUtilities.ReadUInt(source); // Read client program version ClientProgramVersion = TDSUtilities.ReadUInt(source); // Read client program identifier ClientPID = TDSUtilities.ReadUInt(source); // Read connection identifier ConnectionID = TDSUtilities.ReadUInt(source); // Instantiate the first optional flags OptionalFlags1 = new TDSLogin7TokenOptionalFlags1((byte)source.ReadByte()); // Instantiate the second optional flags OptionalFlags2 = new TDSLogin7TokenOptionalFlags2((byte)source.ReadByte()); // Instantiate type flags TypeFlags = new TDSLogin7TokenTypeFlags((byte)source.ReadByte()); // Instantiate the third optional flags OptionalFlags3 = new TDSLogin7TokenOptionalFlags3((byte)source.ReadByte()); // Read client time zone ClientTimeZone = TDSUtilities.ReadInt(source); // Read client locale identifier ClientLCID = TDSUtilities.ReadUInt(source); // Prepare a collection of property values that will be set later IList <TDSLogin7TokenOffsetProperty> variableProperties = new List <TDSLogin7TokenOffsetProperty>(); // Read client host name variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("HostName"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source))); // Read user name and password variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("UserID"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source))); variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("Password"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source))); // Read application name variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("ApplicationName"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source))); // Read server name variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("ServerName"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source))); // Check if extension is used if (OptionalFlags3.ExtensionFlag) { // Read Feature extension. Note that this is just an offset of the value, not the value itself variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("FeatureExt"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source), true)); } else { // Skip unused TDSUtilities.ReadUShort(source); TDSUtilities.ReadUShort(source); } // Read client library name variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("LibraryName"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source))); // Read language variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("Language"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source))); // Read database variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("Database"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source))); ClientID = new byte[6]; // Read unique client identifier source.Read(ClientID, 0, ClientID.Length); // Read SSPI blob variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("SSPI"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source))); // Read database file to be attached variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("AttachDatabaseFile"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source))); // Read password change variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("ChangePassword"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source))); // Read long SSPI uint sspiLength = TDSUtilities.ReadUInt(source); // At this point we surpassed the fixed packet length long inflationOffset = FixedPacketLength; // Order strings in ascending order by offset // For the most cases this should not change the order of the options in the stream, but just in case variableProperties = variableProperties.OrderBy(p => p.Position).ToList(); // We can't use "foreach" because FeatureExt processing changes the collection hence we can only go index-based way int iCurrentProperty = 0; // Iterate over each property while (iCurrentProperty < variableProperties.Count) { // Get the property at the indexed position TDSLogin7TokenOffsetProperty property = variableProperties[iCurrentProperty]; // Check if length is positive if (property.Length == 0) { // Move to the next propety iCurrentProperty++; continue; } // Ensure that current offset points to the option while (inflationOffset < property.Position) { // Read the stream source.ReadByte(); // Advance position inflationOffset++; } // Check special properties if (property.Property.Name == "Password" || property.Property.Name == "ChangePassword") { // Read passwod string property.Property.SetValue(this, TDSUtilities.ReadPasswordString(source, (ushort)(property.Length * 2)), null); // Advance the position inflationOffset += (property.Length * 2); } else if (property.Property.Name == "SSPI") { // If cbSSPI < USHRT_MAX, then this length MUST be used for SSPI and cbSSPILong MUST be ignored. // If cbSSPI == USHRT_MAX, then cbSSPILong MUST be checked. if (property.Length == ushort.MaxValue) { // If cbSSPILong > 0, then that value MUST be used. If cbSSPILong ==0, then cbSSPI (USHRT_MAX) MUST be used. if (sspiLength > 0) { // We don't know how to handle SSPI packets that exceed TDS packet size throw new NotSupportedException("Long SSPI blobs are not supported yet"); } } // Use short length instead sspiLength = property.Length; // Allocate buffer for SSPI data SSPI = new byte[sspiLength]; // Read SSPI blob source.Read(SSPI, 0, SSPI.Length); // Advance the position inflationOffset += sspiLength; } else if (property.Property.Name == "FeatureExt") { // Check if this is the property or a pointer to the property if (property.IsOffsetOffset) { // Read the actual offset of the feature extension property.Position = TDSUtilities.ReadUInt(source); // Mark that now we have actual value property.IsOffsetOffset = false; // Advance the position inflationOffset += sizeof(uint); // Re-order the collection variableProperties = variableProperties.OrderBy(p => p.Position).ToList(); // Subtract position to stay on the same spot for subsequent property iCurrentProperty--; } else { // Create a list of features. FeatureExt = new TDSLogin7FeatureOptionsToken(); // Inflate feature extension FeatureExt.Inflate(source); // Advance position by the size of the inflated token inflationOffset += FeatureExt.InflationSize; } } else { // Read the string and assign it to the property of this instance property.Property.SetValue(this, TDSUtilities.ReadString(source, (ushort)(property.Length * 2)), null); // Advance the position inflationOffset += (property.Length * 2); } // Advance to the next property iCurrentProperty++; } return(true); }
public override bool Inflate(Stream source) { var len = source.ReadByte(); if (len == -1) { return(false); } ParamMetaData = TDSUtilities.ReadString(source, (ushort)(len * 2)); StatusFlags = new TDSRPCRequestStatusFlags((byte)source.ReadByte()); DataType = (TDSDataType)source.ReadByte(); // Dispatch further reading based on the type switch (DataType) { case TDSDataType.Binary: case TDSDataType.VarBinary: case TDSDataType.Char: case TDSDataType.VarChar: // The above types are deprecated after TDS 7205. case TDSDataType.BitN: case TDSDataType.Guid: case TDSDataType.IntN: case TDSDataType.MoneyN: case TDSDataType.FloatN: case TDSDataType.DateTimeN: { // Byte length DataTypeSpecific = source.ReadByte(); break; } case TDSDataType.DateN: { // No details DataTypeSpecific = null; break; } case TDSDataType.TimeN: case TDSDataType.DateTime2N: case TDSDataType.DateTimeOffsetN: { // Scale DataTypeSpecific = source.ReadByte(); break; } case TDSDataType.DecimalN: case TDSDataType.NumericN: { // Read values byte length = (byte)source.ReadByte(); byte precision = (byte)source.ReadByte(); byte scale = (byte)source.ReadByte(); // Decimal data type specific DataTypeSpecific = new TDSDecimalColumnSpecific(length, precision, scale); break; } case TDSDataType.BigBinary: case TDSDataType.BigVarBinary: { // Short length DataTypeSpecific = TDSUtilities.ReadUShort(source); break; } case TDSDataType.BigChar: case TDSDataType.BigVarChar: case TDSDataType.NChar: case TDSDataType.NVarChar: { // SHILOH CHAR types have collation associated with it. TDSShilohVarCharColumnSpecific typedSpecific = new TDSShilohVarCharColumnSpecific(); // Read length typedSpecific.Length = TDSUtilities.ReadUShort(source); // Create collation typedSpecific.Collation = new TDSColumnDataCollation(); // Read collation typedSpecific.Collation.WCID = TDSUtilities.ReadUInt(source); typedSpecific.Collation.SortID = (byte)source.ReadByte(); DataTypeSpecific = typedSpecific; break; } case TDSDataType.Text: case TDSDataType.NText: { // YukonTextType.Len + YukonTextType.tdsCollationInfo + YukonTextType.cParts // cb = sizeof(LONG) + sizeof(TDSCOLLATION) + sizeof(BYTE); break; } case TDSDataType.Image: { // Data length DataTypeSpecific = TDSUtilities.ReadUInt(source); break; } case TDSDataType.SSVariant: { // Data length DataTypeSpecific = TDSUtilities.ReadUInt(source); break; } case TDSDataType.Udt: { // hr = GetUDTColFmt(pvOwner, dwTimeout); break; } case TDSDataType.Xml: { // cb = sizeof(lpColFmt->YukonXmlType.bSchemaPresent); break; } } Value = TDSRowTokenBase.InflateColumnData(source, DataType, DataTypeSpecific); return(true); }
/// <summary> /// Inflate the token /// NOTE: This operation is not continuable and assumes that the entire token is available in the stream /// </summary> /// <param name="source">Stream to inflate the token from</param> /// <returns>TRUE if inflation is complete</returns> public override bool Inflate(Stream source) { // Prepare a list of options IList <TDSPreLoginTokenOption> options = new List <TDSPreLoginTokenOption>(); // Inflate all options until terminator is detected do { // Create a new option options.Add(new TDSPreLoginTokenOption()); // Inflate it if (!options[options.Count - 1].Inflate(source)) { return(false); } }while (options[options.Count - 1].Type != TDSPreLoginTokenOptionType.Terminator); // Order the options in ascending order by offset // For the most cases this should not change the order of the options in the stream, but just in case options = options.OrderBy(o => o.Position).ToList(); // Calculate current inflation offset ushort inflationOffset = (ushort)options.Sum(o => o.TokenLength); // Iterate through each option and inflate it foreach (TDSPreLoginTokenOption option in options) { // Ensure that current offset points to the option while (inflationOffset < option.Position) { // Read the stream source.ReadByte(); // Advance position inflationOffset++; } // Check the type of the pre-login packet option type switch (option.Type) { case TDSPreLoginTokenOptionType.Version: { // Check if version fits if (option.Length >= 6) { // Read the data of the specified length at the specified position Version = new Version( source.ReadByte() & 0xff, // Major source.ReadByte(), // Minor (source.ReadByte() << 8) + source.ReadByte()); // Build (swap bytes) // Read sub-build SubBuild = TDSUtilities.ReadUShort(source); // Update the offset inflationOffset += 6; } break; } case TDSPreLoginTokenOptionType.Encryption: { // Check is option fits if (option.Length >= 1) { // Read encryption Encryption = (TDSPreLoginTokenEncryptionType)source.ReadByte(); // Update the offset inflationOffset += 1; } break; } case TDSPreLoginTokenOptionType.Instance: { // Currently does nothing. break; } case TDSPreLoginTokenOptionType.ThreadID: { // Check if thread ID fits if (option.Length >= 4) { // Read the data of the specified length at the specified position (big-endian) ThreadID = TDSUtilities.ReadUInt(source); // Update the offset inflationOffset += 4; } break; } case TDSPreLoginTokenOptionType.Mars: { // Check is option fits if (option.Length >= 1) { // Read byte IsMARS = (source.ReadByte() == 0x01); // Update the offset inflationOffset += 1; } break; } case TDSPreLoginTokenOptionType.TraceID: { if (option.Length >= 36) { // Allocate memory ClientTraceID = new byte[16]; // Read connection Trace ID source.Read(ClientTraceID, 0, 16); // Allocate memory ActivityID = new byte[20]; // Read Activity ID. source.Read(ActivityID, 0, 20); // Update the offset inflationOffset += 36; } break; } case TDSPreLoginTokenOptionType.FederatedAuthenticationRequired: { if (option.Length >= 1) { // Read authentication type. FedAuthRequired = (TdsPreLoginFedAuthRequiredOption)source.ReadByte(); // Update the offset inflationOffset += 1; } break; } case TDSPreLoginTokenOptionType.NonceOption: { if (option.Length >= 32) { //Allocate memory Nonce = new byte[32]; // Read Nonce. source.Read(Nonce, 0, 32); // Update the offset inflationOffset += 32; } break; } } } return(true); }
/// <summary> /// Inflate the token /// NOTE: This operation is not continuable and assumes that the entire token is available in the stream /// </summary> /// <param name="source">Stream to inflate the token from</param> public override bool Inflate(Stream source) { // Allocate headers Headers = new List <TDSPacketToken>(); // Read total length uint totalLength = TDSUtilities.ReadUInt(source); // Take total length DWORD into account totalLength -= 4; // Keep reading the stream until we inflate all headers while (totalLength > 0) { // Read header length uint headerLength = TDSUtilities.ReadUInt(source); // Update total length before we start modifying it totalLength -= headerLength; // Take header length DWORD into account headerLength -= 4; // Check if header length allows header type if (headerLength >= 2) { // Read header type TDSHeaderType type = (TDSHeaderType)TDSUtilities.ReadUShort(source); // Take header type into account headerLength -= 2; // Based on the header type inflate the header switch (type) { case TDSHeaderType.QueryNotifications: { // Create instance Headers.Add(new TDSQueryNotificationsHeader()); break; } case TDSHeaderType.TransactionDescriptor: { // Create instance Headers.Add(new TDSTransactionDescriptorHeader()); break; } case TDSHeaderType.Trace: { // Create instance Headers.Add(new TDSTraceHeader()); break; } default: { // We don't know this token throw new ArgumentException("Unrecognized header type", "Header Type"); } } // Inflate the last header if (!Headers.Last().Inflate(source)) { // We failed to inflate this token so we can't proceed throw new Exception(string.Format("Failed to inflate header \"{0}\"", type)); } } } // We're done inflating return(true); }
/// <summary> /// Inflate the token /// </summary> /// <param name="source">Stream to inflate the token from</param> /// <returns>TRUE if inflation is complete</returns> public bool Inflate(Stream source) { // Read user type UserType = TDSUtilities.ReadUInt(source); // Read flags Flags = new TDSColumnDataFlags(TDSUtilities.ReadUShort(source)); // Read server type DataType = (TDSDataType)source.ReadByte(); // Dispatch further reading based on the type switch (DataType) { case TDSDataType.Binary: case TDSDataType.VarBinary: case TDSDataType.Char: case TDSDataType.VarChar: // The above types are deprecated after TDS 7205. case TDSDataType.BitN: case TDSDataType.Guid: case TDSDataType.IntN: case TDSDataType.MoneyN: case TDSDataType.FloatN: case TDSDataType.DateTimeN: { // Byte length DataTypeSpecific = source.ReadByte(); break; } case TDSDataType.DateN: { // No details DataTypeSpecific = null; break; } case TDSDataType.TimeN: case TDSDataType.DateTime2N: case TDSDataType.DateTimeOffsetN: { // Scale DataTypeSpecific = source.ReadByte(); break; } case TDSDataType.DecimalN: case TDSDataType.NumericN: { // Read values byte length = (byte)source.ReadByte(); byte precision = (byte)source.ReadByte(); byte scale = (byte)source.ReadByte(); // Decimal data type specific DataTypeSpecific = new TDSDecimalColumnSpecific(length, precision, scale); break; } case TDSDataType.BigBinary: case TDSDataType.BigVarBinary: { // Short length DataTypeSpecific = TDSUtilities.ReadUShort(source); break; } case TDSDataType.BigChar: case TDSDataType.BigVarChar: case TDSDataType.NChar: case TDSDataType.NVarChar: { // SHILOH CHAR types have collation associated with it. TDSShilohVarCharColumnSpecific typedSpecific = new TDSShilohVarCharColumnSpecific(); // Read length typedSpecific.Length = TDSUtilities.ReadUShort(source); // Create collation typedSpecific.Collation = new TDSColumnDataCollation(); // Read collation typedSpecific.Collation.WCID = TDSUtilities.ReadUInt(source); typedSpecific.Collation.SortID = (byte)source.ReadByte(); DataTypeSpecific = typedSpecific; break; } case TDSDataType.Text: case TDSDataType.NText: { // YukonTextType.Len + YukonTextType.tdsCollationInfo + YukonTextType.cParts // cb = sizeof(LONG) + sizeof(TDSCOLLATION) + sizeof(BYTE); break; } case TDSDataType.Image: { // Data length DataTypeSpecific = TDSUtilities.ReadUInt(source); break; } case TDSDataType.SSVariant: { // Data length DataTypeSpecific = TDSUtilities.ReadUInt(source); break; } case TDSDataType.Udt: { // hr = GetUDTColFmt(pvOwner, dwTimeout); break; } case TDSDataType.Xml: { // cb = sizeof(lpColFmt->YukonXmlType.bSchemaPresent); break; } } // Check if table name is available if (DataType == TDSDataType.Text || DataType == TDSDataType.NText || DataType == TDSDataType.Image) { // Allocate table name container TableName = new List <string>(); // Read part count byte partCount = (byte)source.ReadByte(); // Write each part for (byte bPart = 0; bPart < partCount; bPart++) { // Read table part length and value TableName.Add(TDSUtilities.ReadString(source, (ushort)(TDSUtilities.ReadUShort(source) * 2))); } } // Read column name Name = TDSUtilities.ReadString(source, (ushort)(source.ReadByte() * 2)); return(true); }
/// <summary> /// Inflate the token /// NOTE: This operation is not continuable and assumes that the entire token is available in the stream /// </summary> /// <param name="source">Stream to inflate the token from</param> /// <returns>TRUE if inflation is complete</returns> public override bool Inflate(Stream source) { // We skip the token identifier because it is read by token factory // Read token length ushort tokenLength = TDSUtilities.ReadUShort(source); // Check if length can accomodate at least the type if (tokenLength == 0) { // We're done inflating this token return(true); } // Read the token type Type = (TDSEnvChangeTokenType)source.ReadByte(); // Update the token length left tokenLength--; // Check if we can squeez anything else if (tokenLength == 0) { // We're done inflating this token return(true); } // Read the rest of the token based on the token type switch (Type) { case TDSEnvChangeTokenType.Database: case TDSEnvChangeTokenType.Language: case TDSEnvChangeTokenType.CharacterSet: case TDSEnvChangeTokenType.PacketSize: case TDSEnvChangeTokenType.RealTimeLogShipping: { // Read new value length byte valueLength = (byte)source.ReadByte(); // Update token length tokenLength--; // Read string of the specified size NewValue = TDSUtilities.ReadString(source, (ushort)(valueLength * 2)); // Update token length tokenLength -= (ushort)(valueLength * 2); // Check if old value can fit in if (tokenLength == 0) { // Old value won't fit in break; } // Read old value length valueLength = (byte)source.ReadByte(); // Update token length tokenLength--; // Read string of the specified size OldValue = TDSUtilities.ReadString(source, (ushort)(valueLength * 2)); // Update token length tokenLength -= (ushort)(valueLength * 2); // Inflation is complete break; } case TDSEnvChangeTokenType.Routing: { // Read the new value length ushort valueLength = TDSUtilities.ReadUShort(source); // Update token length tokenLength -= 2; // sizeof(ushort) // Instantiate new value NewValue = new TDSRoutingEnvChangeTokenValue(); // Inflate new value if (!(NewValue as TDSRoutingEnvChangeTokenValue).Inflate(source)) { // We should never reach this point throw new Exception("Routing information inflation failed"); } // Read always-zero old value unsigned short if (TDSUtilities.ReadUShort(source) != 0) { // We should never reach this point throw new Exception("Non-zero old value for routing information"); } break; } case TDSEnvChangeTokenType.SQLCollation: { // Read new value length byte valueLength = (byte)source.ReadByte(); // Update token length tokenLength--; // Check if old value can fit in if (tokenLength == 0) { // Old value won't fit in break; } // Allocate the buffer byte[] byteValue = new byte[valueLength]; // Read bytes off the wire source.Read(byteValue, 0, byteValue.Length); // Set new value NewValue = byteValue; // Update token length tokenLength -= valueLength; // Check if old value can fit in if (tokenLength == 0) { // Old value won't fit in break; } // Read old value length valueLength = (byte)source.ReadByte(); // Update token length tokenLength--; // Check if old value can fit in if (tokenLength == 0) { // Old value won't fit in break; } // Allocate the buffer byteValue = new byte[valueLength]; // Read bytes off the wire source.Read(byteValue, 0, byteValue.Length); // Set old value OldValue = byteValue; // Update token length tokenLength -= valueLength; // Inflation is complete break; } default: { // Skip the rest of the token byte[] tokenData = new byte[tokenLength]; source.Read(tokenData, 0, tokenData.Length); break; } } return(true); }