public override void ExecuteStatement(MySqlPacket packetToExecute)
        {
            base.ExecuteStatement(packetToExecute);
            int pos = packetToExecute.Position;
            packetToExecute.Position = 1;
            int statementId = packetToExecute.ReadInteger(4);
            packetToExecute.Position = pos;

            MySqlTrace.TraceEvent(TraceEventType.Information, MySqlTraceEventType.StatementExecuted,
                Resources.TraceStatementExecuted, driverId, statementId, ThreadID);
        }
        public MySqlStream(Encoding encoding)
        {
            // we have no idea what the real value is so we start off with the max value
            // The real value will be set in NativeDriver.Configure()
            maxPacketSize = ulong.MaxValue;

            // we default maxBlockSize to MaxValue since we will get the 'real' value in
            // the authentication handshake and we know that value will not exceed
            // true maxBlockSize prior to that.
            maxBlockSize = Int32.MaxValue;

            packet = new MySqlPacket(encoding);
            bufferStream = new MemoryStream();
        }
        void IMySqlValue.WriteValue(MySqlPacket packet, bool binary, object value, int length)
        {
            MySqlDateTime dtValue;

            string valueAsString = value as string;

            if (value is DateTime)
                dtValue = new MySqlDateTime(type, (DateTime)value);
            else if (valueAsString != null)
                dtValue = new MySqlDateTime(type, DateTime.Parse(valueAsString, CultureInfo.CurrentCulture));
            else if (value is MySqlDateTime)
                dtValue = (MySqlDateTime)value;
            else
                throw new MySqlException("Unable to serialize date/time value.");

            if (!binary)
            {
                SerializeText(packet, dtValue);
                return;
            }

            if (type == MySqlDbType.Timestamp)
                packet.WriteByte(11);
            else
                packet.WriteByte(7);

            packet.WriteInteger(dtValue.Year, 2);
            packet.WriteByte((byte)dtValue.Month);
            packet.WriteByte((byte)dtValue.Day);
            if (type == MySqlDbType.Date)
            {
                packet.WriteByte(0);
                packet.WriteByte(0);
                packet.WriteByte(0);
            }
            else
            {
                packet.WriteByte((byte)dtValue.Hour);
                packet.WriteByte((byte)dtValue.Minute);
                packet.WriteByte((byte)dtValue.Second);
            }

            if (type == MySqlDbType.Timestamp)
                packet.WriteInteger(dtValue.Millisecond, 4);
        }
        IMySqlValue IMySqlValue.ReadValue(MySqlPacket packet, long length, bool nullVal)
        {
            if (nullVal) return new MySqlDateTime(type, true);

            if (length >= 0)
            {
                string value = packet.ReadString(length);
                return ParseMySql(value);
            }

            long bufLength = packet.ReadByte();
            int year = 0, month = 0, day = 0;
            int hour = 0, minute = 0, second = 0;

            if (bufLength >= 4)
            {
                year = packet.ReadInteger(2);
                month = packet.ReadByte();
                day = packet.ReadByte();
            }

            if (bufLength > 4)
            {
                hour = packet.ReadByte();
                minute = packet.ReadByte();
                second = packet.ReadByte();
            }

            if (bufLength > 7)
                packet.ReadInteger(4);

            return new MySqlDateTime(type, year, month, day, hour, minute, second);
        }
 void IMySqlValue.SkipValue(MySqlPacket packet)
 {
     packet.ReadByte();
 }
 /// <summary>
 /// Serializes the given parameter to the given memory stream
 /// </summary>
 /// <remarks>
 /// <para>This method is called by PrepareSqlBuffers to convert the given
 /// parameter to bytes and write those bytes to the given memory stream.
 /// </para>
 /// </remarks>
 /// <returns>True if the parameter was successfully serialized, false otherwise.</returns>
 private bool SerializeParameter(MySqlParameterCollection parameters,
                                 MySqlPacket packet, string parmName)
 {
     MySqlParameter parameter = parameters.GetParameterFlexible(parmName, false);
     if (parameter == null)
     {
         // if we are allowing user variables and the parameter name starts with @
         // then we can't throw an exception
         if (parmName.StartsWith("@") && ShouldIgnoreMissingParameter(parmName))
             return false;
         throw new MySqlException(
             String.Format(Resources.ParameterMustBeDefined, parmName));
     }
     parameter.Serialize(packet, false, Connection.Settings);
     return true;
 }
        IMySqlValue IMySqlValue.ReadValue(MySqlPacket packet, long length, bool nullVal)
        {
            if (nullVal)
                return new MySqlInt64(true);

            if (length == -1)
                return new MySqlInt64((long)packet.ReadULong(8));
            else
                return new MySqlInt64(Int64.Parse(packet.ReadString(length)));
        }
 void IMySqlValue.SkipValue(MySqlPacket packet)
 {
     packet.Position += 8;
 }
 private void ReadEOF()
 {
     packet = stream.ReadPacket();
     CheckEOF();
 }
 public void ExecuteStatement(MySqlPacket packetToExecute)
 {
     warnings = 0;
     packetToExecute.Buffer[4] = (byte)DBCmd.EXECUTE;
     ExecutePacket(packetToExecute);
     serverStatus |= ServerStatusFlags.AnotherQuery;
 }
        public IMySqlValue ReadValue(MySqlPacket packet, long length, bool isNull)
        {
            this.isNull = isNull;
            if (isNull)
                return this;

            if (length == -1)
                length = packet.ReadFieldLength();

            if (ReadAsString)
                mValue = UInt64.Parse(packet.ReadString(length));
            else
                mValue = (UInt64)packet.ReadBitValue((int)length);
            return this;
        }
 public void WriteValue(MySqlPacket packet, bool binary, object value, int length)
 {
     ulong v = (value is UInt64) ? (UInt64)value : Convert.ToUInt64(value);
     if (binary)
         packet.WriteInteger((long)v, 8);
     else
         packet.WriteStringNoNull(v.ToString());
 }
 public void SkipValue(MySqlPacket packet)
 {
     int len = (int)packet.ReadFieldLength();
     packet.Position += len;
 }
        private void WriteOldGuid(MySqlPacket packet, Guid guid, bool binary)
        {
            byte[] bytes = guid.ToByteArray();

            if (binary)
            {
                packet.WriteLength(bytes.Length);
                packet.Write(bytes);
            }
            else
            {
                packet.WriteStringNoNull("_binary ");
                packet.WriteByte((byte)'\'');
                EscapeByteArray(bytes, bytes.Length, packet);
                packet.WriteByte((byte)'\'');
            }
        }
Exemple #15
0
 public virtual void ExecuteStatement(MySqlPacket packetToExecute)
 {
     handler.ExecuteStatement(packetToExecute);
 }
        //        private void ClearFetchedRow()
        //        {
        //            if (lastCommandResult == 0) return;
        //TODO
        /*			CommandResult result = (CommandResult)commandResults[lastCommandResult];
                    result.ReadRemainingColumns();

                    stream.OpenPacket();
                    if (! stream.IsLastPacket)
                        throw new MySqlException("Cursor reading out of sync");

                    ReadEOF(false);
                    lastCommandResult = 0;*/
        //        }
        /// <summary>
        /// FetchDataRow is the method that the data reader calls to see if there is another
        /// row to fetch.  In the non-prepared mode, it will simply read the next data packet.
        /// In the prepared mode (statementId > 0), it will
        /// </summary>
        public bool FetchDataRow(int statementId, int columns)
        {
            /*			ClearFetchedRow();

                        if (!commandResults.ContainsKey(statementId)) return false;

                        if ( (serverStatus & ServerStatusFlags.LastRowSent) != 0)
                            return false;

                        stream.StartPacket(9, true);
                        stream.WriteByte((byte)DBCmd.FETCH);
                        stream.WriteInteger(statementId, 4);
                        stream.WriteInteger(1, 4);
                        stream.Flush();

                        lastCommandResult = statementId;
                            */
            packet = stream.ReadPacket();
            if (packet.IsLastPacket)
            {
                CheckEOF();
                return false;
            }
            nullMap = null;
            if (statementId > 0)
                ReadNullMap(columns);

            return true;
        }
        private void GetColumnData(MySqlField field)
        {
            stream.Encoding = Encoding;
            packet = stream.ReadPacket();
            field.Encoding = Encoding;
            field.CatalogName = packet.ReadLenString();
            field.DatabaseName = packet.ReadLenString();
            field.TableName = packet.ReadLenString();
            field.RealTableName = packet.ReadLenString();
            field.ColumnName = packet.ReadLenString();
            field.OriginalColumnName = packet.ReadLenString();
            packet.ReadByte();
            field.CharacterSetIndex = packet.ReadInteger(2);
            field.ColumnLength = packet.ReadInteger(4);
            MySqlDbType type = (MySqlDbType)packet.ReadByte();
            ColumnFlags colFlags;
            if ((connectionFlags & ClientFlags.LONG_FLAG) != 0)
                colFlags = (ColumnFlags)packet.ReadInteger(2);
            else
                colFlags = (ColumnFlags)packet.ReadByte();
            field.Scale = (byte)packet.ReadByte();

            if (packet.HasMoreData)
            {
                packet.ReadInteger(2); // reserved
            }

            if (type == MySqlDbType.Decimal || type == MySqlDbType.NewDecimal)
            {
                field.Precision = (byte)(field.ColumnLength - 2);
                if ((colFlags & ColumnFlags.UNSIGNED) != 0)
                    field.Precision++;
            }

            field.SetTypeAndFlags(type, colFlags);
        }
        public int GetResult(ref int affectedRow, ref int insertedId)
        {
            try
            {
                packet = stream.ReadPacket();
            }
            catch (TimeoutException)
            {
                // Do not reset serverStatus, allow to reenter, e.g when
                // ResultSet is closed.
                throw;
            }
            catch (Exception)
            {
                serverStatus = 0;
                throw;
            }

            int fieldCount = (int)packet.ReadFieldLength();
            if (-1 == fieldCount)
            {
                string filename = packet.ReadString();
                SendFileToServer(filename);

                return GetResult(ref affectedRow, ref insertedId);
            }
            else if (fieldCount == 0)
            {
                // the code to read last packet will set these server status vars
                // again if necessary.
                serverStatus &= ~(ServerStatusFlags.AnotherQuery |
                                  ServerStatusFlags.MoreResults);
                affectedRow = (int)packet.ReadFieldLength();
                insertedId = (int)packet.ReadFieldLength();

                serverStatus = (ServerStatusFlags)packet.ReadInteger(2);
                warnings += packet.ReadInteger(2);
                if (packet.HasMoreData)
                {
                    packet.ReadLenString(); //TODO: server message
                }
            }
            return fieldCount;
        }
        private void ReadOk(bool read)
        {
            try
            {
                if (read)
                    packet = stream.ReadPacket();
                byte marker = (byte)packet.ReadByte();
                if (marker != 0)
                {
                    throw new MySqlException("Out of sync with server", true, null);
                }

                packet.ReadFieldLength(); /* affected rows */
                packet.ReadFieldLength(); /* last insert id */
                if (packet.HasMoreData)
                {
                    serverStatus = (ServerStatusFlags)packet.ReadInteger(2);
                    packet.ReadInteger(2);  /* warning count */
                    if (packet.HasMoreData)
                    {
                        packet.ReadLenString();  /* message */
                    }
                }
            }
            catch (MySqlException ex)
            {
                HandleException(ex);
                throw;
            }
        }
        public void Open()
        {
            // connect to one of our specified hosts
            try
            {
                if (Settings.ConnectionProtocol == MySqlConnectionProtocol.SharedMemory)
                {
                    SharedMemoryStream str = new SharedMemoryStream(Settings.SharedMemoryName);
                    str.Open(Settings.ConnectionTimeout);
                    baseStream = str;
                }
                else
                {
                    string pipeName = Settings.PipeName;
                    if (Settings.ConnectionProtocol != MySqlConnectionProtocol.NamedPipe)
                        pipeName = null;
            #if !DNX
                    StreamCreator sc = new StreamCreator(Settings.Server, Settings.Port, pipeName,Settings.Keepalive);
            #else
                    StreamCreator sc = new StreamCreator(Settings.Server, Settings.Port, Settings.Keepalive);
            #endif
                    baseStream = sc.GetStream(Settings.ConnectionTimeout);
                }
            }
            catch (Exception ex)
            {
                throw new MySqlException(Resources.UnableToConnectToHost,
                    (int)MySqlErrorCode.UnableToConnectToHost, ex);
            }

            if (baseStream == null)
                throw new MySqlException(Resources.UnableToConnectToHost,
                    (int)MySqlErrorCode.UnableToConnectToHost);

            int maxSinglePacket = 255 * 255 * 255;
            stream = new MySqlStream(baseStream, Encoding, false);

            stream.ResetTimeout((int)Settings.ConnectionTimeout * 1000);

            // read off the welcome packet and parse out it's values
            packet = stream.ReadPacket();
            int protocol = packet.ReadByte();
            string versionString = packet.ReadString();
            version = DBVersion.Parse(versionString);
            if (!version.isAtLeast(5, 0, 0))
                throw new NotSupportedException(Resources.ServerTooOld);
            threadId = packet.ReadInteger(4);
            encryptionSeed = packet.ReadString();

            maxSinglePacket = (256 * 256 * 256) - 1;

            // read in Server capabilities if they are provided
            ClientFlags serverCaps = 0;
            if (packet.HasMoreData)
                serverCaps = (ClientFlags)packet.ReadInteger(2);

            /* New protocol with 16 bytes to describe server characteristics */
            owner.ConnectionCharSetIndex = (int)packet.ReadByte();

            serverStatus = (ServerStatusFlags)packet.ReadInteger(2);

            // Since 5.5, high bits of server caps are stored after status.
            // Previously, it was part of reserved always 0x00 13-byte filler.
            uint serverCapsHigh = (uint)packet.ReadInteger(2);
            serverCaps |= (ClientFlags)(serverCapsHigh << 16);

            packet.Position += 11;
            string seedPart2 = packet.ReadString();
            encryptionSeed += seedPart2;

            string authenticationMethod = "";
            if ((serverCaps & ClientFlags.PLUGIN_AUTH) != 0)
            {
                authenticationMethod = packet.ReadString();
            }

            // based on our settings, set our connection flags
            SetConnectionFlags(serverCaps);

            packet.Clear();
            packet.WriteInteger((int)connectionFlags, 4);

            #if !CF
            if ((serverCaps & ClientFlags.SSL) == 0)
            {
                if ((Settings.SslMode != MySqlSslMode.None)
                && (Settings.SslMode != MySqlSslMode.Preferred))
                {
                    // Client requires SSL connections.
                    string message = String.Format(Resources.NoServerSSLSupport,
                        Settings.Server);
                    throw new MySqlException(message);
                }
            }
            else if (Settings.SslMode != MySqlSslMode.None)
            {
                stream.SendPacket(packet);
                StartSSL();
                packet.Clear();
                packet.WriteInteger((int)connectionFlags, 4);
            }
            #endif

            packet.WriteInteger(maxSinglePacket, 4);
            packet.WriteByte(8);
            packet.Write(new byte[23]);

            Authenticate(false);

            // if we are using compression, then we use our CompressedStream class
            // to hide the ugliness of managing the compression
            if ((connectionFlags & ClientFlags.COMPRESS) != 0)
                stream = new MySqlStream(baseStream, Encoding, true);

            // give our stream the server version we are connected to.
            // We may have some fields that are read differently based
            // on the version of the server we are connected to.
            packet.Version = version;
            stream.MaxBlockSize = maxSinglePacket;
        }
 void IMySqlValue.WriteValue(MySqlPacket packet, bool binary, object val, int length)
 {
     long v = (val is Int64) ? (Int64)val : Convert.ToInt64(val);
     if (binary)
         packet.WriteInteger(v, 8);
     else
         packet.WriteStringNoNull(v.ToString());
 }
        public int PrepareStatement(string sql, ref MySqlField[] parameters)
        {
            //TODO: check this
            //ClearFetchedRow();

            packet.Length = sql.Length * 4 + 5;
            byte[] buffer = packet.Buffer;
            int len = Encoding.GetBytes(sql, 0, sql.Length, packet.Buffer, 5);
            packet.Position = len + 5;
            buffer[4] = (byte)DBCmd.PREPARE;
            ExecutePacket(packet);

            packet = stream.ReadPacket();

            int marker = packet.ReadByte();
            if (marker != 0)
                throw new MySqlException("Expected prepared statement marker");

            int statementId = packet.ReadInteger(4);
            int numCols = packet.ReadInteger(2);
            int numParams = packet.ReadInteger(2);
            //TODO: find out what this is needed for
            packet.ReadInteger(3);
            if (numParams > 0)
            {
                parameters = owner.GetColumns(numParams);
                // we set the encoding for each parameter back to our connection encoding
                // since we can't trust what is coming back from the server
                for (int i = 0; i < parameters.Length; i++)
                    parameters[i].Encoding = Encoding;
            }

            if (numCols > 0)
            {
                while (numCols-- > 0)
                {
                    packet = stream.ReadPacket();
                    //TODO: handle streaming packets
                }

                ReadEOF();
            }

            return statementId;
        }
        private void InternalBindParameters(string sql, MySqlParameterCollection parameters,
            MySqlPacket packet)
        {
            bool sqlServerMode = command.Connection.Settings.SqlServerMode;

            if (packet == null)
            {
                packet = new MySqlPacket(Driver.Encoding);
                packet.Version = Driver.Version;
                packet.WriteByte(0);
            }

            MySqlTokenizer tokenizer = new MySqlTokenizer(sql);
            tokenizer.ReturnComments = true;
            tokenizer.SqlServerMode = sqlServerMode;

            int pos = 0;
            string token = tokenizer.NextToken();
            while (token != null)
            {
                // serialize everything that came before the token (i.e. whitespace)
                packet.WriteStringNoNull(sql.Substring(pos, tokenizer.StartIndex - pos));
                pos = tokenizer.StopIndex;
                if (MySqlTokenizer.IsParameter(token))
                {
                    if (SerializeParameter(parameters, packet, token))
                        token = null;
                }
                if (token != null)
                {
                    if (sqlServerMode && tokenizer.Quoted && token.StartsWith("["))
                        token = String.Format("`{0}`", token.Substring(1, token.Length - 2));
                    packet.WriteStringNoNull(token);
                }
                token = tokenizer.NextToken();
            }
            buffers.Add(packet);
        }
 /// <summary>
 /// Query is the method that is called to send all queries to the server
 /// </summary>
 public void SendQuery(MySqlPacket queryPacket)
 {
     warnings = 0;
     queryPacket.Buffer[4] = (byte)DBCmd.QUERY;
     ExecutePacket(queryPacket);
     // the server will respond in one of several ways with the first byte indicating
     // the type of response.
     // 0 == ok packet.  This indicates non-select queries
     // 0xff == error packet.  This is handled in stream.OpenPacket
     // > 0 = number of columns in select query
     // We don't actually read the result here since a single query can generate
     // multiple resultsets and we don't want to duplicate code.  See ReadResult
     // Instead we set our internal server status flag to indicate that we have a query waiting.
     // This flag will be maintained by ReadResult
     serverStatus |= ServerStatusFlags.AnotherQuery;
 }
        IMySqlValue IMySqlValue.ReadValue(MySqlPacket packet, long length, bool nullVal)
        {
            if (nullVal)
                return new MySqlByte(true);

            if (length == -1)
                return new MySqlByte((sbyte)packet.ReadByte());
            else
            {
                string s = packet.ReadString(length);
                MySqlByte b = new MySqlByte(SByte.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture));
                b.TreatAsBoolean = TreatAsBoolean;
                return b;
            }
        }
        /// <summary>
        /// Perform an authentication against a 4.1.1 server
        /// <param name="reset">
        /// True, if this function is called as part of CHANGE_USER request
        /// (connection reset)
        /// False, for first-time logon
        /// </param>
        /// </summary>
        private void AuthenticateNew(bool reset)
        {
            if ((connectionFlags & ClientFlags.SECURE_CONNECTION) == 0)
                AuthenticateOld();

            packet.Write(Crypt.Get411Password(Settings.Password, encryptionSeed));
            if ((connectionFlags & ClientFlags.CONNECT_WITH_DB) != 0 && Settings.Database != null)
                packet.WriteString(Settings.Database);
            else
                packet.WriteString(""); // Add a null termination to the string.

            if (Settings.IntegratedSecurity)
            {
                // Append authentication method after the database name in the
                // handshake authentication packet.If we're sending CHANGE_USER
                // also write charset number after database name prior to plugin name
                if (reset)
                {
                    packet.WriteInteger(8, 2); // Charset number
                }
                packet.WriteString(AuthenticationWindowsPlugin);
                stream.SendPacket(packet);
                AuthenticateSSPI();
                return;
            }
            else
            {
                stream.SendPacket(packet);
            }

            // this result means the server wants us to send the password using
            // old encryption
            packet = stream.ReadPacket();
            if (packet.IsLastPacket)
            {
                packet.Clear();
                packet.WriteString(Crypt.EncryptPassword(
                                       Settings.Password, encryptionSeed.Substring(0, 8), true));
                stream.SendPacket(packet);
                ReadOk(true);
            }
            ReadOk(false);
        }
 void IMySqlValue.WriteValue(MySqlPacket packet, bool binary, object val, int length)
 {
     sbyte v = (val is sbyte) ? (sbyte)val : Convert.ToSByte(val);
     if (binary)
         packet.WriteByte((byte)v);
     else
         packet.WriteStringNoNull(v.ToString());
 }
        private void AuthenticateSSPI()
        {
            string targetName = ""; // target name (required by Kerberos)

            // First packet sent by server should include target name (for
            // Kerberos) as UTF8 string. It might however be prepended by junk
            // at the start of the string (0xfe"authentication_win_client"\0,
            // see Bug#57442), this junk will be ignored. Target name can also
            // be an empty string if server is not running in a domain environment,
            // in this case authentication will fallback to NTLM.

            // Note that 0xfe byte at the start could also indicate that windows
            // authentication is not supported by sérver, we throw an exception
            // if this happens.

            packet = stream.ReadPacket();
            byte b = packet.ReadByte();
            if (b == 0xfe)
            {
                string authMethod = packet.ReadString();
                if (authMethod.Equals(AuthenticationWindowsPlugin))
                {
                    targetName = packet.ReadString(Encoding.UTF8);
                }
                else
                {
                    // User has requested Windows authentication,  bail out.
                    throw new MySqlException("unexpected authentication method " +
                        authMethod);
                }
            }
            else
            {
                targetName = Encoding.UTF8.GetString(packet.Buffer, 0, packet.Buffer.Length);
            }

            // Do SSPI authentication handshake
            SSPI sspi = new SSPI(targetName, stream.BaseStream, stream.SequenceByte);
            sspi.AuthenticateClient();

            // read ok packet.
            packet = stream.ReadPacket();
            ReadOk(false);
        }
 void IMySqlValue.SkipValue(MySqlPacket packet)
 {
     int len = packet.ReadByte();
     packet.Position += len;
 }
 private void ExecutePacket(MySqlPacket packetToExecute)
 {
     try
     {
         warnings = 0;
         stream.SequenceByte = 0;
         stream.SendPacket(packetToExecute);
     }
     catch (MySqlException ex)
     {
         HandleException(ex);
         throw;
     }
 }
        private void SerializeText(MySqlPacket packet, MySqlDateTime value)
        {
            string val = String.Empty;

            val = String.Format("{0:0000}-{1:00}-{2:00}",
                value.Year, value.Month, value.Day);
            if (type != MySqlDbType.Date)
                val = String.Format("{0} {1:00}:{2:00}:{3:00}", val,
                    value.Hour, value.Minute, value.Second);
            packet.WriteStringNoNull("'" + val + "'");
        }
Exemple #32
0
 public virtual void SendQuery(MySqlPacket p)
 {
     handler.SendQuery(p);
     firstResult = true;
 }