internal void QueryInterfaceIDBCreateCommand(OleDbConnectionString constr)
 {
     if (!constr.HaveQueriedForCreateCommand || (constr.DangerousIDBCreateCommandCreateCommand != null))
     {
         IntPtr zero = IntPtr.Zero;
         RuntimeHelpers.PrepareConstrainedRegions();
         try
         {
             UnsafeNativeMethods.IUnknownQueryInterface delegateForFunctionPointer = (UnsafeNativeMethods.IUnknownQueryInterface) Marshal.GetDelegateForFunctionPointer(Marshal.ReadIntPtr(Marshal.ReadIntPtr(base.handle, 0), 0), typeof(UnsafeNativeMethods.IUnknownQueryInterface));
             int num = delegateForFunctionPointer(base.handle, ref ODB.IID_IDBCreateCommand, ref zero);
             if ((0 <= num) && (IntPtr.Zero != zero))
             {
                 IntPtr ptr = Marshal.ReadIntPtr(Marshal.ReadIntPtr(zero, 0), 3 * IntPtr.Size);
                 this.DangerousIDBCreateCommandCreateCommand = (UnsafeNativeMethods.IDBCreateCommandCreateCommand) Marshal.GetDelegateForFunctionPointer(ptr, typeof(UnsafeNativeMethods.IDBCreateCommandCreateCommand));
                 constr.DangerousIDBCreateCommandCreateCommand = this.DangerousIDBCreateCommandCreateCommand;
             }
             constr.HaveQueriedForCreateCommand = true;
         }
         finally
         {
             if (IntPtr.Zero != zero)
             {
                 IntPtr handle = base.handle;
                 base.handle = zero;
                 Marshal.Release(handle);
             }
         }
     }
 }
Example #2
0
        private Dictionary <string, OleDbPropertyInfo> GetProviderInfo(string provider)
        {
            Dictionary <string, OleDbPropertyInfo>?providerInfo = _propertyInfo;

            if (null == providerInfo)
            {
                providerInfo = new Dictionary <string, OleDbPropertyInfo>(StringComparer.OrdinalIgnoreCase);
                if (!ADP.IsEmpty(provider))
                {
                    Dictionary <string, OleDbPropertyInfo>?hash = null;
                    try
                    {
                        StringBuilder builder = new StringBuilder();
                        AppendKeyValuePair(builder, DbConnectionStringKeywords.Provider, provider);
                        OleDbConnectionString constr = new OleDbConnectionString(builder.ToString(), true);

                        // load provider without calling Initialize or CreateDataSource
                        using (OleDbConnectionInternal connection = new OleDbConnectionInternal(constr, null))
                        {
                            // get all the init property information for the provider
                            hash = connection.GetPropertyInfo(new Guid[] { OleDbPropertySetGuid.DBInitAll }) !;
                            foreach (KeyValuePair <string, OleDbPropertyInfo> entry in hash)
                            {
                                Keywords          index;
                                OleDbPropertyInfo info = entry.Value;
                                if (!s_keywords.TryGetValue(info._description !, out index))
                                {
                                    if ((OleDbPropertySetGuid.DBInit == info._propertySet) &&
                                        ((ODB.DBPROP_INIT_ASYNCH == info._propertyID) ||
                                         (ODB.DBPROP_INIT_HWND == info._propertyID) ||
                                         (ODB.DBPROP_INIT_PROMPT == info._propertyID)))
                                    {
                                        continue; // skip this keyword
                                    }
                                    providerInfo[info._description !] = info;
Example #3
0
        internal void GetDataSource(OleDbConnectionString constr, ref DataSourceWrapper datasrcWrapper) {
            OleDbHResult hr;
            UnsafeNativeMethods.IDataInitializeGetDataSource GetDataSource = DangerousIDataInitializeGetDataSource;
            bool mustRelease = false;
            RuntimeHelpers.PrepareConstrainedRegions();
            try {
                DangerousAddRef(ref mustRelease);

                // this is the string that DataLinks / OLE DB Services will use to create the provider
                string connectionString = constr.ActualConnectionString;
                
                // base.handle is the 'this' pointer for making the COM call to GetDataSource
                // the datasrcWrapper will store the IID_IDBInitialize pointer
                // call IDataInitiailze::GetDataSource via the delegate
                hr = GetDataSource(base.handle, IntPtr.Zero, ODB.CLSCTX_ALL, connectionString, ref ODB.IID_IDBInitialize, ref datasrcWrapper);
            }
            finally {
                if (mustRelease) {
                    DangerousRelease();
                }
            }
            if (hr < 0) { // ignore infomsg
                if (OleDbHResult.REGDB_E_CLASSNOTREG == hr) {
                    throw ODB.ProviderUnavailable(constr.Provider, null);
                }
                Exception e = OleDbConnection.ProcessResults(hr, null, null);
                Debug.Assert(null != e, "CreateProviderError");
                throw e;
            }
            else if (datasrcWrapper.IsInvalid) {
                SafeNativeMethods.Wrapper.ClearErrorInfo();
                throw ODB.ProviderUnavailable(constr.Provider, null);
            }
            Debug.Assert(!datasrcWrapper.IsInvalid, "bad DataSource");
        }
 public override TypeConverter.StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
 {
     TypeConverter.StandardValuesCollection valuess = this._standardValues;
     if (this._standardValues == null)
     {
         DataTable     elements = new OleDbEnumerator().GetElements();
         DataColumn    column2  = elements.Columns["SOURCES_NAME"];
         DataColumn    column   = elements.Columns["SOURCES_TYPE"];
         List <string> values   = new List <string>(elements.Rows.Count);
         foreach (DataRow row in elements.Rows)
         {
             int num = (int)row[column];
             if ((1 == num) || (3 == num))
             {
                 string item = (string)row[column2];
                 if (!OleDbConnectionString.IsMSDASQL(item.ToLower(CultureInfo.InvariantCulture)) && (0 > values.IndexOf(item)))
                 {
                     values.Add(item);
                 }
             }
         }
         valuess = new TypeConverter.StandardValuesCollection(values);
         this._standardValues = valuess;
     }
     return(valuess);
 }
 internal OleDbPermission(OleDbConnectionString constr) : base(constr)
 {
     if ((constr == null) || constr.IsEmpty)
     {
         base.Add(ADP.StrEmpty, ADP.StrEmpty, KeyRestrictionBehavior.AllowOnly);
     }
 }
        protected override DbConnectionOptions CreateConnectionOptions(string connectionString, DbConnectionOptions previous)
        {
            Debug.Assert(!ADP.IsEmpty(connectionString), "null connectionString");
            OleDbConnectionString result = new OleDbConnectionString(connectionString, (null != previous));

            return(result);
        }
Example #7
0
 internal void QueryInterfaceIDBCreateCommand(OleDbConnectionString constr)
 {
     if (!constr.HaveQueriedForCreateCommand || (constr.DangerousIDBCreateCommandCreateCommand != null))
     {
         IntPtr zero = IntPtr.Zero;
         RuntimeHelpers.PrepareConstrainedRegions();
         try
         {
             UnsafeNativeMethods.IUnknownQueryInterface delegateForFunctionPointer = (UnsafeNativeMethods.IUnknownQueryInterface)Marshal.GetDelegateForFunctionPointer(Marshal.ReadIntPtr(Marshal.ReadIntPtr(base.handle, 0), 0), typeof(UnsafeNativeMethods.IUnknownQueryInterface));
             int num = delegateForFunctionPointer(base.handle, ref ODB.IID_IDBCreateCommand, ref zero);
             if ((0 <= num) && (IntPtr.Zero != zero))
             {
                 IntPtr ptr = Marshal.ReadIntPtr(Marshal.ReadIntPtr(zero, 0), 3 * IntPtr.Size);
                 this.DangerousIDBCreateCommandCreateCommand   = (UnsafeNativeMethods.IDBCreateCommandCreateCommand)Marshal.GetDelegateForFunctionPointer(ptr, typeof(UnsafeNativeMethods.IDBCreateCommandCreateCommand));
                 constr.DangerousIDBCreateCommandCreateCommand = this.DangerousIDBCreateCommandCreateCommand;
             }
             constr.HaveQueriedForCreateCommand = true;
         }
         finally
         {
             if (IntPtr.Zero != zero)
             {
                 IntPtr handle = base.handle;
                 base.handle = zero;
                 Marshal.Release(handle);
             }
         }
     }
 }
Example #8
0
 internal OleDbPermission(OleDbConnectionString constr) : base(constr)
 {
     if ((constr == null) || constr.IsEmpty)
     {
         base.Add(ADP.StrEmpty, ADP.StrEmpty, KeyRestrictionBehavior.AllowOnly);
     }
 }
Example #9
0
        internal void VerifyIDBCreateCommand(OleDbConnectionString constr)
        {
            // DangerousAddRef/DangerousRelease are not neccessary here in the current implementation
            // only used from within OleDbConnectionInternal.ctor->DataSourceWrapper.InitializeAndCreateSession

            Debug.Assert(constr.HaveQueriedForCreateCommand, "expected HaveQueriedForCreateCommand");
            Debug.Assert(null != constr.DangerousIDBCreateCommandCreateCommand, "expected DangerousIDBCreateCommandCreateCommand");

            // native COM rules are the QI result is the 'this' pointer
            // the pointer stored at that location is the vtable
            // since IDBCreateCommand is a public,shipped COM interface, its layout will not change (ever)
            IntPtr vtable = Marshal.ReadIntPtr(base.handle, 0);
            IntPtr method = Marshal.ReadIntPtr(vtable, 3 * IntPtr.Size);

            // obtain the cached delegate to be cached on this instance
            UnsafeNativeMethods.IDBCreateCommandCreateCommand CreateCommand = constr.DangerousIDBCreateCommandCreateCommand;

            // since the delegate lifetime is longer than the original instance used to create it
            // we double check before each usage to verify the delegates function pointer
            if ((null == CreateCommand) || (method != Marshal.GetFunctionPointerForDelegate(CreateCommand)))
            {
                CreateCommand = (UnsafeNativeMethods.IDBCreateCommandCreateCommand)Marshal.GetDelegateForFunctionPointer(method, typeof(UnsafeNativeMethods.IDBCreateCommandCreateCommand));
                constr.DangerousIDBCreateCommandCreateCommand = CreateCommand;
            }
            // since this instance can be used to create multiple commands
            // cache it on the class so that the function pointer doesn't have to be validated every time
            DangerousIDBCreateCommandCreateCommand = CreateCommand;
        }
 internal void GetDataSource(OleDbConnectionString constr, ref DataSourceWrapper datasrcWrapper)
 {
     OleDbHResult result;
     UnsafeNativeMethods.IDataInitializeGetDataSource dangerousIDataInitializeGetDataSource = this.DangerousIDataInitializeGetDataSource;
     bool success = false;
     RuntimeHelpers.PrepareConstrainedRegions();
     try
     {
         base.DangerousAddRef(ref success);
         string actualConnectionString = constr.ActualConnectionString;
         result = dangerousIDataInitializeGetDataSource(base.handle, IntPtr.Zero, 0x17, actualConnectionString, ref ODB.IID_IDBInitialize, ref datasrcWrapper);
     }
     finally
     {
         if (success)
         {
             base.DangerousRelease();
         }
     }
     if (result < OleDbHResult.S_OK)
     {
         if (OleDbHResult.REGDB_E_CLASSNOTREG == result)
         {
             throw ODB.ProviderUnavailable(constr.Provider, null);
         }
         throw OleDbConnection.ProcessResults(result, null, null);
     }
     if (datasrcWrapper.IsInvalid)
     {
         SafeNativeMethods.Wrapper.ClearErrorInfo();
         throw ODB.ProviderUnavailable(constr.Provider, null);
     }
 }
Example #11
0
        internal void GetDataSource(OleDbConnectionString constr, ref DataSourceWrapper datasrcWrapper)
        {
            OleDbHResult result;

            UnsafeNativeMethods.IDataInitializeGetDataSource dangerousIDataInitializeGetDataSource = this.DangerousIDataInitializeGetDataSource;
            bool success = false;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                base.DangerousAddRef(ref success);
                string actualConnectionString = constr.ActualConnectionString;
                result = dangerousIDataInitializeGetDataSource(base.handle, IntPtr.Zero, 0x17, actualConnectionString, ref ODB.IID_IDBInitialize, ref datasrcWrapper);
            }
            finally
            {
                if (success)
                {
                    base.DangerousRelease();
                }
            }
            if (result < OleDbHResult.S_OK)
            {
                if (OleDbHResult.REGDB_E_CLASSNOTREG == result)
                {
                    throw ODB.ProviderUnavailable(constr.Provider, null);
                }
                throw OleDbConnection.ProcessResults(result, null, null);
            }
            if (datasrcWrapper.IsInvalid)
            {
                SafeNativeMethods.Wrapper.ClearErrorInfo();
                throw ODB.ProviderUnavailable(constr.Provider, null);
            }
        }
Example #12
0
        private int _oledbservices; // set during Validate

        static public OleDbConnectionString ParseString(string connectionString) {
            OleDbConnectionString constr = null;
            if (!ADP.IsEmpty(connectionString)) {

                constr = (DBConnectionString.CacheQuery(connectionString, _oledbParseCache) as OleDbConnectionString);
                if (null == constr) {
#if USECRYPTO
                    string encrypted = null/*Crypto.EncryptString(connectionString)*/;
                    string hashvalue = (null == encrypted) ? Crypto.ComputeHash(connectionString) : encrypted;
                    constr = (DBConnectionString.CacheQuery(hashvalue, _oledbParseCache) as OleDbConnectionString);
                    if (null == constr) {
                        constr = new OleDbConnectionString(connectionString, encrypted);
#else
                        constr = new OleDbConnectionString(connectionString);
#endif
                        if (constr.ShouldCache()) {
#if USECRYPTO
                            if (!constr.IsEncrypted) {
                                hashvalue = connectionString;
                            }
                            CacheAdd(hashvalue, constr, ref _oledbParseCache);
#else
                            CacheAdd(connectionString, constr, ref _oledbParseCache);
#endif
                        }
#if USECRYPTO
                    }
#endif
                }
            }
            return constr;
        }
Example #13
0
        // if OleDbConnectionString.DangerousIDBCreateCommandCreateCommand does not exist
        // this method will be called to query for IDBCreateCommand (and cache that interface pointer)
        // or it will be known that IDBCreateCommand is not supported
        internal unsafe void QueryInterfaceIDBCreateCommand(OleDbConnectionString constr)
        {
            // DangerousAddRef/DangerousRelease are not neccessary here in the current implementation
            // only used from within OleDbConnectionInternal.ctor->DataSourceWrapper.InitializeAndCreateSession

            // caching the fact if we have queried for IDBCreateCommand or not
            // the command object is not supported by all providers, they would use IOpenRowset
            // added extra if condition
            // If constr.HaveQueriedForCreateCommand is false, this is the first time through this method and we need to set up the cache for sure.
            // If two threads try to set the cache at the same time, everything should be okay. There can be multiple delegates that point to the same unmanaged function.
            // If constr.HaveQueriedForCreateCommand is true, we have already tried to query for IDBCreateCommand on a previous call to this method, but based on that alone,
            //     we don't know if another thread set the flag, or if the provider really doesn't support commands.
            // If constr.HaveQueriedForCreateCommand is true and constr.DangerousIDBCreateCommandCreateCommand is not null, that means that another thread has set it after we
            //     determined we needed to call QueryInterfaceIDBCreateCommand -- otherwise we would have called VerifyIDBCreateCommand instead
            // In that case, we still need to set our local DangerousIDBCreateCommandCreateCommand, so we want to go through the if block even though the cache has been set on constr already
            if (!constr.HaveQueriedForCreateCommand || (null != constr.DangerousIDBCreateCommandCreateCommand))
            {
                IntPtr idbCreateCommand = IntPtr.Zero;
                RuntimeHelpers.PrepareConstrainedRegions();
                try
                {
                    // native COM rules are the QI result is the 'this' pointer
                    // the pointer stored at that location is the vtable
                    // since IUnknown is a public,shipped COM interface, its layout will not change (ever)
                    IntPtr vtable = Marshal.ReadIntPtr(base.handle, 0);
                    IntPtr method = Marshal.ReadIntPtr(vtable, 0);
                    UnsafeNativeMethods.IUnknownQueryInterface QueryInterface = (UnsafeNativeMethods.IUnknownQueryInterface)Marshal.GetDelegateForFunctionPointer(method, typeof(UnsafeNativeMethods.IUnknownQueryInterface));

                    int hresult;
                    fixed(Guid *riid = &ODB.IID_IDBCreateCommand)
                    {
                        hresult = QueryInterface(base.handle, riid, &idbCreateCommand);
                    }
                    if ((0 <= hresult) && (IntPtr.Zero != idbCreateCommand))
                    {
                        vtable = Marshal.ReadIntPtr(idbCreateCommand, 0);
                        method = Marshal.ReadIntPtr(vtable, 3 * IntPtr.Size);

                        DangerousIDBCreateCommandCreateCommand        = (UnsafeNativeMethods.IDBCreateCommandCreateCommand)Marshal.GetDelegateForFunctionPointer(method, typeof(UnsafeNativeMethods.IDBCreateCommandCreateCommand));
                        constr.DangerousIDBCreateCommandCreateCommand = DangerousIDBCreateCommandCreateCommand;
                    }

                    // caching the fact that we have queried for IDBCreateCommand
                    constr.HaveQueriedForCreateCommand = true;
                }
                finally
                {
                    if (IntPtr.Zero != idbCreateCommand)
                    {
                        IntPtr ptr = base.handle;
                        base.handle = idbCreateCommand;
                        Marshal.Release(ptr);
                    }
                }
            }
            //else if constr.HaveQueriedForCreateCommand is true and constr.DangerousIDBCreateCommandCreateCommand is still null, it means that this provider doesn't support commands
        }
Example #14
0
        internal void VerifyIDBCreateCommand(OleDbConnectionString constr)
        {
            IntPtr ptr = Marshal.ReadIntPtr(Marshal.ReadIntPtr(base.handle, 0), 3 * IntPtr.Size);

            UnsafeNativeMethods.IDBCreateCommandCreateCommand dangerousIDBCreateCommandCreateCommand = constr.DangerousIDBCreateCommandCreateCommand;
            if ((dangerousIDBCreateCommandCreateCommand == null) || (ptr != Marshal.GetFunctionPointerForDelegate(dangerousIDBCreateCommandCreateCommand)))
            {
                dangerousIDBCreateCommandCreateCommand        = (UnsafeNativeMethods.IDBCreateCommandCreateCommand)Marshal.GetDelegateForFunctionPointer(ptr, typeof(UnsafeNativeMethods.IDBCreateCommandCreateCommand));
                constr.DangerousIDBCreateCommandCreateCommand = dangerousIDBCreateCommandCreateCommand;
            }
            this.DangerousIDBCreateCommandCreateCommand = dangerousIDBCreateCommandCreateCommand;
        }
        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 SchemaSupport[] GetSchemaRowsetInformation()
        {
            OleDbConnectionString connectionString = this.ConnectionString;

            SchemaSupport[] schemaSupport = connectionString.SchemaSupport;
            if (schemaSupport != null)
            {
                return(schemaSupport);
            }
            using (IDBSchemaRowsetWrapper wrapper = this.IDBSchemaRowset())
            {
                OleDbHResult result;
                System.Data.Common.UnsafeNativeMethods.IDBSchemaRowset dbSchemaRowset = wrapper.Value;
                if (dbSchemaRowset == null)
                {
                    return(null);
                }
                int    schemaCount        = 0;
                IntPtr ptrZero            = ADP.PtrZero;
                IntPtr schemaRestrictions = ADP.PtrZero;
                using (new DualCoTaskMem(dbSchemaRowset, out schemaCount, out ptrZero, out schemaRestrictions, out result))
                {
                    dbSchemaRowset = null;
                    if (result < OleDbHResult.S_OK)
                    {
                        this.ProcessResults(result);
                    }
                    schemaSupport = new SchemaSupport[schemaCount];
                    if (ADP.PtrZero != ptrZero)
                    {
                        int index = 0;
                        for (int i = 0; index < schemaSupport.Length; i += ODB.SizeOf_Guid)
                        {
                            IntPtr ptr = ADP.IntPtrOffset(ptrZero, index * ODB.SizeOf_Guid);
                            schemaSupport[index]._schemaRowset = (Guid)Marshal.PtrToStructure(ptr, typeof(Guid));
                            index++;
                        }
                    }
                    if (ADP.PtrZero != schemaRestrictions)
                    {
                        for (int j = 0; j < schemaSupport.Length; j++)
                        {
                            schemaSupport[j]._restrictions = Marshal.ReadInt32(schemaRestrictions, j * 4);
                        }
                    }
                }
                connectionString.SchemaSupport = schemaSupport;
                return(schemaSupport);
            }
        }
        // @devnote: should be multithread safe
        static public void ReleaseObjectPool()
        {
            (new OleDbPermission(PermissionState.Unrestricted)).Demand();

            IntPtr hscp;

            Bid.ScopeEnter(out hscp, "<oledb.OleDbConnection.ReleaseObjectPool|API>\n");
            try {
                OleDbConnectionString.ReleaseObjectPool();
                OleDbConnectionInternal.ReleaseObjectPool();
                OleDbConnectionFactory.SingletonInstance.ClearAllPools();
            }
            finally {
                Bid.ScopeLeave(ref hscp);
            }
        }
Example #18
0
 static internal PermissionSet CreatePermission(OleDbConnectionString constr) {
     OleDbPermission p = new OleDbPermission(constr);
     if (null == constr) {
         p.Add(ADP.StrEmpty, ADP.StrEmpty, KeyRestrictionBehavior.AllowOnly); // ExecuteOnly permission
     }
     PermissionSet permission;
     NamedPermissionSet fulltrust = new NamedPermissionSet("FullTrust"); // MDAC 83159
     fulltrust.Assert();
     try {
         permission = new PermissionSet(fulltrust);
         permission.AddPermission(p);
     }
     finally {
         CodeAccessPermission.RevertAssert();
     }
     return permission;
 }
Example #19
0
        internal void GetDataSource(OleDbConnectionString constr, ref DataSourceWrapper datasrcWrapper)
        {
            OleDbHResult hr;

            UnsafeNativeMethods.IDataInitializeGetDataSource GetDataSource = DangerousIDataInitializeGetDataSource !;
            bool mustRelease = false;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                DangerousAddRef(ref mustRelease);

                // this is the string that DataLinks / OLE DB Services will use to create the provider
                string connectionString = constr.ActualConnectionString !;

                // base.handle is the 'this' pointer for making the COM call to GetDataSource
                // the datasrcWrapper will store the IID_IDBInitialize pointer
                // call IDataInitiailze::GetDataSource via the delegate
                hr = GetDataSource(base.handle, IntPtr.Zero, ODB.CLSCTX_ALL, connectionString, ref ODB.IID_IDBInitialize, ref datasrcWrapper);
            }
            finally
            {
                if (mustRelease)
                {
                    DangerousRelease();
                }
            }
            if (hr < 0)
            { // ignore infomsg
                if (OleDbHResult.REGDB_E_CLASSNOTREG == hr)
                {
                    throw ODB.ProviderUnavailable(constr.Provider, null);
                }
                Exception?e = OleDbConnection.ProcessResults(hr, null, null);
                Debug.Assert(null != e, "CreateProviderError");
                throw e;
            }
            else if (datasrcWrapper.IsInvalid)
            {
                SafeNativeMethods.Wrapper.ClearErrorInfo();
                throw ODB.ProviderUnavailable(constr.Provider, null);
            }
            Debug.Assert(!datasrcWrapper.IsInvalid, "bad DataSource");
        }
        internal Dictionary <string, OleDbPropertyInfo> GetPropertyInfo(Guid[] propertySets)
        {
            bool isopen = HasSession;
            OleDbConnectionString constr = ConnectionString;
            Dictionary <string, OleDbPropertyInfo> properties = null;

            if (null == propertySets)
            {
                propertySets = new Guid[0];
            }
            using (PropertyIDSet propidset = new PropertyIDSet(propertySets)) {
                using (IDBPropertiesWrapper idbProperties = IDBProperties()) {
                    using (PropertyInfoSet infoset = new PropertyInfoSet(idbProperties.Value, propidset)) {
                        properties = infoset.GetValues();
                    }
                }
            }
            return(properties);
        }
 internal OleDbConnectionInternal(OleDbConnectionString constr, OleDbConnection connection)
 {
     this.ConnectionString = constr;
     if (constr.PossiblePrompt && !Environment.UserInteractive)
     {
         throw ODB.PossiblePromptNotUserInteractive();
     }
     try
     {
         OleDbServicesWrapper objectPool = GetObjectPool();
         this._datasrcwrp = new DataSourceWrapper();
         objectPool.GetDataSource(constr, ref this._datasrcwrp);
         if (connection != null)
         {
             this._sessionwrp = new SessionWrapper();
             OleDbHResult hresult = this._datasrcwrp.InitializeAndCreateSession(constr, ref this._sessionwrp);
             if ((OleDbHResult.S_OK > hresult) || this._sessionwrp.IsInvalid)
             {
                 throw OleDbConnection.ProcessResults(hresult, null, null);
             }
             OleDbConnection.ProcessResults(hresult, connection, connection);
         }
     }
     catch
     {
         if (this._sessionwrp != null)
         {
             this._sessionwrp.Dispose();
             this._sessionwrp = null;
         }
         if (this._datasrcwrp != null)
         {
             this._datasrcwrp.Dispose();
             this._datasrcwrp = null;
         }
         throw;
     }
 }
Example #22
0
            public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
            {
                StandardValuesCollection dataSourceNames = _standardValues;

                if (null == _standardValues)
                {
                    // Get the sources rowset for the SQLOLEDB enumerator
                    DataTable table = (new OleDbEnumerator()).GetElements();

                    DataColumn column2 = table.Columns["SOURCES_NAME"];
                    DataColumn column5 = table.Columns["SOURCES_TYPE"];
                    //DataColumn column4 = table.Columns["SOURCES_DESCRIPTION"];

                    System.Collections.Generic.List <string> providerNames = new System.Collections.Generic.List <string>(table.Rows.Count);
                    foreach (DataRow row in table.Rows)
                    {
                        int sourceType = (int)row[column5];
                        if (DBSOURCETYPE_DATASOURCE_TDP == sourceType || DBSOURCETYPE_DATASOURCE_MDP == sourceType)
                        {
                            string progid = (string)row[column2];
                            if (!OleDbConnectionString.IsMSDASQL(progid.ToLowerInvariant()))
                            {
                                if (0 > providerNames.IndexOf(progid))
                                {
                                    providerNames.Add(progid);
                                }
                            }
                        }
                    }

                    // Create the standard values collection that contains the sources
                    dataSourceNames = new StandardValuesCollection(providerNames);
                    _standardValues = dataSourceNames;
                }
                return(dataSourceNames);
            }
Example #23
0
        private Dictionary <string, OleDbPropertyInfo> GetProviderInfo(string provider)
        {
            Dictionary <string, OleDbPropertyInfo> providerInfo = _propertyInfo;

            if (null == providerInfo)
            {
                providerInfo = new Dictionary <string, OleDbPropertyInfo>(StringComparer.OrdinalIgnoreCase);
                if (!ADP.IsEmpty(provider))
                {
                    Dictionary <string, OleDbPropertyInfo> hash = null;
                    try
                    {
                        StringBuilder builder = new StringBuilder();
                        AppendKeyValuePair(builder, DbConnectionStringKeywords.Provider, provider);
                        OleDbConnectionString constr = new OleDbConnectionString(builder.ToString(), true);

                        // load provider without calling Initialize or CreateDataSource
                        using (OleDbConnectionInternal connection = new OleDbConnectionInternal(constr, (OleDbConnection)null))
                        {
                            // get all the init property information for the provider
                            hash = connection.GetPropertyInfo(new Guid[] { OleDbPropertySetGuid.DBInitAll });
                            foreach (KeyValuePair <string, OleDbPropertyInfo> entry in hash)
                            {
                                Keywords          index;
                                OleDbPropertyInfo info = entry.Value;
                                if (!s_keywords.TryGetValue(info._description, out index))
                                {
                                    if ((OleDbPropertySetGuid.DBInit == info._propertySet) &&
                                        ((ODB.DBPROP_INIT_ASYNCH == info._propertyID) ||
                                         (ODB.DBPROP_INIT_HWND == info._propertyID) ||
                                         (ODB.DBPROP_INIT_PROMPT == info._propertyID)))
                                    {
                                        continue; // skip this keyword
                                    }
                                    providerInfo[info._description] = info;
                                }
                            }

                            // what are the unique propertysets?
                            List <Guid> listPropertySets = new List <Guid>();
                            foreach (KeyValuePair <string, OleDbPropertyInfo> entry in hash)
                            {
                                OleDbPropertyInfo info = entry.Value;
                                if (!listPropertySets.Contains(info._propertySet))
                                {
                                    listPropertySets.Add(info._propertySet);
                                }
                            }
                            Guid[] arrayPropertySets = new Guid[listPropertySets.Count];
                            listPropertySets.CopyTo(arrayPropertySets, 0);

                            // get all the init property values for the provider
                            using (PropertyIDSet propidset = new PropertyIDSet(arrayPropertySets))
                            {
                                using (IDBPropertiesWrapper idbProperties = connection.IDBProperties())
                                {
                                    OleDbHResult hr;
                                    using (DBPropSet propset = new DBPropSet(idbProperties.Value, propidset, out hr))
                                    {
                                        // OleDbConnectionStringBuilder is ignoring/hiding potential errors of OLEDB provider when reading its properties information
                                        if (0 <= (int)hr)
                                        {
                                            int count = propset.PropertySetCount;
                                            for (int i = 0; i < count; ++i)
                                            {
                                                Guid        propertyset;
                                                tagDBPROP[] props = propset.GetPropertySet(i, out propertyset);

                                                // attach the default property value to the property info
                                                foreach (tagDBPROP prop in props)
                                                {
                                                    foreach (KeyValuePair <string, OleDbPropertyInfo> entry in hash)
                                                    {
                                                        OleDbPropertyInfo info = entry.Value;
                                                        if ((info._propertyID == prop.dwPropertyID) && (info._propertySet == propertyset))
                                                        {
                                                            info._defaultValue = prop.vValue;

                                                            if (null == info._defaultValue)
                                                            {
                                                                if (typeof(string) == info._type)
                                                                {
                                                                    info._defaultValue = "";
                                                                }
                                                                else if (typeof(int) == info._type)
                                                                {
                                                                    info._defaultValue = 0;
                                                                }
                                                                else if (typeof(bool) == info._type)
                                                                {
                                                                    info._defaultValue = false;
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    catch (System.InvalidOperationException e)
                    {
                        ADP.TraceExceptionWithoutRethrow(e);
                    }
                    catch (System.Data.OleDb.OleDbException e)
                    {
                        ADP.TraceExceptionWithoutRethrow(e);
                    }
                    catch (System.Security.SecurityException e)
                    {
                        ADP.TraceExceptionWithoutRethrow(e);
                    }
                }
                _propertyInfo = providerInfo;
            }
            return(providerInfo);
        }
 internal OleDbHResult InitializeAndCreateSession(OleDbConnectionString constr, ref SessionWrapper sessionWrapper)
 {
     OleDbHResult result;
     bool success = false;
     IntPtr zero = IntPtr.Zero;
     RuntimeHelpers.PrepareConstrainedRegions();
     try
     {
         base.DangerousAddRef(ref success);
         IntPtr ptr = Marshal.ReadIntPtr(Marshal.ReadIntPtr(base.handle, 0), 0);
         UnsafeNativeMethods.IUnknownQueryInterface dangerousDataSourceIUnknownQueryInterface = constr.DangerousDataSourceIUnknownQueryInterface;
         if ((dangerousDataSourceIUnknownQueryInterface == null) || (ptr != Marshal.GetFunctionPointerForDelegate(dangerousDataSourceIUnknownQueryInterface)))
         {
             dangerousDataSourceIUnknownQueryInterface = (UnsafeNativeMethods.IUnknownQueryInterface) Marshal.GetDelegateForFunctionPointer(ptr, typeof(UnsafeNativeMethods.IUnknownQueryInterface));
             constr.DangerousDataSourceIUnknownQueryInterface = dangerousDataSourceIUnknownQueryInterface;
         }
         ptr = Marshal.ReadIntPtr(Marshal.ReadIntPtr(base.handle, 0), 3 * IntPtr.Size);
         UnsafeNativeMethods.IDBInitializeInitialize dangerousIDBInitializeInitialize = constr.DangerousIDBInitializeInitialize;
         if ((dangerousIDBInitializeInitialize == null) || (ptr != Marshal.GetFunctionPointerForDelegate(dangerousIDBInitializeInitialize)))
         {
             dangerousIDBInitializeInitialize = (UnsafeNativeMethods.IDBInitializeInitialize) Marshal.GetDelegateForFunctionPointer(ptr, typeof(UnsafeNativeMethods.IDBInitializeInitialize));
             constr.DangerousIDBInitializeInitialize = dangerousIDBInitializeInitialize;
         }
         result = dangerousIDBInitializeInitialize(base.handle);
         if ((OleDbHResult.S_OK > result) && (OleDbHResult.DB_E_ALREADYINITIALIZED != result))
         {
             return result;
         }
         result = (OleDbHResult) dangerousDataSourceIUnknownQueryInterface(base.handle, ref ODB.IID_IDBCreateSession, ref zero);
         if ((OleDbHResult.S_OK > result) || !(IntPtr.Zero != zero))
         {
             return result;
         }
         ptr = Marshal.ReadIntPtr(Marshal.ReadIntPtr(zero, 0), 3 * IntPtr.Size);
         UnsafeNativeMethods.IDBCreateSessionCreateSession dangerousIDBCreateSessionCreateSession = constr.DangerousIDBCreateSessionCreateSession;
         if ((dangerousIDBCreateSessionCreateSession == null) || (ptr != Marshal.GetFunctionPointerForDelegate(dangerousIDBCreateSessionCreateSession)))
         {
             dangerousIDBCreateSessionCreateSession = (UnsafeNativeMethods.IDBCreateSessionCreateSession) Marshal.GetDelegateForFunctionPointer(ptr, typeof(UnsafeNativeMethods.IDBCreateSessionCreateSession));
             constr.DangerousIDBCreateSessionCreateSession = dangerousIDBCreateSessionCreateSession;
         }
         if (constr.DangerousIDBCreateCommandCreateCommand != null)
         {
             result = dangerousIDBCreateSessionCreateSession(zero, IntPtr.Zero, ref ODB.IID_IDBCreateCommand, ref sessionWrapper);
             if ((OleDbHResult.S_OK <= result) && !sessionWrapper.IsInvalid)
             {
                 sessionWrapper.VerifyIDBCreateCommand(constr);
             }
             return result;
         }
         result = dangerousIDBCreateSessionCreateSession(zero, IntPtr.Zero, ref ODB.IID_IUnknown, ref sessionWrapper);
         if ((OleDbHResult.S_OK <= result) && !sessionWrapper.IsInvalid)
         {
             sessionWrapper.QueryInterfaceIDBCreateCommand(constr);
         }
     }
     finally
     {
         if (IntPtr.Zero != zero)
         {
             Marshal.Release(zero);
         }
         if (success)
         {
             base.DangerousRelease();
         }
     }
     return result;
 }
        internal OleDbHResult InitializeAndCreateSession(OleDbConnectionString constr, ref SessionWrapper sessionWrapper)
        {
            OleDbHResult result;
            bool         success = false;
            IntPtr       zero    = IntPtr.Zero;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                base.DangerousAddRef(ref success);
                IntPtr ptr = Marshal.ReadIntPtr(Marshal.ReadIntPtr(base.handle, 0), 0);
                UnsafeNativeMethods.IUnknownQueryInterface dangerousDataSourceIUnknownQueryInterface = constr.DangerousDataSourceIUnknownQueryInterface;
                if ((dangerousDataSourceIUnknownQueryInterface == null) || (ptr != Marshal.GetFunctionPointerForDelegate(dangerousDataSourceIUnknownQueryInterface)))
                {
                    dangerousDataSourceIUnknownQueryInterface        = (UnsafeNativeMethods.IUnknownQueryInterface)Marshal.GetDelegateForFunctionPointer(ptr, typeof(UnsafeNativeMethods.IUnknownQueryInterface));
                    constr.DangerousDataSourceIUnknownQueryInterface = dangerousDataSourceIUnknownQueryInterface;
                }
                ptr = Marshal.ReadIntPtr(Marshal.ReadIntPtr(base.handle, 0), 3 * IntPtr.Size);
                UnsafeNativeMethods.IDBInitializeInitialize dangerousIDBInitializeInitialize = constr.DangerousIDBInitializeInitialize;
                if ((dangerousIDBInitializeInitialize == null) || (ptr != Marshal.GetFunctionPointerForDelegate(dangerousIDBInitializeInitialize)))
                {
                    dangerousIDBInitializeInitialize        = (UnsafeNativeMethods.IDBInitializeInitialize)Marshal.GetDelegateForFunctionPointer(ptr, typeof(UnsafeNativeMethods.IDBInitializeInitialize));
                    constr.DangerousIDBInitializeInitialize = dangerousIDBInitializeInitialize;
                }
                result = dangerousIDBInitializeInitialize(base.handle);
                if ((OleDbHResult.S_OK > result) && (OleDbHResult.DB_E_ALREADYINITIALIZED != result))
                {
                    return(result);
                }
                result = (OleDbHResult)dangerousDataSourceIUnknownQueryInterface(base.handle, ref ODB.IID_IDBCreateSession, ref zero);
                if ((OleDbHResult.S_OK > result) || !(IntPtr.Zero != zero))
                {
                    return(result);
                }
                ptr = Marshal.ReadIntPtr(Marshal.ReadIntPtr(zero, 0), 3 * IntPtr.Size);
                UnsafeNativeMethods.IDBCreateSessionCreateSession dangerousIDBCreateSessionCreateSession = constr.DangerousIDBCreateSessionCreateSession;
                if ((dangerousIDBCreateSessionCreateSession == null) || (ptr != Marshal.GetFunctionPointerForDelegate(dangerousIDBCreateSessionCreateSession)))
                {
                    dangerousIDBCreateSessionCreateSession        = (UnsafeNativeMethods.IDBCreateSessionCreateSession)Marshal.GetDelegateForFunctionPointer(ptr, typeof(UnsafeNativeMethods.IDBCreateSessionCreateSession));
                    constr.DangerousIDBCreateSessionCreateSession = dangerousIDBCreateSessionCreateSession;
                }
                if (constr.DangerousIDBCreateCommandCreateCommand != null)
                {
                    result = dangerousIDBCreateSessionCreateSession(zero, IntPtr.Zero, ref ODB.IID_IDBCreateCommand, ref sessionWrapper);
                    if ((OleDbHResult.S_OK <= result) && !sessionWrapper.IsInvalid)
                    {
                        sessionWrapper.VerifyIDBCreateCommand(constr);
                    }
                    return(result);
                }
                result = dangerousIDBCreateSessionCreateSession(zero, IntPtr.Zero, ref ODB.IID_IUnknown, ref sessionWrapper);
                if ((OleDbHResult.S_OK <= result) && !sessionWrapper.IsInvalid)
                {
                    sessionWrapper.QueryInterfaceIDBCreateCommand(constr);
                }
            }
            finally
            {
                if (IntPtr.Zero != zero)
                {
                    Marshal.Release(zero);
                }
                if (success)
                {
                    base.DangerousRelease();
                }
            }
            return(result);
        }
 internal OleDbPermission(OleDbConnectionString constr) : base(constr)   // for Open
 {
 }
 protected override DbConnectionOptions CreateConnectionOptions(string connectionString, DbConnectionOptions previous) {
     Debug.Assert(!ADP.IsEmpty(connectionString), "null connectionString");
     OleDbConnectionString result = new OleDbConnectionString(connectionString, (null != previous));
     return result;
 }
        internal OleDbConnectionInternal(OleDbConnectionString constr, OleDbConnection connection) : base () {
#if DEBUG
            try { // use this to help validate this object is only created after the following permission has been previously demanded in the current codepath
                if (null != connection) {
                    connection.UserConnectionOptions.DemandPermission();
                }
                else {
                    constr.DemandPermission();
                }
            }
            catch(System.Security.SecurityException) {
                System.Diagnostics.Debug.Assert(false, "unexpected SecurityException for current codepath");
                throw;
            }
#endif
            Debug.Assert((null != constr) && !constr.IsEmpty, "empty connectionstring");
            ConnectionString = constr;

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

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

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

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

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

                    // process the HResult here instead of from the SafeHandle because the possibility
                    // of an InfoMessageEvent.
                    if ((0 <= hr) && !_sessionwrp.IsInvalid) { // process infonessage events
                        OleDbConnection.ProcessResults(hr, connection, connection);
                    }
                    else {
                        Exception e = OleDbConnection.ProcessResults(hr, null, null);
                        Debug.Assert(null != e, "CreateSessionError");
                        throw e;
                    }
                    Debug.Assert(!_sessionwrp.IsInvalid, "bad Session");
                }
            }
            catch {
                if (null != _sessionwrp) {
                    _sessionwrp.Dispose();
                    _sessionwrp = null;
                }
                if (null != _datasrcwrp) {
                    _datasrcwrp.Dispose();
                    _datasrcwrp = null;
                }
                throw;
            }
        }
Example #29
0
        internal void VerifyIDBCreateCommand(OleDbConnectionString constr) {
            // DangerousAddRef/DangerousRelease are not neccessary here in the current implementation
            // only used from within OleDbConnectionInternal.ctor->DataSourceWrapper.InitializeAndCreateSession

            Debug.Assert(constr.HaveQueriedForCreateCommand, "expected HaveQueriedForCreateCommand");
            Debug.Assert(null != constr.DangerousIDBCreateCommandCreateCommand, "expected DangerousIDBCreateCommandCreateCommand");
            
            // native COM rules are the QI result is the 'this' pointer
            // the pointer stored at that location is the vtable
            // since IDBCreateCommand is a public,shipped COM interface, its layout will not change (ever)
            IntPtr vtable = Marshal.ReadIntPtr(base.handle, 0);
            IntPtr method = Marshal.ReadIntPtr(vtable, 3 * IntPtr.Size);

            // obtain the cached delegate to be cached on this instance
            UnsafeNativeMethods.IDBCreateCommandCreateCommand CreateCommand = constr.DangerousIDBCreateCommandCreateCommand;

            // since the delegate lifetime is longer than the original instance used to create it
            // we double check before each usage to verify the delegates function pointer
            if ((null == CreateCommand) || (method != Marshal.GetFunctionPointerForDelegate(CreateCommand))) {
                CreateCommand = (UnsafeNativeMethods.IDBCreateCommandCreateCommand)Marshal.GetDelegateForFunctionPointer(method, typeof(UnsafeNativeMethods.IDBCreateCommandCreateCommand));
                constr.DangerousIDBCreateCommandCreateCommand = CreateCommand;
            }
            // since this instance can be used to create multiple commands
            // cache it on the class so that the function pointer doesn't have to be validated every time
            DangerousIDBCreateCommandCreateCommand = CreateCommand;
        }
Example #30
0
        // if OleDbConnectionString.DangerousIDBCreateCommandCreateCommand does not exist
        // this method will be called to query for IDBCreateCommand (and cache that interface pointer)
        // or it will be known that IDBCreateCommand is not supported
        internal void QueryInterfaceIDBCreateCommand(OleDbConnectionString constr) {
            // DangerousAddRef/DangerousRelease are not neccessary here in the current implementation
            // only used from within OleDbConnectionInternal.ctor->DataSourceWrapper.InitializeAndCreateSession

            // caching the fact if we have queried for IDBCreateCommand or not
            // the command object is not supported by all providers, they would use IOpenRowset
            // SQLBU:446413, SQLHotfix:1138 -- added extra if condition
            // If constr.HaveQueriedForCreateCommand is false, this is the first time through this method and we need to set up the cache for sure.
            // If two threads try to set the cache at the same time, everything should be okay. There can be multiple delegates that point to the same unmanaged function.
            // If constr.HaveQueriedForCreateCommand is true, we have already tried to query for IDBCreateCommand on a previous call to this method, but based on that alone,
            //     we don't know if another thread set the flag, or if the provider really doesn't support commands.
            // If constr.HaveQueriedForCreateCommand is true and constr.DangerousIDBCreateCommandCreateCommand is not null, that means that another thread has set it after we
            //     determined we needed to call QueryInterfaceIDBCreateCommand -- otherwise we would have called VerifyIDBCreateCommand instead 
            // In that case, we still need to set our local DangerousIDBCreateCommandCreateCommand, so we want to go through the if block even though the cache has been set on constr already            
            if (!constr.HaveQueriedForCreateCommand || (null != constr.DangerousIDBCreateCommandCreateCommand)) {
                IntPtr idbCreateCommand = IntPtr.Zero;
                RuntimeHelpers.PrepareConstrainedRegions();
                try {
                    // native COM rules are the QI result is the 'this' pointer
                    // the pointer stored at that location is the vtable
                    // since IUnknown is a public,shipped COM interface, its layout will not change (ever)
                    IntPtr vtable = Marshal.ReadIntPtr(base.handle, 0);
                    IntPtr method = Marshal.ReadIntPtr(vtable, 0);
                    UnsafeNativeMethods.IUnknownQueryInterface QueryInterface = (UnsafeNativeMethods.IUnknownQueryInterface)Marshal.GetDelegateForFunctionPointer(method, typeof(UnsafeNativeMethods.IUnknownQueryInterface));

                    int hresult = QueryInterface(base.handle, ref ODB.IID_IDBCreateCommand, ref idbCreateCommand);  // 
                    if ((0 <= hresult) && (IntPtr.Zero != idbCreateCommand)) {
                        vtable = Marshal.ReadIntPtr(idbCreateCommand, 0);
                        method = Marshal.ReadIntPtr(vtable, 3 * IntPtr.Size);

                        DangerousIDBCreateCommandCreateCommand = (UnsafeNativeMethods.IDBCreateCommandCreateCommand)Marshal.GetDelegateForFunctionPointer(method, typeof(UnsafeNativeMethods.IDBCreateCommandCreateCommand));
                        constr.DangerousIDBCreateCommandCreateCommand = DangerousIDBCreateCommandCreateCommand;                        
                    }
                    
                    // caching the fact that we have queried for IDBCreateCommand
                    constr.HaveQueriedForCreateCommand = true;
                }
                finally {
                    if (IntPtr.Zero != idbCreateCommand) {
                        IntPtr ptr = base.handle;
                        base.handle = idbCreateCommand;
                        Marshal.Release(ptr);
                    }
                }
            }
            //else if constr.HaveQueriedForCreateCommand is true and constr.DangerousIDBCreateCommandCreateCommand is still null, it means that this provider doesn't support commands
        }
        private Dictionary<string,OleDbPropertyInfo> GetProviderInfo(string provider) {
            Dictionary<string,OleDbPropertyInfo> providerInfo = _propertyInfo;
            if (null == providerInfo) {
                providerInfo = new Dictionary<string,OleDbPropertyInfo>(StringComparer.OrdinalIgnoreCase);
                if (!ADP.IsEmpty(provider)) {
                    Dictionary<string,OleDbPropertyInfo> hash = null;
                    try {
                        StringBuilder builder = new StringBuilder();
                        AppendKeyValuePair(builder, DbConnectionStringKeywords.Provider, provider);
                        OleDbConnectionString constr = new OleDbConnectionString(builder.ToString(), true);
                        constr.CreatePermissionSet().Demand();

                        // load provider without calling Initialize or CreateDataSource
                        using(OleDbConnectionInternal connection = new OleDbConnectionInternal(constr, (OleDbConnection)null)) {

                            // get all the init property information for the provider
                            hash = connection.GetPropertyInfo(new Guid[] { OleDbPropertySetGuid.DBInitAll });
                            foreach(KeyValuePair<string,OleDbPropertyInfo> entry in hash) {
                                Keywords index;
                                OleDbPropertyInfo info = entry.Value;
                                if (!_keywords.TryGetValue(info._description, out index)) {
                                    if ((OleDbPropertySetGuid.DBInit == info._propertySet) &&
                                            ((ODB.DBPROP_INIT_ASYNCH == info._propertyID) ||
                                             (ODB.DBPROP_INIT_HWND == info._propertyID) ||
                                             (ODB.DBPROP_INIT_PROMPT == info._propertyID))) {
                                        continue; // skip this keyword
                                    }
                                    providerInfo[info._description] = info;
                                }
                            }

                            // what are the unique propertysets?
                            List<Guid> listPropertySets= new List<Guid>();
                            foreach(KeyValuePair<string,OleDbPropertyInfo> entry in hash) {
                                OleDbPropertyInfo info = entry.Value;
                                if (!listPropertySets.Contains(info._propertySet)) {
                                    listPropertySets.Add(info._propertySet);
                                }
                            }
                            Guid[] arrayPropertySets = new Guid[listPropertySets.Count];
                            listPropertySets.CopyTo(arrayPropertySets, 0);

                            // get all the init property values for the provider
                            using(PropertyIDSet propidset = new PropertyIDSet(arrayPropertySets)) {
                                using(IDBPropertiesWrapper idbProperties = connection.IDBProperties()) {

                                    OleDbHResult hr;
                                    using(DBPropSet propset = new DBPropSet(idbProperties.Value, propidset, out hr)) {
                                        // VSDD 671375: OleDbConnectionStringBuilder is ignoring/hiding potential errors of OLEDB provider when reading its properties information
                                        if (0 <= (int)hr) {
                                            int count = propset.PropertySetCount;
                                            for(int i = 0; i < count; ++i) {
                                                Guid propertyset;
                                                tagDBPROP[] props = propset.GetPropertySet(i, out propertyset);

                                                // attach the default property value to the property info
                                                foreach(tagDBPROP prop in props) {

                                                    foreach(KeyValuePair<string,OleDbPropertyInfo> entry in hash) {
                                                        OleDbPropertyInfo info = entry.Value;
                                                        if ((info._propertyID == prop.dwPropertyID) && (info._propertySet == propertyset)) {
                                                            info._defaultValue = prop.vValue;

                                                            if (null == info._defaultValue) {
                                                                if (typeof(string) == info._type) {
                                                                    info._defaultValue = "";
                                                                }
                                                                else if (typeof(Int32) == info._type) {
                                                                    info._defaultValue = 0;
                                                                }
                                                                else if (typeof(Boolean) == info._type) {
                                                                    info._defaultValue = false;
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    catch(System.InvalidOperationException e) {
                        ADP.TraceExceptionWithoutRethrow(e);
                    }
                    catch(System.Data.OleDb.OleDbException e) {
                        ADP.TraceExceptionWithoutRethrow(e);
                    }
                    catch(System.Security.SecurityException e) {
                        ADP.TraceExceptionWithoutRethrow(e);
                    }
                }
                _propertyInfo = providerInfo;
            }
            return providerInfo;
        }
        private Dictionary <string, OleDbPropertyInfo> GetProviderInfo(string provider)
        {
            Dictionary <string, OleDbPropertyInfo> dictionary = this._propertyInfo;

            if (dictionary == null)
            {
                dictionary = new Dictionary <string, OleDbPropertyInfo>(StringComparer.OrdinalIgnoreCase);
                if (!ADP.IsEmpty(provider))
                {
                    Dictionary <string, OleDbPropertyInfo> propertyInfo = null;
                    try
                    {
                        StringBuilder builder = new StringBuilder();
                        DbConnectionStringBuilder.AppendKeyValuePair(builder, "Provider", provider);
                        OleDbConnectionString constr = new OleDbConnectionString(builder.ToString(), true);
                        constr.CreatePermissionSet().Demand();
                        using (OleDbConnectionInternal internal2 = new OleDbConnectionInternal(constr, null))
                        {
                            Guid[] propertySets = new Guid[] { OleDbPropertySetGuid.DBInitAll };
                            propertyInfo = internal2.GetPropertyInfo(propertySets);
                            foreach (KeyValuePair <string, OleDbPropertyInfo> pair3 in propertyInfo)
                            {
                                Keywords          keywords;
                                OleDbPropertyInfo info2 = pair3.Value;
                                if (!_keywords.TryGetValue(info2._description, out keywords) && ((OleDbPropertySetGuid.DBInit != info2._propertySet) || (((200 != info2._propertyID) && (60 != info2._propertyID)) && (0x40 != info2._propertyID))))
                                {
                                    dictionary[info2._description] = info2;
                                }
                            }
                            List <Guid> list = new List <Guid>();
                            foreach (KeyValuePair <string, OleDbPropertyInfo> pair2 in propertyInfo)
                            {
                                OleDbPropertyInfo info3 = pair2.Value;
                                if (!list.Contains(info3._propertySet))
                                {
                                    list.Add(info3._propertySet);
                                }
                            }
                            Guid[] array = new Guid[list.Count];
                            list.CopyTo(array, 0);
                            using (PropertyIDSet set2 = new PropertyIDSet(array))
                            {
                                using (IDBPropertiesWrapper wrapper = internal2.IDBProperties())
                                {
                                    OleDbHResult result;
                                    using (DBPropSet set = new DBPropSet(wrapper.Value, set2, out result))
                                    {
                                        if (OleDbHResult.S_OK <= result)
                                        {
                                            int propertySetCount = set.PropertySetCount;
                                            for (int i = 0; i < propertySetCount; i++)
                                            {
                                                Guid guid;
                                                foreach (tagDBPROP gdbprop in set.GetPropertySet(i, out guid))
                                                {
                                                    foreach (KeyValuePair <string, OleDbPropertyInfo> pair in propertyInfo)
                                                    {
                                                        OleDbPropertyInfo info = pair.Value;
                                                        if ((info._propertyID == gdbprop.dwPropertyID) && (info._propertySet == guid))
                                                        {
                                                            info._defaultValue = gdbprop.vValue;
                                                            if (info._defaultValue == null)
                                                            {
                                                                if (typeof(string) == info._type)
                                                                {
                                                                    info._defaultValue = "";
                                                                }
                                                                else if (typeof(int) == info._type)
                                                                {
                                                                    info._defaultValue = 0;
                                                                }
                                                                else if (typeof(bool) == info._type)
                                                                {
                                                                    info._defaultValue = false;
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    catch (InvalidOperationException exception3)
                    {
                        ADP.TraceExceptionWithoutRethrow(exception3);
                    }
                    catch (OleDbException exception2)
                    {
                        ADP.TraceExceptionWithoutRethrow(exception2);
                    }
                    catch (SecurityException exception)
                    {
                        ADP.TraceExceptionWithoutRethrow(exception);
                    }
                }
                this._propertyInfo = dictionary;
            }
            return(dictionary);
        }
Example #33
0
 static internal void Demand(OleDbConnectionString constr) {
     PermissionSet permission = ((null != constr) ? constr._permission : OleDbConnection.OleDbPermission);
     permission.Demand();
 }
Example #34
0
        private OleDbConnectionString(string connectionString) : base(connectionString, UdlSupport.LoadFromFile) {
#endif
            _permission = OleDbConnectionString.CreatePermission(this);
        }
Example #35
0
 // @devnote: should be multithread safe
 static public void ReleaseObjectPool()
 {
     OleDbConnectionString.ReleaseObjectPool();
     OleDbConnectionInternal.ReleaseObjectPool();
     OleDbConnectionFactory.SingletonInstance.ClearAllPools();
 }
Example #36
0
        internal OleDbHResult InitializeAndCreateSession(OleDbConnectionString constr, ref SessionWrapper sessionWrapper) {
            OleDbHResult hr;
            bool mustRelease = false;
            IntPtr idbCreateSession = IntPtr.Zero;
            RuntimeHelpers.PrepareConstrainedRegions();
            try {
                DangerousAddRef(ref mustRelease);
                
                // native COM rules are the QI result is the 'this' pointer
                // the pointer stored at that location is the vtable
                // since IUnknown is a public,shipped COM interface, its layout will not change (ever)
                IntPtr vtable = Marshal.ReadIntPtr(base.handle, 0);
                IntPtr method = Marshal.ReadIntPtr(vtable, 0);
                
                // we cache the QueryInterface delegate to prevent recreating it on every call
                UnsafeNativeMethods.IUnknownQueryInterface QueryInterface = constr.DangerousDataSourceIUnknownQueryInterface;

                // since the delegate lifetime is longer than the original instance used to create it
                // we double check before each usage to verify the delegates function pointer
                if ((null == QueryInterface) || (method != Marshal.GetFunctionPointerForDelegate(QueryInterface))) {
                    QueryInterface = (UnsafeNativeMethods.IUnknownQueryInterface)Marshal.GetDelegateForFunctionPointer(method, typeof(UnsafeNativeMethods.IUnknownQueryInterface));
                    constr.DangerousDataSourceIUnknownQueryInterface = QueryInterface;
                }
                
                // native COM rules are the QI result is the 'this' pointer
                // the pointer stored at that location is the vtable
                // since IDBInitialize is a public,shipped COM interface, its layout will not change (ever)
                vtable = Marshal.ReadIntPtr(base.handle, 0);
                method = Marshal.ReadIntPtr(vtable, 3 * IntPtr.Size);  // Initialize is the 4'th vtable entry

                // we cache the Initialize delegate to prevent recreating it on every call
                UnsafeNativeMethods.IDBInitializeInitialize Initialize = constr.DangerousIDBInitializeInitialize;
                
                // since the delegate lifetime is longer than the original instance used to create it
                // we double check before each usage to verify the delegates function pointer
                if ((null == Initialize) || (method != Marshal.GetFunctionPointerForDelegate(Initialize))) {
                    Initialize = (UnsafeNativeMethods.IDBInitializeInitialize)Marshal.GetDelegateForFunctionPointer(method, typeof(UnsafeNativeMethods.IDBInitializeInitialize));
                    constr.DangerousIDBInitializeInitialize = Initialize;
                }

                // call IDBInitialize::Initialize via the delegate
                hr = Initialize(base.handle);

                // we don't ever expect DB_E_ALREADYINITIALIZED, but since we checked in V1.0 - its propagated along
                if ((0 <= hr) || (OleDbHResult.DB_E_ALREADYINITIALIZED == hr)) {
                    
                    // call IUnknown::QueryInterface via the delegate
                    hr = (OleDbHResult)QueryInterface(base.handle, ref ODB.IID_IDBCreateSession, ref idbCreateSession);
                    if ((0 <= hr) && (IntPtr.Zero != idbCreateSession)) {
                        
                        // native COM rules are the QI result is the 'this' pointer
                        // the pointer stored at that location is the vtable
                        // since IDBCreateSession is a public,shipped COM interface, its layout will not change (ever)
                        vtable = Marshal.ReadIntPtr(idbCreateSession, 0);
                        method = Marshal.ReadIntPtr(vtable, 3 * IntPtr.Size);  // CreateSession is the 4'th vtable entry
                        
                        UnsafeNativeMethods.IDBCreateSessionCreateSession CreateSession = constr.DangerousIDBCreateSessionCreateSession;                                

                        // since the delegate lifetime is longer than the original instance used to create it
                        // we double check before each usage to verify the delegates function pointer
                        if ((null == CreateSession) || (method != Marshal.GetFunctionPointerForDelegate(CreateSession))) {
                            CreateSession = (UnsafeNativeMethods.IDBCreateSessionCreateSession)Marshal.GetDelegateForFunctionPointer(method, typeof(UnsafeNativeMethods.IDBCreateSessionCreateSession));
                            constr.DangerousIDBCreateSessionCreateSession = CreateSession;
                        }

                        // if I have a delegate for CreateCommand directly ask for IDBCreateCommand
                        if (null != constr.DangerousIDBCreateCommandCreateCommand) {
                            // call IDBCreateSession::CreateSession via the delegate directly for IDBCreateCommand
                            hr = CreateSession(idbCreateSession, IntPtr.Zero, ref ODB.IID_IDBCreateCommand, ref sessionWrapper);
                            if ((0 <= hr) && !sessionWrapper.IsInvalid) {                                        
                                // double check the cached delegate is correct
                                sessionWrapper.VerifyIDBCreateCommand(constr);
                            }
                        }
                        else {
                            // otherwise ask for IUnknown (it may be first time usage or IDBCreateCommand not supported)
                            hr = CreateSession(idbCreateSession, IntPtr.Zero, ref ODB.IID_IUnknown, ref sessionWrapper);
                            if ((0 <= hr) && !sessionWrapper.IsInvalid) {
                                // and check support for IDBCreateCommand and create delegate for CreateCommand
                                sessionWrapper.QueryInterfaceIDBCreateCommand(constr);
                            }
                        }
                    }
                }
            }
            finally {
                if (IntPtr.Zero != idbCreateSession) {
                    // release the QI for IDBCreateSession
                    Marshal.Release(idbCreateSession);
                }
                if (mustRelease) {
                    // release the AddRef on DataLinks
                    DangerousRelease();
                }
            }
            return hr;
        }
        internal OleDbConnectionInternal(OleDbConnectionString constr, OleDbConnection connection) : base()
        {
            Debug.Assert((null != constr) && !constr.IsEmpty, "empty connectionstring");
            ConnectionString = constr;

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

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

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

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

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

                    // process the HResult here instead of from the SafeHandle because the possibility
                    // of an InfoMessageEvent.
                    if ((0 <= hr) && !_sessionwrp.IsInvalid)
                    { // process infonessage events
                        OleDbConnection.ProcessResults(hr, connection, connection);
                    }
                    else
                    {
                        Exception e = OleDbConnection.ProcessResults(hr, null, null);
                        Debug.Assert(null != e, "CreateSessionError");
                        throw e;
                    }
                    Debug.Assert(!_sessionwrp.IsInvalid, "bad Session");
                }
            }
            catch
            {
                if (null != _sessionwrp)
                {
                    _sessionwrp.Dispose();
                    _sessionwrp = null;
                }
                if (null != _datasrcwrp)
                {
                    _datasrcwrp.Dispose();
                    _datasrcwrp = null;
                }
                throw;
            }
        }
 private Dictionary<string, OleDbPropertyInfo> GetProviderInfo(string provider)
 {
     Dictionary<string, OleDbPropertyInfo> dictionary = this._propertyInfo;
     if (dictionary == null)
     {
         dictionary = new Dictionary<string, OleDbPropertyInfo>(StringComparer.OrdinalIgnoreCase);
         if (!ADP.IsEmpty(provider))
         {
             Dictionary<string, OleDbPropertyInfo> propertyInfo = null;
             try
             {
                 StringBuilder builder = new StringBuilder();
                 DbConnectionStringBuilder.AppendKeyValuePair(builder, "Provider", provider);
                 OleDbConnectionString constr = new OleDbConnectionString(builder.ToString(), true);
                 constr.CreatePermissionSet().Demand();
                 using (OleDbConnectionInternal internal2 = new OleDbConnectionInternal(constr, null))
                 {
                     Guid[] propertySets = new Guid[] { OleDbPropertySetGuid.DBInitAll };
                     propertyInfo = internal2.GetPropertyInfo(propertySets);
                     foreach (KeyValuePair<string, OleDbPropertyInfo> pair3 in propertyInfo)
                     {
                         Keywords keywords;
                         OleDbPropertyInfo info2 = pair3.Value;
                         if (!_keywords.TryGetValue(info2._description, out keywords) && ((OleDbPropertySetGuid.DBInit != info2._propertySet) || (((200 != info2._propertyID) && (60 != info2._propertyID)) && (0x40 != info2._propertyID))))
                         {
                             dictionary[info2._description] = info2;
                         }
                     }
                     List<Guid> list = new List<Guid>();
                     foreach (KeyValuePair<string, OleDbPropertyInfo> pair2 in propertyInfo)
                     {
                         OleDbPropertyInfo info3 = pair2.Value;
                         if (!list.Contains(info3._propertySet))
                         {
                             list.Add(info3._propertySet);
                         }
                     }
                     Guid[] array = new Guid[list.Count];
                     list.CopyTo(array, 0);
                     using (PropertyIDSet set2 = new PropertyIDSet(array))
                     {
                         using (IDBPropertiesWrapper wrapper = internal2.IDBProperties())
                         {
                             OleDbHResult result;
                             using (DBPropSet set = new DBPropSet(wrapper.Value, set2, out result))
                             {
                                 if (OleDbHResult.S_OK <= result)
                                 {
                                     int propertySetCount = set.PropertySetCount;
                                     for (int i = 0; i < propertySetCount; i++)
                                     {
                                         Guid guid;
                                         foreach (tagDBPROP gdbprop in set.GetPropertySet(i, out guid))
                                         {
                                             foreach (KeyValuePair<string, OleDbPropertyInfo> pair in propertyInfo)
                                             {
                                                 OleDbPropertyInfo info = pair.Value;
                                                 if ((info._propertyID == gdbprop.dwPropertyID) && (info._propertySet == guid))
                                                 {
                                                     info._defaultValue = gdbprop.vValue;
                                                     if (info._defaultValue == null)
                                                     {
                                                         if (typeof(string) == info._type)
                                                         {
                                                             info._defaultValue = "";
                                                         }
                                                         else if (typeof(int) == info._type)
                                                         {
                                                             info._defaultValue = 0;
                                                         }
                                                         else if (typeof(bool) == info._type)
                                                         {
                                                             info._defaultValue = false;
                                                         }
                                                     }
                                                 }
                                             }
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
             catch (InvalidOperationException exception3)
             {
                 ADP.TraceExceptionWithoutRethrow(exception3);
             }
             catch (OleDbException exception2)
             {
                 ADP.TraceExceptionWithoutRethrow(exception2);
             }
             catch (SecurityException exception)
             {
                 ADP.TraceExceptionWithoutRethrow(exception);
             }
         }
         this._propertyInfo = dictionary;
     }
     return dictionary;
 }
 internal void VerifyIDBCreateCommand(OleDbConnectionString constr)
 {
     IntPtr ptr = Marshal.ReadIntPtr(Marshal.ReadIntPtr(base.handle, 0), 3 * IntPtr.Size);
     UnsafeNativeMethods.IDBCreateCommandCreateCommand dangerousIDBCreateCommandCreateCommand = constr.DangerousIDBCreateCommandCreateCommand;
     if ((dangerousIDBCreateCommandCreateCommand == null) || (ptr != Marshal.GetFunctionPointerForDelegate(dangerousIDBCreateCommandCreateCommand)))
     {
         dangerousIDBCreateCommandCreateCommand = (UnsafeNativeMethods.IDBCreateCommandCreateCommand) Marshal.GetDelegateForFunctionPointer(ptr, typeof(UnsafeNativeMethods.IDBCreateCommandCreateCommand));
         constr.DangerousIDBCreateCommandCreateCommand = dangerousIDBCreateCommandCreateCommand;
     }
     this.DangerousIDBCreateCommandCreateCommand = dangerousIDBCreateCommandCreateCommand;
 }
Example #40
0
        internal unsafe OleDbHResult InitializeAndCreateSession(OleDbConnectionString constr, ref SessionWrapper sessionWrapper)
        {
            OleDbHResult hr;
            bool         mustRelease      = false;
            IntPtr       idbCreateSession = IntPtr.Zero;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                DangerousAddRef(ref mustRelease);

                // native COM rules are the QI result is the 'this' pointer
                // the pointer stored at that location is the vtable
                // since IUnknown is a public,shipped COM interface, its layout will not change (ever)
                IntPtr vtable = Marshal.ReadIntPtr(base.handle, 0);
                IntPtr method = Marshal.ReadIntPtr(vtable, 0);

                // we cache the QueryInterface delegate to prevent recreating it on every call
                UnsafeNativeMethods.IUnknownQueryInterface?QueryInterface = constr.DangerousDataSourceIUnknownQueryInterface;

                // since the delegate lifetime is longer than the original instance used to create it
                // we double check before each usage to verify the delegates function pointer
                if ((null == QueryInterface) || (method != Marshal.GetFunctionPointerForDelegate(QueryInterface)))
                {
                    QueryInterface = (UnsafeNativeMethods.IUnknownQueryInterface)Marshal.GetDelegateForFunctionPointer(method, typeof(UnsafeNativeMethods.IUnknownQueryInterface));
                    constr.DangerousDataSourceIUnknownQueryInterface = QueryInterface;
                }

                // native COM rules are the QI result is the 'this' pointer
                // the pointer stored at that location is the vtable
                // since IDBInitialize is a public,shipped COM interface, its layout will not change (ever)
                vtable = Marshal.ReadIntPtr(base.handle, 0);
                method = Marshal.ReadIntPtr(vtable, 3 * IntPtr.Size);  // Initialize is the 4'th vtable entry

                // we cache the Initialize delegate to prevent recreating it on every call
                UnsafeNativeMethods.IDBInitializeInitialize?Initialize = constr.DangerousIDBInitializeInitialize;

                // since the delegate lifetime is longer than the original instance used to create it
                // we double check before each usage to verify the delegates function pointer
                if ((null == Initialize) || (method != Marshal.GetFunctionPointerForDelegate(Initialize)))
                {
                    Initialize = (UnsafeNativeMethods.IDBInitializeInitialize)Marshal.GetDelegateForFunctionPointer(method, typeof(UnsafeNativeMethods.IDBInitializeInitialize));
                    constr.DangerousIDBInitializeInitialize = Initialize;
                }

                // call IDBInitialize::Initialize via the delegate
                hr = Initialize(base.handle);

                // we don't ever expect DB_E_ALREADYINITIALIZED, but since we checked in V1.0 - its propagated along
                if ((0 <= hr) || (OleDbHResult.DB_E_ALREADYINITIALIZED == hr))
                {
                    // call IUnknown::QueryInterface via the delegate
                    fixed(Guid *riid = &ODB.IID_IDBCreateSession)
                    {
                        hr = (OleDbHResult)QueryInterface(base.handle, riid, &idbCreateSession);
                    }
                    if ((0 <= hr) && (IntPtr.Zero != idbCreateSession))
                    {
                        // native COM rules are the QI result is the 'this' pointer
                        // the pointer stored at that location is the vtable
                        // since IDBCreateSession is a public,shipped COM interface, its layout will not change (ever)
                        vtable = Marshal.ReadIntPtr(idbCreateSession, 0);
                        method = Marshal.ReadIntPtr(vtable, 3 * IntPtr.Size);  // CreateSession is the 4'th vtable entry

                        UnsafeNativeMethods.IDBCreateSessionCreateSession?CreateSession = constr.DangerousIDBCreateSessionCreateSession;

                        // since the delegate lifetime is longer than the original instance used to create it
                        // we double check before each usage to verify the delegates function pointer
                        if ((null == CreateSession) || (method != Marshal.GetFunctionPointerForDelegate(CreateSession)))
                        {
                            CreateSession = (UnsafeNativeMethods.IDBCreateSessionCreateSession)Marshal.GetDelegateForFunctionPointer(method, typeof(UnsafeNativeMethods.IDBCreateSessionCreateSession));
                            constr.DangerousIDBCreateSessionCreateSession = CreateSession;
                        }

                        // if I have a delegate for CreateCommand directly ask for IDBCreateCommand
                        if (null != constr.DangerousIDBCreateCommandCreateCommand)
                        {
                            // call IDBCreateSession::CreateSession via the delegate directly for IDBCreateCommand
                            fixed(Guid *riid = &ODB.IID_IDBCreateCommand)
                            {
                                bool           addRefd    = false;
                                SessionWrapper newWrapper = new SessionWrapper();

                                sessionWrapper.DangerousAddRef(ref addRefd);
                                IntPtr originalHandle = sessionWrapper.DangerousGetHandle();
                                IntPtr handle         = originalHandle;

                                try
                                {
                                    hr = CreateSession(idbCreateSession, IntPtr.Zero, riid, &handle);
                                }
                                finally
                                {
                                    if (addRefd)
                                    {
                                        sessionWrapper.DangerousRelease();
                                    }
                                    if (handle != originalHandle)
                                    {
                                        Marshal.InitHandle(newWrapper, handle);
                                        sessionWrapper = newWrapper;
                                    }
                                }
                            }
                            if ((0 <= hr) && !sessionWrapper.IsInvalid)
                            {
                                // double check the cached delegate is correct
                                sessionWrapper.VerifyIDBCreateCommand(constr);
                            }
                        }
                        else
                        {
                            // otherwise ask for IUnknown (it may be first time usage or IDBCreateCommand not supported)
                            fixed(Guid *riid = &ODB.IID_IUnknown)
                            {
                                bool           addRefd    = false;
                                SessionWrapper newWrapper = new SessionWrapper();

                                sessionWrapper.DangerousAddRef(ref addRefd);
                                IntPtr originalHandle = sessionWrapper.DangerousGetHandle();
                                IntPtr handle         = originalHandle;

                                try
                                {
                                    hr = CreateSession(idbCreateSession, IntPtr.Zero, riid, &handle);
                                }
                                finally
                                {
                                    if (addRefd)
                                    {
                                        sessionWrapper.DangerousRelease();
                                    }
                                    if (handle != originalHandle)
                                    {
                                        Marshal.InitHandle(newWrapper, handle);
                                        sessionWrapper = newWrapper;
                                    }
                                }
                            }
                            if ((0 <= hr) && !sessionWrapper.IsInvalid)
                            {
                                // and check support for IDBCreateCommand and create delegate for CreateCommand
                                sessionWrapper.QueryInterfaceIDBCreateCommand(constr);
                            }
                        }
                    }
                }
            }
            finally
            {
                if (IntPtr.Zero != idbCreateSession)
                {
                    // release the QI for IDBCreateSession
                    Marshal.Release(idbCreateSession);
                }
                if (mustRelease)
                {
                    // release the AddRef on DataLinks
                    DangerousRelease();
                }
            }
            return(hr);
        }