diff --git a/src/libraries/System.Data.OleDb/src/DbPropSet.cs b/src/libraries/System.Data.OleDb/src/DbPropSet.cs
index c0b719c737372d..0adeb559986882 100644
--- a/src/libraries/System.Data.OleDb/src/DbPropSet.cs
+++ b/src/libraries/System.Data.OleDb/src/DbPropSet.cs
@@ -105,9 +105,17 @@ private void SetLastErrorInfo(OleDbHResult lastErrorHr)
OleDbHResult errorInfoHr = UnsafeNativeMethods.GetErrorInfo(0, out errorInfo); // 0 - IErrorInfo exists, 1 - no IErrorInfo
if ((errorInfoHr == OleDbHResult.S_OK) && (errorInfo != null))
{
- ODB.GetErrorDescription(errorInfo, lastErrorHr, out message);
- // note that either GetErrorInfo or GetErrorDescription might fail in which case we will have only the HRESULT value in exception message
+ try
+ {
+ ODB.GetErrorDescription(errorInfo, lastErrorHr, out message);
+ // note that either GetErrorInfo or GetErrorDescription might fail in which case we will have only the HRESULT value in exception message
+ }
+ finally
+ {
+ UnsafeNativeMethods.ReleaseErrorInfoObject(errorInfo);
+ }
}
+
lastErrorFromProvider = new COMException(message, (int)lastErrorHr);
}
diff --git a/src/libraries/System.Data.OleDb/src/ILLink/ILLink.Suppressions.xml b/src/libraries/System.Data.OleDb/src/ILLink/ILLink.Suppressions.xml
index 52bca59a2fc21b..c9d79f066f046c 100644
--- a/src/libraries/System.Data.OleDb/src/ILLink/ILLink.Suppressions.xml
+++ b/src/libraries/System.Data.OleDb/src/ILLink/ILLink.Suppressions.xml
@@ -1,30 +1,6 @@
-
- ILLink
- IL2050
- member
- M:System.Data.OleDb.DBPropSet.SetLastErrorInfo(System.Data.OleDb.OleDbHResult)
-
-
- ILLink
- IL2050
- member
- M:System.Data.OleDb.OleDbConnection.ProcessResults(System.Data.OleDb.OleDbHResult,System.Data.OleDb.OleDbConnection,System.Object)
-
-
- ILLink
- IL2050
- member
- M:System.Data.OleDb.OleDbDataAdapter.FillClose(System.Boolean,System.Object)
-
-
- ILLink
- IL2050
- member
- M:System.Data.OleDb.OleDbDataAdapter.FillFromADODB(System.Object,System.Object,System.String,System.Boolean)
-
ILLink
IL2067
@@ -102,5 +78,6 @@
IL2111
member
M:System.Data.OleDb.OleDbDataReader.BuildSchemaTable(System.Data.OleDb.MetaData[])
-
-
\ No newline at end of file
+
+
+
diff --git a/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs
new file mode 100644
index 00000000000000..92a54fe9e223ed
--- /dev/null
+++ b/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs
@@ -0,0 +1,118 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Collections;
+using System.Diagnostics;
+using System.Data.Common;
+using System.IO;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+namespace System.Data.OleDb
+{
+ ///
+ /// The ComWrappers implementation for System.Data.OleDb's COM interop usages.
+ ///
+ /// Supports IErrorInfo COM interface.
+ ///
+ internal unsafe sealed class OleDbComWrappers : ComWrappers
+ {
+ private const int S_OK = (int)OleDbHResult.S_OK;
+ private static readonly Guid IID_IErrorInfo = new Guid(0x1CF2B120, 0x547D, 0x101B, 0x8E, 0x65, 0x08, 0x00, 0x2B, 0x2B, 0xD1, 0x19);
+
+ internal static OleDbComWrappers Instance { get; } = new OleDbComWrappers();
+
+ private OleDbComWrappers() { }
+
+ protected override unsafe ComInterfaceEntry* ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count)
+ {
+ throw new NotImplementedException();
+ }
+
+ protected override object CreateObject(IntPtr externalComObject, CreateObjectFlags flags)
+ {
+ Debug.Assert(flags == CreateObjectFlags.UniqueInstance);
+
+ Guid errorInfoIID = IID_IErrorInfo;
+ int hr = Marshal.QueryInterface(externalComObject, ref errorInfoIID, out IntPtr comObject);
+ if (hr == S_OK)
+ {
+ return new ErrorInfoWrapper(comObject);
+ }
+
+ throw new NotImplementedException();
+ }
+
+ protected override void ReleaseObjects(IEnumerable objects)
+ {
+ throw new NotImplementedException();
+ }
+
+ // Doc and type layout: https://docs.microsoft.com/windows/win32/api/oaidl/nn-oaidl-ierrorinfo
+ private class ErrorInfoWrapper : UnsafeNativeMethods.IErrorInfo, IDisposable
+ {
+ private readonly IntPtr _wrappedInstance;
+
+ public ErrorInfoWrapper(IntPtr wrappedInstance)
+ {
+ _wrappedInstance = wrappedInstance;
+ }
+
+ public void Dispose()
+ {
+ Marshal.Release(_wrappedInstance);
+ }
+
+ [Obsolete("not used", true)]
+ void UnsafeNativeMethods.IErrorInfo.GetGUID(/*deleted parameter signature*/)
+ {
+ throw new NotImplementedException();
+ }
+
+ public unsafe System.Data.OleDb.OleDbHResult GetSource(out string? source)
+ {
+ IntPtr pSource = IntPtr.Zero;
+ int errorCode = ((delegate* unmanaged)(*(*(void***)_wrappedInstance + 4 /* IErrorInfo.GetSource slot */)))
+ (_wrappedInstance, &pSource);
+ if (pSource == IntPtr.Zero || errorCode < 0)
+ {
+ source = null;
+ }
+ else
+ {
+ source = Marshal.PtrToStringBSTR(pSource);
+ }
+
+ if (pSource != IntPtr.Zero)
+ {
+ Marshal.FreeBSTR(pSource);
+ }
+
+ return (System.Data.OleDb.OleDbHResult)errorCode;
+ }
+
+ public unsafe System.Data.OleDb.OleDbHResult GetDescription(out string? description)
+ {
+ IntPtr pDescription = IntPtr.Zero;
+ int errorCode = ((delegate* unmanaged)(*(*(void***)_wrappedInstance + 5 /* IErrorInfo.GetDescription slot */)))
+ (_wrappedInstance, &pDescription);
+ if (pDescription == IntPtr.Zero || errorCode < 0)
+ {
+ description = null;
+ }
+ else
+ {
+ description = Marshal.PtrToStringBSTR(pDescription);
+ }
+
+ if (pDescription != IntPtr.Zero)
+ {
+ Marshal.FreeBSTR(pDescription);
+ }
+
+ return (System.Data.OleDb.OleDbHResult)errorCode;
+ }
+ }
+
+ }
+}
diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnection.cs b/src/libraries/System.Data.OleDb/src/OleDbConnection.cs
index 8d78f2ac49323e..7e456b936fba7b 100644
--- a/src/libraries/System.Data.OleDb/src/OleDbConnection.cs
+++ b/src/libraries/System.Data.OleDb/src/OleDbConnection.cs
@@ -587,32 +587,35 @@ internal bool SupportSchemaRowset(Guid schema)
OleDbHResult hr = UnsafeNativeMethods.GetErrorInfo(0, out errorInfo); // 0 - IErrorInfo exists, 1 - no IErrorInfo
if ((OleDbHResult.S_OK == hr) && (null != errorInfo))
{
- if (hresult < 0)
+ try
{
- // UNDONE: if authentication failed - throw a unique exception object type
- //if (/*OLEDB_Error.DB_SEC_E_AUTH_FAILED*/unchecked((int)0x80040E4D) == hr) {
- //}
- //else if (/*OLEDB_Error.DB_E_CANCELED*/unchecked((int)0x80040E4E) == hr) {
- //}
- // else {
- e = OleDbException.CreateException(errorInfo, hresult, null);
- //}
-
- if (OleDbHResult.DB_E_OBJECTOPEN == hresult)
+ if (hresult < 0)
{
- e = ADP.OpenReaderExists(e);
- }
+ // UNDONE: if authentication failed - throw a unique exception object type
+ //if (/*OLEDB_Error.DB_SEC_E_AUTH_FAILED*/unchecked((int)0x80040E4D) == hr) {
+ //}
+ //else if (/*OLEDB_Error.DB_E_CANCELED*/unchecked((int)0x80040E4E) == hr) {
+ //}
+ // else {
+ e = OleDbException.CreateException(errorInfo, hresult, null);
+ //}
+
+ if (OleDbHResult.DB_E_OBJECTOPEN == hresult)
+ {
+ e = ADP.OpenReaderExists(e);
+ }
- ResetState(connection);
- }
- else if (null != connection)
- {
- connection.OnInfoMessage(errorInfo, hresult);
+ ResetState(connection);
+ }
+ else if (null != connection)
+ {
+ connection.OnInfoMessage(errorInfo, hresult);
+ }
}
- else
+ finally
{
+ UnsafeNativeMethods.ReleaseErrorInfoObject(errorInfo);
}
- Marshal.ReleaseComObject(errorInfo);
}
else if (0 < hresult)
{
diff --git a/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.cs b/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.cs
index 9c6fb06c90101c..7972bb788617ed 100644
--- a/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.cs
+++ b/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.cs
@@ -259,8 +259,7 @@ record = (adodb as UnsafeNativeMethods.ADORecordConstruction);
// Current provider does not support returning multiple recordsets from a single execution.
if (ODB.ADODB_NextResultError != (int)hr)
{
- UnsafeNativeMethods.IErrorInfo? errorInfo = null;
- UnsafeNativeMethods.GetErrorInfo(0, out errorInfo);
+ SafeNativeMethods.Wrapper.ClearErrorInfo();
string message = string.Empty;
throw new COMException(message, (int)hr);
@@ -430,8 +429,7 @@ private void FillClose(bool isrecordset, object value)
}
if ((0 < (int)hr) && (ODB.ADODB_AlreadyClosedError != (int)hr))
{
- UnsafeNativeMethods.IErrorInfo? errorInfo = null;
- UnsafeNativeMethods.GetErrorInfo(0, out errorInfo);
+ SafeNativeMethods.Wrapper.ClearErrorInfo();
string message = string.Empty;
throw new COMException(message, (int)hr);
}
diff --git a/src/libraries/System.Data.OleDb/src/OleDbException.cs b/src/libraries/System.Data.OleDb/src/OleDbException.cs
index be01b4b4f00849..31205aa04acd67 100644
--- a/src/libraries/System.Data.OleDb/src/OleDbException.cs
+++ b/src/libraries/System.Data.OleDb/src/OleDbException.cs
@@ -70,13 +70,8 @@ internal static OleDbException CreateException(UnsafeNativeMethods.IErrorInfo er
string? message = null;
string? source = null;
OleDbHResult hr = 0;
-
- if (null != errorInfo)
- {
- hr = errorInfo.GetDescription(out message);
-
- hr = errorInfo.GetSource(out source);
- }
+ hr = errorInfo.GetDescription(out message);
+ hr = errorInfo.GetSource(out source);
int count = errors.Count;
if (0 < errors.Count)
diff --git a/src/libraries/System.Data.OleDb/src/OleDb_Util.cs b/src/libraries/System.Data.OleDb/src/OleDb_Util.cs
index 1426320311c419..2598fb5dfd553c 100644
--- a/src/libraries/System.Data.OleDb/src/OleDb_Util.cs
+++ b/src/libraries/System.Data.OleDb/src/OleDb_Util.cs
@@ -334,7 +334,7 @@ internal static InvalidOperationException DBBindingGetVector()
internal static OleDbHResult GetErrorDescription(UnsafeNativeMethods.IErrorInfo errorInfo, OleDbHResult hresult, out string message)
{
- OleDbHResult hr = errorInfo.GetDescription(out message);
+ OleDbHResult hr = errorInfo.GetDescription(out message!);
if (((int)hr < 0) && ADP.IsEmpty(message))
{
message = FailedGetDescription(hr) + Environment.NewLine + ODB.ELookup(hresult);
diff --git a/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj b/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj
index a5e9b248302241..e7b80a71a61c34 100644
--- a/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj
+++ b/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj
@@ -111,6 +111,13 @@ System.Data.OleDb.OleDbTransaction
+
+
+
+
+
+
+