Beispiel #1
0
        // goal: call virtual property getters only once per parameter
        internal bool BindParameter(int index, Bindings bindings)
        {
            int    changeID = _changeID;
            object?value    = Value;

            NativeDBType dbtype = GetBindType(value);

            if (OleDbType.Empty == dbtype.enumOleDbType)
            {
                throw ODB.UninitializedParameters(index, dbtype.enumOleDbType);
            }
            _coerceMetaType = dbtype;
            value           = CoerceValue(value, dbtype);
            CoercedValue    = value;

            ParameterDirection direction = Direction;

            byte precision;

            if (ShouldSerializePrecision())
            {
                precision = PrecisionInternal;
            }
            else
            {
                precision = ValuePrecision(value);
            }
            if (0 == precision)
            {
                precision = dbtype.maxpre;
            }

            byte scale;

            if (ShouldSerializeScale())
            {
                scale = ScaleInternal;
            }
            else
            {
                scale = ValueScale(value);
            }

            int wtype = dbtype.wType;
            int bytecount, size;

            if (dbtype.islong)
            { // long data (image, text, ntext)
                bytecount = ADP.PtrSize;
                if (ShouldSerializeSize())
                {
                    size = Size;
                }
                else
                {
                    if (NativeDBType.STR == dbtype.dbType)
                    {
                        size = int.MaxValue;
                    }
                    else if (NativeDBType.WSTR == dbtype.dbType)
                    {
                        size = int.MaxValue / 2;
                    }
                    else
                    {
                        size = int.MaxValue;
                    }
                }
                wtype |= NativeDBType.BYREF;
            }
            else if (dbtype.IsVariableLength)
            { // variable length data (varbinary, varchar, nvarchar)
                if (!ShouldSerializeSize() && ADP.IsDirection(this, ParameterDirection.Output))
                {
                    throw ADP.UninitializedParameterSize(index, _coerceMetaType.dataType !);
                }

                bool computedSize;
                if (ShouldSerializeSize())
                {
                    size         = Size;
                    computedSize = false;
                }
                else
                {
                    size         = ValueSize(value);
                    computedSize = true;
                }
                if (0 < size)
                {
                    if (NativeDBType.WSTR == dbtype.wType)
                    {
                        // maximum 0x3FFFFFFE characters, computed this way to avoid overflow exception
                        bytecount = Math.Min(size, 0x3FFFFFFE) * 2 + 2;
                    }
                    else
                    {
                        Debug.Assert(NativeDBType.STR != dbtype.wType, "should have ANSI binding, describing is okay");
                        bytecount = size;
                    }

                    if (computedSize)
                    {
                        if (NativeDBType.STR == dbtype.dbType)
                        {
                            // maximum 0x7ffffffe characters, computed this way to avoid overflow exception
                            size = Math.Min(size, 0x3FFFFFFE) * 2;
                        }
                    }

                    if (ODB.LargeDataSize < bytecount)
                    {
                        bytecount = ADP.PtrSize;
                        wtype    |= NativeDBType.BYREF;
                    }
                }
                else if (0 == size)
                {
                    if (NativeDBType.WSTR == wtype)
                    { // allow space for null termination character
                        bytecount = 2;
                        // 0 == size, okay for (STR == dbType)
                    }
                    else
                    {
                        Debug.Assert(NativeDBType.STR != dbtype.wType, "should have ANSI binding, describing is okay");
                        bytecount = 0;
                    }
                }
                else if (-1 == size)
                {
                    bytecount = ADP.PtrSize;
                    wtype    |= NativeDBType.BYREF;
                }
                else
                {
                    throw ADP.InvalidSizeValue(size);
                }
            }
            else
            { // fixed length data
                bytecount = dbtype.fixlen;
                size      = bytecount;
            }
            bindings.CurrentIndex = index;

            // tagDBPARAMBINDINFO info for SetParameterInfo
            bindings.DataSourceType = dbtype.dbString.DangerousGetHandle(); // NOTE: This is a constant and isn't exposed publicly, so there really isn't a potential for Handle Recycling.
            bindings.Name           = ADP.PtrZero;
            bindings.ParamSize      = new IntPtr(size);
            bindings.Flags          = GetBindFlags(direction);
            //bindings.Precision    = precision;
            //bindings.Scale        = scale;

            // tagDBBINDING info for CreateAccessor
            bindings.Ordinal   = (IntPtr)(index + 1);
            bindings.Part      = dbtype.dbPart;
            bindings.ParamIO   = GetBindDirection(direction);
            bindings.Precision = precision;
            bindings.Scale     = scale;
            bindings.DbType    = wtype;
            bindings.MaxLen    = bytecount; // also increments databuffer size (uses DbType)
                                            //bindings.ValueOffset  = bindings.DataBufferSize; // set via MaxLen
                                            //bindings.LengthOffset = i * sizeof_int64;
                                            //bindings.StatusOffset = i * sizeof_int64 + sizeof_int32;
                                            //bindings.TypeInfoPtr  = 0;
                                            //bindings.ObjectPtr    = 0;
                                            //bindings.BindExtPtr   = 0;
                                            //bindings.MemOwner     = /*DBMEMOWNER_CLIENTOWNED*/0;
                                            //bindings.Flags        = 0;

            //bindings.ParameterChangeID = changeID; // bind until something changes
            Debug.Assert(_changeID == changeID, "parameter has unexpectedly changed");

            return(IsParameterComputed());
        }
Beispiel #2
0
        private int FillFromADODB(object data, object adodb, string?srcTable, bool multipleResults)
        {
            Debug.Assert(null != data, "FillFromADODB: null data object");
            Debug.Assert(null != adodb, "FillFromADODB: null ADODB");
            Debug.Assert(!(adodb is DataTable), "call Fill( (DataTable) value)");
            Debug.Assert(!(adodb is DataSet), "call Fill( (DataSet) value)");

            /*
             * IntPtr adodbptr = ADP.PtrZero;
             * try { // generate a new COM Callable Wrapper around the user object so they can't ReleaseComObject on us.
             *  adodbptr = Marshal.GetIUnknownForObject(adodb);
             *  adodb = System.Runtime.Remoting.Services.EnterpriseServicesHelper.WrapIUnknownWithComObject(adodbptr);
             * }
             * finally {
             *  if (ADP.PtrZero != adodbptr) {
             *      Marshal.Release(adodbptr);
             *  }
             * }
             */

            bool closeRecordset = multipleResults;

            UnsafeNativeMethods.ADORecordsetConstruction?recordset = (adodb as UnsafeNativeMethods.ADORecordsetConstruction);
            UnsafeNativeMethods.ADORecordConstruction?   record    = null;

            if (null != recordset)
            {
                if (multipleResults)
                {
                    // The NextRecordset method is not available on a disconnected Recordset object, where ActiveConnection has been set to NULL
                    object activeConnection;
                    activeConnection = ((UnsafeNativeMethods.Recordset15)adodb).get_ActiveConnection();

                    if (null == activeConnection)
                    {
                        multipleResults = false;
                    }
                }
            }
            else
            {
                record = (adodb as UnsafeNativeMethods.ADORecordConstruction);

                if (null != record)
                {
                    multipleResults = false; // IRow implies CommandBehavior.SingleRow which implies CommandBehavior.SingleResult
                }
            }
            // else throw ODB.Fill_NotADODB("adodb"); /* throw later, less code here*/

            int results = 0;

            if (null != recordset)
            {
                int      resultCount = 0;
                bool     incrementResultCount;
                object[] value = new object[1];

                do
                {
                    string?tmp = null;
                    if (data is DataSet)
                    {
                        tmp = GetSourceTableName(srcTable !, resultCount);
                    }
                    results += FillFromRecordset(data, recordset, tmp, out incrementResultCount);

                    if (multipleResults)
                    {
                        value[0] = DBNull.Value;

                        object       nextresult;
                        OleDbHResult hr = ((UnsafeNativeMethods.Recordset15)adodb).NextRecordset(out _, out nextresult);

                        if (0 > hr)
                        {
                            // Current provider does not support returning multiple recordsets from a single execution.
                            if (ODB.ADODB_NextResultError != (int)hr)
                            {
                                SafeNativeMethods.Wrapper.ClearErrorInfo();

                                string message = string.Empty;
                                throw new COMException(message, (int)hr);
                            }
                            break;
                        }
                        adodb = nextresult;
                        if (null != adodb)
                        {
                            recordset = (UnsafeNativeMethods.ADORecordsetConstruction)adodb;

                            if (incrementResultCount)
                            {
                                resultCount++;
                            }
                            continue;
                        }
                    }
                    break;
                } while (null != recordset);

                if ((null != recordset) && (closeRecordset || (null == adodb)))
                {
                    FillClose(true, recordset);
                }
            }
            else if (null != record)
            {
                results = FillFromRecord(data, record, srcTable !);
                if (closeRecordset)
                {
                    FillClose(false, record);
                }
            }
            else
            {
                throw ODB.Fill_NotADODB("adodb");
            }
            return(results);
        }
        private string ValidateConnectionString(string connectionString)
        {
            if (ConvertValueToBoolean(KEY.Asynchronous_Processing, false))
            {
                throw ODB.AsynchronousNotSupported();
            }

            int connectTimeout = ConvertValueToInt32(KEY.Connect_Timeout, 0);

            if (connectTimeout < 0)
            {
                throw ADP.InvalidConnectTimeoutValue();
            }

            string?progid = ConvertValueToString(KEY.Data_Provider, null);

            if (null != progid)
            {
                progid = progid.Trim();
                if (0 < progid.Length)
                { // don't fail on empty 'Data Provider' value
                    ValidateProvider(progid);
                }
            }
            progid = ConvertValueToString(KEY.RemoteProvider, null);
            if (null != progid)
            {
                progid = progid.Trim();
                if (0 < progid.Length)
                { // don't fail on empty 'Data Provider' value
                    ValidateProvider(progid);
                }
            }
            progid = ConvertValueToString(KEY.Provider, string.Empty) !.Trim();
            ValidateProvider(progid); // will fail on empty 'Provider' value

            // initialize to default
            // If the value is not provided in connection string and OleDbServices registry key has not been set by the provider,
            // the default for the provider is -1 (all services are ON).
            // our default is -13, we turn off ODB.DBPROPVAL_OS_AGR_AFTERSESSION and ODB.DBPROPVAL_OS_CLIENTCURSOR flags
            _oledbServices = DbConnectionStringDefaults.OleDbServices;

            bool hasOleDBServices = (base.ContainsKey(KEY.Ole_DB_Services) && !ADP.IsEmpty((string?)base[KEY.Ole_DB_Services]));

            if (!hasOleDBServices)
            { // don't touch registry if they have OLE DB Services
                string?classid = (string?)ADP.ClassesRootRegistryValue(progid + "\\CLSID", string.Empty);
                if ((null != classid) && (0 < classid.Length))
                {
                    // CLSID detection of 'Microsoft OLE DB Provider for ODBC Drivers'
                    Guid classidProvider = new Guid(classid);
                    if (ODB.CLSID_MSDASQL == classidProvider)
                    {
                        throw ODB.MSDASQLNotSupported();
                    }
                    object?tmp = ADP.ClassesRootRegistryValue("CLSID\\{" + classidProvider.ToString("D", CultureInfo.InvariantCulture) + "}", ODB.OLEDB_SERVICES);
                    if (null != tmp)
                    {
                        // @devnote: some providers like MSDataShape don't have the OLEDB_SERVICES value
                        // the MSDataShape provider doesn't support the 'Ole Db Services' keyword
                        // hence, if the value doesn't exist - don't prepend to string
                        try
                        {
                            _oledbServices = (int)tmp;
                        }
                        catch (InvalidCastException e)
                        {
                            ADP.TraceExceptionWithoutRethrow(e);
                        }
                        _oledbServices &= ~(ODB.DBPROPVAL_OS_AGR_AFTERSESSION | ODB.DBPROPVAL_OS_CLIENTCURSOR);

                        StringBuilder builder = new StringBuilder();
                        builder.Append(KEY.Ole_DB_Services);
                        builder.Append('=');
                        builder.Append(_oledbServices.ToString(CultureInfo.InvariantCulture));
                        builder.Append(';');
                        builder.Append(connectionString);
                        connectionString = builder.ToString();
                    }
                }
            }
            else
            {
                // parse the Ole Db Services value from connection string
                _oledbServices = ConvertValueToInt32(KEY.Ole_DB_Services, DbConnectionStringDefaults.OleDbServices);
            }

            return(connectionString);
        }
        // known difference: when getting the parameters for a sproc, the
        //   return value gets marked as a return value but for a sql stmt
        //   the return value gets marked as an output parameter.
        private static OleDbParameter[] DeriveParametersFromStoredProcedure(OleDbConnection connection, OleDbCommand command)
        {
            OleDbParameter[] plist = Array.Empty <OleDbParameter>();

            if (connection.SupportSchemaRowset(OleDbSchemaGuid.Procedure_Parameters))
            {
                string quotePrefix, quoteSuffix;
                connection.GetLiteralQuotes(ADP.DeriveParameters, out quotePrefix, out quoteSuffix);

                object[] parsed = MultipartIdentifier.ParseMultipartIdentifier(command.CommandText, quotePrefix, quoteSuffix, '.', 4, true, SR.OLEDB_OLEDBCommandText, false);
                if (null == parsed[3])
                {
                    throw ADP.NoStoredProcedureExists(command.CommandText);
                }

                object[] restrictions = new object[4];
                object   value;

                // Parse returns an enforced 4 part array
                // 0) Server - ignored but removal would be a run-time breaking change from V1.0
                // 1) Catalog
                // 2) Schema
                // 3) ProcedureName

                // Restrictions array which is passed to OleDb API expects:
                // 0) Catalog
                // 1) Schema
                // 2) ProcedureName
                // 3) ParameterName (leave null)

                // Copy from Parse format to OleDb API format
                Array.Copy(parsed, 1, restrictions, 0, 3);

                //if (cmdConnection.IsServer_msdaora) {
                //    restrictions[1] = Convert.ToString(cmdConnection.UserId).ToUpper();
                //}
                DataTable table = connection.GetSchemaRowset(OleDbSchemaGuid.Procedure_Parameters, restrictions);

                if (null != table)
                {
                    DataColumnCollection columns = table.Columns;

                    DataColumn parameterName      = null;
                    DataColumn parameterDirection = null;
                    DataColumn dataType           = null;
                    DataColumn maxLen             = null;
                    DataColumn numericPrecision   = null;
                    DataColumn numericScale       = null;
                    DataColumn backendtype        = null;

                    int index = columns.IndexOf(ODB.PARAMETER_NAME);
                    if (-1 != index)
                    {
                        parameterName = columns[index];
                    }

                    index = columns.IndexOf(ODB.PARAMETER_TYPE);
                    if (-1 != index)
                    {
                        parameterDirection = columns[index];
                    }

                    index = columns.IndexOf(ODB.DATA_TYPE);
                    if (-1 != index)
                    {
                        dataType = columns[index];
                    }

                    index = columns.IndexOf(ODB.CHARACTER_MAXIMUM_LENGTH);
                    if (-1 != index)
                    {
                        maxLen = columns[index];
                    }

                    index = columns.IndexOf(ODB.NUMERIC_PRECISION);
                    if (-1 != index)
                    {
                        numericPrecision = columns[index];
                    }

                    index = columns.IndexOf(ODB.NUMERIC_SCALE);
                    if (-1 != index)
                    {
                        numericScale = columns[index];
                    }

                    index = columns.IndexOf(ODB.TYPE_NAME);
                    if (-1 != index)
                    {
                        backendtype = columns[index];
                    }

                    DataRow[] dataRows = table.Select(null, ODB.ORDINAL_POSITION_ASC, DataViewRowState.CurrentRows);
                    plist = new OleDbParameter[dataRows.Length];
                    for (index = 0; index < dataRows.Length; ++index)
                    {
                        DataRow dataRow = dataRows[index];

                        OleDbParameter parameter = new OleDbParameter();

                        if ((null != parameterName) && !dataRow.IsNull(parameterName, DataRowVersion.Default))
                        {
                            // $CONSIDER - not trimming the @ from the beginning but to left the designer do that
                            parameter.ParameterName = Convert.ToString(dataRow[parameterName, DataRowVersion.Default], CultureInfo.InvariantCulture).TrimStart(new char[] { '@', ' ', ':' });
                        }
                        if ((null != parameterDirection) && !dataRow.IsNull(parameterDirection, DataRowVersion.Default))
                        {
                            short direction = Convert.ToInt16(dataRow[parameterDirection, DataRowVersion.Default], CultureInfo.InvariantCulture);
                            parameter.Direction = ConvertToParameterDirection(direction);
                        }
                        if ((null != dataType) && !dataRow.IsNull(dataType, DataRowVersion.Default))
                        {
                            // need to ping FromDBType, otherwise WChar->WChar when the user really wants VarWChar
                            short wType = Convert.ToInt16(dataRow[dataType, DataRowVersion.Default], CultureInfo.InvariantCulture);
                            parameter.OleDbType = NativeDBType.FromDBType(wType, false, false).enumOleDbType;
                        }
                        if ((null != maxLen) && !dataRow.IsNull(maxLen, DataRowVersion.Default))
                        {
                            parameter.Size = Convert.ToInt32(dataRow[maxLen, DataRowVersion.Default], CultureInfo.InvariantCulture);
                        }
                        switch (parameter.OleDbType)
                        {
                        case OleDbType.Decimal:
                        case OleDbType.Numeric:
                        case OleDbType.VarNumeric:
                            if ((null != numericPrecision) && !dataRow.IsNull(numericPrecision, DataRowVersion.Default))
                            {
                                // @devnote: unguarded cast from Int16 to Byte
                                parameter.PrecisionInternal = (byte)Convert.ToInt16(dataRow[numericPrecision], CultureInfo.InvariantCulture);
                            }
                            if ((null != numericScale) && !dataRow.IsNull(numericScale, DataRowVersion.Default))
                            {
                                // @devnote: unguarded cast from Int16 to Byte
                                parameter.ScaleInternal = (byte)Convert.ToInt16(dataRow[numericScale], CultureInfo.InvariantCulture);
                            }
                            break;

                        case OleDbType.VarBinary:
                        case OleDbType.VarChar:
                        case OleDbType.VarWChar:
                            value = dataRow[backendtype, DataRowVersion.Default];
                            if (value is string)
                            {
                                string backendtypename = ((string)value).ToLower(CultureInfo.InvariantCulture);
                                switch (backendtypename)
                                {
                                case "binary":
                                    parameter.OleDbType = OleDbType.Binary;
                                    break;

                                //case "varbinary":
                                //    parameter.OleDbType = OleDbType.VarBinary;
                                //    break;
                                case "image":
                                    parameter.OleDbType = OleDbType.LongVarBinary;
                                    break;

                                case "char":
                                    parameter.OleDbType = OleDbType.Char;
                                    break;

                                //case "varchar":
                                //case "varchar2":
                                //    parameter.OleDbType = OleDbType.VarChar;
                                //    break;
                                case "text":
                                    parameter.OleDbType = OleDbType.LongVarChar;
                                    break;

                                case "nchar":
                                    parameter.OleDbType = OleDbType.WChar;
                                    break;

                                //case "nvarchar":
                                //    parameter.OleDbType = OleDbType.VarWChar;
                                case "ntext":
                                    parameter.OleDbType = OleDbType.LongVarWChar;
                                    break;
                                }
                            }
                            break;
                        }
                        //if (AdapterSwitches.OleDbSql.TraceVerbose) {
                        //    ADP.Trace_Parameter("StoredProcedure", parameter);
                        //}
                        plist[index] = parameter;
                    }
                }
                if ((0 == plist.Length) && connection.SupportSchemaRowset(OleDbSchemaGuid.Procedures))
                {
                    restrictions = new object[4] {
                        null, null, command.CommandText, null
                    };
                    table = connection.GetSchemaRowset(OleDbSchemaGuid.Procedures, restrictions);
                    if (0 == table.Rows.Count)
                    {
                        throw ADP.NoStoredProcedureExists(command.CommandText);
                    }
                }
            }
            else if (connection.SupportSchemaRowset(OleDbSchemaGuid.Procedures))
            {
                object[] restrictions = new object[4] {
                    null, null, command.CommandText, null
                };
                DataTable table = connection.GetSchemaRowset(OleDbSchemaGuid.Procedures, restrictions);
                if (0 == table.Rows.Count)
                {
                    throw ADP.NoStoredProcedureExists(command.CommandText);
                }
                // we don't ever expect a procedure with 0 parameters, they should have at least a return value
                throw ODB.NoProviderSupportForSProcResetParameters(connection.Provider);
            }
            else
            {
                throw ODB.NoProviderSupportForSProcResetParameters(connection.Provider);
            }
            return(plist);
        }
Beispiel #5
0
        internal void Value(object value)
        {
            if (value == null)
            {
                this.SetValueEmpty();
            }
            else if (Convert.IsDBNull(value))
            {
                this.SetValueDBNull();
            }
            else
            {
                switch (this.DbType)
                {
                case 0:
                    this.SetValueEmpty();
                    return;

                case 1:
                    this.SetValueDBNull();
                    return;

                case 2:
                    this.Value_I2((short)value);
                    return;

                case 3:
                    this.Value_I4((int)value);
                    return;

                case 4:
                    this.Value_R4((float)value);
                    return;

                case 5:
                    this.Value_R8((double)value);
                    return;

                case 6:
                    this.Value_CY((decimal)value);
                    return;

                case 7:
                    this.Value_DATE((DateTime)value);
                    return;

                case 8:
                    this.Value_BSTR((string)value);
                    return;

                case 9:
                    this.Value_IDISPATCH(value);
                    return;

                case 10:
                    this.Value_ERROR((int)value);
                    return;

                case 11:
                    this.Value_BOOL((bool)value);
                    return;

                case 12:
                    this.Value_VARIANT(value);
                    return;

                case 13:
                    this.Value_IUNKNOWN(value);
                    return;

                case 14:
                    this.Value_DECIMAL((decimal)value);
                    return;

                case 0x10:
                    if (!(value is short))
                    {
                        this.Value_I1((sbyte)value);
                        return;
                    }
                    this.Value_I1(Convert.ToSByte((short)value, CultureInfo.InvariantCulture));
                    return;

                case 0x11:
                    this.Value_UI1((byte)value);
                    return;

                case 0x12:
                    if (!(value is int))
                    {
                        this.Value_UI2((ushort)value);
                        return;
                    }
                    this.Value_UI2(Convert.ToUInt16((int)value, CultureInfo.InvariantCulture));
                    return;

                case 0x13:
                    if (!(value is long))
                    {
                        this.Value_UI4((uint)value);
                        return;
                    }
                    this.Value_UI4(Convert.ToUInt32((long)value, CultureInfo.InvariantCulture));
                    return;

                case 20:
                    this.Value_I8((long)value);
                    return;

                case 0x15:
                    if (!(value is decimal))
                    {
                        this.Value_UI8((ulong)value);
                        return;
                    }
                    this.Value_UI8(Convert.ToUInt64((decimal)value, CultureInfo.InvariantCulture));
                    return;

                case 0x40:
                    this.Value_FILETIME((DateTime)value);
                    return;

                case 0x80:
                    this.Value_BYTES((byte[])value);
                    return;

                case 130:
                    if (!(value is string))
                    {
                        this.Value_WSTR((char[])value);
                        return;
                    }
                    this.Value_WSTR((string)value);
                    return;

                case 0x83:
                    this.Value_NUMERIC((decimal)value);
                    return;

                case 0x85:
                    this.Value_DBDATE((DateTime)value);
                    return;

                case 0x86:
                    this.Value_DBTIME((TimeSpan)value);
                    return;

                case 0x87:
                    this.Value_DBTIMESTAMP((DateTime)value);
                    return;

                case 0x8a:
                    this.Value_VARIANT(value);
                    return;

                case 0x48:
                    this.Value_GUID((Guid)value);
                    return;

                case 0x4080:
                    this.Value_ByRefBYTES((byte[])value);
                    return;

                case 0x4082:
                    if (!(value is string))
                    {
                        this.Value_ByRefWSTR((char[])value);
                        return;
                    }
                    this.Value_ByRefWSTR((string)value);
                    return;
                }
                throw ODB.SVtUnknown(this.DbType);
            }
        }
        /// <include file='doc\OleDbError.uex' path='docs/doc[@for="OleDbError.GetErrorInfo"]/*' />
        private void GetErrorInfo(UnsafeNativeMethods.IErrorRecords errorRecords, int index) {
            int lcid = System.Globalization.CultureInfo.CurrentCulture.LCID;
            UnsafeNativeMethods.IErrorInfo errorInfo = null;
            int hr = errorRecords.GetErrorInfo(index, lcid, out errorInfo);
            if ((0 <= hr) && (null != errorInfo)) {
#if DEBUG
                ODB.Trace_Begin(4, "IErrorInfo", "GetDescription");
#endif
                hr = errorInfo.GetDescription(out message);
#if DEBUG
                ODB.Trace_End(4, "IErrorInfo", "GetDescription", hr, this.message);
#endif
                if (ODB.DB_E_NOLOCALE == hr) { // MDAC 87303
                    Marshal.ReleaseComObject(errorInfo);
#if DEBUG
                    ODB.Trace_Begin(4, "Kernel32", "GetUserDefaultLCID");
#endif
                    lcid = UnsafeNativeMethods.GetUserDefaultLCID();
#if DEBUG
                    ODB.Trace_End(4, "Kernel32", "GetUserDefaultLCID", lcid);
                    ODB.Trace_Begin(4, "IErrorRecords", "GetErrorInfo");
#endif
                    hr = errorRecords.GetErrorInfo(index, lcid, out errorInfo);
#if DEBUG
                    ODB.Trace_End(4, "IErrorRecords", "GetErrorInfo", hr);
#endif
                    if ((0 <= hr) && (null != errorInfo)) {
#if DEBUG
                        ODB.Trace_Begin(4, "IErrorInfo", "GetDescription", "retry");
#endif
                        hr = errorInfo.GetDescription(out this.message);
#if DEBUG
                        ODB.Trace_End(4, "IErrorInfo", "GetDescription", hr, this.message);
#endif
                   }
                }
                if ((hr < 0) && ADP.IsEmpty(this.message)) {
                    this.message = ODB.FailedGetDescription(hr);
                }
                if (null != errorInfo) {
#if DEBUG
                    ODB.Trace_Begin(4, "IErrorInfo", "GetSource");
#endif
                    hr = errorInfo.GetSource(out this.source);
#if DEBUG
                    ODB.Trace_End(4, "IErrorInfo", "GetSource", hr, this.source);
#endif
                    if (ODB.DB_E_NOLOCALE == hr) { // MDAC 87303
                        Marshal.ReleaseComObject(errorInfo);

#if DEBUG
                        ODB.Trace_Begin(4, "Kernel32", "GetUserDefaultLCID");
#endif
                        lcid = UnsafeNativeMethods.GetUserDefaultLCID();
#if DEBUG
                        ODB.Trace_End(4, "Kernel32", "GetUserDefaultLCID", lcid);
                        ODB.Trace_Begin(4, "IErrorRecords", "GetErrorInfo");
#endif
                        hr = errorRecords.GetErrorInfo(index, lcid, out errorInfo);
#if DEBUG
                        ODB.Trace_End(4, "IErrorRecords", "GetErrorInfo", hr);
#endif
                        if ((0 <= hr) && (null != errorInfo)) {
#if DEBUG
                            ODB.Trace_Begin(4, "IErrorInfo", "GetSource", "retry");
#endif
                            hr = errorInfo.GetSource(out this.source);
#if DEBUG
                            ODB.Trace_End(4, "IErrorInfo", "GetSource", hr, this.source);
#endif
                        }
                    }
                    if ((hr < 0) && ADP.IsEmpty(this.source)) {
                        this.source = ODB.FailedGetSource(hr);
                    }
                    Marshal.ReleaseComObject(errorInfo);
                }
            }
        }
Beispiel #7
0
 internal static string FailedGetSource(OleDbHResult errorcode)
 {
     return(SR.Format(SR.OleDb_FailedGetSource, ODB.ELookup(errorcode)));
 }
Beispiel #8
0
 static private void ValidateNotMSDASQL(string progid) {
     progid = progid.ToLower(CultureInfo.InvariantCulture); //MDAC 65389
     if ((ODB.MSDASQL == progid) || progid.StartsWith(ODB.MSDASQLdot) || (ODB.DefaultDescription_MSDASQL == progid)) {
         throw ODB.MSDASQLNotSupported();
     }
 }
Beispiel #9
0
 internal static string NoErrorMessage(OleDbHResult errorcode)
 {
     return(SR.Format(SR.OleDb_NoErrorMessage, ODB.ELookup(errorcode)));
 }
Beispiel #10
0
 internal static string FailedGetDescription(OleDbHResult errorcode)
 {
     return(SR.Format(SR.OleDb_FailedGetDescription, ODB.ELookup(errorcode)));
 }
Beispiel #11
0
        internal static OleDbException NoErrorInformation(string provider, OleDbHResult hr, Exception inner)
        {
            OleDbException e;

            if (!ADP.IsEmpty(provider))
            {
                e = new OleDbException(SR.Format(SR.OleDb_NoErrorInformation2, provider, ODB.ELookup(hr)), hr, inner);
            }
            else
            {
                e = new OleDbException(SR.Format(SR.OleDb_NoErrorInformation, ODB.ELookup(hr)), hr, inner);
            }
            ADP.TraceExceptionAsReturnValue(e);
            return(e);
        }
Beispiel #12
0
        static internal NativeDBType FromDBType(short dbType, bool isLong, bool isFixed)
        {
            switch (dbType)
            {
            //case EMPTY:
            //case NULL:
            case I2:            return(D_SmallInt);

            case I4:            return(D_Integer);

            case R4:            return(D_Single);

            case R8:            return(D_Double);

            case CY:            return(D_Currency);

            case DATE:          return(D_Date);

            case BSTR:          return(D_BSTR);

            case IDISPATCH:     return(D_IDispatch);

            case ERROR:         return(D_Error);

            case BOOL:          return(D_Boolean);

            case VARIANT:       return(D_Variant);

            case IUNKNOWN:      return(D_IUnknown);

            case DECIMAL:       return(D_Decimal);

            case I1:            return(D_TinyInt);

            case UI1:           return(D_UnsignedTinyInt);

            case UI2:           return(D_UnsignedSmallInt);

            case UI4:           return(D_UnsignedInt);

            case I8:            return(D_BigInt);

            case UI8:           return(D_UnsignedBigInt);

            case FILETIME:      return(D_Filetime);

            case GUID:          return(D_Guid);

            case BYTES:         return((isLong) ? D_LongVarBinary : (isFixed) ? D_Binary : D_VarBinary);

            case STR:           return((isLong) ? D_LongVarChar : (isFixed) ? D_Char : D_VarChar);

            case WSTR:          return((isLong) ? D_LongVarWChar : (isFixed) ? D_WChar : D_VarWChar);

            case NUMERIC:       return(D_Numeric);

            //case UDT:
            case DBDATE:        return(D_DBDate);

            case DBTIME:        return(D_DBTime);

            case DBTIMESTAMP:   return(D_DBTimeStamp);

            case HCHAPTER:      return(D_Chapter);

            case PROPVARIANT:   return(D_PropVariant);

            case VARNUMERIC:    return(D_VarNumeric);

            case XML:           return(D_Xml);

            case UDT:           return(D_Udt);

            //case VECTOR:
            //case ARRAY:
            //case BYREF:
            //case RESERVED:
            default:
                if (0 != (NativeDBType.VECTOR & dbType))
                {
                    throw ODB.DBBindingGetVector();
                }
                return(D_Variant); // MDAC 72067
            }
        }
Beispiel #13
0
        static internal NativeDBType FromDataType(OleDbType enumOleDbType)
        {
            switch (enumOleDbType)                                       // @perfnote: Enum.IsDefined
            {
            case OleDbType.Empty:            return(D_Empty);            //   0

            case OleDbType.SmallInt:         return(D_SmallInt);         //   2

            case OleDbType.Integer:          return(D_Integer);          //   3

            case OleDbType.Single:           return(D_Single);           //   4

            case OleDbType.Double:           return(D_Double);           //   5

            case OleDbType.Currency:         return(D_Currency);         //   6

            case OleDbType.Date:             return(D_Date);             //   7

            case OleDbType.BSTR:             return(D_BSTR);             //   8

            case OleDbType.IDispatch:        return(D_IDispatch);        //   9

            case OleDbType.Error:            return(D_Error);            //  10

            case OleDbType.Boolean:          return(D_Boolean);          //  11

            case OleDbType.Variant:          return(D_Variant);          //  12

            case OleDbType.IUnknown:         return(D_IUnknown);         //  13

            case OleDbType.Decimal:          return(D_Decimal);          //  14

            case OleDbType.TinyInt:          return(D_TinyInt);          //  16

            case OleDbType.UnsignedTinyInt:  return(D_UnsignedTinyInt);  //  17

            case OleDbType.UnsignedSmallInt: return(D_UnsignedSmallInt); //  18

            case OleDbType.UnsignedInt:      return(D_UnsignedInt);      //  19

            case OleDbType.BigInt:           return(D_BigInt);           //  20

            case OleDbType.UnsignedBigInt:   return(D_UnsignedBigInt);   //  21

            case OleDbType.Filetime:         return(D_Filetime);         //  64

            case OleDbType.Guid:             return(D_Guid);             //  72

            case OleDbType.Binary:           return(D_Binary);           // 128

            case OleDbType.Char:             return(D_Char);             // 129

            case OleDbType.WChar:            return(D_WChar);            // 130

            case OleDbType.Numeric:          return(D_Numeric);          // 131

            case OleDbType.DBDate:           return(D_DBDate);           // 133

            case OleDbType.DBTime:           return(D_DBTime);           // 134

            case OleDbType.DBTimeStamp:      return(D_DBTimeStamp);      // 135

            case OleDbType.PropVariant:      return(D_PropVariant);      // 138

            case OleDbType.VarNumeric:       return(D_VarNumeric);       // 139

            case OleDbType.VarChar:          return(D_VarChar);          // 200

            case OleDbType.LongVarChar:      return(D_LongVarChar);      // 201

            case OleDbType.VarWChar:         return(D_VarWChar);         // 202 // MDAC 64983: ORA-12704: character set mismatch

            case OleDbType.LongVarWChar:     return(D_LongVarWChar);     // 203

            case OleDbType.VarBinary:        return(D_VarBinary);        // 204

            case OleDbType.LongVarBinary:    return(D_LongVarBinary);    // 205

            default:
                throw ODB.InvalidOleDbType(enumOleDbType);
            }
        }
Beispiel #14
0
        //protected override int Fill(DataTable dataTable, IDataReader dataReader) {
        //    return base.Fill(dataTable, dataReader);
        //}

        private int FillFromRecordset(object data, UnsafeNativeMethods.ADORecordsetConstruction recordset, string?srcTable, out bool incrementResultCount)
        {
            incrementResultCount = false;

            IntPtr chapter; /*ODB.DB_NULL_HCHAPTER*/
            object?result;

            try
            {
                result  = recordset.get_Rowset();
                chapter = recordset.get_Chapter();
            }
            catch (Exception e)
            {
                // UNDONE - should not be catching all exceptions!!!
                if (!ADP.IsCatchableExceptionType(e))
                {
                    throw;
                }

                throw ODB.Fill_EmptyRecordSet("ADODBRecordSet", e);
            }

            if (null != result)
            {
                CommandBehavior behavior = (MissingSchemaAction.AddWithKey != MissingSchemaAction) ? 0 : CommandBehavior.KeyInfo;
                behavior |= CommandBehavior.SequentialAccess;

                OleDbDataReader?dataReader = null;
                try
                {
                    // intialized with chapter only since we don't want ReleaseChapter called for this chapter handle
                    ChapterHandle chapterHandle = ChapterHandle.CreateChapterHandle(chapter);

                    dataReader = new OleDbDataReader(null, null, 0, behavior);
                    dataReader.InitializeIRowset(result, chapterHandle, ADP.RecordsUnaffected);
                    dataReader.BuildMetaInfo();

                    incrementResultCount = (0 < dataReader.FieldCount);
                    if (incrementResultCount)
                    {
                        if (data is DataTable)
                        {
                            return(base.Fill((DataTable)data, dataReader));
                        }
                        else
                        {
                            return(base.Fill((DataSet)data, srcTable !, dataReader, 0, 0));
                        }
                    }
                }
                finally
                {
                    if (null != dataReader)
                    {
                        dataReader.Close();
                    }
                }
            }
            return(0);
        }
Beispiel #15
0
        internal object Value()
        {
            object obj2 = this._value;

            if (obj2 != null)
            {
                return(obj2);
            }
            switch (this.StatusValue())
            {
            case DBStatus.S_OK:
            {
                short dbType = this.DbType;
                if (dbType > 0x40)
                {
                    switch (dbType)
                    {
                    case 0x80:
                        obj2 = this.Value_BYTES();
                        goto Label_0381;

                    case 130:
                        obj2 = this.Value_WSTR();
                        goto Label_0381;

                    case 0x83:
                        obj2 = this.Value_NUMERIC();
                        goto Label_0381;

                    case 0x85:
                        obj2 = this.Value_DBDATE();
                        goto Label_0381;

                    case 0x86:
                        obj2 = this.Value_DBTIME();
                        goto Label_0381;

                    case 0x87:
                        obj2 = this.Value_DBTIMESTAMP();
                        goto Label_0381;

                    case 0x88:
                        obj2 = this.Value_HCHAPTER();
                        goto Label_0381;

                    case 0x8a:
                        obj2 = this.Value_VARIANT();
                        goto Label_0381;

                    case 0x48:
                        obj2 = this.Value_GUID();
                        goto Label_0381;

                    case 0x4080:
                        obj2 = this.Value_ByRefBYTES();
                        goto Label_0381;

                    case 0x4082:
                        obj2 = this.Value_ByRefWSTR();
                        goto Label_0381;
                    }
                    break;
                }
                switch (dbType)
                {
                case 0:
                case 1:
                    obj2 = DBNull.Value;
                    goto Label_0381;

                case 2:
                    obj2 = this.Value_I2();
                    goto Label_0381;

                case 3:
                    obj2 = this.Value_I4();
                    goto Label_0381;

                case 4:
                    obj2 = this.Value_R4();
                    goto Label_0381;

                case 5:
                    obj2 = this.Value_R8();
                    goto Label_0381;

                case 6:
                    obj2 = this.Value_CY();
                    goto Label_0381;

                case 7:
                    obj2 = this.Value_DATE();
                    goto Label_0381;

                case 8:
                    obj2 = this.Value_BSTR();
                    goto Label_0381;

                case 9:
                    obj2 = this.Value_IDISPATCH();
                    goto Label_0381;

                case 10:
                    obj2 = this.Value_ERROR();
                    goto Label_0381;

                case 11:
                    obj2 = this.Value_BOOL();
                    goto Label_0381;

                case 12:
                    obj2 = this.Value_VARIANT();
                    goto Label_0381;

                case 13:
                    obj2 = this.Value_IUNKNOWN();
                    goto Label_0381;

                case 14:
                    obj2 = this.Value_DECIMAL();
                    goto Label_0381;

                case 0x10:
                    obj2 = this.Value_I1();
                    goto Label_0381;

                case 0x11:
                    obj2 = this.Value_UI1();
                    goto Label_0381;

                case 0x12:
                    obj2 = this.Value_UI2();
                    goto Label_0381;

                case 0x13:
                    obj2 = this.Value_UI4();
                    goto Label_0381;

                case 20:
                    obj2 = this.Value_I8();
                    goto Label_0381;

                case 0x15:
                    obj2 = this.Value_UI8();
                    goto Label_0381;

                case 0x40:
                    obj2 = this.Value_FILETIME();
                    goto Label_0381;
                }
                break;
            }

            case DBStatus.S_ISNULL:
            case DBStatus.S_DEFAULT:
                obj2 = DBNull.Value;
                goto Label_0381;

            case DBStatus.S_TRUNCATED:
                switch (this.DbType)
                {
                case 0x80:
                    obj2 = this.Value_BYTES();
                    goto Label_0381;

                case 130:
                    obj2 = this.Value_WSTR();
                    goto Label_0381;

                case 0x4080:
                    obj2 = this.Value_ByRefBYTES();
                    goto Label_0381;

                case 0x4082:
                    obj2 = this.Value_ByRefWSTR();
                    goto Label_0381;
                }
                throw ODB.GVtUnknown(this.DbType);

            default:
                throw this.CheckTypeValueStatusValue();
            }
            throw ODB.GVtUnknown(this.DbType);
Label_0381:
            this._value = obj2;
            return(obj2);
        }
Beispiel #16
0
        internal OleDbConnectionInternal(OleDbConnectionString constr, OleDbConnection connection) : base()
        {
            Debug.Assert((null != constr) && !constr.IsEmpty, "empty connectionstring");
            ConnectionString = constr;

            if (constr.PossiblePrompt && !System.Environment.UserInteractive)
            {
                throw ODB.PossiblePromptNotUserInteractive();
            }

            try
            {
                // this is the native DataLinks object which pools the native datasource/session
                OleDbServicesWrapper wrapper = OleDbConnectionInternal.GetObjectPool();
                _datasrcwrp = new DataSourceWrapper();

                // DataLinks wrapper will call IDataInitialize::GetDataSource to create the DataSource
                // uses constr.ActualConnectionString, no InfoMessageEvent checking
                wrapper.GetDataSource(constr, ref _datasrcwrp);
                Debug.Assert(!_datasrcwrp.IsInvalid, "bad DataSource");

                // initialization is delayed because of OleDbConnectionStringBuilder only wants
                // pre-Initialize IDBPropertyInfo & IDBProperties on the data source
                if (null != connection)
                {
                    _sessionwrp = new SessionWrapper();

                    // From the DataSource object, will call IDBInitialize.Initialize & IDBCreateSession.CreateSession
                    // We always need both called so we use a single call for a single DangerousAddRef/DangerousRelease pair.
                    OleDbHResult hr = _datasrcwrp.InitializeAndCreateSession(constr, ref _sessionwrp);

                    // process the HResult here instead of from the SafeHandle because the possibility
                    // of an InfoMessageEvent.
                    if ((0 <= hr) && !_sessionwrp.IsInvalid)
                    { // process infonessage events
                        OleDbConnection.ProcessResults(hr, connection, connection);
                    }
                    else
                    {
                        Exception e = OleDbConnection.ProcessResults(hr, null, null);
                        Debug.Assert(null != e, "CreateSessionError");
                        throw e;
                    }
                    Debug.Assert(!_sessionwrp.IsInvalid, "bad Session");
                }
            }
            catch
            {
                if (null != _sessionwrp)
                {
                    _sessionwrp.Dispose();
                    _sessionwrp = null;
                }
                if (null != _datasrcwrp)
                {
                    _datasrcwrp.Dispose();
                    _datasrcwrp = null;
                }
                throw;
            }
        }
Beispiel #17
0
        override protected string ValidateParse() {
            int connectTimeout = base.CheckConvertToInt32(KEY.Connect_Timeout, 0);
            if (connectTimeout < 0) {
                throw ADP.InvalidConnectTimeoutValue();
            }

            if (!CheckConvertToBoolean(KEY.Persist_Security_Info, false)) {
                // because we allow the user direct access to the ole db properties and
                // we've changed the default of 'persisit security info' from true to false
                // we need to force the provider to hide the password
                //if (!base.Contains(KEY.Ole_DB_Services) || (null == (value = base[KEY.Ole_DB_Services]))) {
                //    hiddenConnectionString += ";persist security info=false;";
                //}
            }

            if (CheckConvertToBoolean(KEY.Asynchronous_Processing, false)) {
                throw ODB.AsynchronousNotSupported();
            }

            bool hasOleDBServices = (base.Contains(KEY.Ole_DB_Services) && !ADP.IsEmpty((string)base[KEY.Ole_DB_Services]));

            string progid = CheckConvertToString(KEY.Data_Provider, null); // MDAC 71923
            if (null != progid) {
                ValidateNotMSDASQL(progid);
            }
            
            progid = CheckConvertToString(KEY.Provider, null);
            if (null != progid) {
                progid = progid.Trim();
            }
            if (ADP.IsEmpty(progid)) {
                throw ODB.NoProviderSpecified();
            }
            if (ODB.MaxProgIdLength <= progid.Length) { // MDAC 63151
                throw ODB.InvalidProviderSpecified();
            }
            ValidateNotMSDASQL(progid);

            if (!hasOleDBServices) { // don't touch registry if they have OLE DB Services
                string classid = (string) ADP.ClassesRootRegistryValue(progid + "\\CLSID", String.Empty);
                if ((null != classid) && (0 < classid.Length)) {
                    // CLSID detection of 'Microsoft OLE DB Provider for ODBC Drivers'
                    if (ODB.CLSID_MSDASQL == new Guid(classid)) {
                        throw ODB.MSDASQLNotSupported();
                    }
                    object tmp = ADP.ClassesRootRegistryValue("CLSID\\" + classid, ODB.OLEDB_SERVICES);
                    if (null != tmp) {
                        Int32 oledbservices = 0;

                        // @devnote: some providers like MSDataShape don't have the OLEDB_SERVICES value
                        // the MSDataShape provider doesn't support the 'Ole Db Services' keyword
                        // hence, if the value doesn't exist - don't prepend to string
                        try {
                            oledbservices  = Convert.ToInt32(tmp);
                        }
                        catch(Exception e) {
                            ADP.TraceException(e);
                        }
                        oledbservices &= ~(ODB.DBPROPVAL_OS_AGR_AFTERSESSION | ODB.DBPROPVAL_OS_CLIENTCURSOR); // NT 347436, MDAC 58606
                        _oledbservices = oledbservices;

                        // prepend 'OLE DB SERVICES=-13' (or with registry bits included)
#if USECRYPTO
                        byte[] newconstr;
                        string prepend = ODB.Ole_DB_Services + "=" + oledbservices.ToString(System.Globalization.CultureInfo.InvariantCulture) + ";";
                        byte[] plainText = Crypto.DecryptString(EncryptedActualConnectionString);
                        GCHandle handle = GCHandle.Alloc(plainText, GCHandleType.Pinned);
                        try {
                            newconstr = new byte[ADP.CharSize*prepend.Length + plainText.Length];
                            GCHandle newhandle = GCHandle.Alloc(newconstr, GCHandleType.Pinned);
                            try {
                                System.Text.Encoding.Unicode.GetBytes(prepend, 0, prepend.Length, newconstr, 0);
                                plainText.CopyTo(newconstr, ADP.CharSize*prepend.Length);
                                newconstr = Crypto.EncryptOrDecryptData(true, newconstr, 0, newconstr.Length);
                            }
                            catch {
                                Array.Clear(newconstr, 0, newconstr.Length);
                                if (newhandle.IsAllocated) {
                                    newhandle.Free();
                                }
                                throw;
                            }
                            if (newhandle.IsAllocated) {
                                newhandle.Free();
                            }
                        }
                        finally {
                            Array.Clear(plainText, 0, plainText.Length);
                            if (handle.IsAllocated) {
                                handle.Free();
                            }
                        }
                        return System.Text.Encoding.Unicode.GetString(newconstr, 0, newconstr.Length);
#else
                        StringBuilder builder = new StringBuilder();
                        builder.Append(ODB.Ole_DB_Services);
                        builder.Append("=");
                        builder.Append(oledbservices.ToString(System.Globalization.CultureInfo.InvariantCulture));
                        builder.Append(";");
                        builder.Append(EncryptedActualConnectionString);
                        return builder.ToString();
#endif
                    }
                }
            }
            else {
                _oledbservices = CheckConvertToInt32(KEY.Ole_DB_Services, 0);
            }
            return EncryptedActualConnectionString;
        }