예제 #1
0
파일: Odbc32.cs 프로젝트: dox0/DotNet471RS3
 static internal ArgumentOutOfRangeException NotSupportedEnumerationValue(Type type, int value)
 {
     return(ADP.ArgumentOutOfRange(Res.GetString(Res.ODBC_NotSupportedEnumerationValue, type.Name, value.ToString(System.Globalization.CultureInfo.InvariantCulture)), type.Name));
 }
예제 #2
0
 public override int ExecuteNonQuery()
 {
     _executeQuery = false;
     ExecuteReaderInternal(CommandBehavior.Default, ADP.ExecuteNonQuery);
     return(ADP.IntPtrToInt32(_recordsAffected));
 }
예제 #3
0
        static private void DemandAccessPermission
        (
            string path,
            System.IO.FileAccess access
        )
        {
            // ensure we demand on valid path
            AssertPathFormat(path);

            FileIOPermissionAccess demandPermissions;

            switch (access)
            {
            case FileAccess.Read:
                demandPermissions = FileIOPermissionAccess.Read;
                break;

            case FileAccess.Write:
                demandPermissions = FileIOPermissionAccess.Write;
                break;

            case FileAccess.ReadWrite:
            default:
                // the caller have to validate the value of 'access' parameter
                Debug.Assert(access == System.IO.FileAccess.ReadWrite);
                demandPermissions = FileIOPermissionAccess.Read | FileIOPermissionAccess.Write;
                break;
            }

            FileIOPermission filePerm;
            bool             pathTooLong = false;

            // check for read and/or write permissions
            try
            {
                filePerm = new FileIOPermission(demandPermissions, path);
                filePerm.Demand();
            }
            catch (PathTooLongException e)
            {
                pathTooLong = true;
                ADP.TraceExceptionWithoutRethrow(e);
            }

            if (pathTooLong)
            {
                // SQLBUVSTS bugs 192677 and 203422: currently, FileIOPermission does not support path longer than MAX_PATH (260)
                // so we cannot demand permissions for long files. We are going to open bug for FileIOPermission to
                // support this.

                // In the meanwhile, we agreed to have try-catch block on the permission demand instead of checking the path length.
                // This way, if/when the 260-chars limitation is fixed in FileIOPermission, we will not need to change our code

                // since we do not want to relax security checks, we have to demand this permission for AllFiles in order to continue!
                // Note: demand for AllFiles will fail in scenarios where the running code does not have this permission (such as ASP.Net)
                // and the only workaround will be reducing the total path length, which means reducing the length of SqlFileStream path
                // components, such as instance name, table name, etc.. to fit into 260 characters
                filePerm          = new FileIOPermission(PermissionState.Unrestricted);
                filePerm.AllFiles = demandPermissions;

                filePerm.Demand();
            }
        }
예제 #4
0
 private Timer CreatePruningTimer() =>
 ADP.UnsafeCreateTimer(
     new TimerCallback(PruneConnectionPoolGroups),
     null,
     PruningDueTime,
     PruningPeriod);
예제 #5
0
        internal DbConnectionPoolGroup GetConnectionPoolGroup(DbConnectionPoolKey key, DbConnectionPoolGroupOptions poolOptions, ref DbConnectionOptions userConnectionOptions)
        {
            if (string.IsNullOrEmpty(key.ConnectionString))
            {
                return((DbConnectionPoolGroup)null);
            }

            DbConnectionPoolGroup connectionPoolGroup;
            Dictionary <DbConnectionPoolKey, DbConnectionPoolGroup> connectionPoolGroups = _connectionPoolGroups;

            if (!connectionPoolGroups.TryGetValue(key, out connectionPoolGroup) || (connectionPoolGroup.IsDisabled && (null != connectionPoolGroup.PoolGroupOptions)))
            {
                // If we can't find an entry for the connection string in
                // our collection of pool entries, then we need to create a
                // new pool entry and add it to our collection.

                DbConnectionOptions connectionOptions = CreateConnectionOptions(key.ConnectionString, userConnectionOptions);
                if (null == connectionOptions)
                {
                    throw ADP.InternalConnectionError(ADP.ConnectionError.ConnectionOptionsMissing);
                }

                if (null == userConnectionOptions)
                { // we only allow one expansion on the connection string
                    userConnectionOptions = connectionOptions;
                }

                // We don't support connection pooling on Win9x
                if (null == poolOptions)
                {
                    if (null != connectionPoolGroup)
                    {
                        // reusing existing pool option in case user originally used SetConnectionPoolOptions
                        poolOptions = connectionPoolGroup.PoolGroupOptions;
                    }
                    else
                    {
                        // Note: may return null for non-pooled connections
                        poolOptions = CreateConnectionPoolGroupOptions(connectionOptions);
                    }
                }

                lock (this)
                {
                    connectionPoolGroups = _connectionPoolGroups;
                    if (!connectionPoolGroups.TryGetValue(key, out connectionPoolGroup))
                    {
                        DbConnectionPoolGroup newConnectionPoolGroup = new DbConnectionPoolGroup(connectionOptions, key, poolOptions);
                        newConnectionPoolGroup.ProviderInfo = CreateConnectionPoolGroupProviderInfo(connectionOptions);

                        // build new dictionary with space for new connection string
                        Dictionary <DbConnectionPoolKey, DbConnectionPoolGroup> newConnectionPoolGroups = new Dictionary <DbConnectionPoolKey, DbConnectionPoolGroup>(1 + connectionPoolGroups.Count);
                        foreach (KeyValuePair <DbConnectionPoolKey, DbConnectionPoolGroup> entry in connectionPoolGroups)
                        {
                            newConnectionPoolGroups.Add(entry.Key, entry.Value);
                        }

                        // lock prevents race condition with PruneConnectionPoolGroups
                        newConnectionPoolGroups.Add(key, newConnectionPoolGroup);
                        connectionPoolGroup   = newConnectionPoolGroup;
                        _connectionPoolGroups = newConnectionPoolGroups;
                    }
                    else
                    {
                        Debug.Assert(!connectionPoolGroup.IsDisabled, "Disabled pool entry discovered");
                    }
                }
                Debug.Assert(null != connectionPoolGroup, "how did we not create a pool entry?");
                Debug.Assert(null != userConnectionOptions, "how did we not have user connection options?");
            }
            else if (null == userConnectionOptions)
            {
                userConnectionOptions = connectionPoolGroup.ConnectionOptions;
            }
            return(connectionPoolGroup);
        }
예제 #6
0
 /// <include file='..\..\..\..\..\..\..\..\doc\snippets\Microsoft.Data.SqlClient.Server\SqlDataRecord.xml' path='docs/members[@name="SqlDataRecord"]/System.Data.IDataRecord.GetData/*' />
 IDataReader System.Data.IDataRecord.GetData(int ordinal)
 {
     throw ADP.NotSupported();
 }
        // 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).ToLowerInvariant();
                                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);
        }
예제 #8
0
        private int GetColumnSize(object value, int offset, int ordinal)
        {
            if ((ODBC32.SQL_C.NUMERIC == this._bindtype._sql_c) && (this._internalPrecision != 0))
            {
                return(Math.Min(this._internalPrecision, 0x1d));
            }
            int maxByteCount = this._bindtype._columnSize;

            if (0 < maxByteCount)
            {
                return(maxByteCount);
            }
            if (ODBC32.SQL_C.NUMERIC == this._typemap._sql_c)
            {
                return(0x3e);
            }
            maxByteCount = this._internalSize;
            if ((this._internalShouldSerializeSize && (0x3fffffff > maxByteCount)) && (maxByteCount >= 0))
            {
                return(maxByteCount);
            }
            if (!this._internalShouldSerializeSize && ((ParameterDirection.Output & this._internalDirection) != ((ParameterDirection)0)))
            {
                throw ADP.UninitializedParameterSize(ordinal, this._bindtype._type);
            }
            if ((value == null) || Convert.IsDBNull(value))
            {
                maxByteCount = 0;
            }
            else if (value is string)
            {
                maxByteCount = ((string)value).Length - offset;
                if (((ParameterDirection.Output & this._internalDirection) != ((ParameterDirection)0)) && (0x3fffffff <= this._internalSize))
                {
                    maxByteCount = Math.Max(maxByteCount, 0x1000);
                }
                if (((ODBC32.SQL_TYPE.CHAR == this._bindtype._sql_type) || (ODBC32.SQL_TYPE.VARCHAR == this._bindtype._sql_type)) || (ODBC32.SQL_TYPE.LONGVARCHAR == this._bindtype._sql_type))
                {
                    maxByteCount = Encoding.Default.GetMaxByteCount(maxByteCount);
                }
            }
            else if (value is char[])
            {
                maxByteCount = ((char[])value).Length - offset;
                if (((ParameterDirection.Output & this._internalDirection) != ((ParameterDirection)0)) && (0x3fffffff <= this._internalSize))
                {
                    maxByteCount = Math.Max(maxByteCount, 0x1000);
                }
                if (((ODBC32.SQL_TYPE.CHAR == this._bindtype._sql_type) || (ODBC32.SQL_TYPE.VARCHAR == this._bindtype._sql_type)) || (ODBC32.SQL_TYPE.LONGVARCHAR == this._bindtype._sql_type))
                {
                    maxByteCount = Encoding.Default.GetMaxByteCount(maxByteCount);
                }
            }
            else if (value is byte[])
            {
                maxByteCount = ((byte[])value).Length - offset;
                if (((ParameterDirection.Output & this._internalDirection) != ((ParameterDirection)0)) && (0x3fffffff <= this._internalSize))
                {
                    maxByteCount = Math.Max(maxByteCount, 0x2000);
                }
            }
            return(Math.Max(2, maxByteCount));
        }
예제 #9
0
        private int GetParameterSize(object value, int offset, int ordinal)
        {
            int length = this._bindtype._bufferSize;

            if (0 >= length)
            {
                if (ODBC32.SQL_C.NUMERIC == this._typemap._sql_c)
                {
                    return(0x206);
                }
                length = this._internalSize;
                if ((!this._internalShouldSerializeSize || (0x3fffffff <= length)) || (length < 0))
                {
                    if ((length <= 0) && ((ParameterDirection.Output & this._internalDirection) != ((ParameterDirection)0)))
                    {
                        throw ADP.UninitializedParameterSize(ordinal, this._bindtype._type);
                    }
                    if ((value == null) || Convert.IsDBNull(value))
                    {
                        if (this._bindtype._sql_c == ODBC32.SQL_C.WCHAR)
                        {
                            length = 2;
                        }
                        else
                        {
                            length = 0;
                        }
                    }
                    else if (value is string)
                    {
                        length = ((((string)value).Length - offset) * 2) + 2;
                    }
                    else if (value is char[])
                    {
                        length = ((((char[])value).Length - offset) * 2) + 2;
                    }
                    else if (value is byte[])
                    {
                        length = ((byte[])value).Length - offset;
                    }
                    if (((ParameterDirection.Output & this._internalDirection) != ((ParameterDirection)0)) && (0x3fffffff <= this._internalSize))
                    {
                        length = Math.Max(length, 0x2000);
                    }
                    return(length);
                }
                if (ODBC32.SQL_C.WCHAR == this._bindtype._sql_c)
                {
                    if (((value is string) && (length < ((string)value).Length)) && (this._bindtype == this._originalbindtype))
                    {
                        length = ((string)value).Length;
                    }
                    return((length * 2) + 2);
                }
                if (((value is byte[]) && (length < ((byte[])value).Length)) && (this._bindtype == this._originalbindtype))
                {
                    length = ((byte[])value).Length;
                }
            }
            return(length);
        }
예제 #10
0
            public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
            {
                if (destinationType == null)
                {
                    throw ADP.ArgumentNull("destinationType");
                }
                if ((destinationType == typeof(InstanceDescriptor)) && (value is OdbcParameter))
                {
                    object[]      objArray3;
                    Type[]        typeArray3;
                    OdbcParameter parameter = (OdbcParameter)value;
                    int           num       = 0;
                    if (OdbcType.NChar != parameter.OdbcType)
                    {
                        num |= 1;
                    }
                    if (parameter.ShouldSerializeSize())
                    {
                        num |= 2;
                    }
                    if (!ADP.IsEmpty(parameter.SourceColumn))
                    {
                        num |= 4;
                    }
                    if (parameter.Value != null)
                    {
                        num |= 8;
                    }
                    if (((ParameterDirection.Input != parameter.Direction) || parameter.IsNullable) || ((parameter.ShouldSerializePrecision() || parameter.ShouldSerializeScale()) || (DataRowVersion.Current != parameter.SourceVersion)))
                    {
                        num |= 0x10;
                    }
                    if (parameter.SourceColumnNullMapping)
                    {
                        num |= 0x20;
                    }
                    switch (num)
                    {
                    case 0:
                    case 1:
                        typeArray3 = new Type[] { typeof(string), typeof(OdbcType) };
                        objArray3  = new object[] { parameter.ParameterName, parameter.OdbcType };
                        break;

                    case 2:
                    case 3:
                        typeArray3 = new Type[] { typeof(string), typeof(OdbcType), typeof(int) };
                        objArray3  = new object[] { parameter.ParameterName, parameter.OdbcType, parameter.Size };
                        break;

                    case 4:
                    case 5:
                    case 6:
                    case 7:
                        typeArray3 = new Type[] { typeof(string), typeof(OdbcType), typeof(int), typeof(string) };
                        objArray3  = new object[] { parameter.ParameterName, parameter.OdbcType, parameter.Size, parameter.SourceColumn };
                        break;

                    case 8:
                        typeArray3 = new Type[] { typeof(string), typeof(object) };
                        objArray3  = new object[] { parameter.ParameterName, parameter.Value };
                        break;

                    default:
                        if ((0x20 & num) == 0)
                        {
                            typeArray3 = new Type[] { typeof(string), typeof(OdbcType), typeof(int), typeof(ParameterDirection), typeof(bool), typeof(byte), typeof(byte), typeof(string), typeof(DataRowVersion), typeof(object) };
                            objArray3  = new object[] { parameter.ParameterName, parameter.OdbcType, parameter.Size, parameter.Direction, parameter.IsNullable, parameter.PrecisionInternal, parameter.ScaleInternal, parameter.SourceColumn, parameter.SourceVersion, parameter.Value };
                        }
                        else
                        {
                            typeArray3 = new Type[] { typeof(string), typeof(OdbcType), typeof(int), typeof(ParameterDirection), typeof(byte), typeof(byte), typeof(string), typeof(DataRowVersion), typeof(bool), typeof(object) };
                            objArray3  = new object[] { parameter.ParameterName, parameter.OdbcType, parameter.Size, parameter.Direction, parameter.PrecisionInternal, parameter.ScaleInternal, parameter.SourceColumn, parameter.SourceVersion, parameter.SourceColumnNullMapping, parameter.Value };
                        }
                        break;
                    }
                    ConstructorInfo constructor = typeof(OdbcParameter).GetConstructor(typeArray3);
                    if (null != constructor)
                    {
                        return(new InstanceDescriptor(constructor, objArray3));
                    }
                }
                return(base.ConvertTo(context, culture, value, destinationType));
            }
예제 #11
0
 internal void CopyTo(DbParameter destination)
 {
     ADP.CheckArgumentNull(destination, "destination");
     this.CloneHelper((OdbcParameter)destination);
 }
예제 #12
0
        public override Task <int> ReadAsync(char[] buffer, int index, int count)
        {
            ValidateReadParameters(buffer, index, count);
            TaskCompletionSource <int> completion = new TaskCompletionSource <int>();

            if (IsClosed)
            {
                completion.SetException(ADP.ExceptionWithStackTrace(ADP.ObjectDisposed(this)));
            }
            else
            {
                try
                {
                    Task original = Interlocked.CompareExchange <Task>(ref _currentTask, completion.Task, null);
                    if (original != null)
                    {
                        completion.SetException(ADP.ExceptionWithStackTrace(ADP.AsyncOperationPending()));
                    }
                    else
                    {
                        bool completedSynchronously = true;
                        int  charsRead     = 0;
                        int  adjustedIndex = index;
                        int  charsNeeded   = count;

                        // Load in peeked char
                        if ((HasPeekedChar) && (charsNeeded > 0))
                        {
                            // Take a copy of _peekedChar in case it is cleared during close
                            int peekedChar = _peekedChar;
                            if (peekedChar >= char.MinValue)
                            {
                                Debug.Assert((_peekedChar >= char.MinValue) && (_peekedChar <= char.MaxValue), string.Format("Bad peeked character: {0}", _peekedChar));
                                buffer[adjustedIndex] = (char)peekedChar;
                                adjustedIndex++;
                                charsRead++;
                                charsNeeded--;
                                _peekedChar = -1;
                            }
                        }

                        int    byteBufferUsed;
                        byte[] byteBuffer = PrepareByteBuffer(charsNeeded, out byteBufferUsed);

                        // Permit a 0 byte read in order to advance the reader to the correct column
                        if ((byteBufferUsed < byteBuffer.Length) || (byteBuffer.Length == 0))
                        {
                            int bytesRead;
                            var reader = _reader;
                            if (reader != null)
                            {
                                Task <int> getBytesTask = reader.GetBytesAsync(_columnIndex, byteBuffer, byteBufferUsed, byteBuffer.Length - byteBufferUsed, Timeout.Infinite, _disposalTokenSource.Token, out bytesRead);
                                if (getBytesTask == null)
                                {
                                    byteBufferUsed += bytesRead;
                                }
                                else
                                {
                                    // We need more data - setup the callback, and mark this as not completed sync
                                    completedSynchronously = false;
                                    getBytesTask.ContinueWith((t) =>
                                    {
                                        _currentTask = null;
                                        // If we completed but the textreader is closed, then report cancellation
                                        if ((t.Status == TaskStatus.RanToCompletion) && (!IsClosed))
                                        {
                                            try
                                            {
                                                int bytesReadFromStream = t.Result;
                                                byteBufferUsed         += bytesReadFromStream;
                                                if (byteBufferUsed > 0)
                                                {
                                                    charsRead += DecodeBytesToChars(byteBuffer, byteBufferUsed, buffer, adjustedIndex, charsNeeded);
                                                }
                                                completion.SetResult(charsRead);
                                            }
                                            catch (Exception ex)
                                            {
                                                completion.SetException(ex);
                                            }
                                        }
                                        else if (IsClosed)
                                        {
                                            completion.SetException(ADP.ExceptionWithStackTrace(ADP.ObjectDisposed(this)));
                                        }
                                        else if (t.Status == TaskStatus.Faulted)
                                        {
                                            if (t.Exception.InnerException is SqlException)
                                            {
                                                // ReadAsync can't throw a SqlException, so wrap it in an IOException
                                                completion.SetException(ADP.ExceptionWithStackTrace(ADP.ErrorReadingFromStream(t.Exception.InnerException)));
                                            }
                                            else
                                            {
                                                completion.SetException(t.Exception.InnerException);
                                            }
                                        }
                                        else
                                        {
                                            completion.SetCanceled();
                                        }
                                    }, TaskScheduler.Default);
                                }


                                if ((completedSynchronously) && (byteBufferUsed > 0))
                                {
                                    // No more data needed, decode what we have
                                    charsRead += DecodeBytesToChars(byteBuffer, byteBufferUsed, buffer, adjustedIndex, charsNeeded);
                                }
                            }
                            else
                            {
                                // Reader is null, close must of happened in the middle of this read
                                completion.SetException(ADP.ExceptionWithStackTrace(ADP.ObjectDisposed(this)));
                            }
                        }


                        if (completedSynchronously)
                        {
                            _currentTask = null;
                            if (IsClosed)
                            {
                                completion.SetCanceled();
                            }
                            else
                            {
                                completion.SetResult(charsRead);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    // In case of any errors, ensure that the completion is completed and the task is set back to null if we switched it
                    completion.TrySetException(ex);
                    Interlocked.CompareExchange(ref _currentTask, null, completion.Task);
                    throw;
                }
            }

            return(completion.Task);
        }
예제 #13
0
파일: Odbc32.cs 프로젝트: dox0/DotNet471RS3
        static internal TypeMap FromSystemType(Type dataType)
        {
            switch (Type.GetTypeCode(dataType))
            {
            case TypeCode.Empty:     throw ADP.InvalidDataType(TypeCode.Empty);

            case TypeCode.Object:
                if (dataType == typeof(System.Byte[]))
                {
                    return(_VarBinary);
                }
                else if (dataType == typeof(System.Guid))
                {
                    return(_UniqueId);
                }
                else if (dataType == typeof(System.TimeSpan))
                {
                    return(_Time);
                }
                else if (dataType == typeof(System.Char[]))
                {
                    return(_NVarChar);
                }
                throw ADP.UnknownDataType(dataType);

            case TypeCode.DBNull:    throw ADP.InvalidDataType(TypeCode.DBNull);

            case TypeCode.Boolean:   return(_Bit);

// devnote: Char is actually not supported. Our _Char type is actually a fixed length string, not a single character
//            case TypeCode.Char:      return _Char;
            case TypeCode.SByte:     return(_SmallInt);

            case TypeCode.Byte:      return(_TinyInt);

            case TypeCode.Int16:     return(_SmallInt);

            case TypeCode.UInt16:    return(_Int);

            case TypeCode.Int32:     return(_Int);

            case TypeCode.UInt32:    return(_BigInt);

            case TypeCode.Int64:     return(_BigInt);

            case TypeCode.UInt64:    return(_Numeric);

            case TypeCode.Single:    return(_Real);

            case TypeCode.Double:    return(_Double);

            case TypeCode.Decimal:   return(_Numeric);

            case TypeCode.DateTime:  return(_DateTime);

            case TypeCode.Char:
            case TypeCode.String:    return(_NVarChar);

            default:                 throw ADP.UnknownDataTypeCode(dataType, Type.GetTypeCode(dataType));
            }
        }
예제 #14
0
파일: Odbc32.cs 프로젝트: dox0/DotNet471RS3
 static internal InvalidOperationException NoMappingForSqlTransactionLevel(int value)
 {
     return(ADP.DataAdapter(Res.GetString(Res.Odbc_NoMappingForSqlTransactionLevel, value.ToString(CultureInfo.InvariantCulture))));
 }
예제 #15
0
 /// <include file='..\..\..\..\..\..\..\..\doc\snippets\Microsoft.Data.SqlClient.Server\SqlDataRecord.xml' path='docs/members[@name="SqlDataRecord"]/GetChar/*' />
 public virtual char GetChar(int ordinal)
 {
     EnsureSubclassOverride();
     throw ADP.NotSupported();
 }
예제 #16
0
        internal void PrepareForBind(OdbcCommand command, short ordinal, ref int parameterBufferSize)
        {
            this.CopyParameterInternal();
            object bytes  = this.ProcessAndGetParameterValue();
            int    offset = this._internalOffset;
            int    length = this._internalSize;

            if (offset > 0)
            {
                if (bytes is string)
                {
                    if (offset > ((string)bytes).Length)
                    {
                        throw ADP.OffsetOutOfRangeException();
                    }
                }
                else if (bytes is char[])
                {
                    if (offset > ((char[])bytes).Length)
                    {
                        throw ADP.OffsetOutOfRangeException();
                    }
                }
                else if (bytes is byte[])
                {
                    if (offset > ((byte[])bytes).Length)
                    {
                        throw ADP.OffsetOutOfRangeException();
                    }
                }
                else
                {
                    offset = 0;
                }
            }
            switch (this._bindtype._sql_type)
            {
            case ODBC32.SQL_TYPE.WLONGVARCHAR:
            case ODBC32.SQL_TYPE.WVARCHAR:
            case ODBC32.SQL_TYPE.WCHAR:
                if (bytes is char)
                {
                    bytes  = bytes.ToString();
                    length = ((string)bytes).Length;
                    offset = 0;
                }
                if (!command.Connection.TestTypeSupport(this._bindtype._sql_type))
                {
                    if (ODBC32.SQL_TYPE.WCHAR == this._bindtype._sql_type)
                    {
                        this._bindtype = TypeMap._Char;
                    }
                    else if (ODBC32.SQL_TYPE.WVARCHAR == this._bindtype._sql_type)
                    {
                        this._bindtype = TypeMap._VarChar;
                    }
                    else if (ODBC32.SQL_TYPE.WLONGVARCHAR == this._bindtype._sql_type)
                    {
                        this._bindtype = TypeMap._Text;
                    }
                }
                break;

            case ODBC32.SQL_TYPE.BIGINT:
                if (!command.Connection.IsV3Driver)
                {
                    this._bindtype = TypeMap._VarChar;
                    if ((bytes != null) && !Convert.IsDBNull(bytes))
                    {
                        bytes  = ((long)bytes).ToString(CultureInfo.CurrentCulture);
                        length = ((string)bytes).Length;
                        offset = 0;
                    }
                }
                break;

            case ODBC32.SQL_TYPE.NUMERIC:
            case ODBC32.SQL_TYPE.DECIMAL:
                if ((!command.Connection.IsV3Driver || !command.Connection.TestTypeSupport(ODBC32.SQL_TYPE.NUMERIC)) || command.Connection.TestRestrictedSqlBindType(this._bindtype._sql_type))
                {
                    this._bindtype = TypeMap._VarChar;
                    if ((bytes != null) && !Convert.IsDBNull(bytes))
                    {
                        bytes  = ((decimal)bytes).ToString(CultureInfo.CurrentCulture);
                        length = ((string)bytes).Length;
                        offset = 0;
                    }
                }
                break;
            }
            ODBC32.SQL_C cHAR = this._bindtype._sql_c;
            if (!command.Connection.IsV3Driver && (cHAR == ODBC32.SQL_C.WCHAR))
            {
                cHAR = ODBC32.SQL_C.CHAR;
                if (((bytes != null) && !Convert.IsDBNull(bytes)) && (bytes is string))
                {
                    CultureInfo info = new CultureInfo(CultureInfo.CurrentCulture.LCID);
                    bytes  = Encoding.GetEncoding(info.TextInfo.ANSICodePage).GetBytes(bytes.ToString());
                    length = ((byte[])bytes).Length;
                }
            }
            int num2 = this.GetParameterSize(bytes, offset, ordinal);

            switch (this._bindtype._sql_type)
            {
            case ODBC32.SQL_TYPE.WVARCHAR:
                if (num2 > 0xfa0)
                {
                    this._bindtype = TypeMap._NText;
                }
                break;

            case ODBC32.SQL_TYPE.VARBINARY:
                if (num2 > 0x1f40)
                {
                    this._bindtype = TypeMap._Image;
                }
                break;

            case ODBC32.SQL_TYPE.VARCHAR:
                if (num2 > 0x1f40)
                {
                    this._bindtype = TypeMap._Text;
                }
                break;
            }
            this._prepared_Sql_C_Type = cHAR;
            this._preparedOffset      = offset;
            this._preparedSize        = length;
            this._preparedValue       = bytes;
            this._preparedBufferSize  = num2;
            this._preparedIntOffset   = parameterBufferSize;
            this._preparedValueOffset = this._preparedIntOffset + IntPtr.Size;
            parameterBufferSize      += num2 + IntPtr.Size;
        }
예제 #17
0
 /// <include file='..\..\..\..\..\..\..\..\doc\snippets\Microsoft.Data.SqlClient.Server\SqlDataRecord.xml' path='docs/members[@name="SqlDataRecord"]/SetChar/*' />
 public virtual void SetChar(int ordinal, char value)
 {
     EnsureSubclassOverride();
     throw ADP.NotSupported();
 }
        private OdbcDataReader ExecuteReaderObject(CommandBehavior behavior, string method, bool needReader, object[] methodArguments, ODBC32.SQL_API odbcApiMethod)
        {
            OdbcDataReader target = null;

            try
            {
                ODBC32.RetCode typeInfo;
                this.DisposeDeadDataReader();
                this.ValidateConnectionAndTransaction(method);
                if ((CommandBehavior.SingleRow & behavior) != CommandBehavior.Default)
                {
                    behavior |= CommandBehavior.SingleResult;
                }
                OdbcStatementHandle statementHandle = this.GetStatementHandle().StatementHandle;
                this._cmdWrapper.Canceling = false;
                if ((this.weakDataReaderReference != null) && this.weakDataReaderReference.IsAlive)
                {
                    object obj2 = this.weakDataReaderReference.Target;
                    if (((obj2 != null) && this.weakDataReaderReference.IsAlive) && !((OdbcDataReader)obj2).IsClosed)
                    {
                        throw ADP.OpenReaderExists();
                    }
                }
                target = new OdbcDataReader(this, this._cmdWrapper, behavior);
                if (!this.Connection.ProviderInfo.NoQueryTimeout)
                {
                    this.TrySetStatementAttribute(statementHandle, ODBC32.SQL_ATTR.QUERY_TIMEOUT, (IntPtr)this.CommandTimeout);
                }
                if ((needReader && this.Connection.IsV3Driver) && (!this.Connection.ProviderInfo.NoSqlSoptSSNoBrowseTable && !this.Connection.ProviderInfo.NoSqlSoptSSHiddenColumns))
                {
                    if (target.IsBehavior(CommandBehavior.KeyInfo))
                    {
                        if (!this._cmdWrapper._ssKeyInfoModeOn)
                        {
                            this.TrySetStatementAttribute(statementHandle, (ODBC32.SQL_ATTR) 0x4cc, (IntPtr)1L);
                            this.TrySetStatementAttribute(statementHandle, ODBC32.SQL_ATTR.SQL_COPT_SS_TXN_ISOLATION, (IntPtr)1L);
                            this._cmdWrapper._ssKeyInfoModeOff = false;
                            this._cmdWrapper._ssKeyInfoModeOn  = true;
                        }
                    }
                    else if (!this._cmdWrapper._ssKeyInfoModeOff)
                    {
                        this.TrySetStatementAttribute(statementHandle, (ODBC32.SQL_ATTR) 0x4cc, (IntPtr)0L);
                        this.TrySetStatementAttribute(statementHandle, ODBC32.SQL_ATTR.SQL_COPT_SS_TXN_ISOLATION, (IntPtr)0L);
                        this._cmdWrapper._ssKeyInfoModeOff = true;
                        this._cmdWrapper._ssKeyInfoModeOn  = false;
                    }
                }
                if (target.IsBehavior(CommandBehavior.KeyInfo) || target.IsBehavior(CommandBehavior.SchemaOnly))
                {
                    typeInfo = statementHandle.Prepare(this.CommandText);
                    if (typeInfo != ODBC32.RetCode.SUCCESS)
                    {
                        this._connection.HandleError(statementHandle, typeInfo);
                    }
                }
                bool          success         = false;
                CNativeBuffer parameterBuffer = this._cmdWrapper._nativeParameterBuffer;
                RuntimeHelpers.PrepareConstrainedRegions();
                try
                {
                    if ((this._parameterCollection != null) && (0 < this._parameterCollection.Count))
                    {
                        int initialSize = this._parameterCollection.CalcParameterBufferSize(this);
                        if ((parameterBuffer == null) || (parameterBuffer.Length < initialSize))
                        {
                            if (parameterBuffer != null)
                            {
                                parameterBuffer.Dispose();
                            }
                            parameterBuffer = new CNativeBuffer(initialSize);
                            this._cmdWrapper._nativeParameterBuffer = parameterBuffer;
                        }
                        else
                        {
                            parameterBuffer.ZeroMemory();
                        }
                        parameterBuffer.DangerousAddRef(ref success);
                        this._parameterCollection.Bind(this, this._cmdWrapper, parameterBuffer);
                    }
                    if (target.IsBehavior(CommandBehavior.SchemaOnly))
                    {
                        goto Label_0443;
                    }
                    if ((target.IsBehavior(CommandBehavior.KeyInfo) || target.IsBehavior(CommandBehavior.SchemaOnly)) && (this.CommandType != System.Data.CommandType.StoredProcedure))
                    {
                        short num2;
                        typeInfo = statementHandle.NumberOfResultColumns(out num2);
                        switch (typeInfo)
                        {
                        case ODBC32.RetCode.SUCCESS:
                        case ODBC32.RetCode.SUCCESS_WITH_INFO:
                            if (num2 > 0)
                            {
                                target.GetSchemaTable();
                            }
                            goto Label_029A;
                        }
                        if (typeInfo != ODBC32.RetCode.NO_DATA)
                        {
                            this._connection.HandleError(statementHandle, typeInfo);
                        }
                    }
Label_029A:
                    switch (odbcApiMethod)
                    {
                    case ODBC32.SQL_API.SQLEXECDIRECT:
                        if (target.IsBehavior(CommandBehavior.KeyInfo) || this._isPrepared)
                        {
                            typeInfo = statementHandle.Execute();
                        }
                        else
                        {
                            typeInfo = statementHandle.ExecuteDirect(this.CommandText);
                        }
                        break;

                    case ODBC32.SQL_API.SQLCOLUMNS:
                        typeInfo = statementHandle.Columns((string)methodArguments[0], (string)methodArguments[1], (string)methodArguments[2], (string)methodArguments[3]);
                        break;

                    case ODBC32.SQL_API.SQLSTATISTICS:
                        typeInfo = statementHandle.Statistics((string)methodArguments[0], (string)methodArguments[1], (string)methodArguments[2], (short)methodArguments[3], (short)methodArguments[4]);
                        break;

                    case ODBC32.SQL_API.SQLTABLES:
                        typeInfo = statementHandle.Tables((string)methodArguments[0], (string)methodArguments[1], (string)methodArguments[2], (string)methodArguments[3]);
                        break;

                    case ODBC32.SQL_API.SQLGETTYPEINFO:
                        typeInfo = statementHandle.GetTypeInfo((short)methodArguments[0]);
                        break;

                    case ODBC32.SQL_API.SQLPROCEDURECOLUMNS:
                        typeInfo = statementHandle.ProcedureColumns((string)methodArguments[0], (string)methodArguments[1], (string)methodArguments[2], (string)methodArguments[3]);
                        break;

                    case ODBC32.SQL_API.SQLPROCEDURES:
                        typeInfo = statementHandle.Procedures((string)methodArguments[0], (string)methodArguments[1], (string)methodArguments[2]);
                        break;

                    default:
                        throw ADP.InvalidOperation(method.ToString());
                    }
                    if ((typeInfo != ODBC32.RetCode.SUCCESS) && (ODBC32.RetCode.NO_DATA != typeInfo))
                    {
                        this._connection.HandleError(statementHandle, typeInfo);
                    }
                }
                finally
                {
                    if (success)
                    {
                        parameterBuffer.DangerousRelease();
                    }
                }
Label_0443:
                this.weakDataReaderReference = new WeakReference(target);
                if (!target.IsBehavior(CommandBehavior.SchemaOnly))
                {
                    target.FirstResult();
                }
                this.cmdState = ConnectionState.Fetching;
            }
            finally
            {
                if (ConnectionState.Fetching != this.cmdState)
                {
                    if (target != null)
                    {
                        if (this._parameterCollection != null)
                        {
                            this._parameterCollection.ClearBindings();
                        }
                        target.Dispose();
                    }
                    if (this.cmdState != ConnectionState.Closed)
                    {
                        this.cmdState = ConnectionState.Closed;
                    }
                }
            }
            return(target);
        }
예제 #19
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; // MDAC 60332, 66668
            Type recordsetType  = null;

            UnsafeNativeMethods.ADORecordConstruction    record    = null;
            UnsafeNativeMethods.ADORecordsetConstruction recordset = null;
            try {
#if DEBUG
                ODB.Trace_Cast("Object", "ADORecordsetConstruction", "get_Rowset");
#endif
                recordset     = (UnsafeNativeMethods.ADORecordsetConstruction)adodb;
                recordsetType = adodb.GetType();

                if (multipleResults)
                {
                    // The NextRecordset method is not available on a disconnected Recordset object, where ActiveConnection has been set to NULL
                    object activeConnection = recordsetType.InvokeMember("ActiveConnection", BindingFlags.GetProperty, null, adodb, new object[0]);
                    if (null == activeConnection)
                    {
                        multipleResults = false;
                    }
                }
            }
            catch (InvalidCastException e) {
                ADP.TraceException(e);

                try {
#if DEBUG
                    ODB.Trace_Cast("Object", "ADORecordConstruction", "get_Row");
#endif
                    record          = (UnsafeNativeMethods.ADORecordConstruction)adodb;
                    multipleResults = false; // IRow implies CommandBehavior.SingleRow which implies CommandBehavior.SingleResult
                }
                catch (InvalidCastException f) {
                    // $Consider: telling use either type of object passed in
                    throw ODB.Fill_NotADODB("adodb", f);
                }
            }
            int results = 0;
            if (null != recordset)
            {
                int      resultCount = 0;
                bool     incrementResultCount; // MDAC 59632
                object[] value = new object[1];

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

                    if (multipleResults)
                    {
                        value[0] = DBNull.Value;
                        try {
                            adodb = recordsetType.InvokeMember("NextRecordset", BindingFlags.InvokeMethod, null, adodb, value);
                            if (null != adodb)
                            {
                                try {
#if DEBUG
                                    ODB.Trace_Cast("ADODB", "ADORecordsetConstruction", "get_Rowset");
#endif
                                    recordset = (UnsafeNativeMethods.ADORecordsetConstruction)adodb;
                                }
                                catch (Exception e) {
                                    ADP.TraceException(e);
                                    break;
                                }
                                recordsetType = adodb.GetType(); // MDAC 59253
                                if (incrementResultCount)
                                {
                                    resultCount++;
                                }
                                continue;
                            }
                        }
                        catch (TargetInvocationException e) { // MDAC 59244, 65506
                            if (e.InnerException is COMException)
                            {
                                FillNextResultError((COMException)e.InnerException, e);
                                closeRecordset = true; // MDAC 60408
                            }
                            else
                            {
                                throw;
                            }
                        }
                        catch (COMException e) {   // used as backup to the TargetInvocationException
                            FillNextResultError(e, e);
                            closeRecordset = true; // MDAC 60408
                        }
                    }
                    break;
                } while(null != recordset);

                if ((null != recordset) && (closeRecordset || (null == adodb)))   // MDAC 59746, 60902
                {
                    FillClose(recordsetType, recordset);
                }
            }
            else if (null != record)
            {
                results = FillFromRecord(data, record, srcTable);
                if (closeRecordset)                     // MDAC 66668
                {
                    FillClose(adodb.GetType(), record); // MDAC 60848
                }
            }
            else
            {
                throw ODB.Fill_NotADODB("adodb", null);
            }
            return(results);
        }
예제 #20
0
        private async Task ReconnectAsync(int timeout)
        {
            try
            {
                long commandTimeoutExpiration = 0;
                if (timeout > 0)
                {
                    commandTimeoutExpiration = ADP.TimerCurrent() + ADP.TimerFromSeconds(timeout);
                }
                CancellationTokenSource cts = new CancellationTokenSource();
                _reconnectionCancellationSource = cts;
                CancellationToken ctoken = cts.Token;
                int retryCount           = _connectRetryCount; // take a snapshot: could be changed by modifying the connection string
                for (int attempt = 0; attempt < retryCount; attempt++)
                {
                    if (ctoken.IsCancellationRequested)
                    {
                        return;
                    }
                    try
                    {
                        try
                        {
                            ForceNewConnection = true;
                            await OpenAsync(ctoken).ConfigureAwait(false);

                            // On success, increment the reconnect count - we don't really care if it rolls over since it is approx.
                            _reconnectCount = unchecked (_reconnectCount + 1);
#if DEBUG
                            Debug.Assert(_recoverySessionData._debugReconnectDataApplied, "Reconnect data was not applied !");
#endif
                        }
                        finally
                        {
                            ForceNewConnection = false;
                        }
                        return;
                    }
                    catch (SqlException e)
                    {
                        if (attempt == retryCount - 1)
                        {
                            throw SQL.CR_AllAttemptsFailed(e, _originalConnectionId);
                        }
                        if (timeout > 0 && ADP.TimerRemaining(commandTimeoutExpiration) < ADP.TimerFromSeconds(ConnectRetryInterval))
                        {
                            throw SQL.CR_NextAttemptWillExceedQueryTimeout(e, _originalConnectionId);
                        }
                    }
                    await Task.Delay(1000 *ConnectRetryInterval, ctoken).ConfigureAwait(false);
                }
            }
            finally
            {
                _recoverySessionData = null;
                _supressStateChangeForReconnection = false;
            }
            Debug.Assert(false, "Should not reach this point");
        }
예제 #21
0
        internal ODBC32.RetCode BeginTransaction(ref IsolationLevel isolevel)
        {
            ODBC32.RetCode  retcode = ODBC32.RetCode.SUCCESS;
            ODBC32.SQL_ATTR isolationAttribute;
            if (IsolationLevel.Unspecified != isolevel)
            {
                ODBC32.SQL_TRANSACTION sql_iso;
                switch (isolevel)
                {
                case IsolationLevel.ReadUncommitted:
                    sql_iso            = ODBC32.SQL_TRANSACTION.READ_UNCOMMITTED;
                    isolationAttribute = ODBC32.SQL_ATTR.TXN_ISOLATION;
                    break;

                case IsolationLevel.ReadCommitted:
                    sql_iso            = ODBC32.SQL_TRANSACTION.READ_COMMITTED;
                    isolationAttribute = ODBC32.SQL_ATTR.TXN_ISOLATION;
                    break;

                case IsolationLevel.RepeatableRead:
                    sql_iso            = ODBC32.SQL_TRANSACTION.REPEATABLE_READ;
                    isolationAttribute = ODBC32.SQL_ATTR.TXN_ISOLATION;
                    break;

                case IsolationLevel.Serializable:
                    sql_iso            = ODBC32.SQL_TRANSACTION.SERIALIZABLE;
                    isolationAttribute = ODBC32.SQL_ATTR.TXN_ISOLATION;
                    break;

                case IsolationLevel.Snapshot:
                    sql_iso = ODBC32.SQL_TRANSACTION.SNAPSHOT;
                    // VSDD 414121: Snapshot isolation level must be set through SQL_COPT_SS_TXN_ISOLATION (http://msdn.microsoft.com/en-us/library/ms131709.aspx)
                    isolationAttribute = ODBC32.SQL_ATTR.SQL_COPT_SS_TXN_ISOLATION;
                    break;

                case IsolationLevel.Chaos:
                    throw ODBC.NotSupportedIsolationLevel(isolevel);

                default:
                    throw ADP.InvalidIsolationLevel(isolevel);
                }

                //Set the isolation level (unless its unspecified)
                retcode = SetConnectionAttribute2(isolationAttribute, (IntPtr)sql_iso, (Int32)ODBC32.SQL_IS.INTEGER);

                //Note: The Driver can return success_with_info to indicate it "rolled" the
                //isolevel to the next higher value.  If this is the case, we need to requery
                //the value if th euser asks for it...
                //We also still propagate the info, since it could be other info as well...

                if (ODBC32.RetCode.SUCCESS_WITH_INFO == retcode)
                {
                    isolevel = IsolationLevel.Unspecified;
                }
            }

            switch (retcode)
            {
            case ODBC32.RetCode.SUCCESS:
            case ODBC32.RetCode.SUCCESS_WITH_INFO:
                //Turn off auto-commit (which basically starts the transaction)
                retcode      = AutoCommitOff();
                _handleState = HandleState.TransactionInProgress;
                break;
            }
            return(retcode);
        }
예제 #22
0
 protected override void Activate(Transaction transaction) => throw ADP.ClosedConnectionError();
예제 #23
0
        internal bool TryGetConnection(DbConnection owningConnection, TaskCompletionSource <DbConnectionInternal> retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, out DbConnectionInternal connection)
        {
            Debug.Assert(null != owningConnection, "null owningConnection?");

            DbConnectionPoolGroup poolGroup;
            DbConnectionPool      connectionPool;

            connection = null;

            //  Work around race condition with clearing the pool between GetConnectionPool obtaining pool
            //  and GetConnection on the pool checking the pool state.  Clearing the pool in this window
            //  will switch the pool into the ShuttingDown state, and GetConnection will return null.
            //  There is probably a better solution involving locking the pool/group, but that entails a major
            //  re-design of the connection pooling synchronization, so is postponed for now.

            // Use retriesLeft to prevent CPU spikes with incremental sleep
            // start with one msec, double the time every retry
            // max time is: 1 + 2 + 4 + ... + 2^(retries-1) == 2^retries -1 == 1023ms (for 10 retries)
            int retriesLeft = 10;
            int timeBetweenRetriesMilliseconds = 1;

            do
            {
                poolGroup = GetConnectionPoolGroup(owningConnection);
                // Doing this on the callers thread is important because it looks up the WindowsIdentity from the thread.
                connectionPool = GetConnectionPool(owningConnection, poolGroup);
                if (null == connectionPool)
                {
                    // If GetConnectionPool returns null, we can be certain that
                    // this connection should not be pooled via DbConnectionPool
                    // or have a disabled pool entry.
                    poolGroup = GetConnectionPoolGroup(owningConnection); // previous entry have been disabled

                    if (retry != null)
                    {
                        Task <DbConnectionInternal> newTask;
                        CancellationTokenSource     cancellationTokenSource = new CancellationTokenSource();
                        lock (s_pendingOpenNonPooled)
                        {
                            // look for an available task slot (completed or empty)
                            int idx;
                            for (idx = 0; idx < s_pendingOpenNonPooled.Length; idx++)
                            {
                                Task task = s_pendingOpenNonPooled[idx];
                                if (task == null)
                                {
                                    s_pendingOpenNonPooled[idx] = GetCompletedTask();
                                    break;
                                }
                                else if (task.IsCompleted)
                                {
                                    break;
                                }
                            }

                            // if didn't find one, pick the next one in round-robin fashion
                            if (idx == s_pendingOpenNonPooled.Length)
                            {
                                idx = (int)(s_pendingOpenNonPooledNext % s_pendingOpenNonPooled.Length);
                                unchecked
                                {
                                    s_pendingOpenNonPooledNext++;
                                }
                            }

                            // now that we have an antecedent task, schedule our work when it is completed.
                            // If it is a new slot or a completed task, this continuation will start right away.
                            newTask = s_pendingOpenNonPooled[idx].ContinueWith((_) =>
                            {
                                Transactions.Transaction originalTransaction = ADP.GetCurrentTransaction();
                                try
                                {
                                    ADP.SetCurrentTransaction(retry.Task.AsyncState as Transactions.Transaction);
                                    var newConnection = CreateNonPooledConnection(owningConnection, poolGroup, userOptions);
                                    if ((oldConnection != null) && (oldConnection.State == ConnectionState.Open))
                                    {
                                        oldConnection.PrepareForReplaceConnection();
                                        oldConnection.Dispose();
                                    }
                                    return(newConnection);
                                }
                                finally
                                {
                                    ADP.SetCurrentTransaction(originalTransaction);
                                }
                            }, cancellationTokenSource.Token, TaskContinuationOptions.LongRunning, TaskScheduler.Default);

                            // Place this new task in the slot so any future work will be queued behind it
                            s_pendingOpenNonPooled[idx] = newTask;
                        }

                        // Set up the timeout (if needed)
                        if (owningConnection.ConnectionTimeout > 0)
                        {
                            int connectionTimeoutMilliseconds = owningConnection.ConnectionTimeout * 1000;
                            cancellationTokenSource.CancelAfter(connectionTimeoutMilliseconds);
                        }

                        // once the task is done, propagate the final results to the original caller
                        newTask.ContinueWith((task) =>
                        {
                            cancellationTokenSource.Dispose();
                            if (task.IsCanceled)
                            {
                                retry.TrySetException(ADP.ExceptionWithStackTrace(ADP.NonPooledOpenTimeout()));
                            }
                            else if (task.IsFaulted)
                            {
                                retry.TrySetException(task.Exception.InnerException);
                            }
                            else
                            {
                                if (!retry.TrySetResult(task.Result))
                                {
                                    // The outer TaskCompletionSource was already completed
                                    // Which means that we don't know if someone has messed with the outer connection in the middle of creation
                                    // So the best thing to do now is to destroy the newly created connection
                                    task.Result.DoomThisConnection();
                                    task.Result.Dispose();
                                }
                            }
                        }, TaskScheduler.Default);

                        return(false);
                    }

                    connection = CreateNonPooledConnection(owningConnection, poolGroup, userOptions);
                }
                else
                {
                    if (((SqlClient.SqlConnection)owningConnection).ForceNewConnection)
                    {
                        Debug.Assert(!(oldConnection is DbConnectionClosed), "Force new connection, but there is no old connection");
                        connection = connectionPool.ReplaceConnection(owningConnection, userOptions, oldConnection);
                    }
                    else
                    {
                        if (!connectionPool.TryGetConnection(owningConnection, retry, userOptions, out connection))
                        {
                            return(false);
                        }
                    }

                    if (connection == null)
                    {
                        // connection creation failed on semaphore waiting or if max pool reached
                        if (connectionPool.IsRunning)
                        {
                            // If GetConnection failed while the pool is running, the pool timeout occurred.
                            throw ADP.PooledOpenTimeout();
                        }
                        else
                        {
                            // We've hit the race condition, where the pool was shut down after we got it from the group.
                            // Yield time slice to allow shut down activities to complete and a new, running pool to be instantiated
                            //  before retrying.
                            Threading.Thread.Sleep(timeBetweenRetriesMilliseconds);
                            timeBetweenRetriesMilliseconds *= 2; // double the wait time for next iteration
                        }
                    }
                }
            } while (connection == null && retriesLeft-- > 0);

            if (connection == null)
            {
                // exhausted all retries or timed out - give up
                throw ADP.PooledOpenTimeout();
            }

            return(true);
        }
예제 #24
0
 public override void EnlistTransaction(Transaction transaction) => throw ADP.ClosedConnectionError();
예제 #25
0
        private OleDbDataReader ExecuteReaderInternal(CommandBehavior behavior, string method)
        {
            OleDbDataReader dataReader         = null;
            OleDbException  nextResultsFailure = null;
            int             state = ODB.InternalStateClosed;

            try
            {
                ValidateConnectionAndTransaction(method);

                if (0 != (CommandBehavior.SingleRow & behavior))
                {
                    // CommandBehavior.SingleRow implies CommandBehavior.SingleResult
                    behavior |= CommandBehavior.SingleResult;
                }

                object executeResult;
                int    resultType;

                switch (CommandType)
                {
                case 0:     // uninitialized CommandType.Text
                case CommandType.Text:
                case CommandType.StoredProcedure:
                    resultType = ExecuteCommand(behavior, out executeResult);
                    break;

                case CommandType.TableDirect:
                    resultType = ExecuteTableDirect(behavior, out executeResult);
                    break;

                default:
                    throw ADP.InvalidCommandType(CommandType);
                }

                if (_executeQuery)
                {
                    try
                    {
                        dataReader = new OleDbDataReader(_connection, this, 0, this.commandBehavior);

                        switch (resultType)
                        {
                        case ODB.ExecutedIMultipleResults:
                            dataReader.InitializeIMultipleResults(executeResult);
                            dataReader.NextResult();
                            break;

                        case ODB.ExecutedIRowset:
                            dataReader.InitializeIRowset(executeResult, ChapterHandle.DB_NULL_HCHAPTER, _recordsAffected);
                            dataReader.BuildMetaInfo();
                            dataReader.HasRowsRead();
                            break;

                        case ODB.ExecutedIRow:
                            dataReader.InitializeIRow(executeResult, _recordsAffected);
                            dataReader.BuildMetaInfo();
                            break;

                        case ODB.PrepareICommandText:
                            if (!_isPrepared)
                            {
                                PrepareCommandText(2);
                            }
                            OleDbDataReader.GenerateSchemaTable(dataReader, _icommandText, behavior);
                            break;

                        default:
                            Debug.Assert(false, "ExecuteReaderInternal: unknown result type");
                            break;
                        }
                        executeResult  = null;
                        _hasDataReader = true;
                        _connection.AddWeakReference(dataReader, OleDbReferenceCollection.DataReaderTag);

                        // command stays in the executing state until the connection
                        // has a datareader to track for it being closed
                        state = ODB.InternalStateOpen;
                    }
                    finally
                    {
                        if (ODB.InternalStateOpen != state)
                        {
                            this.canceling = true;
                            if (null != dataReader)
                            {
                                ((IDisposable)dataReader).Dispose();
                                dataReader = null;
                            }
                        }
                    }
                    Debug.Assert(null != dataReader, "ExecuteReader should never return a null DataReader");
                }
                else
                { // optimized code path for ExecuteNonQuery to not create a OleDbDataReader object
                    try
                    {
                        if (ODB.ExecutedIMultipleResults == resultType)
                        {
                            UnsafeNativeMethods.IMultipleResults multipleResults = (UnsafeNativeMethods.IMultipleResults)executeResult;

                            // may cause a Connection.ResetState which closes connection
                            nextResultsFailure = OleDbDataReader.NextResults(multipleResults, _connection, this, out _recordsAffected);
                        }
                    }
                    finally
                    {
                        try
                        {
                            if (null != executeResult)
                            {
                                Marshal.ReleaseComObject(executeResult);
                                executeResult = null;
                            }
                            CloseFromDataReader(ParameterBindings);
                        }
                        catch (Exception e)
                        {
                            // UNDONE - should not be catching all exceptions!!!
                            if (!ADP.IsCatchableExceptionType(e))
                            {
                                throw;
                            }
                            if (null != nextResultsFailure)
                            {
                                nextResultsFailure = new OleDbException(nextResultsFailure, e);
                            }
                            else
                            {
                                throw;
                            }
                        }
                    }
                }
            }
            finally
            { // finally clear executing state
                try
                {
                    if ((null == dataReader) && (ODB.InternalStateOpen != state))
                    {
                        ParameterCleanup();
                    }
                }
                catch (Exception e)
                {
                    // UNDONE - should not be catching all exceptions!!!
                    if (!ADP.IsCatchableExceptionType(e))
                    {
                        throw;
                    }
                    if (null != nextResultsFailure)
                    {
                        nextResultsFailure = new OleDbException(nextResultsFailure, e);
                    }
                    else
                    {
                        throw;
                    }
                }
                if (null != nextResultsFailure)
                {
                    throw nextResultsFailure;
                }
            }
            return(dataReader);
        }
 public override bool ContainsKey(string keyword)
 {
     ADP.CheckArgumentNull(keyword, nameof(keyword));
     return(s_keywords.ContainsKey(keyword) || base.ContainsKey(keyword));
 }
예제 #27
0
        private void InitializeEaBuffer(byte[] transactionContext)
        {
            if (transactionContext.Length >= UInt16.MaxValue)
            {
                throw ADP.ArgumentOutOfRange("transactionContext");
            }

            UnsafeNativeMethods.FILE_FULL_EA_INFORMATION eaBuffer;
            eaBuffer.nextEntryOffset = 0;
            eaBuffer.flags           = 0;
            eaBuffer.EaName          = 0;

            // string will be written as ANSI chars, so Length == ByteLength in this case
            eaBuffer.EaNameLength  = (byte)EA_NAME_STRING.Length;
            eaBuffer.EaValueLength = (ushort)transactionContext.Length;

            // allocate sufficient memory to contain the FILE_FULL_EA_INFORMATION struct and
            //   the contiguous name/value pair in eaName (note: since the struct already
            //   contains one byte for eaName, we don't need to allocate a byte for the
            //   null character separator).
            m_cbBuffer = Marshal.SizeOf(eaBuffer) + eaBuffer.EaNameLength + eaBuffer.EaValueLength;

            IntPtr pbBuffer = IntPtr.Zero;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
            }
            finally
            {
                pbBuffer = Marshal.AllocHGlobal(m_cbBuffer);
                if (pbBuffer != IntPtr.Zero)
                {
                    SetHandle(pbBuffer);
                }
            }

            bool mustRelease = false;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                DangerousAddRef(ref mustRelease);
                IntPtr ptr = DangerousGetHandle();

                // write struct into buffer
                Marshal.StructureToPtr(eaBuffer, ptr, false);

                // write property name into buffer
                System.Text.ASCIIEncoding ascii = new System.Text.ASCIIEncoding();
                byte [] asciiName = ascii.GetBytes(EA_NAME_STRING);

                // calculate offset at which to write the name/value pair
                System.Diagnostics.Debug.Assert(Marshal.OffsetOf(typeof(UnsafeNativeMethods.FILE_FULL_EA_INFORMATION), "EaName").ToInt64() <= (Int64)Int32.MaxValue);
                int cbOffset = Marshal.OffsetOf(typeof(UnsafeNativeMethods.FILE_FULL_EA_INFORMATION), "EaName").ToInt32();
                for (int i = 0; cbOffset < m_cbBuffer && i < eaBuffer.EaNameLength; i++, cbOffset++)
                {
                    Marshal.WriteByte(ptr, cbOffset, asciiName[i]);
                }

                System.Diagnostics.Debug.Assert(cbOffset < m_cbBuffer);

                // write null character separator
                Marshal.WriteByte(ptr, cbOffset, 0);
                cbOffset++;

                System.Diagnostics.Debug.Assert(cbOffset < m_cbBuffer || transactionContext.Length == 0 && cbOffset == m_cbBuffer);

                // write transaction context ID
                for (int i = 0; cbOffset < m_cbBuffer && i < eaBuffer.EaValueLength; i++, cbOffset++)
                {
                    Marshal.WriteByte(ptr, cbOffset, transactionContext[i]);
                }
            }
            finally
            {
                if (mustRelease)
                {
                    DangerousRelease();
                }
            }
        }
 private void SetValue(string keyword, string value)
 {
     ADP.CheckArgumentNull(value, keyword);
     base[keyword] = value;
 }
예제 #29
0
        private void OpenSqlFileStream
        (
            string path,
            byte[] transactionContext,
            System.IO.FileAccess access,
            System.IO.FileOptions options,
            Int64 allocationSize
        )
        {
            //-----------------------------------------------------------------
            // precondition validation

            // these should be checked by any caller of this method

            // ensure we have validated and normalized the path before
            Debug.Assert(path != null);
            Debug.Assert(transactionContext != null);

            if (access != FileAccess.Read && access != FileAccess.Write && access != FileAccess.ReadWrite)
            {
                throw ADP.ArgumentOutOfRange("access");
            }

            // FileOptions is a set of flags, so AND the given value against the set of values we do not support
            if ((options & ~(FileOptions.WriteThrough | FileOptions.Asynchronous | FileOptions.RandomAccess | FileOptions.SequentialScan)) != 0)
            {
                throw ADP.ArgumentOutOfRange("options");
            }

            //-----------------------------------------------------------------

            // normalize the provided path
            //   * compress path to remove any occurences of '.' or '..'
            //   * trim whitespace from the beginning and end of the path
            //   * ensure that the path starts with '\\'
            //   * ensure that the path does not start with '\\.\'
            //   * ensure that the path is not longer than Int16.MaxValue
            path = GetFullPathInternal(path);

            // ensure the running code has permission to read/write the file
            DemandAccessPermission(path, access);

            FileFullEaInformation    eaBuffer   = null;
            SecurityQualityOfService qos        = null;
            UnicodeString            objectName = null;

            Microsoft.Win32.SafeHandles.SafeFileHandle hFile = null;

            int nDesiredAccess = UnsafeNativeMethods.FILE_READ_ATTRIBUTES | UnsafeNativeMethods.SYNCHRONIZE;

            UInt32 dwCreateOptions     = 0;
            UInt32 dwCreateDisposition = 0;

            System.IO.FileShare shareAccess = System.IO.FileShare.None;

            switch (access)
            {
            case System.IO.FileAccess.Read:
                nDesiredAccess     |= UnsafeNativeMethods.FILE_READ_DATA;
                shareAccess         = System.IO.FileShare.Delete | System.IO.FileShare.ReadWrite;
                dwCreateDisposition = (uint)UnsafeNativeMethods.CreationDisposition.FILE_OPEN;
                break;

            case System.IO.FileAccess.Write:
                nDesiredAccess     |= UnsafeNativeMethods.FILE_WRITE_DATA;
                shareAccess         = System.IO.FileShare.Delete | System.IO.FileShare.Read;
                dwCreateDisposition = (uint)UnsafeNativeMethods.CreationDisposition.FILE_OVERWRITE;
                break;

            case System.IO.FileAccess.ReadWrite:
            default:
                // we validate the value of 'access' parameter in the beginning of this method
                Debug.Assert(access == System.IO.FileAccess.ReadWrite);

                nDesiredAccess     |= UnsafeNativeMethods.FILE_READ_DATA | UnsafeNativeMethods.FILE_WRITE_DATA;
                shareAccess         = System.IO.FileShare.Delete | System.IO.FileShare.Read;
                dwCreateDisposition = (uint)UnsafeNativeMethods.CreationDisposition.FILE_OVERWRITE;
                break;
            }

            if ((options & System.IO.FileOptions.WriteThrough) != 0)
            {
                dwCreateOptions |= (uint)UnsafeNativeMethods.CreateOption.FILE_WRITE_THROUGH;
            }

            if ((options & System.IO.FileOptions.Asynchronous) == 0)
            {
                dwCreateOptions |= (uint)UnsafeNativeMethods.CreateOption.FILE_SYNCHRONOUS_IO_NONALERT;
            }

            if ((options & System.IO.FileOptions.SequentialScan) != 0)
            {
                dwCreateOptions |= (uint)UnsafeNativeMethods.CreateOption.FILE_SEQUENTIAL_ONLY;
            }

            if ((options & System.IO.FileOptions.RandomAccess) != 0)
            {
                dwCreateOptions |= (uint)UnsafeNativeMethods.CreateOption.FILE_RANDOM_ACCESS;
            }

            try
            {
                eaBuffer = new FileFullEaInformation(transactionContext);

                qos = new SecurityQualityOfService(UnsafeNativeMethods.SecurityImpersonationLevel.SecurityAnonymous,
                                                   false, false);

                // NOTE: the Name property is intended to reveal the publicly available moniker for the
                //   FILESTREAM attributed column data. We will not surface the internal processing that
                //   takes place to create the mappedPath.
                string mappedPath = InitializeNtPath(path);
                objectName = new UnicodeString(mappedPath);

                UnsafeNativeMethods.OBJECT_ATTRIBUTES oa;
                oa.length                   = Marshal.SizeOf(typeof(UnsafeNativeMethods.OBJECT_ATTRIBUTES));
                oa.rootDirectory            = IntPtr.Zero;
                oa.attributes               = (int)UnsafeNativeMethods.Attributes.CaseInsensitive;
                oa.securityDescriptor       = IntPtr.Zero;
                oa.securityQualityOfService = qos;
                oa.objectName               = objectName;

                UnsafeNativeMethods.IO_STATUS_BLOCK ioStatusBlock;

                uint oldMode;
                uint retval = 0;

                UnsafeNativeMethods.SetErrorModeWrapper(UnsafeNativeMethods.SEM_FAILCRITICALERRORS, out oldMode);
                try
                {
                    Bid.Trace("<sc.SqlFileStream.OpenSqlFileStream|ADV> %d#, desiredAccess=0x%08x, allocationSize=%I64d, fileAttributes=0x%08x, shareAccess=0x%08x, dwCreateDisposition=0x%08x, createOptions=0x%08x\n",
                              ObjectID, (int)nDesiredAccess, allocationSize, 0, (int)shareAccess, dwCreateDisposition, dwCreateOptions);

                    retval = UnsafeNativeMethods.NtCreateFile(out hFile, nDesiredAccess,
                                                              ref oa, out ioStatusBlock, ref allocationSize,
                                                              0, shareAccess, dwCreateDisposition, dwCreateOptions,
                                                              eaBuffer, (uint)eaBuffer.Length);
                }
                finally
                {
                    UnsafeNativeMethods.SetErrorModeWrapper(oldMode, out oldMode);
                }

                switch (retval)
                {
                case 0:
                    break;

                case UnsafeNativeMethods.STATUS_SHARING_VIOLATION:
                    throw ADP.InvalidOperation(Res.GetString(Res.SqlFileStream_FileAlreadyInTransaction));

                case UnsafeNativeMethods.STATUS_INVALID_PARAMETER:
                    throw ADP.Argument(Res.GetString(Res.SqlFileStream_InvalidParameter));

                case UnsafeNativeMethods.STATUS_OBJECT_NAME_NOT_FOUND:
                {
                    System.IO.DirectoryNotFoundException e = new System.IO.DirectoryNotFoundException();
                    ADP.TraceExceptionAsReturnValue(e);
                    throw e;
                }

                default:
                {
                    uint error = UnsafeNativeMethods.RtlNtStatusToDosError(retval);
                    if (error == UnsafeNativeMethods.ERROR_MR_MID_NOT_FOUND)
                    {
                        // status code could not be mapped to a Win32 error code
                        error = retval;
                    }

                    System.ComponentModel.Win32Exception e = new System.ComponentModel.Win32Exception(unchecked ((int)error));
                    ADP.TraceExceptionAsReturnValue(e);
                    throw e;
                }
                }

                if (hFile.IsInvalid)
                {
                    System.ComponentModel.Win32Exception e = new System.ComponentModel.Win32Exception(UnsafeNativeMethods.ERROR_INVALID_HANDLE);
                    ADP.TraceExceptionAsReturnValue(e);
                    throw e;
                }

                UnsafeNativeMethods.FileType fileType = UnsafeNativeMethods.GetFileType(hFile);
                if (fileType != UnsafeNativeMethods.FileType.Disk)
                {
                    hFile.Dispose();
                    throw ADP.Argument(Res.GetString(Res.SqlFileStream_PathNotValidDiskResource));
                }

                // if the user is opening the SQL FileStream in read/write mode, we assume that they want to scan
                //   through current data and then append new data to the end, so we need to tell SQL Server to preserve
                //   the existing file contents.
                if (access == System.IO.FileAccess.ReadWrite)
                {
                    uint ioControlCode = UnsafeNativeMethods.CTL_CODE(UnsafeNativeMethods.FILE_DEVICE_FILE_SYSTEM,
                                                                      IoControlCodeFunctionCode, (byte)UnsafeNativeMethods.Method.METHOD_BUFFERED,
                                                                      (byte)UnsafeNativeMethods.Access.FILE_ANY_ACCESS);
                    uint cbBytesReturned = 0;

                    if (!UnsafeNativeMethods.DeviceIoControl(hFile, ioControlCode, IntPtr.Zero, 0, IntPtr.Zero, 0, out cbBytesReturned, IntPtr.Zero))
                    {
                        System.ComponentModel.Win32Exception e = new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
                        ADP.TraceExceptionAsReturnValue(e);
                        throw e;
                    }
                }

                // now that we've successfully opened a handle on the path and verified that it is a file,
                //   use the SafeFileHandle to initialize our internal System.IO.FileStream instance
                // NOTE: need to assert UnmanagedCode permissions for this constructor. This is relatively benign
                //   in that we've done much the same validation as in the FileStream(string path, ...) ctor case
                //   most notably, validating that the handle type corresponds to an on-disk file.
                bool bRevertAssert = false;
                try
                {
                    SecurityPermission sp = new SecurityPermission(SecurityPermissionFlag.UnmanagedCode);
                    sp.Assert();
                    bRevertAssert = true;

                    System.Diagnostics.Debug.Assert(m_fs == null);
#if MOBILE
                    m_fs = new System.IO.FileStream(hFile.DangerousGetHandle(), access, ((options & System.IO.FileOptions.Asynchronous) != 0), DefaultBufferSize);
#else
                    m_fs = new System.IO.FileStream(hFile, access, DefaultBufferSize, ((options & System.IO.FileOptions.Asynchronous) != 0));
#endif
                }
                finally
                {
                    if (bRevertAssert)
                    {
                        SecurityPermission.RevertAssert();
                    }
                }
            }
            catch
            {
                if (hFile != null && !hFile.IsInvalid)
                {
                    hFile.Dispose();
                }

                throw;
            }
            finally
            {
                if (eaBuffer != null)
                {
                    eaBuffer.Dispose();
                    eaBuffer = null;
                }

                if (qos != null)
                {
                    qos.Dispose();
                    qos = null;
                }

                if (objectName != null)
                {
                    objectName.Dispose();
                    objectName = null;
                }
            }
        }
예제 #30
0
파일: Odbc32.cs 프로젝트: dox0/DotNet471RS3
 static internal ArgumentException GetSchemaRestrictionRequired()
 {
     return(ADP.Argument(Res.GetString(Res.ODBC_GetSchemaRestrictionRequired)));
 }