internal SchemaSupport[] GetSchemaRowsetInformation()
        {
            OleDbConnectionString constr = ConnectionString;

            SchemaSupport[] supportedSchemas = constr.SchemaSupport;
            if (null != supportedSchemas)
            {
                return(supportedSchemas);
            }
            using (IDBSchemaRowsetWrapper wrapper = IDBSchemaRowset())
            {
                UnsafeNativeMethods.IDBSchemaRowset dbSchemaRowset = wrapper.Value;
                if (null == dbSchemaRowset)
                {
                    return(null); // IDBSchemaRowset not supported
                }

                OleDbHResult hr;
                int          schemaCount        = 0;
                IntPtr       schemaGuids        = ADP.PtrZero;
                IntPtr       schemaRestrictions = ADP.PtrZero;

                using (DualCoTaskMem safehandle = new DualCoTaskMem(dbSchemaRowset, out schemaCount, out schemaGuids, out schemaRestrictions, out hr))
                {
                    dbSchemaRowset = null;
                    if (hr < 0)
                    { // ignore infomsg
                        ProcessResults(hr);
                    }

                    supportedSchemas = new SchemaSupport[schemaCount];
                    if (ADP.PtrZero != schemaGuids)
                    {
                        for (int i = 0, offset = 0; i < supportedSchemas.Length; ++i, offset += ODB.SizeOf_Guid)
                        {
                            IntPtr ptr = ADP.IntPtrOffset(schemaGuids, i * ODB.SizeOf_Guid);
                            supportedSchemas[i]._schemaRowset = (Guid)Marshal.PtrToStructure(ptr, typeof(Guid));
                        }
                    }
                    if (ADP.PtrZero != schemaRestrictions)
                    {
                        for (int i = 0; i < supportedSchemas.Length; ++i)
                        {
                            supportedSchemas[i]._restrictions = Marshal.ReadInt32(schemaRestrictions, i * 4);
                        }
                    }
                }
                constr.SchemaSupport = supportedSchemas;
                return(supportedSchemas);
            }
        }
        internal string GetLiteralInfo(int literal)
        {
            using (IDBInfoWrapper wrapper = IDBInfo())
            {
                UnsafeNativeMethods.IDBInfo dbInfo = wrapper.Value;
                if (null == dbInfo)
                {
                    return(null);
                }
                string       literalValue = null;
                IntPtr       literalInfo  = ADP.PtrZero;
                int          literalCount = 0;
                OleDbHResult hr;

                using (DualCoTaskMem handle = new DualCoTaskMem(dbInfo, new int[1] {
                    literal
                }, out literalCount, out literalInfo, out hr))
                {
                    // All literals were either invalid or unsupported. The provider allocates memory for *prgLiteralInfo and sets the value of the fSupported element in all of the structures to FALSE. The consumer frees this memory when it no longer needs the information.
                    if (OleDbHResult.DB_E_ERRORSOCCURRED != hr)
                    {
                        if ((1 == literalCount) && Marshal.ReadInt32(literalInfo, ODB.OffsetOf_tagDBLITERALINFO_it) == literal)
                        {
                            literalValue = Marshal.PtrToStringUni(Marshal.ReadIntPtr(literalInfo, 0));
                        }
                        if (hr < 0)
                        { // ignore infomsg
                            ProcessResults(hr);
                        }
                    }
                    else
                    {
                        SafeNativeMethods.Wrapper.ClearErrorInfo();
                    }
                }
                return(literalValue);
            }
        }
        private void BuildSchemaTableRowset(object handle) {
            Debug.Assert(null == _dbSchemaTable, "BuildSchemaTableRowset - non-null SchemaTable");
            Debug.Assert(null != handle, "BuildSchemaTableRowset(object) - unexpected null handle");

            Bid.Trace("<oledb.IUnknown.QueryInterface|API|OLEDB|rowset_row> %d, IColumnsRowset\n", ObjectID);
            UnsafeNativeMethods.IColumnsRowset icolumnsRowset = (handle as UnsafeNativeMethods.IColumnsRowset);

            if (null != icolumnsRowset) {
                UnsafeNativeMethods.IRowset rowset = null;
                IntPtr cOptColumns;
                OleDbHResult hr;

                using(DualCoTaskMem prgOptColumns = new DualCoTaskMem(icolumnsRowset, out cOptColumns, out hr)) {
                    Debug.Assert((0 == hr) || prgOptColumns.IsInvalid, "GetAvailableCOlumns: unexpected return");

                    Bid.Trace("<oledb.IColumnsRowset.GetColumnsRowset|API|OLEDB> %d#, IID_IRowset\n", ObjectID);
                    hr = icolumnsRowset.GetColumnsRowset(ADP.PtrZero, cOptColumns, prgOptColumns, ref ODB.IID_IRowset, 0, ADP.PtrZero, out rowset);
                    Bid.Trace("<oledb.IColumnsRowset.GetColumnsRowset|API|OLEDB|RET> %08X{HRESULT}\n", hr);
                }

                Debug.Assert((0 <= hr) || (null == rowset), "if GetColumnsRowset failed, rowset should be null");
                if (hr < 0) {
                    ProcessResults(hr);
                }
                DumpToSchemaTable(rowset);

                // VSTFDEVDIV 479576: release the rowset to avoid race condition between the GC and the user code causing
                // "Connection is busy with results for another command" exception
                if (null != rowset) {
                    Marshal.ReleaseComObject(rowset);
                }
            }
            else {
                Bid.Trace("<oledb.IUnknown.QueryInterface|API|OLEDB|RET> %08X{HRESULT}\n", OleDbHResult.E_NOINTERFACE);
                _useIColumnsRowset = false; // MDAC 72653
                BuildSchemaTableInfo(handle, false, false);
            }
        }
        internal DataTable BuildInfoLiterals()
        {
            using (IDBInfoWrapper wrapper = IDBInfo())
            {
                UnsafeNativeMethods.IDBInfo dbInfo = wrapper.Value;
                if (null == dbInfo)
                {
                    return(null);
                }

                DataTable table = new DataTable("DbInfoLiterals");
                table.Locale = CultureInfo.InvariantCulture;
                DataColumn literalName  = new DataColumn("LiteralName", typeof(String));
                DataColumn literalValue = new DataColumn("LiteralValue", typeof(String));
                DataColumn invalidChars = new DataColumn("InvalidChars", typeof(String));
                DataColumn invalidStart = new DataColumn("InvalidStartingChars", typeof(String));
                DataColumn literal      = new DataColumn("Literal", typeof(Int32));
                DataColumn maxlen       = new DataColumn("Maxlen", typeof(Int32));

                table.Columns.Add(literalName);
                table.Columns.Add(literalValue);
                table.Columns.Add(invalidChars);
                table.Columns.Add(invalidStart);
                table.Columns.Add(literal);
                table.Columns.Add(maxlen);

                OleDbHResult hr;
                int          literalCount = 0;
                IntPtr       literalInfo  = ADP.PtrZero;
                using (DualCoTaskMem handle = new DualCoTaskMem(dbInfo, null, out literalCount, out literalInfo, out hr))
                {
                    // All literals were either invalid or unsupported. The provider allocates memory for *prgLiteralInfo and sets the value of the fSupported element in all of the structures to FALSE. The consumer frees this memory when it no longer needs the information.
                    if (OleDbHResult.DB_E_ERRORSOCCURRED != hr)
                    {
                        long             offset = literalInfo.ToInt64();
                        tagDBLITERALINFO tag    = new tagDBLITERALINFO();
                        for (int i = 0; i < literalCount; ++i, offset += ODB.SizeOf_tagDBLITERALINFO)
                        {
                            Marshal.PtrToStructure((IntPtr)offset, tag);

                            DataRow row = table.NewRow();
                            row[literalName]  = ((OleDbLiteral)tag.it).ToString();
                            row[literalValue] = tag.pwszLiteralValue;
                            row[invalidChars] = tag.pwszInvalidChars;
                            row[invalidStart] = tag.pwszInvalidStartingChars;
                            row[literal]      = tag.it;
                            row[maxlen]       = tag.cchMaxLen;

                            table.Rows.Add(row);
                            row.AcceptChanges();
                        }
                        if (hr < 0)
                        { // ignore infomsg
                            ProcessResults(hr);
                        }
                    }
                    else
                    {
                        SafeNativeMethods.Wrapper.ClearErrorInfo();
                    }
                }
                return(table);
            }
        }
        private void BuildSchemaTableInfo(object handle, bool filterITypeInfo, bool filterChapters) {
            Debug.Assert(null == _dbSchemaTable, "non-null SchemaTable");
            Debug.Assert(null == _metadata, "non-null metadata");
            Debug.Assert(null != handle, "unexpected null rowset");

            Bid.Trace("<oledb.IUnknown.QueryInterface|API|OLEDB|rowset_row> %d#, IColumnsInfo\n", ObjectID);
            UnsafeNativeMethods.IColumnsInfo icolumnsInfo = (handle as UnsafeNativeMethods.IColumnsInfo);
            if (null == icolumnsInfo) {
                 Bid.Trace("<oledb.IUnknown.QueryInterface|API|OLEDB|RET> %08X{HRESULT}\n", OleDbHResult.E_NOINTERFACE);
                _dbSchemaTable = null;
#if DEBUG
                if (handle is UnsafeNativeMethods.IRow) {
                    Debug.Assert(false, "bad IRow - IColumnsInfo not available");
                }
                else {
                    Debug.Assert(handle is UnsafeNativeMethods.IRowset, "bad IRowset - IColumnsInfo not available");
                }
#endif
                return;
            }

            OleDbHResult hr;
            IntPtr columnCount = ADP.PtrZero; // column count
            IntPtr columnInfos = ADP.PtrZero; // ptr to byvalue tagDBCOLUMNINFO[]

            using(DualCoTaskMem safehandle = new DualCoTaskMem(icolumnsInfo, out columnCount, out columnInfos, out hr)) {
                if (hr < 0) {
                    ProcessResults(hr);
                }
                if (0 < (int)columnCount) {
                    BuildSchemaTableInfoTable(columnCount.ToInt32(), columnInfos, filterITypeInfo, filterChapters);
                }
            }
        }
 private void BuildSchemaTableRowset(object handle)
 {
     Bid.Trace("<oledb.IUnknown.QueryInterface|API|OLEDB|rowset_row> %d, IColumnsRowset\n", this.ObjectID);
     UnsafeNativeMethods.IColumnsRowset icolumnsRowset = handle as UnsafeNativeMethods.IColumnsRowset;
     if (icolumnsRowset != null)
     {
         OleDbHResult result;
         IntPtr ptr;
         System.Data.Common.UnsafeNativeMethods.IRowset ppColRowset = null;
         using (DualCoTaskMem mem = new DualCoTaskMem(icolumnsRowset, out ptr, out result))
         {
             Bid.Trace("<oledb.IColumnsRowset.GetColumnsRowset|API|OLEDB> %d#, IID_IRowset\n", this.ObjectID);
             result = icolumnsRowset.GetColumnsRowset(ADP.PtrZero, ptr, mem, ref ODB.IID_IRowset, 0, ADP.PtrZero, out ppColRowset);
             Bid.Trace("<oledb.IColumnsRowset.GetColumnsRowset|API|OLEDB|RET> %08X{HRESULT}\n", result);
         }
         if (result < OleDbHResult.S_OK)
         {
             this.ProcessResults(result);
         }
         this.DumpToSchemaTable(ppColRowset);
         if (ppColRowset != null)
         {
             Marshal.ReleaseComObject(ppColRowset);
         }
     }
     else
     {
         Bid.Trace("<oledb.IUnknown.QueryInterface|API|OLEDB|RET> %08X{HRESULT}\n", OleDbHResult.E_NOINTERFACE);
         this._useIColumnsRowset = false;
         this.BuildSchemaTableInfo(handle, false, false);
     }
 }
        internal SchemaSupport[] GetSchemaRowsetInformation() {
            OleDbConnectionString constr = ConnectionString;
            SchemaSupport[] supportedSchemas = constr.SchemaSupport;
            if (null != supportedSchemas) {
                return supportedSchemas;
            }
            using(IDBSchemaRowsetWrapper wrapper = IDBSchemaRowset()) {
                UnsafeNativeMethods.IDBSchemaRowset dbSchemaRowset = wrapper.Value;
                if (null == dbSchemaRowset) {
                    return null; // IDBSchemaRowset not supported
                }

                OleDbHResult hr;
                int schemaCount = 0;
                IntPtr schemaGuids = ADP.PtrZero;
                IntPtr schemaRestrictions = ADP.PtrZero;

                using(DualCoTaskMem safehandle = new DualCoTaskMem(dbSchemaRowset, out schemaCount, out schemaGuids, out schemaRestrictions, out hr)) {
                    dbSchemaRowset = null;
                    if (hr < 0) { // ignore infomsg
                        ProcessResults(hr);
                    }

                    supportedSchemas = new SchemaSupport[schemaCount];
                    if (ADP.PtrZero != schemaGuids) {
                        for (int i = 0, offset = 0; i < supportedSchemas.Length; ++i, offset += ODB.SizeOf_Guid) {
                            IntPtr ptr = ADP.IntPtrOffset(schemaGuids, i * ODB.SizeOf_Guid);
                            supportedSchemas[i]._schemaRowset =  (Guid) Marshal.PtrToStructure(ptr, typeof(Guid));
                        }
                    }
                    if (ADP.PtrZero != schemaRestrictions) {
                        for (int i = 0; i < supportedSchemas.Length; ++i) {
                            supportedSchemas[i]._restrictions = Marshal.ReadInt32(schemaRestrictions, i * 4);
                        }
                    }
                }
                constr.SchemaSupport = supportedSchemas;
                return supportedSchemas;
            }
        }
        internal string GetLiteralInfo(int literal) {
            using(IDBInfoWrapper wrapper = IDBInfo()) {
                UnsafeNativeMethods.IDBInfo dbInfo = wrapper.Value;
                if (null == dbInfo) {
                    return null;
                }
                string literalValue = null;
                IntPtr literalInfo = ADP.PtrZero;
                int literalCount = 0;
                OleDbHResult hr;

                using(DualCoTaskMem handle = new DualCoTaskMem(dbInfo, new int[1] { literal }, out literalCount, out literalInfo, out hr)) {
                    // All literals were either invalid or unsupported. The provider allocates memory for *prgLiteralInfo and sets the value of the fSupported element in all of the structures to FALSE. The consumer frees this memory when it no longer needs the information.
                    if (OleDbHResult.DB_E_ERRORSOCCURRED != hr) {
                        if ((1 == literalCount) && Marshal.ReadInt32(literalInfo, ODB.OffsetOf_tagDBLITERALINFO_it) == literal) { // WebData 98612
                            literalValue = Marshal.PtrToStringUni(Marshal.ReadIntPtr(literalInfo, 0));
                        }
                        if (hr < 0) { // ignore infomsg
                            ProcessResults(hr);
                        }
                    }
                    else {
                        SafeNativeMethods.Wrapper.ClearErrorInfo();
                    }
                }
                return literalValue;
            }
        }
        internal DataTable BuildInfoLiterals() {
            using(IDBInfoWrapper wrapper = IDBInfo()) {
                UnsafeNativeMethods.IDBInfo dbInfo = wrapper.Value;
                if (null == dbInfo) {
                    return null;
                }

                DataTable table = new DataTable("DbInfoLiterals");
                table.Locale = CultureInfo.InvariantCulture;
                DataColumn literalName  = new DataColumn("LiteralName", typeof(String));
                DataColumn literalValue = new DataColumn("LiteralValue", typeof(String));
                DataColumn invalidChars = new DataColumn("InvalidChars", typeof(String));
                DataColumn invalidStart = new DataColumn("InvalidStartingChars", typeof(String));
                DataColumn literal      = new DataColumn("Literal", typeof(Int32));
                DataColumn maxlen       = new DataColumn("Maxlen", typeof(Int32));

                table.Columns.Add(literalName);
                table.Columns.Add(literalValue);
                table.Columns.Add(invalidChars);
                table.Columns.Add(invalidStart);
                table.Columns.Add(literal);
                table.Columns.Add(maxlen);

                OleDbHResult hr;
                int literalCount = 0;
                IntPtr literalInfo = ADP.PtrZero;
                using(DualCoTaskMem handle = new DualCoTaskMem(dbInfo, null, out literalCount, out literalInfo, out hr)) {
                    // All literals were either invalid or unsupported. The provider allocates memory for *prgLiteralInfo and sets the value of the fSupported element in all of the structures to FALSE. The consumer frees this memory when it no longer needs the information.
                    if (OleDbHResult.DB_E_ERRORSOCCURRED != hr) {
                        long offset = literalInfo.ToInt64();
                        tagDBLITERALINFO tag = new tagDBLITERALINFO();
                        for (int i = 0; i < literalCount; ++i, offset += ODB.SizeOf_tagDBLITERALINFO) {
                            Marshal.PtrToStructure((IntPtr)offset, tag);

                            DataRow row = table.NewRow();
                            row[literalName ] = ((OleDbLiteral) tag.it).ToString();
                            row[literalValue] = tag.pwszLiteralValue;
                            row[invalidChars] = tag.pwszInvalidChars;
                            row[invalidStart] = tag.pwszInvalidStartingChars;
                            row[literal     ] = tag.it;
                            row[maxlen      ] = tag.cchMaxLen;

                            table.Rows.Add(row);
                            row.AcceptChanges();
                        }
                        if (hr < 0) { // ignore infomsg
                            ProcessResults(hr);
                        }
                    }
                    else {
                        SafeNativeMethods.Wrapper.ClearErrorInfo();
                    }
                }
                return table;
            }
        }