Exemple #1
0
        /// <summary>
        /// Deflate the token
        /// </summary>
        /// <param name="destination">Stream to deflate token to</param>
        public override void Deflate(Stream destination)
        {
            // Allocate temporary cache
            MemoryStream cache = new MemoryStream();

            // Write header type
            TDSUtilities.WriteUShort(cache, (ushort)TDSHeaderType.QueryNotifications);

            // Write notification ID string
            TDSUtilities.WriteUShort(cache, (ushort)(string.IsNullOrEmpty(NotifyID) ? 0 : NotifyID.Length));
            TDSUtilities.WriteString(cache, NotifyID);

            // Write service broker deployment
            TDSUtilities.WriteUShort(cache, (ushort)(string.IsNullOrEmpty(SerciceBrokerDeployment) ? 0 : SerciceBrokerDeployment.Length));
            TDSUtilities.WriteString(cache, SerciceBrokerDeployment);

            // Write timeout
            TDSUtilities.WriteUInt(cache, Timeout);

            // Write the header length including self into the destination
            TDSUtilities.WriteUInt(destination, (uint)(cache.Length + 4));

            // Write cached header data
            cache.WriteTo(destination);
        }
Exemple #2
0
        /// <summary>
        /// Deflate the token
        /// </summary>
        /// <param name="destination">Stream to deflate token to</param>
        public override void Deflate(Stream destination)
        {
            // Allocate temporary cache
            MemoryStream cache = new MemoryStream();

            // Write header type
            TDSUtilities.WriteUShort(cache, (ushort)TDSHeaderType.Trace);

            byte[] guidBytes = new byte[16];

            // Check if activity ID is available
            if (ActivityID != null)
            {
                guidBytes = ActivityID.ToByteArray();
            }

            // Write trace identifier
            cache.Write(guidBytes, 0, guidBytes.Length);

            // Write activity identifier
            TDSUtilities.WriteUInt(cache, SequenceNumber);

            // Write the header length including self into the destination
            TDSUtilities.WriteUInt(destination, (uint)(cache.Length + 4));

            // Write cached header data
            cache.WriteTo(destination);
        }
        /// <summary>
        /// Deflate the token
        /// </summary>
        /// <param name="destination">Stream to deflate token to</param>
        public override void Deflate(Stream destination)
        {
            // Write token identifier
            destination.WriteByte((byte)TDSTokenType.Order);

            // Write the length
            TDSUtilities.WriteUShort(destination, sizeof(ushort));

            // Write value
            TDSUtilities.WriteUShort(destination, Number);
        }
        /// <summary>
        /// Deflate the token
        /// </summary>
        /// <param name="destination">Stream to deflate token to</param>
        public override void Deflate(Stream destination)
        {
            // Write token identifier
            destination.WriteByte((byte)TDSTokenType.DoneProcedure);

            // Write status
            TDSUtilities.WriteUShort(destination, (ushort)Status);

            // Write command
            TDSUtilities.WriteUShort(destination, (ushort)Command);

            // Write row count
            TDSUtilities.WriteULong(destination, RowCount);
        }
Exemple #5
0
        /// <summary>
        /// Deflate the token
        /// </summary>
        /// <param name="destination">Stream to deflate token to</param>
        public override void Deflate(Stream destination)
        {
            // Write token identifier
            destination.WriteByte((byte)TDSTokenType.SSPI);

            // Write length
            TDSUtilities.WriteUShort(destination, (ushort)((Payload != null) ? Payload.Length : 0));

            // Check if data is available
            if (Payload != null)
            {
                // Write the data
                destination.Write(Payload, 0, Payload.Length);
            }
        }
Exemple #6
0
        /// <summary>
        /// Deflate the token
        /// </summary>
        /// <param name="destination">Stream to deflate token to</param>
        public override void Deflate(Stream destination)
        {
            // Write token identifier
            destination.WriteByte((byte)TDSTokenType.Error);

            // Calculate the length
            ushort totalLength = (ushort)(sizeof(uint)                                                                                     // Number
                                          + sizeof(byte)                                                                                   // State
                                          + sizeof(byte)                                                                                   // Class
                                          + sizeof(ushort) + (string.IsNullOrEmpty(Message) ? 0 : Message.Length) * sizeof(char)           // Message
                                          + sizeof(byte) + (string.IsNullOrEmpty(ServerName) ? 0 : ServerName.Length) * sizeof(char)       // Server Name
                                          + sizeof(byte) + (string.IsNullOrEmpty(ProcedureName) ? 0 : ProcedureName.Length) * sizeof(char) // Procedure Name
                                          + sizeof(uint));                                                                                 // Line number

            // Write token length
            TDSUtilities.WriteUShort(destination, totalLength);

            // Write the number
            TDSUtilities.WriteUInt(destination, Number);

            // Write state
            destination.WriteByte((byte)State);

            // Write class
            destination.WriteByte((byte)Class);

            // Write message text length
            TDSUtilities.WriteUShort(destination, (ushort)(string.IsNullOrEmpty(Message) ? 0 : Message.Length));

            // Write the message itself
            TDSUtilities.WriteString(destination, Message);

            // Write server name length
            destination.WriteByte((byte)(string.IsNullOrEmpty(ServerName) ? 0 : ServerName.Length));

            // Write server name
            TDSUtilities.WriteString(destination, ServerName);

            // Write procedure name length
            destination.WriteByte((byte)(string.IsNullOrEmpty(ProcedureName) ? 0 : ProcedureName.Length));

            // Write procedure name
            TDSUtilities.WriteString(destination, ProcedureName);

            // Write the line number
            TDSUtilities.WriteUInt(destination, Line);
        }
Exemple #7
0
        /// <summary>
        /// Deflate the token
        /// </summary>
        /// <param name="destination">Stream to deflate token to</param>
        public override void Deflate(Stream destination)
        {
            // Allocate temporary cache
            MemoryStream cache = new MemoryStream();

            // Write header type
            TDSUtilities.WriteUShort(cache, (ushort)TDSHeaderType.TransactionDescriptor);

            // Write transaction descriptor
            TDSUtilities.WriteULong(cache, TransactionDescriptor);

            // Write outstanding request count
            TDSUtilities.WriteUInt(cache, OutstandingRequestCount);

            // Write the header length including self into the destination
            TDSUtilities.WriteUInt(destination, (uint)(cache.Length + 4));

            // Write cached header data
            cache.WriteTo(destination);
        }
        /// <summary>
        /// Deflate the token
        /// </summary>
        /// <param name="destination">Stream to deflate token to</param>
        public override void Deflate(Stream destination)
        {
            // Write token identifier
            destination.WriteByte((byte)TDSTokenType.ColumnInfo);

            // Allocate a memory stream for column information block
            MemoryStream cache = new MemoryStream();

            // Deflate all properties into the cache
            foreach (TDSColumnProperty column in Columns)
            {
                column.Deflate(cache);
            }

            // Write the length of the token
            TDSUtilities.WriteUShort(destination, (ushort)cache.Length);

            // Write the cache itself
            cache.WriteTo(destination);
        }
        /// <summary>
        /// Deflate the token
        /// </summary>
        /// <param name="destination">Stream to deflate token to</param>
        public override void Deflate(Stream destination)
        {
            // Write token identifier
            destination.WriteByte((byte)TDSTokenType.ColumnMetadata);

            // Check if there's any metadata
            if (Columns != null && Columns.Count > 0)
            {
                // Write column count
                TDSUtilities.WriteUShort(destination, (ushort)Columns.Count);

                // Iterate through each column and deflate it
                foreach (TDSColumnData column in Columns)
                {
                    // Deflate each column
                    column.Deflate(destination);
                }
            }
            else
            {
                // Indicate that there's no metadata
                TDSUtilities.WriteUShort(destination, (ushort)0xFFFF);
            }
        }
        /// <summary>
        /// Deflate the token
        /// </summary>
        /// <param name="destination">Stream to deflate token to</param>
        public virtual void Deflate(Stream destination)
        {
            // Write protocol value
            destination.WriteByte((byte)Protocol);

            // Based on the protocol type read the rest of the token
            switch (Protocol)
            {
            default:
            case TDSRoutingEnvChangeTokenValueType.TCP:
            {
                // Write port
                TDSUtilities.WriteUShort(destination, (ushort)ProtocolProperty);

                // Write alternate server name length
                TDSUtilities.WriteUShort(destination, (ushort)(string.IsNullOrEmpty(AlternateServer) ? 0 : AlternateServer.Length));

                // Write alternate server name
                TDSUtilities.WriteString(destination, AlternateServer);

                break;
            }
            }
        }
        public static void DeflateTypeVarByte(Stream destination, TDSDataType column, object data, Object dataTypeSpecific)
        {
            // Dispatch further reading based on the type
            switch (column)
            {
            case TDSDataType.Null:
            {
                // No data associated with it
                break;
            }

            case TDSDataType.DateTime2N:
            {
                DateTime date    = (DateTime)data;
                uint     days    = (uint)(date - new DateTime(1, 1, 1)).TotalDays;
                var      seconds = (int)(date - new DateTime(date.Year, date.Month, date.Day)).TotalSeconds;
                ulong    scaledSeconds;
                switch ((byte)dataTypeSpecific)
                {
                case 1:
                case 2:
                    destination.WriteByte(6);

                    scaledSeconds = (ulong)(seconds * Math.Pow(10, 3));
                    destination.WriteByte((byte)scaledSeconds);
                    destination.WriteByte((byte)(scaledSeconds >> 8));
                    destination.WriteByte((byte)(scaledSeconds >> 16));
                    break;

                case 3:
                case 4:
                    destination.WriteByte(7);
                    scaledSeconds = (ulong)(seconds * Math.Pow(10, 4));
                    destination.WriteByte((byte)scaledSeconds);
                    destination.WriteByte((byte)(scaledSeconds >> 8));
                    destination.WriteByte((byte)(scaledSeconds >> 16));
                    destination.WriteByte((byte)(scaledSeconds >> 24));
                    break;

                case 5:
                case 6:
                case 7:
                    destination.WriteByte(8);
                    scaledSeconds = (ulong)(seconds * Math.Pow(10, 5));
                    destination.WriteByte((byte)scaledSeconds);
                    destination.WriteByte((byte)(scaledSeconds >> 8));
                    destination.WriteByte((byte)(scaledSeconds >> 16));
                    destination.WriteByte((byte)(scaledSeconds >> 24));
                    destination.WriteByte((byte)(scaledSeconds >> 32));
                    break;
                }
                destination.WriteByte((byte)days);
                destination.WriteByte((byte)(days >> 8));
                destination.WriteByte((byte)(days >> 16));
                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;
            }

            case TDSDataType.Xml:
            {
                // Check if data is available
                if (data == null)
                {
                    // No data
                    TDSUtilities.WriteUShort(destination, 0xFFFF);
                }
                else
                {
                    // Get bytes
                    byte[] bytes = Encoding.UTF8.GetBytes((string)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));
            }
            }
        }
Exemple #12
0
        /// <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>
        /// Deflate the token
        /// </summary>
        /// <param name="destination">Stream to deflate token to</param>
        public override void Deflate(Stream destination)
        {
            // Calculate total length by adding strings
            uint totalPacketLength = (uint)(FixedPacketLength
                                            + (uint)(string.IsNullOrEmpty(HostName) ? 0 : HostName.Length * 2)                     // HostName
                                            + (uint)(string.IsNullOrEmpty(UserID) ? 0 : UserID.Length * 2)                         // UserID
                                            + (uint)(string.IsNullOrEmpty(Password) ? 0 : Password.Length * 2)                     // Password
                                            + (uint)(string.IsNullOrEmpty(ApplicationName) ? 0 : ApplicationName.Length * 2)       // ApplicationName
                                            + (uint)(string.IsNullOrEmpty(ServerName) ? 0 : ServerName.Length * 2)                 // ServerName
                                            + (uint)(string.IsNullOrEmpty(LibraryName) ? 0 : LibraryName.Length * 2)               // LibraryName
                                            + (uint)(string.IsNullOrEmpty(Language) ? 0 : Language.Length * 2)                     // Language
                                            + (uint)(string.IsNullOrEmpty(Database) ? 0 : Database.Length * 2)                     // Database
                                            + (uint)(string.IsNullOrEmpty(AttachDatabaseFile) ? 0 : AttachDatabaseFile.Length * 2) // AttachDatabaseFile
                                            + (uint)(string.IsNullOrEmpty(ChangePassword) ? 0 : ChangePassword.Length * 2)         // ChangePassword
                                            + (uint)(SSPI == null ? 0 : SSPI.Length)                                               // SSPI
                                            + 0);                                                                                  // Feature extension

            MemoryStream featureExtension = null;

            // Check if we have a feature extension
            if (FeatureExt != null)
            {
                // Allocate feature extension block
                featureExtension = new MemoryStream();

                // Serialize feature extension
                FeatureExt.Deflate(featureExtension);

                // Update total lentgh
                totalPacketLength += (uint)(sizeof(uint) /* Offset of feature extension data */ + featureExtension.Length /* feature extension itself*/);
            }

            // Write packet length
            TDSUtilities.WriteUInt(destination, totalPacketLength);

            // Compile TDS version
            uint tdsVersion = Convert.ToUInt32(string.Format("{0:X}", Math.Max(TDSVersion.Major, 0)) + string.Format("{0:X}", Math.Max(TDSVersion.Minor, 0)) + string.Format("{0:X2}", Math.Max(TDSVersion.Build, 0)) + string.Format("{0:X4}", Math.Max(TDSVersion.Revision, 0)), 16);

            // Write TDS version
            TDSUtilities.WriteUInt(destination, tdsVersion);

            // Write packet length
            TDSUtilities.WriteUInt(destination, PacketSize);

            // Write client program version
            TDSUtilities.WriteUInt(destination, ClientProgramVersion);

            // Write client program identifier
            TDSUtilities.WriteUInt(destination, ClientPID);

            // Write connection identifier
            TDSUtilities.WriteUInt(destination, ConnectionID);

            // Write the first optional flags
            destination.WriteByte(OptionalFlags1.ToByte());

            // Write the second optional flags
            destination.WriteByte(OptionalFlags2.ToByte());

            // Instantiate type flags
            destination.WriteByte(TypeFlags.ToByte());

            // Write the third optional flags
            destination.WriteByte(OptionalFlags3.ToByte());

            // Write client time zone
            TDSUtilities.WriteInt(destination, ClientTimeZone);

            // Write client locale identifier
            TDSUtilities.WriteUInt(destination, ClientLCID);

            // Prepare a collection of property values that will be set later
            IList <TDSLogin7TokenOffsetProperty> variableProperties = new List <TDSLogin7TokenOffsetProperty>();

            // Write client host name
            variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("HostName"), FixedPacketLength, (ushort)(string.IsNullOrEmpty(HostName) ? 0 : HostName.Length)));
            TDSUtilities.WriteUShort(destination, (ushort)variableProperties.Last().Position);
            TDSUtilities.WriteUShort(destination, (ushort)variableProperties.Last().Length);

            // Write user name and password
            variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("UserID"), (ushort)(variableProperties.Last().Position + variableProperties.Last().Length * 2), (ushort)(string.IsNullOrEmpty(UserID) ? 0 : UserID.Length)));
            TDSUtilities.WriteUShort(destination, (ushort)variableProperties.Last().Position);
            TDSUtilities.WriteUShort(destination, (ushort)variableProperties.Last().Length);

            variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("Password"), (ushort)(variableProperties.Last().Position + variableProperties.Last().Length * 2), (ushort)(string.IsNullOrEmpty(Password) ? 0 : Password.Length)));
            TDSUtilities.WriteUShort(destination, (ushort)variableProperties.Last().Position);
            TDSUtilities.WriteUShort(destination, (ushort)variableProperties.Last().Length);

            // Write application name
            variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("ApplicationName"), (ushort)(variableProperties.Last().Position + variableProperties.Last().Length * 2), (ushort)(string.IsNullOrEmpty(ApplicationName) ? 0 : ApplicationName.Length)));
            TDSUtilities.WriteUShort(destination, (ushort)variableProperties.Last().Position);
            TDSUtilities.WriteUShort(destination, (ushort)variableProperties.Last().Length);

            // Write server name
            variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("ServerName"), (ushort)(variableProperties.Last().Position + variableProperties.Last().Length * 2), (ushort)(string.IsNullOrEmpty(ServerName) ? 0 : ServerName.Length)));
            TDSUtilities.WriteUShort(destination, (ushort)variableProperties.Last().Position);
            TDSUtilities.WriteUShort(destination, (ushort)variableProperties.Last().Length);

            // Check if we have a feature extension block
            if (FeatureExt != null)
            {
                // Write the offset of the feature extension offset (pointer to pointer)
                variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("FeatureExt"), (ushort)(variableProperties.Last().Position + variableProperties.Last().Length * 2), sizeof(uint) / 2, true)); // Should be 4 bytes, devided by 2 because the next guy multiplies by 2
                TDSUtilities.WriteUShort(destination, (ushort)variableProperties.Last().Position);
                TDSUtilities.WriteUShort(destination, (ushort)(variableProperties.Last().Length * 2));                                                                                                                      // Compensate for division by 2 above
            }
            else
            {
                // Skip unused
                TDSUtilities.WriteUShort(destination, 0);
                TDSUtilities.WriteUShort(destination, 0);
            }

            // Write client library name
            // We do not need to account for skipped unused bytes here because they're already accounted in fixedPacketLength
            variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("LibraryName"), (ushort)(variableProperties.Last().Position + variableProperties.Last().Length * 2), (ushort)(string.IsNullOrEmpty(LibraryName) ? 0 : LibraryName.Length)));
            TDSUtilities.WriteUShort(destination, (ushort)variableProperties.Last().Position);
            TDSUtilities.WriteUShort(destination, (ushort)variableProperties.Last().Length);

            // Write language
            variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("Language"), (ushort)(variableProperties.Last().Position + variableProperties.Last().Length * 2), (ushort)(string.IsNullOrEmpty(Language) ? 0 : Language.Length)));
            TDSUtilities.WriteUShort(destination, (ushort)variableProperties.Last().Position);
            TDSUtilities.WriteUShort(destination, (ushort)variableProperties.Last().Length);

            // Write database
            variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("Database"), (ushort)(variableProperties.Last().Position + variableProperties.Last().Length * 2), (ushort)(string.IsNullOrEmpty(Database) ? 0 : Database.Length)));
            TDSUtilities.WriteUShort(destination, (ushort)variableProperties.Last().Position);
            TDSUtilities.WriteUShort(destination, (ushort)variableProperties.Last().Length);

            // Check if client is defined
            if (ClientID == null)
            {
                // Allocate empty identifier
                ClientID = new byte[6];
            }

            // Write unique client identifier
            destination.Write(ClientID, 0, 6);

            // Write SSPI
            variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("SSPI"), (ushort)(variableProperties.Last().Position + variableProperties.Last().Length * 2), (ushort)(SSPI == null ? 0 : SSPI.Length)));
            TDSUtilities.WriteUShort(destination, (ushort)variableProperties.Last().Position);
            TDSUtilities.WriteUShort(destination, (ushort)variableProperties.Last().Length);

            // Write database file to be attached. NOTE, "variableProperties.Last().Length" without " * 2" because the preceeding buffer isn't string
            variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("AttachDatabaseFile"), (ushort)(variableProperties.Last().Position + variableProperties.Last().Length), (ushort)(string.IsNullOrEmpty(AttachDatabaseFile) ? 0 : AttachDatabaseFile.Length)));
            TDSUtilities.WriteUShort(destination, (ushort)variableProperties.Last().Position);
            TDSUtilities.WriteUShort(destination, (ushort)variableProperties.Last().Length);

            // Write password change
            variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("ChangePassword"), (ushort)(variableProperties.Last().Position + variableProperties.Last().Length * 2), (ushort)(string.IsNullOrEmpty(ChangePassword) ? 0 : ChangePassword.Length)));
            TDSUtilities.WriteUShort(destination, (ushort)variableProperties.Last().Position);
            TDSUtilities.WriteUShort(destination, (ushort)variableProperties.Last().Length);

            // Skip long SSPI
            TDSUtilities.WriteUInt(destination, 0);

            // We will be changing collection as we go and serialize everything. As such we can't use foreach and iterator.
            int iCurrentProperty = 0;

            // Iterate through the collection
            while (iCurrentProperty < variableProperties.Count)
            {
                // Get current property by index
                TDSLogin7TokenOffsetProperty property = variableProperties[iCurrentProperty];

                // Check if length is positive
                if (property.Length == 0)
                {
                    // Move to the next property
                    iCurrentProperty++;
                    continue;
                }

                // Check special properties
                if (property.Property.Name == "Password" || property.Property.Name == "ChangePassword")
                {
                    // Write encrypted string value
                    TDSUtilities.WritePasswordString(destination, (string)property.Property.GetValue(this, null));
                }
                else if (property.Property.Name == "FeatureExt")
                {
                    // Check if we are to serialize the offset or the actual data
                    if (property.IsOffsetOffset)
                    {
                        // Property will be written at the offset immediately following all variable length data
                        property.Position = variableProperties.Last().Position + variableProperties.Last().Length;

                        // Write the position at which we'll be serializing the feature extension block
                        TDSUtilities.WriteUInt(destination, property.Position);

                        // Order strings in ascending order by offset
                        variableProperties = variableProperties.OrderBy(p => p.Position).ToList();

                        // Compensate increment to the next position in order to stay on the same
                        iCurrentProperty--;

                        // No longer offset, actual data is going to follow
                        property.IsOffsetOffset = false;
                    }
                    else
                    {
                        // Transfer deflated feature extension into the login stream
                        featureExtension.WriteTo(destination);
                    }
                }
                else if (property.Property.Name == "SSPI")
                {
                    // Write SSPI
                    destination.Write(SSPI, 0, SSPI.Length);
                }
                else
                {
                    // Write the string value
                    TDSUtilities.WriteString(destination, (string)property.Property.GetValue(this, null));
                }

                // Move to the next property
                iCurrentProperty++;
            }
        }
        /// <summary>
        /// Deflate the token
        /// </summary>
        /// <param name="destination">Stream to deflate token to</param>
        public override void Deflate(Stream destination)
        {
            destination.WriteByte((byte)TDSTokenType.ReturnValue);

            TDSUtilities.WriteUShort(destination, ParamOrdinal);

            destination.WriteByte((byte)ParamName.Length);
            TDSUtilities.WriteString(destination, ParamName);

            destination.WriteByte((byte)Status);

            TDSUtilities.WriteUInt(destination, UserType);

            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);
                break;
            }
            }

            Microsoft.SqlServer.TDS.Row.TDSRowTokenBase.DeflateTypeVarByte(destination, DataType, Value, DataTypeSpecific);
        }
        /// <summary>
        /// Deflate the token
        /// </summary>
        /// <param name="destination">Stream to deflate token to</param>
        public override void Deflate(Stream destination)
        {
            IList <TDSPreLoginTokenOption> options = new List <TDSPreLoginTokenOption>();

            // Prepare the sequence of options to serialize
            options.Add(new TDSPreLoginTokenOption(TDSPreLoginTokenOptionType.Version, 6));
            options.Add(new TDSPreLoginTokenOption(TDSPreLoginTokenOptionType.ThreadID, 4));
            options.Add(new TDSPreLoginTokenOption(TDSPreLoginTokenOptionType.Mars, 1));

            //Check if the option is needed.
            if (ActivityID != null && ClientTraceID != null)
            {
                options.Add(new TDSPreLoginTokenOption(TDSPreLoginTokenOptionType.TraceID, 36));
            }

            // Add Federated authentication
            if (FedAuthRequired == TdsPreLoginFedAuthRequiredOption.FedAuthRequired || FedAuthRequired == TdsPreLoginFedAuthRequiredOption.Illegal)
            {
                options.Add(new TDSPreLoginTokenOption(TDSPreLoginTokenOptionType.FederatedAuthenticationRequired, 1));
            }

            // Check if the option is needed to be added.
            if (Nonce != null)
            {
                options.Add(new TDSPreLoginTokenOption(TDSPreLoginTokenOptionType.NonceOption, (ushort)Nonce.Length));
            }

            options.Add(new TDSPreLoginTokenOption(TDSPreLoginTokenOptionType.Encryption, 1));
            options.Add(new TDSPreLoginTokenOption(TDSPreLoginTokenOptionType.Terminator, 0));

            // Calculate the total size of the token metadata
            ushort dataOffset = (ushort)options.Sum(t => t.TokenLength);

            // Update all the offsets
            foreach (TDSPreLoginTokenOption option in options)
            {
                // Update token offset
                option.Position = dataOffset;

                // Update data offset
                dataOffset += option.Length;
            }

            // Serialize all tokens first
            foreach (TDSPreLoginTokenOption option in options)
            {
                // Deflate a token option
                option.Deflate(destination);
            }

            // Write version
            destination.WriteByte((byte)(Version.Major & 0xff));
            destination.WriteByte((byte)(Version.Minor & 0xff));
            destination.WriteByte((byte)((Version.Build >> 8) & 0xff));
            destination.WriteByte((byte)(Version.Build & 0xff));

            // Write sub-version
            TDSUtilities.WriteUShort(destination, SubBuild);

            // Write thread ID
            TDSUtilities.WriteUInt(destination, ThreadID);

            // Write MARS
            destination.WriteByte((byte)(IsMARS ? 0x01 : 0x00));

            // Write traceID
            if (ClientTraceID != null)
            {
                destination.Write(ClientTraceID, 0, ClientTraceID.Length);
            }

            // Write ActivityID
            if (ActivityID != null)
            {
                destination.Write(ActivityID, 0, ActivityID.Length);
            }

            // Write federated auth required part
            if (FedAuthRequired == TdsPreLoginFedAuthRequiredOption.FedAuthRequired || FedAuthRequired == TdsPreLoginFedAuthRequiredOption.Illegal)
            {
                destination.WriteByte((byte)FedAuthRequired);
            }

            // Write Nonce.
            if (Nonce != null)
            {
                destination.Write(Nonce, 0, Nonce.Length);
            }

            // Write Encryption
            destination.WriteByte((byte)Encryption);
        }
Exemple #16
0
        /// <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>
        /// Deflate the token
        /// </summary>
        /// <param name="destination">Stream to deflate token to</param>
        public override void Deflate(Stream destination)
        {
            // Allocate stream for token data
            // We need to cache it to calculate the environment change token length
            MemoryStream cache = new MemoryStream();

            // Write environment change type
            cache.WriteByte((byte)Type);

            // Write 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:
            {
                // Write new value length
                cache.WriteByte((byte)(string.IsNullOrEmpty((string)NewValue) ? 0 : ((string)NewValue).Length));

                // Write new value
                TDSUtilities.WriteString(cache, (string)NewValue);

                // Write old value length
                cache.WriteByte((byte)(string.IsNullOrEmpty((string)OldValue) ? 0 : ((string)OldValue).Length));

                // Write old value
                TDSUtilities.WriteString(cache, (string)OldValue);

                break;
            }

            case TDSEnvChangeTokenType.Routing:
            {
                // Create a sub-cache to determine the value length
                MemoryStream subCache = new MemoryStream();

                // Check if new value exists
                if (NewValue != null)
                {
                    // Deflate token value
                    (NewValue as TDSRoutingEnvChangeTokenValue).Deflate(subCache);
                }

                // Write new value length
                TDSUtilities.WriteUShort(cache, (ushort)subCache.Length);

                // Write new value
                subCache.WriteTo(cache);

                // Write zero for the old value length
                TDSUtilities.WriteUShort(cache, 0);

                break;
            }

            case TDSEnvChangeTokenType.SQLCollation:
            {
                // Write new value length
                cache.WriteByte((byte)(NewValue != null ? ((byte[])NewValue).Length : 0));

                // Check if we have a new value
                if (NewValue != null)
                {
                    // Write new value
                    cache.Write((byte[])NewValue, 0, ((byte[])NewValue).Length);
                }

                // Write old value length
                cache.WriteByte((byte)(OldValue != null ? ((byte[])OldValue).Length : 0));

                // Check if we have a old value
                if (OldValue != null)
                {
                    // Write old value
                    cache.Write((byte[])OldValue, 0, ((byte[])OldValue).Length);
                }

                break;
            }

            default:
            {
                throw new Exception("Unrecognized environment change type");
            }
            }

            // Write token identifier
            destination.WriteByte((byte)TDSTokenType.EnvironmentChange);

            // Write length
            TDSUtilities.WriteUShort(destination, (ushort)cache.Length);

            // Write token data
            cache.WriteTo(destination);
        }