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); }
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; }