/// <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 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> /// Prepare response to the query about connection end-point /// </summary> private TDSMessage _PrepareConnectionInfoResponse(ITDSServerSession session) { // Prepare result metadata TDSColMetadataToken metadataToken = new TDSColMetadataToken(); // Start the first column TDSColumnData column = new TDSColumnData(); column.DataType = TDSDataType.NVarChar; column.DataTypeSpecific = new TDSShilohVarCharColumnSpecific(40, new TDSColumnDataCollation(13632521, 52)); column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; column.Name = "net_transport"; // Add a column to the response metadataToken.Columns.Add(column); // Start the second column column = new TDSColumnData(); column.DataType = TDSDataType.BigVarChar; column.DataTypeSpecific = new TDSShilohVarCharColumnSpecific(48, new TDSColumnDataCollation(13632521, 52)); column.Flags.IsNullable = true; column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; column.Name = "local_net_address"; // Add a column to the response metadataToken.Columns.Add(column); // Start the third column column = new TDSColumnData(); column.DataType = TDSDataType.IntN; column.DataTypeSpecific = (byte)4; column.Flags.IsNullable = true; column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; column.Name = "local_tcp_port"; // 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); // Add row rowToken.Data.Add(session.ServerEndPointInfo.Transport.ToString()); rowToken.Data.Add(session.ServerEndPointInfo.Address.ToString()); rowToken.Data.Add(session.ServerEndPointInfo.Port); // 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); }
/// <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); }
/// <summary> /// Prepare response for query of class of the SQL Server instance /// </summary> private TDSMessage _PrepareTestSQLServerClassResponse(ITDSServerSession session) { // Prepare result metadata TDSColMetadataToken metadataToken = new TDSColMetadataToken(); // Start first column TDSColumnData column = new TDSColumnData(); column.DataType = TDSDataType.NVarChar; column.DataTypeSpecific = new TDSShilohVarCharColumnSpecific(256, new TDSColumnDataCollation(13632521, 52)); column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; // 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); // Get the server class rowToken.Data.Add(session.Server.GetType().FullName); // 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); }
/// <summary> /// Prepare response for query whether this is a SQL Azure instance /// </summary> private TDSMessage _PrepareIsAzure(ITDSServerSession session) { // Prepare result metadata TDSColMetadataToken metadataToken = new TDSColMetadataToken(); // Start a new column TDSColumnData column = new TDSColumnData(); column.DataType = TDSDataType.IntN; column.DataTypeSpecific = (byte)4; column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; column.Flags.IsComputed = true; column.Flags.IsNullable = true; // TODO: Must be nullable, otherwise something is wrong with SqlClient // 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); // Per http://msdn.microsoft.com/en-us/library/ms174396.aspx // 4 = Express (This is returned for Express, Express with Advanced Services, and Windows Embedded SQL.) rowToken.Data.Add(4); // 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); }
/// <summary> /// Prepare configuration response /// </summary> private TDSMessage _PrepareConfigurationResponse(ITDSServerSession session) { // Prepare result metadata TDSColMetadataToken metadataToken = new TDSColMetadataToken(); // Start the first column TDSColumnData column = new TDSColumnData(); column.DataType = TDSDataType.IntN; column.DataTypeSpecific = (byte)2; column.Flags.IsNullable = true; column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; column.Name = "TraceFlag"; // Add a column to the response metadataToken.Columns.Add(column); // Start the second column column = new TDSColumnData(); column.DataType = TDSDataType.IntN; column.DataTypeSpecific = (byte)2; column.Flags.IsNullable = true; column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; column.Name = "Status"; // Add a column to the response metadataToken.Columns.Add(column); // Start the third column column = new TDSColumnData(); column.DataType = TDSDataType.IntN; column.DataTypeSpecific = (byte)2; column.Flags.IsNullable = true; column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; column.Name = "Global"; // Add a column to the response metadataToken.Columns.Add(column); // Start the fourth column column = new TDSColumnData(); column.DataType = TDSDataType.IntN; column.DataTypeSpecific = (byte)2; column.Flags.IsNullable = true; column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; column.Name = "Session"; // Add a column to the response metadataToken.Columns.Add(column); // Log response TDSUtilities.Log(Log, "Response", metadataToken); // Create DONE token TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Count, TDSDoneTokenCommandType.Select, 0); // Log response TDSUtilities.Log(Log, "Response", doneToken); // Serialize tokens into the message return new TDSMessage(TDSMessageType.Response, metadataToken, doneToken); }
/// <summary> /// Deflate the column into the stream /// </summary> /// <param name="destination">Stream to deflate token to</param> /// <param name="column">Column metadata</param> /// <param name="data">Column value</param> protected virtual void DeflateColumn(Stream destination, TDSColumnData column, object data) { // Dispatch further reading based on the type switch (column.DataType) { case TDSDataType.Null: { // No data associated with it break; } case TDSDataType.Bit: { destination.WriteByte((byte)((bool)data ? 1 : 0)); break; } case TDSDataType.Int1: { // Bit, 1 byte data representation destination.WriteByte((byte)data); break; } case TDSDataType.Int2: { // SmallInt, 2 byte data representation TDSUtilities.WriteUShort(destination, unchecked((ushort)((short)data))); break; } case TDSDataType.Int4: { // Int, 4 byte data representation TDSUtilities.WriteUInt(destination, unchecked((uint)((int)data))); break; } case TDSDataType.Float8: { // Float (8 byte data representation) byte[] floatBytes = BitConverter.GetBytes((double)data); destination.Write(floatBytes, 0, floatBytes.Length); break; } case TDSDataType.Int8: { // BigInt (8 byte data representation) TDSUtilities.WriteULong(destination, unchecked((ulong)((long)data))); break; } case TDSDataType.BitN: { // Check if data is available if (data == null) { // No data destination.WriteByte(0); } else { // One byte data destination.WriteByte(1); // Data destination.WriteByte((byte)((bool)data ? 1 : 0)); } break; } case TDSDataType.IntN: { // Check if data is available if (data == null) { // No data destination.WriteByte(0); } else if (data is byte) { // One-byte data destination.WriteByte(1); // Bit data destination.WriteByte((byte)data); } else if (data is short) { // One-byte data destination.WriteByte(2); // Short data TDSUtilities.WriteUShort(destination, unchecked((ushort)(short)data)); } else if (data is int) { // One-byte data destination.WriteByte(4); // Integer data TDSUtilities.WriteUInt(destination, unchecked((uint)(int)data)); } else if (data is long) { // One-byte data destination.WriteByte(8); // Long data TDSUtilities.WriteULong(destination, unchecked((ulong)(long)data)); } else { // We don't know how to deflate this integer throw new InvalidDataException(string.Format("Unable to deflate integer of type {0}", data.GetType().FullName)); } break; } case TDSDataType.Guid: { // Check if data is available if (data == null) { // No data destination.WriteByte(0); } else { // Get bytes byte[] guidBytes = ((Guid)data).ToByteArray(); // One byte data length destination.WriteByte((byte)guidBytes.Length); // Data destination.Write(guidBytes, 0, guidBytes.Length); } break; } case TDSDataType.BigChar: case TDSDataType.BigVarChar: { // Check if data is available if (data == null) { // No data TDSUtilities.WriteUShort(destination, 0xFFFF); } else { // Get bytes byte[] textBytes = Encoding.ASCII.GetBytes((string)data); // One data length TDSUtilities.WriteUShort(destination, (ushort)textBytes.Length); // Data destination.Write(textBytes, 0, textBytes.Length); } break; } case TDSDataType.NVarChar: { // Check if data is available if (data == null) { // No data TDSUtilities.WriteUShort(destination, 0xFFFF); } else { // Get bytes byte[] textBytes = Encoding.Unicode.GetBytes((string)data); // One data length TDSUtilities.WriteUShort(destination, (ushort)textBytes.Length); // Data destination.Write(textBytes, 0, textBytes.Length); } break; } case TDSDataType.BigVarBinary: case TDSDataType.BigBinary: { // Check if data is available if (data == null) { // No data TDSUtilities.WriteUShort(destination, 0xFFFF); } else { // Get bytes byte[] bytes = (byte[])data; // One data length TDSUtilities.WriteUShort(destination, (ushort)bytes.Length); // Data destination.Write(bytes, 0, bytes.Length); } break; } default: { // We don't know this type throw new NotImplementedException(string.Format("Unrecognized data type {0} for deflation", column.DataType)); } } }
/// <summary> /// Prepare response for options /// </summary> private TDSMessage _PrepareOptionsResponse(ITDSServerSession session) { // Prepare result metadata TDSColMetadataToken metadataToken = new TDSColMetadataToken(); // Start a new column TDSColumnData column = new TDSColumnData(); column.DataType = TDSDataType.Int4; column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; column.Flags.IsComputed = true; // 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); // Convert to generic session GenericTDSServerSession genericSession = session as GenericTDSServerSession; // Serialize the options into the bit mask int options = 0; // Check transaction abort on error if (genericSession.TransactionAbortOnError) { options |= 0x4000; } // Check numeric round abort if (genericSession.NumericRoundAbort) { options |= 0x2000; } // Check concatenation of nulls yields null if (genericSession.ConcatNullYieldsNull) { options |= 0x1000; } // Check ansi null default OFF if (!genericSession.AnsiNullDefaultOn) { options |= 0x800; } // Check ansi null default ON if (genericSession.AnsiNullDefaultOn) { options |= 0x400; } // Check no count if (genericSession.NoCount) { options |= 0x200; } // Check quoted identifier if (genericSession.QuotedIdentifier) { options |= 0x100; } // Check arithmetic ignore if (genericSession.ArithIgnore) { options |= 0x80; } // Check arithmetic abort if (genericSession.ArithAbort) { options |= 0x40; } // Check ansi nulls if (genericSession.AnsiNulls) { options |= 0x20; } // Check ansi padding if (genericSession.AnsiPadding) { options |= 0x10; } // Check ansi warnings if (genericSession.AnsiWarnings) { options |= 0x8; } // Check cursor close on commit if (genericSession.CursorCloseOnCommit) { options |= 0x4; } // Check implicit transactions if (genericSession.ImplicitTransactions) { options |= 0x2; } // Read the value from the session rowToken.Data.Add(options); // 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); }
/// <summary> /// Prepare response for transaction isolation level /// </summary> private TDSMessage _PrepareTransactionIsolationLevelResponse(ITDSServerSession session) { // Prepare result metadata TDSColMetadataToken metadataToken = new TDSColMetadataToken(); // Start a new column TDSColumnData column = new TDSColumnData(); column.DataType = TDSDataType.Int2; column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; column.Name = "transaction_isolation_level"; // 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); // Read the value from the session rowToken.Data.Add((short)(session as GenericTDSServerSession).TransactionIsolationLevel); // 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); }
/// <summary> /// Prepare response for language /// </summary> private TDSMessage _PrepareLanguageResponse(ITDSServerSession session) { // Prepare result metadata TDSColMetadataToken metadataToken = new TDSColMetadataToken(); // Start a new column TDSColumnData column = new TDSColumnData(); column.DataType = TDSDataType.NVarChar; column.DataTypeSpecific = new TDSShilohVarCharColumnSpecific(256, new TDSColumnDataCollation(13632521, 52)); column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; column.Flags.IsNullable = true; column.Name = "language"; // 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); // Generate a date format string rowToken.Data.Add(LanguageString.ToString((session as GenericTDSServerSession).Language)); // 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); }
/// <summary> /// Prepare response for ANSI null default on /// </summary> private TDSMessage _PrepareAnsiNullDefaultOnResponse(ITDSServerSession session) { // Prepare result metadata TDSColMetadataToken metadataToken = new TDSColMetadataToken(); // Start a new column TDSColumnData column = new TDSColumnData(); column.DataType = TDSDataType.Bit; column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; column.Name = "ansi_null_dflt_on"; // 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); // Read the value from the session rowToken.Data.Add((session as GenericTDSServerSession).AnsiNullDefaultOn); // 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); }
/// <summary> /// Prepare response to connection reset request count /// </summary> private TDSMessage _PrepareAuthSchemeResponse(ITDSServerSession session) { // Prepare result metadata TDSColMetadataToken metadataToken = new TDSColMetadataToken(); // Start the first column TDSColumnData column = new TDSColumnData(); column.DataType = TDSDataType.NVarChar; column.DataTypeSpecific = new TDSShilohVarCharColumnSpecific(40, new TDSColumnDataCollation(13632521, 52)); column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; column.Name = "auth_scheme"; // 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 which authentication method are we using // @TODO add Federated Authentication once VSTS 1072394 is resolved if (session.SQLUserID != null) { // Add row rowToken.Data.Add("SQL"); } else { // Add row rowToken.Data.Add("NTML"); } // 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); }
/// <summary> /// Prepare response to connection reset request count /// </summary> private TDSMessage _PrepareSPIDResponse(ITDSServerSession session) { // Prepare result metadata TDSColMetadataToken metadataToken = new TDSColMetadataToken(); // Start the first column TDSColumnData column = new TDSColumnData(); column.DataType = TDSDataType.NVarChar; column.DataTypeSpecific = new TDSShilohVarCharColumnSpecific(128, new TDSColumnDataCollation(13632521, 52)); column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; column.Flags.IsNullable = true; column.Flags.IsComputed = true; // 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); // Add row rowToken.Data.Add(session.SessionID.ToString()); // 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); }
/// <summary> /// Prepare response to the query about connection encryption /// </summary> private TDSMessage _PrepareEncryptionInfoResponse(ITDSServerSession session) { // Prepare result metadata TDSColMetadataToken metadataToken = new TDSColMetadataToken(); // Start the first column TDSColumnData column = new TDSColumnData(); column.DataType = TDSDataType.NVarChar; column.DataTypeSpecific = new TDSShilohVarCharColumnSpecific(40, new TDSColumnDataCollation(13632521, 52)); column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; column.Name = "encrypt_option"; // 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 if encryption is enabled if (session.Encryption == TDSEncryptionType.Full) { // Add row rowToken.Data.Add("TRUE"); } else { // Add row rowToken.Data.Add("FALSE"); } // 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); }
/// <summary> /// Prepare response to server ping /// </summary> private TDSMessage _PreparePingResponse(ITDSServerSession session) { // Prepare result metadata TDSColMetadataToken metadataToken = new TDSColMetadataToken(); // Start the first column TDSColumnData column = new TDSColumnData(); column.DataType = TDSDataType.IntN; column.DataTypeSpecific = (byte)4; column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; column.Flags.IsNullable = true; // TODO: Must be nullable, otherwise something is wrong with SqlClient column.Flags.IsComputed = true; // 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); // Add row rowToken.Data.Add((int)1); // 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); }
/// <summary> /// Prepare response for context info /// </summary> private TDSMessage _PrepareContextInfoResponse(ITDSServerSession session) { // Prepare result metadata TDSColMetadataToken metadataToken = new TDSColMetadataToken(); // Start a new column TDSColumnData column = new TDSColumnData(); column.DataType = TDSDataType.BigVarBinary; column.DataTypeSpecific = (ushort)128; column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; // 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); // Prepare context info container byte[] contextInfo = null; // Check if session has a context info if ((session as GenericTDSServerSession).ContextInfo != null) { // Allocate a container contextInfo = new byte[128]; // Copy context info into the container Array.Copy((session as GenericTDSServerSession).ContextInfo, contextInfo, (session as GenericTDSServerSession).ContextInfo.Length); } // Set context info rowToken.Data.Add(contextInfo); // 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); }
/// <summary> /// Prepare response for server instance name query /// </summary> private TDSMessage _PrepareInstanceNameResponse(ITDSServerSession session) { // Prepare result metadata TDSColMetadataToken metadataToken = new TDSColMetadataToken(); // Start first column TDSColumnData column = new TDSColumnData(); column.DataType = TDSDataType.NVarChar; column.DataTypeSpecific = new TDSShilohVarCharColumnSpecific(256, new TDSColumnDataCollation(13632521, 52)); column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; // 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); // Start with server name string value = ServerArguments.ServerName; // Check if server name contains a slash if (value.Contains("\\")) { // Take everything after the slash value = value.Substring(value.IndexOf('\\') + 1); } else { // Instance is unnamed value = null; } // Add row rowToken.Data.Add(value); // 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); }
/// <summary> /// Prepare response for user nane query that OLE DB stack dispatches upon connection /// </summary> private TDSMessage _PrepareOleDbReadOnlyUserName(ITDSServerSession session) { // Prepare result metadata TDSColMetadataToken metadataToken = new TDSColMetadataToken(); // Start first column TDSColumnData column = new TDSColumnData(); column.DataType = TDSDataType.BigVarChar; column.DataTypeSpecific = new TDSShilohVarCharColumnSpecific(1, new TDSColumnDataCollation(13632521, 52)); column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; // Add a column to the response metadataToken.Columns.Add(column); // Start second column column = new TDSColumnData(); column.DataType = TDSDataType.NVarChar; column.DataTypeSpecific = new TDSShilohVarCharColumnSpecific(128, new TDSColumnDataCollation(13632521, 52)); column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; // 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); // Add row rowToken.Data.Add("N"); rowToken.Data.Add("dbo"); // 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); }
/// <summary> /// Inflate a particular column from the stream /// </summary> /// <param name="source">Stream to inflate the column from</param> /// <param name="column">Metadata about the column</param> /// <returns>TRUE if inflation is complete</returns> protected virtual object InflateColumn(Stream source, TDSColumnData column) { // Dispatch further reading based on the type switch (column.DataType) { case TDSDataType.Null: { // No data associated with it return null; } 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 ((column.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)column.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.DataType)); } } }
/// <summary> /// Prepare current database response /// </summary> private TDSMessage _PrepareDatabaseResponse(ITDSServerSession session) { // Prepare result metadata TDSColMetadataToken metadataToken = new TDSColMetadataToken(); // Start the first column TDSColumnData column = new TDSColumnData(); column.DataType = TDSDataType.NVarChar; column.DataTypeSpecific = new TDSShilohVarCharColumnSpecific(256, new TDSColumnDataCollation(13632521, 52)); column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; column.Name = "name"; // Add a column to the response metadataToken.Columns.Add(column); // Start the second column column = new TDSColumnData(); column.DataType = TDSDataType.IntN; column.DataTypeSpecific = (byte)1; column.Flags.IsNullable = true; column.Name = "state"; // 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); // Add row rowToken.Data.Add(session.Database); rowToken.Data.Add((byte)0); // Online // 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); }