예제 #1
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);
        }
        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);
        }
예제 #3
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 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;
 }