/// <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 /// </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> /// Deflate the token /// </summary> /// <param name="destination">Stream to deflate token to</param> public void Deflate(Stream destination) { // Write user type TDSUtilities.WriteUInt(destination, UserType); // Convert flags to value and write them TDSUtilities.WriteUShort(destination, Flags.ToUShort()); // Write type destination.WriteByte((byte)DataType); // Dispatch further writing based on the type switch (DataType) { case TDSDataType.Binary: case TDSDataType.VarBinary: case TDSDataType.Char: case TDSDataType.VarChar: case TDSDataType.BitN: case TDSDataType.Guid: case TDSDataType.IntN: case TDSDataType.MoneyN: case TDSDataType.FloatN: case TDSDataType.DateTimeN: { // Byte length destination.WriteByte((byte)DataTypeSpecific); break; } case TDSDataType.DateN: { // No details break; } case TDSDataType.TimeN: case TDSDataType.DateTime2N: case TDSDataType.DateTimeOffsetN: { // Scale destination.WriteByte((byte)DataTypeSpecific); break; } case TDSDataType.DecimalN: case TDSDataType.NumericN: { // Cast to type-specific information TDSDecimalColumnSpecific typeSpecific = DataTypeSpecific as TDSDecimalColumnSpecific; // Write values destination.WriteByte(typeSpecific.Length); destination.WriteByte(typeSpecific.Precision); destination.WriteByte(typeSpecific.Scale); break; } case TDSDataType.BigBinary: case TDSDataType.BigVarBinary: { // Short length TDSUtilities.WriteUShort(destination, (ushort)DataTypeSpecific); break; } case TDSDataType.BigChar: case TDSDataType.BigVarChar: case TDSDataType.NChar: case TDSDataType.NVarChar: { // Cast to type specific information TDSShilohVarCharColumnSpecific typedSpecific = DataTypeSpecific as TDSShilohVarCharColumnSpecific; // Write length TDSUtilities.WriteUShort(destination, typedSpecific.Length); // Write collation TDSUtilities.WriteUInt(destination, typedSpecific.Collation.WCID); destination.WriteByte(typedSpecific.Collation.SortID); break; } case TDSDataType.Text: case TDSDataType.NText: { // YukonTextType.Len + YukonTextType.tdsCollationInfo + YukonTextType.cParts // cb = sizeof(LONG) + sizeof(TDSCOLLATION) + sizeof(BYTE); break; } case TDSDataType.Image: { // Integer length TDSUtilities.WriteUInt(destination, (uint)DataTypeSpecific); break; } case TDSDataType.SSVariant: { // Data length TDSUtilities.WriteUInt(destination, (uint)DataTypeSpecific); break; } case TDSDataType.Udt: { // hr = GetUDTColFmt(pvOwner, dwTimeout); break; } case TDSDataType.Xml: { // cb = sizeof(lpColFmt->YukonXmlType.bSchemaPresent); destination.WriteByte(0); break; } } // Check if we need to write table name if ((DataType == TDSDataType.Text || DataType == TDSDataType.NText || DataType == TDSDataType.Image) && (TableName != null)) { // Write part count destination.WriteByte((byte)TableName.Count); // Write each part foreach (string part in TableName) { // Write table part length TDSUtilities.WriteUShort(destination, (ushort)(string.IsNullOrEmpty(part) ? 0 : part.Length)); // Write table part TDSUtilities.WriteString(destination, part); } } // Write column name length destination.WriteByte((byte)(string.IsNullOrEmpty(Name) ? 0 : Name.Length)); // Write column name TDSUtilities.WriteString(destination, Name); }
/// <summary> /// Prepare response for session user name query /// </summary> private TDSMessage _PrepareSessionUserResponse(ITDSServerSession session) { // Prepare result metadata TDSColMetadataToken metadataToken = new TDSColMetadataToken(); // Prepare column type-specific data TDSShilohVarCharColumnSpecific nVarChar = new TDSShilohVarCharColumnSpecific(256, new TDSColumnDataCollation(13632521, 52)); // Prepare the first column TDSColumnData column = new TDSColumnData(); column.DataType = TDSDataType.NVarChar; column.Flags.Updatable = TDSColumnDataUpdatableFlag.Unknown; column.Flags.IsNullable = true; column.DataTypeSpecific = nVarChar; column.Name = "nt_user_name"; // Add a column to the response metadataToken.Columns.Add(column); // Prepare the second column column = new TDSColumnData(); column.DataType = TDSDataType.NVarChar; column.Flags.Updatable = TDSColumnDataUpdatableFlag.Unknown; column.Flags.IsNullable = true; column.DataTypeSpecific = nVarChar; column.Name = "nt_domain"; // Add a column to the response metadataToken.Columns.Add(column); // Prepare the third column column = new TDSColumnData(); column.DataType = TDSDataType.NVarChar; column.Flags.Updatable = TDSColumnDataUpdatableFlag.Unknown; column.DataTypeSpecific = nVarChar; column.Name = "login_name"; // Add a column to the response metadataToken.Columns.Add(column); // Log response TDSUtilities.Log(Log, "Response", metadataToken); // Prepare result data TDSRowToken rowToken = new TDSRowToken(metadataToken); // Check user type if (session.SQLUserID != null) { // Add row rowToken.Data.Add(null); // nt_user_name rowToken.Data.Add(null); // nt_domain rowToken.Data.Add(session.SQLUserID); // login_name } else if (session.NTUserAuthenticationContext != null) { // Get user identifier string userID = session.NTUserAuthenticationContext.GetRemoteIdentity().Name; // Look for traditional separator for form "<domain>\<user>" int indexOfSeparator = userID.IndexOf('\\'); string domain = null; string user = null; // Parse domain and user out of the entry if (indexOfSeparator != -1) { // Extract parts domain = userID.Substring(0, indexOfSeparator); user = userID.Substring(indexOfSeparator + 1); } else { // Look for a different type of separator for form "<user>@<domain>" indexOfSeparator = userID.IndexOf('@'); // Check if found if (indexOfSeparator != -1) { // Extract parts domain = userID.Substring(indexOfSeparator + 1); user = userID.Substring(0, indexOfSeparator); } else { // We don't recognize this user so don't parse it domain = null; user = userID; } } // Add row rowToken.Data.Add(user); // nt_user_name rowToken.Data.Add(domain); // nt_domain rowToken.Data.Add(userID); // login_name } else { // We don't have a user, which is very strange since we're in query engine already rowToken.Data.Add(null); // nt_user_name rowToken.Data.Add(null); // nt_domain rowToken.Data.Add(null); // login_name } // Log response TDSUtilities.Log(Log, "Response", rowToken); // Create DONE token TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Count, TDSDoneTokenCommandType.Select, 1); // Log response TDSUtilities.Log(Log, "Response", doneToken); // Serialize tokens into the message return new TDSMessage(TDSMessageType.Response, metadataToken, rowToken, doneToken); }