From b91ee8d7694af6f0a3a69ee5561373c75edf8da0 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Mon, 28 Jun 2021 18:32:51 +0600 Subject: [PATCH 01/36] First round of converting System.Data.OleDb to COMWrappers This change just remove warning from ILLink and do not make attempt to convert other COM object creation to use ComWrappers Also I have to add target net5.0-windows where ComWrappers would be used. Same concerns regarding testing as in https://github.com/dotnet/runtime/pull/54636 Two calls inside OleDbDataAdapter call GetErrorInfo but do not do anything with results. That's probably mistake from previous refactoring. These parts does not touched and left as is. Need advice on that specific parts how to proceed. --- .../src/DbPropSet.COMWrappers.cs | 31 ++++ .../src/DbPropSet.NoCOMWrappers.cs | 29 ++++ .../System.Data.OleDb/src/DbPropSet.cs | 17 +- .../src/ILLink/ILLink.Suppressions.xml | 26 +-- .../System.Data.OleDb/src/OleDbComWrappers.cs | 108 ++++++++++++ .../src/OleDbConnection.COMWrappers.cs | 99 +++++++++++ .../src/OleDbConnection.NoCOMWrappers.cs | 101 ++++++++++++ .../System.Data.OleDb/src/OleDbConnection.cs | 82 ---------- .../src/OleDbDataAdapter.COMWrappers.cs | 154 ++++++++++++++++++ .../src/OleDbDataAdapter.NoCOMWrappers.cs | 154 ++++++++++++++++++ .../System.Data.OleDb/src/OleDbDataAdapter.cs | 143 +--------------- .../src/OleDbException.COMWrappers.cs | 60 +++++++ .../src/OleDbException.NoCOMWrappers.cs | 60 +++++++ .../System.Data.OleDb/src/OleDbException.cs | 46 +----- .../src/OleDb_Util.COMWrappers.cs | 29 ++++ .../src/OleDb_Util.NoCOMWrappers.cs | 29 ++++ .../System.Data.OleDb/src/OleDb_Util.cs | 16 +- .../src/System.Data.OleDb.csproj | 21 ++- .../src/UnsafeNativeMethods.COMWrappers.cs | 19 +++ .../src/UnsafeNativeMethods.NoCOMWrappers.cs | 19 +++ .../src/UnsafeNativeMethods.cs | 7 +- 21 files changed, 917 insertions(+), 333 deletions(-) create mode 100644 src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs create mode 100644 src/libraries/System.Data.OleDb/src/DbPropSet.NoCOMWrappers.cs create mode 100644 src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs create mode 100644 src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs create mode 100644 src/libraries/System.Data.OleDb/src/OleDbConnection.NoCOMWrappers.cs create mode 100644 src/libraries/System.Data.OleDb/src/OleDbDataAdapter.COMWrappers.cs create mode 100644 src/libraries/System.Data.OleDb/src/OleDbDataAdapter.NoCOMWrappers.cs create mode 100644 src/libraries/System.Data.OleDb/src/OleDbException.COMWrappers.cs create mode 100644 src/libraries/System.Data.OleDb/src/OleDbException.NoCOMWrappers.cs create mode 100644 src/libraries/System.Data.OleDb/src/OleDb_Util.COMWrappers.cs create mode 100644 src/libraries/System.Data.OleDb/src/OleDb_Util.NoCOMWrappers.cs create mode 100644 src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs create mode 100644 src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.NoCOMWrappers.cs diff --git a/src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs new file mode 100644 index 00000000000000..be594070f28893 --- /dev/null +++ b/src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs @@ -0,0 +1,31 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Data.Common; +using System.Diagnostics; +using System.Globalization; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace System.Data.OleDb +{ + internal sealed partial class DBPropSet + { + private void SetLastErrorInfo(OleDbHResult lastErrorHr) + { + // note: OleDbHResult is actually a simple wrapper over HRESULT with OLEDB-specific codes + string message = string.Empty; + IntPtr pErrorInfo; + OleDbHResult errorInfoHr = UnsafeNativeMethods.GetErrorInfo(0, out pErrorInfo); // 0 - IErrorInfo exists, 1 - no IErrorInfo + if ((errorInfoHr == OleDbHResult.S_OK) && (pErrorInfo != IntPtr.Zero)) + { + using OleDbComWrappers.IErrorInfo errorInfo = (OleDbComWrappers.IErrorInfo)OleDbComWrappers.Instance + .GetOrCreateObjectForComInstance(pErrorInfo, CreateObjectFlags.UniqueInstance);; + 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 + } + lastErrorFromProvider = new COMException(message, (int)lastErrorHr); + } + } +} diff --git a/src/libraries/System.Data.OleDb/src/DbPropSet.NoCOMWrappers.cs b/src/libraries/System.Data.OleDb/src/DbPropSet.NoCOMWrappers.cs new file mode 100644 index 00000000000000..e8958298fddd6d --- /dev/null +++ b/src/libraries/System.Data.OleDb/src/DbPropSet.NoCOMWrappers.cs @@ -0,0 +1,29 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Data.Common; +using System.Diagnostics; +using System.Globalization; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace System.Data.OleDb +{ + internal sealed partial class DBPropSet + { + private void SetLastErrorInfo(OleDbHResult lastErrorHr) + { + // note: OleDbHResult is actually a simple wrapper over HRESULT with OLEDB-specific codes + UnsafeNativeMethods.IErrorInfo? errorInfo = null; + string message = string.Empty; + + 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 + } + lastErrorFromProvider = new COMException(message, (int)lastErrorHr); + } + } +} diff --git a/src/libraries/System.Data.OleDb/src/DbPropSet.cs b/src/libraries/System.Data.OleDb/src/DbPropSet.cs index 756c4612c3f1f7..20bac1b0ab1de0 100644 --- a/src/libraries/System.Data.OleDb/src/DbPropSet.cs +++ b/src/libraries/System.Data.OleDb/src/DbPropSet.cs @@ -9,7 +9,7 @@ namespace System.Data.OleDb { - internal sealed class DBPropSet : SafeHandle + internal sealed partial class DBPropSet : SafeHandle { private readonly int propertySetCount; @@ -96,21 +96,6 @@ internal DBPropSet(UnsafeNativeMethods.ICommandProperties properties, PropertyID } } - private void SetLastErrorInfo(OleDbHResult lastErrorHr) - { - // note: OleDbHResult is actually a simple wrapper over HRESULT with OLEDB-specific codes - UnsafeNativeMethods.IErrorInfo? errorInfo = null; - string message = string.Empty; - - 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 - } - lastErrorFromProvider = new COMException(message, (int)lastErrorHr); - } - public override bool IsInvalid { get 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 5386e4bd294fcc..6e4daea51ae81e 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 @@ -92,4 +68,4 @@ M:System.Data.OleDb.OleDbMetaDataFactory.GetDataSourceInformationTable(System.Data.OleDb.OleDbConnection,System.Data.OleDb.OleDbConnectionInternal) - \ 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..c4bb1e6dbc5fe1 --- /dev/null +++ b/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs @@ -0,0 +1,108 @@ +// 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.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 class OleDbComWrappers : ComWrappers + { + private const int S_OK = (int)Interop.HRESULT.S_OK; + + 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 = IErrorInfo.IID; + 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(); + } + + internal interface IErrorInfo + { + static readonly Guid IID = new Guid(0x1CF2B120, 0x547D, 0x101B, 0x8E, 0xBB, 0x65, 0x08, 0x00, 0x2B, 0x2B, 0xD1, 0x19); + + System.Data.OleDb.OleDbHResult GetSource(out string source); + + System.Data.OleDb.OleDbHResult GetDescription(out string description); + } + + private class ErrorInfoWrapper : IErrorInfo + { + private readonly IntPtr _wrappedInstance; + + public PictureWrapper(IntPtr wrappedInstance) + { + _wrappedInstance = wrappedInstance; + } + + public void Dispose() + { + Marshal.Release(_wrappedInstance); + } + + public unsafe System.Data.OleDb.OleDbHResult GetSource(out string source) + { + IntPtr pSource; + int errorCode = ((delegate* unmanaged)(*(*(void***)_wrappedInstance + 4 /* IErrorInfo.GetSource slot */))) + (_wrappedInstance, &pSource); + if (pSource == IntPtr.Zero) + { + source = null; + } + else + { + source = Marshal.PtrToStringBSTR(pSource); + } + + return (System.Data.OleDb.OleDbHResult)errorCode; + } + + public unsafe System.Data.OleDb.OleDbHResult GetDescription(out string description) + { + IntPtr pDescription; + int errorCode = ((delegate* unmanaged)(*(*(void***)_wrappedInstance + 5 /* IErrorInfo.GetDescription slot */))) + (_wrappedInstance, &pDescription); + if (pDescription == IntPtr.Zero) + { + description = null; + } + else + { + description = Marshal.PtrToStringBSTR(pDescription); + } + + return (System.Data.OleDb.OleDbHResult)errorCode; + } + } + + } +} diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs new file mode 100644 index 00000000000000..021f38467d6701 --- /dev/null +++ b/src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs @@ -0,0 +1,99 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.ComponentModel; +using System.Data.Common; +using System.Data.ProviderBase; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Runtime.InteropServices; +using System.Text; + +namespace System.Data.OleDb +{ + using SysTx = Transactions; + + public sealed partial class OleDbConnection + { + internal static Exception? ProcessResults(OleDbHResult hresult, OleDbConnection? connection, object? src) + { + if ((0 <= (int)hresult) && ((null == connection) || (null == connection.Events[EventInfoMessage]))) + { + SafeNativeMethods.Wrapper.ClearErrorInfo(); + return null; + } + + // ErrorInfo object is to be checked regardless the hresult returned by the function called + Exception? e = null; + IntPtr pErrorInfo; + OleDbHResult hr = UnsafeNativeMethods.GetErrorInfo(0, out pErrorInfo); // 0 - IErrorInfo exists, 1 - no IErrorInfo + if ((OleDbHResult.S_OK == hr) && (null != errorInfo)) + { + using OleDbComWrappers.IErrorInfo errorInfo = (OleDbComWrappers.IErrorInfo)OleDbComWrappers.Instance + .GetOrCreateObjectForComInstance(pErrorInfo, CreateObjectFlags.UniqueInstance);; + if (hresult < 0) + { + // 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); + } + } + else if (0 < hresult) + { + // @devnote: OnInfoMessage with no ErrorInfo + } + else if ((int)hresult < 0) + { + e = ODB.NoErrorInformation((null != connection) ? connection.Provider : null, hresult, null); // OleDbException + + ResetState(connection); + } + if (null != e) + { + ADP.TraceExceptionAsReturnValue(e); + } + return e; + } + + internal void OnInfoMessage(OleDbComWrappers.IErrorInfo errorInfo, OleDbHResult errorCode) + { + OleDbInfoMessageEventHandler? handler = (OleDbInfoMessageEventHandler?)Events[EventInfoMessage]; + if (null != handler) + { + try + { + OleDbException exception = OleDbException.CreateException(errorInfo, errorCode, null); + OleDbInfoMessageEventArgs e = new OleDbInfoMessageEventArgs(exception); + handler(this, e); + } + catch (Exception e) + { // eat the exception + // UNDONE - should not be catching all exceptions!!! + if (!ADP.IsCatchableOrSecurityExceptionType(e)) + { + throw; + } + + ADP.TraceExceptionWithoutRethrow(e); + } + } + } + } +} diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnection.NoCOMWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbConnection.NoCOMWrappers.cs new file mode 100644 index 00000000000000..01c411375064ca --- /dev/null +++ b/src/libraries/System.Data.OleDb/src/OleDbConnection.NoCOMWrappers.cs @@ -0,0 +1,101 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.ComponentModel; +using System.Data.Common; +using System.Data.ProviderBase; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Runtime.InteropServices; +using System.Text; + +namespace System.Data.OleDb +{ + using SysTx = Transactions; + + public sealed partial class OleDbConnection + { + internal static Exception? ProcessResults(OleDbHResult hresult, OleDbConnection? connection, object? src) + { + if ((0 <= (int)hresult) && ((null == connection) || (null == connection.Events[EventInfoMessage]))) + { + SafeNativeMethods.Wrapper.ClearErrorInfo(); + return null; + } + + // ErrorInfo object is to be checked regardless the hresult returned by the function called + Exception? e = null; + UnsafeNativeMethods.IErrorInfo? errorInfo = null; + OleDbHResult hr = UnsafeNativeMethods.GetErrorInfo(0, out errorInfo); // 0 - IErrorInfo exists, 1 - no IErrorInfo + if ((OleDbHResult.S_OK == hr) && (null != errorInfo)) + { + if (hresult < 0) + { + // 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); + } + else + { + } + Marshal.ReleaseComObject(errorInfo); + } + else if (0 < hresult) + { + // @devnote: OnInfoMessage with no ErrorInfo + } + else if ((int)hresult < 0) + { + e = ODB.NoErrorInformation((null != connection) ? connection.Provider : null, hresult, null); // OleDbException + + ResetState(connection); + } + if (null != e) + { + ADP.TraceExceptionAsReturnValue(e); + } + return e; + } + + internal void OnInfoMessage(UnsafeNativeMethods.IErrorInfo errorInfo, OleDbHResult errorCode) + { + OleDbInfoMessageEventHandler? handler = (OleDbInfoMessageEventHandler?)Events[EventInfoMessage]; + if (null != handler) + { + try + { + OleDbException exception = OleDbException.CreateException(errorInfo, errorCode, null); + OleDbInfoMessageEventArgs e = new OleDbInfoMessageEventArgs(exception); + handler(this, e); + } + catch (Exception e) + { // eat the exception + // UNDONE - should not be catching all exceptions!!! + if (!ADP.IsCatchableOrSecurityExceptionType(e)) + { + throw; + } + + ADP.TraceExceptionWithoutRethrow(e); + } + } + } + } +} diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnection.cs b/src/libraries/System.Data.OleDb/src/OleDbConnection.cs index 6417087aa62302..c9a1bcd39325f9 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbConnection.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbConnection.cs @@ -488,30 +488,6 @@ internal bool HasLiveReader(OleDbCommand cmd) return result; } - internal void OnInfoMessage(UnsafeNativeMethods.IErrorInfo errorInfo, OleDbHResult errorCode) - { - OleDbInfoMessageEventHandler? handler = (OleDbInfoMessageEventHandler?)Events[EventInfoMessage]; - if (null != handler) - { - try - { - OleDbException exception = OleDbException.CreateException(errorInfo, errorCode, null); - OleDbInfoMessageEventArgs e = new OleDbInfoMessageEventArgs(exception); - handler(this, e); - } - catch (Exception e) - { // eat the exception - // UNDONE - should not be catching all exceptions!!! - if (!ADP.IsCatchableOrSecurityExceptionType(e)) - { - throw; - } - - ADP.TraceExceptionWithoutRethrow(e); - } - } - } - public override void Open() { InnerConnection.OpenConnection(this, ConnectionFactory); @@ -573,64 +549,6 @@ internal bool SupportSchemaRowset(Guid schema) return GetOpenConnection().ValidateTransaction(transaction, method); } - internal static Exception? ProcessResults(OleDbHResult hresult, OleDbConnection? connection, object? src) - { - if ((0 <= (int)hresult) && ((null == connection) || (null == connection.Events[EventInfoMessage]))) - { - SafeNativeMethods.Wrapper.ClearErrorInfo(); - return null; - } - - // ErrorInfo object is to be checked regardless the hresult returned by the function called - Exception? e = null; - UnsafeNativeMethods.IErrorInfo? errorInfo = null; - OleDbHResult hr = UnsafeNativeMethods.GetErrorInfo(0, out errorInfo); // 0 - IErrorInfo exists, 1 - no IErrorInfo - if ((OleDbHResult.S_OK == hr) && (null != errorInfo)) - { - if (hresult < 0) - { - // 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); - } - else - { - } - Marshal.ReleaseComObject(errorInfo); - } - else if (0 < hresult) - { - // @devnote: OnInfoMessage with no ErrorInfo - } - else if ((int)hresult < 0) - { - e = ODB.NoErrorInformation((null != connection) ? connection.Provider : null, hresult, null); // OleDbException - - ResetState(connection); - } - if (null != e) - { - ADP.TraceExceptionAsReturnValue(e); - } - return e; - } - // @devnote: should be multithread safe public static void ReleaseObjectPool() { diff --git a/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.COMWrappers.cs new file mode 100644 index 00000000000000..d3c639c521a609 --- /dev/null +++ b/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.COMWrappers.cs @@ -0,0 +1,154 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.ComponentModel; +using System.Data.Common; +using System.Diagnostics; +using System.Runtime.InteropServices; + +namespace System.Data.OleDb +{ + public sealed partial class OleDbDataAdapter + { + private int FillFromADODB(object data, object adodb, string? srcTable, bool multipleResults) + { + Debug.Assert(null != data, "FillFromADODB: null data object"); + Debug.Assert(null != adodb, "FillFromADODB: null ADODB"); + Debug.Assert(!(adodb is DataTable), "call Fill( (DataTable) value)"); + Debug.Assert(!(adodb is DataSet), "call Fill( (DataSet) value)"); + + /* + IntPtr adodbptr = ADP.PtrZero; + try { // generate a new COM Callable Wrapper around the user object so they can't ReleaseComObject on us. + adodbptr = Marshal.GetIUnknownForObject(adodb); + adodb = System.Runtime.Remoting.Services.EnterpriseServicesHelper.WrapIUnknownWithComObject(adodbptr); + } + finally { + if (ADP.PtrZero != adodbptr) { + Marshal.Release(adodbptr); + } + } + */ + + bool closeRecordset = multipleResults; + UnsafeNativeMethods.ADORecordsetConstruction? recordset = (adodb as UnsafeNativeMethods.ADORecordsetConstruction); + UnsafeNativeMethods.ADORecordConstruction? record = null; + + if (null != recordset) + { + if (multipleResults) + { + // The NextRecordset method is not available on a disconnected Recordset object, where ActiveConnection has been set to NULL + object activeConnection; + activeConnection = ((UnsafeNativeMethods.Recordset15)adodb).get_ActiveConnection(); + + if (null == activeConnection) + { + multipleResults = false; + } + } + } + else + { + record = (adodb as UnsafeNativeMethods.ADORecordConstruction); + + if (null != record) + { + multipleResults = false; // IRow implies CommandBehavior.SingleRow which implies CommandBehavior.SingleResult + } + } + // else throw ODB.Fill_NotADODB("adodb"); /* throw later, less code here*/ + + int results = 0; + if (null != recordset) + { + int resultCount = 0; + bool incrementResultCount; + object[] value = new object[1]; + + do + { + string? tmp = null; + if (data is DataSet) + { + tmp = GetSourceTableName(srcTable!, resultCount); + } + results += FillFromRecordset(data, recordset, tmp, out incrementResultCount); + + if (multipleResults) + { + value[0] = DBNull.Value; + + object recordsAffected; + object nextresult; + OleDbHResult hr = ((UnsafeNativeMethods.Recordset15)adodb).NextRecordset(out recordsAffected, out nextresult); + + if (0 > hr) + { + // Current provider does not support returning multiple recordsets from a single execution. + if (ODB.ADODB_NextResultError != (int)hr) + { + IntPtr pErrorInfo; + UnsafeNativeMethods.GetErrorInfo(0, out pErrorInfo); + + string message = string.Empty; + throw new COMException(message, (int)hr); + } + break; + } + adodb = nextresult; + if (null != adodb) + { + recordset = (UnsafeNativeMethods.ADORecordsetConstruction)adodb; + + if (incrementResultCount) + { + resultCount++; + } + continue; + } + } + break; + } while (null != recordset); + + if ((null != recordset) && (closeRecordset || (null == adodb))) + { + FillClose(true, recordset); + } + } + else if (null != record) + { + results = FillFromRecord(data, record, srcTable!); + if (closeRecordset) + { + FillClose(false, record); + } + } + else + { + throw ODB.Fill_NotADODB("adodb"); + } + return results; + } + + private void FillClose(bool isrecordset, object value) + { + OleDbHResult hr; + if (isrecordset) + { + hr = ((UnsafeNativeMethods.Recordset15)value).Close(); + } + else + { + hr = ((UnsafeNativeMethods._ADORecord)value).Close(); + } + if ((0 < (int)hr) && (ODB.ADODB_AlreadyClosedError != (int)hr)) + { + IntPtr pErrorInfo; + UnsafeNativeMethods.GetErrorInfo(0, out pErrorInfo); + string message = string.Empty; + throw new COMException(message, (int)hr); + } + } + } +} diff --git a/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.NoCOMWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.NoCOMWrappers.cs new file mode 100644 index 00000000000000..d51f2915475b13 --- /dev/null +++ b/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.NoCOMWrappers.cs @@ -0,0 +1,154 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.ComponentModel; +using System.Data.Common; +using System.Diagnostics; +using System.Runtime.InteropServices; + +namespace System.Data.OleDb +{ + public sealed partial class OleDbDataAdapter + { + private int FillFromADODB(object data, object adodb, string? srcTable, bool multipleResults) + { + Debug.Assert(null != data, "FillFromADODB: null data object"); + Debug.Assert(null != adodb, "FillFromADODB: null ADODB"); + Debug.Assert(!(adodb is DataTable), "call Fill( (DataTable) value)"); + Debug.Assert(!(adodb is DataSet), "call Fill( (DataSet) value)"); + + /* + IntPtr adodbptr = ADP.PtrZero; + try { // generate a new COM Callable Wrapper around the user object so they can't ReleaseComObject on us. + adodbptr = Marshal.GetIUnknownForObject(adodb); + adodb = System.Runtime.Remoting.Services.EnterpriseServicesHelper.WrapIUnknownWithComObject(adodbptr); + } + finally { + if (ADP.PtrZero != adodbptr) { + Marshal.Release(adodbptr); + } + } + */ + + bool closeRecordset = multipleResults; + UnsafeNativeMethods.ADORecordsetConstruction? recordset = (adodb as UnsafeNativeMethods.ADORecordsetConstruction); + UnsafeNativeMethods.ADORecordConstruction? record = null; + + if (null != recordset) + { + if (multipleResults) + { + // The NextRecordset method is not available on a disconnected Recordset object, where ActiveConnection has been set to NULL + object activeConnection; + activeConnection = ((UnsafeNativeMethods.Recordset15)adodb).get_ActiveConnection(); + + if (null == activeConnection) + { + multipleResults = false; + } + } + } + else + { + record = (adodb as UnsafeNativeMethods.ADORecordConstruction); + + if (null != record) + { + multipleResults = false; // IRow implies CommandBehavior.SingleRow which implies CommandBehavior.SingleResult + } + } + // else throw ODB.Fill_NotADODB("adodb"); /* throw later, less code here*/ + + int results = 0; + if (null != recordset) + { + int resultCount = 0; + bool incrementResultCount; + object[] value = new object[1]; + + do + { + string? tmp = null; + if (data is DataSet) + { + tmp = GetSourceTableName(srcTable!, resultCount); + } + results += FillFromRecordset(data, recordset, tmp, out incrementResultCount); + + if (multipleResults) + { + value[0] = DBNull.Value; + + object recordsAffected; + object nextresult; + OleDbHResult hr = ((UnsafeNativeMethods.Recordset15)adodb).NextRecordset(out recordsAffected, out nextresult); + + if (0 > hr) + { + // 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); + + string message = string.Empty; + throw new COMException(message, (int)hr); + } + break; + } + adodb = nextresult; + if (null != adodb) + { + recordset = (UnsafeNativeMethods.ADORecordsetConstruction)adodb; + + if (incrementResultCount) + { + resultCount++; + } + continue; + } + } + break; + } while (null != recordset); + + if ((null != recordset) && (closeRecordset || (null == adodb))) + { + FillClose(true, recordset); + } + } + else if (null != record) + { + results = FillFromRecord(data, record, srcTable!); + if (closeRecordset) + { + FillClose(false, record); + } + } + else + { + throw ODB.Fill_NotADODB("adodb"); + } + return results; + } + + private void FillClose(bool isrecordset, object value) + { + OleDbHResult hr; + if (isrecordset) + { + hr = ((UnsafeNativeMethods.Recordset15)value).Close(); + } + else + { + hr = ((UnsafeNativeMethods._ADORecord)value).Close(); + } + if ((0 < (int)hr) && (ODB.ADODB_AlreadyClosedError != (int)hr)) + { + UnsafeNativeMethods.IErrorInfo? errorInfo = null; + UnsafeNativeMethods.GetErrorInfo(0, out errorInfo); + string message = string.Empty; + throw new COMException(message, (int)hr); + } + } + } +} diff --git a/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.cs b/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.cs index a9aa7d1d56b334..2462a9e80d7b1a 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.cs @@ -10,7 +10,7 @@ namespace System.Data.OleDb { [Designer("Microsoft.VSDesigner.Data.VS.OleDbDataAdapterDesigner, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] [ToolboxItem("Microsoft.VSDesigner.Data.VS.OleDbDataAdapterToolboxItem, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] - public sealed class OleDbDataAdapter : DbDataAdapter, IDbDataAdapter, ICloneable + public sealed partial class OleDbDataAdapter : DbDataAdapter, IDbDataAdapter, ICloneable { private static readonly object EventRowUpdated = new object(); private static readonly object EventRowUpdating = new object(); @@ -181,127 +181,6 @@ public int Fill(DataSet dataSet, object ADODBRecordSet, string srcTable) return FillFromADODB((object)dataSet, ADODBRecordSet, srcTable, true); } - private int FillFromADODB(object data, object adodb, string? srcTable, bool multipleResults) - { - Debug.Assert(null != data, "FillFromADODB: null data object"); - Debug.Assert(null != adodb, "FillFromADODB: null ADODB"); - Debug.Assert(!(adodb is DataTable), "call Fill( (DataTable) value)"); - Debug.Assert(!(adodb is DataSet), "call Fill( (DataSet) value)"); - - /* - IntPtr adodbptr = ADP.PtrZero; - try { // generate a new COM Callable Wrapper around the user object so they can't ReleaseComObject on us. - adodbptr = Marshal.GetIUnknownForObject(adodb); - adodb = System.Runtime.Remoting.Services.EnterpriseServicesHelper.WrapIUnknownWithComObject(adodbptr); - } - finally { - if (ADP.PtrZero != adodbptr) { - Marshal.Release(adodbptr); - } - } - */ - - bool closeRecordset = multipleResults; - UnsafeNativeMethods.ADORecordsetConstruction? recordset = (adodb as UnsafeNativeMethods.ADORecordsetConstruction); - UnsafeNativeMethods.ADORecordConstruction? record = null; - - if (null != recordset) - { - if (multipleResults) - { - // The NextRecordset method is not available on a disconnected Recordset object, where ActiveConnection has been set to NULL - object activeConnection; - activeConnection = ((UnsafeNativeMethods.Recordset15)adodb).get_ActiveConnection(); - - if (null == activeConnection) - { - multipleResults = false; - } - } - } - else - { - record = (adodb as UnsafeNativeMethods.ADORecordConstruction); - - if (null != record) - { - multipleResults = false; // IRow implies CommandBehavior.SingleRow which implies CommandBehavior.SingleResult - } - } - // else throw ODB.Fill_NotADODB("adodb"); /* throw later, less code here*/ - - int results = 0; - if (null != recordset) - { - int resultCount = 0; - bool incrementResultCount; - object[] value = new object[1]; - - do - { - string? tmp = null; - if (data is DataSet) - { - tmp = GetSourceTableName(srcTable!, resultCount); - } - results += FillFromRecordset(data, recordset, tmp, out incrementResultCount); - - if (multipleResults) - { - value[0] = DBNull.Value; - - object recordsAffected; - object nextresult; - OleDbHResult hr = ((UnsafeNativeMethods.Recordset15)adodb).NextRecordset(out recordsAffected, out nextresult); - - if (0 > hr) - { - // 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); - - string message = string.Empty; - throw new COMException(message, (int)hr); - } - break; - } - adodb = nextresult; - if (null != adodb) - { - recordset = (UnsafeNativeMethods.ADORecordsetConstruction)adodb; - - if (incrementResultCount) - { - resultCount++; - } - continue; - } - } - break; - } while (null != recordset); - - if ((null != recordset) && (closeRecordset || (null == adodb))) - { - FillClose(true, recordset); - } - } - else if (null != record) - { - results = FillFromRecord(data, record, srcTable!); - if (closeRecordset) - { - FillClose(false, record); - } - } - else - { - throw ODB.Fill_NotADODB("adodb"); - } - return results; - } - //protected override int Fill(DataTable dataTable, IDataReader dataReader) { // return base.Fill(dataTable, dataReader); //} @@ -417,26 +296,6 @@ private int FillFromRecord(object data, UnsafeNativeMethods.ADORecordConstructio return 0; } - private void FillClose(bool isrecordset, object value) - { - OleDbHResult hr; - if (isrecordset) - { - hr = ((UnsafeNativeMethods.Recordset15)value).Close(); - } - else - { - hr = ((UnsafeNativeMethods._ADORecord)value).Close(); - } - if ((0 < (int)hr) && (ODB.ADODB_AlreadyClosedError != (int)hr)) - { - UnsafeNativeMethods.IErrorInfo? errorInfo = null; - UnsafeNativeMethods.GetErrorInfo(0, out errorInfo); - string message = string.Empty; - throw new COMException(message, (int)hr); - } - } - protected override void OnRowUpdated(RowUpdatedEventArgs value) { OleDbRowUpdatedEventHandler? handler = (OleDbRowUpdatedEventHandler?)Events[EventRowUpdated]; diff --git a/src/libraries/System.Data.OleDb/src/OleDbException.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbException.COMWrappers.cs new file mode 100644 index 00000000000000..9d48a0be85793b --- /dev/null +++ b/src/libraries/System.Data.OleDb/src/OleDbException.COMWrappers.cs @@ -0,0 +1,60 @@ +// 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.Generic; +using System.ComponentModel; +using System.Data.Common; +using System.Diagnostics; +using System.Globalization; +using System.Runtime.Serialization; +using System.Text; + +namespace System.Data.OleDb +{ + public sealed partial class OleDbException + { + internal static OleDbException CreateException(OleDbComWrappers.IErrorInfo errorInfo, OleDbHResult errorCode, Exception? inner) + { + OleDbErrorCollection errors = new OleDbErrorCollection(errorInfo); + string? message = null; + string? source = null; + OleDbHResult hr = 0; + + if (null != errorInfo) + { + hr = errorInfo.GetDescription(out message); + + hr = errorInfo.GetSource(out source); + } + + int count = errors.Count; + if (0 < errors.Count) + { + StringBuilder builder = new StringBuilder(); + + if ((null != message) && (message != errors[0].Message)) + { + builder.Append(message.TrimEnd(ODB.ErrorTrimCharacters)); + if (1 < count) + { + builder.Append(Environment.NewLine); + } + } + for (int i = 0; i < count; ++i) + { + if (0 < i) + { + builder.Append(Environment.NewLine); + } + builder.Append(errors[i].Message.TrimEnd(ODB.ErrorTrimCharacters)); + } + message = builder.ToString(); + } + if (ADP.IsEmpty(message)) + { + message = ODB.NoErrorMessage(errorCode); + } + return new OleDbException(message, inner, source, errorCode, errors); + } + } +} diff --git a/src/libraries/System.Data.OleDb/src/OleDbException.NoCOMWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbException.NoCOMWrappers.cs new file mode 100644 index 00000000000000..7c56157a917098 --- /dev/null +++ b/src/libraries/System.Data.OleDb/src/OleDbException.NoCOMWrappers.cs @@ -0,0 +1,60 @@ +// 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.Generic; +using System.ComponentModel; +using System.Data.Common; +using System.Diagnostics; +using System.Globalization; +using System.Runtime.Serialization; +using System.Text; + +namespace System.Data.OleDb +{ + public sealed partial class OleDbException + { + internal static OleDbException CreateException(UnsafeNativeMethods.IErrorInfo errorInfo, OleDbHResult errorCode, Exception? inner) + { + OleDbErrorCollection errors = new OleDbErrorCollection(errorInfo); + string? message = null; + string? source = null; + OleDbHResult hr = 0; + + if (null != errorInfo) + { + hr = errorInfo.GetDescription(out message); + + hr = errorInfo.GetSource(out source); + } + + int count = errors.Count; + if (0 < errors.Count) + { + StringBuilder builder = new StringBuilder(); + + if ((null != message) && (message != errors[0].Message)) + { + builder.Append(message.TrimEnd(ODB.ErrorTrimCharacters)); + if (1 < count) + { + builder.Append(Environment.NewLine); + } + } + for (int i = 0; i < count; ++i) + { + if (0 < i) + { + builder.Append(Environment.NewLine); + } + builder.Append(errors[i].Message.TrimEnd(ODB.ErrorTrimCharacters)); + } + message = builder.ToString(); + } + if (ADP.IsEmpty(message)) + { + message = ODB.NoErrorMessage(errorCode); + } + return new OleDbException(message, inner, source, errorCode, errors); + } + } +} diff --git a/src/libraries/System.Data.OleDb/src/OleDbException.cs b/src/libraries/System.Data.OleDb/src/OleDbException.cs index 410e9cb33da820..b47ec58f9991c8 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbException.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbException.cs @@ -11,7 +11,7 @@ namespace System.Data.OleDb { - public sealed class OleDbException : System.Data.Common.DbException + public sealed partial class OleDbException : System.Data.Common.DbException { private readonly OleDbErrorCollection oledbErrors; @@ -64,50 +64,6 @@ public OleDbErrorCollection Errors } } - internal static OleDbException CreateException(UnsafeNativeMethods.IErrorInfo errorInfo, OleDbHResult errorCode, Exception? inner) - { - OleDbErrorCollection errors = new OleDbErrorCollection(errorInfo); - string? message = null; - string? source = null; - OleDbHResult hr = 0; - - if (null != errorInfo) - { - hr = errorInfo.GetDescription(out message); - - hr = errorInfo.GetSource(out source); - } - - int count = errors.Count; - if (0 < errors.Count) - { - StringBuilder builder = new StringBuilder(); - - if ((null != message) && (message != errors[0].Message)) - { - builder.Append(message.TrimEnd(ODB.ErrorTrimCharacters)); - if (1 < count) - { - builder.Append(Environment.NewLine); - } - } - for (int i = 0; i < count; ++i) - { - if (0 < i) - { - builder.Append(Environment.NewLine); - } - builder.Append(errors[i].Message.TrimEnd(ODB.ErrorTrimCharacters)); - } - message = builder.ToString(); - } - if (ADP.IsEmpty(message)) - { - message = ODB.NoErrorMessage(errorCode); - } - return new OleDbException(message, inner, source, errorCode, errors); - } - internal static OleDbException CombineExceptions(List exceptions) { Debug.Assert(0 < exceptions.Count, "missing exceptions"); diff --git a/src/libraries/System.Data.OleDb/src/OleDb_Util.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDb_Util.COMWrappers.cs new file mode 100644 index 00000000000000..e73512ad0760b2 --- /dev/null +++ b/src/libraries/System.Data.OleDb/src/OleDb_Util.COMWrappers.cs @@ -0,0 +1,29 @@ +// 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.Data.Common; +using System.Diagnostics; +using System.Globalization; +using System.Runtime.InteropServices; +using System.Text; + +namespace System.Data.OleDb +{ + internal static partial class ODB + { + internal static OleDbHResult GetErrorDescription(OleDbComWrappers.IErrorInfo errorInfo, OleDbHResult hresult, out string message) + { + OleDbHResult hr = errorInfo.GetDescription(out message); + if (((int)hr < 0) && ADP.IsEmpty(message)) + { + message = FailedGetDescription(hr) + Environment.NewLine + ODB.ELookup(hresult); + } + if (ADP.IsEmpty(message)) + { + message = ODB.ELookup(hresult); + } + return hr; + } + } +} diff --git a/src/libraries/System.Data.OleDb/src/OleDb_Util.NoCOMWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDb_Util.NoCOMWrappers.cs new file mode 100644 index 00000000000000..7dea23cd64c5ec --- /dev/null +++ b/src/libraries/System.Data.OleDb/src/OleDb_Util.NoCOMWrappers.cs @@ -0,0 +1,29 @@ +// 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.Data.Common; +using System.Diagnostics; +using System.Globalization; +using System.Runtime.InteropServices; +using System.Text; + +namespace System.Data.OleDb +{ + internal static partial class ODB + { + internal static OleDbHResult GetErrorDescription(UnsafeNativeMethods.IErrorInfo errorInfo, OleDbHResult hresult, out string message) + { + OleDbHResult hr = errorInfo.GetDescription(out message); + if (((int)hr < 0) && ADP.IsEmpty(message)) + { + message = FailedGetDescription(hr) + Environment.NewLine + ODB.ELookup(hresult); + } + if (ADP.IsEmpty(message)) + { + message = ODB.ELookup(hresult); + } + return hr; + } + } +} diff --git a/src/libraries/System.Data.OleDb/src/OleDb_Util.cs b/src/libraries/System.Data.OleDb/src/OleDb_Util.cs index b0a39dea96c734..e7ae36ccfb4254 100644 --- a/src/libraries/System.Data.OleDb/src/OleDb_Util.cs +++ b/src/libraries/System.Data.OleDb/src/OleDb_Util.cs @@ -10,7 +10,7 @@ namespace System.Data.OleDb { - internal static class ODB + internal static partial class ODB { // OleDbCommand internal static void CommandParameterStatus(StringBuilder builder, int index, DBStatus status) @@ -332,20 +332,6 @@ internal static InvalidOperationException DBBindingGetVector() return ADP.InvalidOperation(SR.Format(SR.OleDb_DBBindingGetVector)); } - internal static OleDbHResult GetErrorDescription(UnsafeNativeMethods.IErrorInfo errorInfo, OleDbHResult hresult, out string message) - { - OleDbHResult hr = errorInfo.GetDescription(out message); - if (((int)hr < 0) && ADP.IsEmpty(message)) - { - message = FailedGetDescription(hr) + Environment.NewLine + ODB.ELookup(hresult); - } - if (ADP.IsEmpty(message)) - { - message = ODB.ELookup(hresult); - } - return hr; - } - // OleDbEnumerator internal static ArgumentException ISourcesRowsetNotSupported() { 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 4140b529697a18..1aee01921331c9 100644 --- a/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj +++ b/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj @@ -1,7 +1,7 @@ true - netstandard2.0-windows;netstandard2.0;net461-windows + $(NetCoreAppCurrent)-windows;netstandard2.0-windows;netstandard2.0;net461-windows true enable @@ -9,7 +9,7 @@ true SR.PlatformNotSupported_OleDb - $(NoWarn);CS0618 + $(NoWarn);CS0618 + + + + + + + + + + + + + + + + + System.Data.OleDb.OleDbMetaData.xml diff --git a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs new file mode 100644 index 00000000000000..54a4ac4ae84ee8 --- /dev/null +++ b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.InteropServices; + +namespace System.Data.Common +{ + internal static partial class UnsafeNativeMethods + { + // + // Oleaut32 + // + + [DllImport(Interop.Libraries.OleAut32, CharSet = CharSet.Unicode, PreserveSig = true)] + internal static extern System.Data.OleDb.OleDbHResult GetErrorInfo( + [In] int dwReserved, + [Out] out System.IntPtr ppIErrorInfo); + } +} diff --git a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.NoCOMWrappers.cs b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.NoCOMWrappers.cs new file mode 100644 index 00000000000000..b88921b19532dc --- /dev/null +++ b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.NoCOMWrappers.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.InteropServices; + +namespace System.Data.Common +{ + internal static partial class UnsafeNativeMethods + { + // + // Oleaut32 + // + + [DllImport(Interop.Libraries.OleAut32, CharSet = CharSet.Unicode, PreserveSig = true)] + internal static extern System.Data.OleDb.OleDbHResult GetErrorInfo( + [In] int dwReserved, + [Out, MarshalAs(UnmanagedType.Interface)] out IErrorInfo ppIErrorInfo); + } +} diff --git a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.cs b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.cs index b7be99491c17a3..4415aa87ab1e25 100644 --- a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.cs +++ b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.cs @@ -8,17 +8,12 @@ namespace System.Data.Common { - internal static class UnsafeNativeMethods + internal static partial class UnsafeNativeMethods { // // Oleaut32 // - [DllImport(Interop.Libraries.OleAut32, CharSet = CharSet.Unicode, PreserveSig = true)] - internal static extern System.Data.OleDb.OleDbHResult GetErrorInfo( - [In] int dwReserved, - [Out, MarshalAs(UnmanagedType.Interface)] out IErrorInfo ppIErrorInfo); - [Guid("00000567-0000-0010-8000-00AA006D2EA4"), InterfaceType(ComInterfaceType.InterfaceIsDual), ComImport, SuppressUnmanagedCodeSecurity] internal interface ADORecordConstruction { From 68ba34ebb547de9ef058b931eb2d678185a2089b Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Tue, 29 Jun 2021 11:22:13 +0600 Subject: [PATCH 02/36] Update src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs Co-authored-by: Aaron Robinson --- src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs index c4bb1e6dbc5fe1..cb83e4a0558c3c 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs @@ -59,7 +59,7 @@ private class ErrorInfoWrapper : IErrorInfo { private readonly IntPtr _wrappedInstance; - public PictureWrapper(IntPtr wrappedInstance) + public ErrorInfoWrapper(IntPtr wrappedInstance) { _wrappedInstance = wrappedInstance; } From 2e0441c01c59d01ef04b2d735a858e651b16da05 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Tue, 29 Jun 2021 11:22:39 +0600 Subject: [PATCH 03/36] Update src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs Co-authored-by: Aaron Robinson --- src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs index cb83e4a0558c3c..60de2735321405 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs @@ -71,7 +71,7 @@ public void Dispose() public unsafe System.Data.OleDb.OleDbHResult GetSource(out string source) { - IntPtr pSource; + IntPtr pSource = IntPtr.Zero; int errorCode = ((delegate* unmanaged)(*(*(void***)_wrappedInstance + 4 /* IErrorInfo.GetSource slot */))) (_wrappedInstance, &pSource); if (pSource == IntPtr.Zero) From 2a753acfb448c86e9db2996688504dca7a68cbed Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Tue, 29 Jun 2021 13:38:42 +0600 Subject: [PATCH 04/36] Apply PR recommendations --- .../src/DbPropSet.COMWrappers.cs | 2 +- .../src/OleDbConnection.COMWrappers.cs | 2 +- .../src/OleDbDataAdapter.COMWrappers.cs | 154 ------------------ .../src/OleDbDataAdapter.NoCOMWrappers.cs | 154 ------------------ .../System.Data.OleDb/src/OleDbDataAdapter.cs | 138 ++++++++++++++++ .../src/System.Data.OleDb.csproj | 2 - .../src/UnsafeNativeMethods.COMWrappers.cs | 6 +- 7 files changed, 143 insertions(+), 315 deletions(-) delete mode 100644 src/libraries/System.Data.OleDb/src/OleDbDataAdapter.COMWrappers.cs delete mode 100644 src/libraries/System.Data.OleDb/src/OleDbDataAdapter.NoCOMWrappers.cs diff --git a/src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs index be594070f28893..b7b6359bee4918 100644 --- a/src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs @@ -17,7 +17,7 @@ private void SetLastErrorInfo(OleDbHResult lastErrorHr) // note: OleDbHResult is actually a simple wrapper over HRESULT with OLEDB-specific codes string message = string.Empty; IntPtr pErrorInfo; - OleDbHResult errorInfoHr = UnsafeNativeMethods.GetErrorInfo(0, out pErrorInfo); // 0 - IErrorInfo exists, 1 - no IErrorInfo + OleDbHResult errorInfoHr = UnsafeNativeMethods.GetErrorInfo(0, &pErrorInfo); // 0 - IErrorInfo exists, 1 - no IErrorInfo if ((errorInfoHr == OleDbHResult.S_OK) && (pErrorInfo != IntPtr.Zero)) { using OleDbComWrappers.IErrorInfo errorInfo = (OleDbComWrappers.IErrorInfo)OleDbComWrappers.Instance diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs index 021f38467d6701..bb0c79f9e2130a 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs @@ -27,7 +27,7 @@ public sealed partial class OleDbConnection // ErrorInfo object is to be checked regardless the hresult returned by the function called Exception? e = null; IntPtr pErrorInfo; - OleDbHResult hr = UnsafeNativeMethods.GetErrorInfo(0, out pErrorInfo); // 0 - IErrorInfo exists, 1 - no IErrorInfo + OleDbHResult hr = UnsafeNativeMethods.GetErrorInfo(0, &pErrorInfo); // 0 - IErrorInfo exists, 1 - no IErrorInfo if ((OleDbHResult.S_OK == hr) && (null != errorInfo)) { using OleDbComWrappers.IErrorInfo errorInfo = (OleDbComWrappers.IErrorInfo)OleDbComWrappers.Instance diff --git a/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.COMWrappers.cs deleted file mode 100644 index d3c639c521a609..00000000000000 --- a/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.COMWrappers.cs +++ /dev/null @@ -1,154 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; -using System.Data.Common; -using System.Diagnostics; -using System.Runtime.InteropServices; - -namespace System.Data.OleDb -{ - public sealed partial class OleDbDataAdapter - { - private int FillFromADODB(object data, object adodb, string? srcTable, bool multipleResults) - { - Debug.Assert(null != data, "FillFromADODB: null data object"); - Debug.Assert(null != adodb, "FillFromADODB: null ADODB"); - Debug.Assert(!(adodb is DataTable), "call Fill( (DataTable) value)"); - Debug.Assert(!(adodb is DataSet), "call Fill( (DataSet) value)"); - - /* - IntPtr adodbptr = ADP.PtrZero; - try { // generate a new COM Callable Wrapper around the user object so they can't ReleaseComObject on us. - adodbptr = Marshal.GetIUnknownForObject(adodb); - adodb = System.Runtime.Remoting.Services.EnterpriseServicesHelper.WrapIUnknownWithComObject(adodbptr); - } - finally { - if (ADP.PtrZero != adodbptr) { - Marshal.Release(adodbptr); - } - } - */ - - bool closeRecordset = multipleResults; - UnsafeNativeMethods.ADORecordsetConstruction? recordset = (adodb as UnsafeNativeMethods.ADORecordsetConstruction); - UnsafeNativeMethods.ADORecordConstruction? record = null; - - if (null != recordset) - { - if (multipleResults) - { - // The NextRecordset method is not available on a disconnected Recordset object, where ActiveConnection has been set to NULL - object activeConnection; - activeConnection = ((UnsafeNativeMethods.Recordset15)adodb).get_ActiveConnection(); - - if (null == activeConnection) - { - multipleResults = false; - } - } - } - else - { - record = (adodb as UnsafeNativeMethods.ADORecordConstruction); - - if (null != record) - { - multipleResults = false; // IRow implies CommandBehavior.SingleRow which implies CommandBehavior.SingleResult - } - } - // else throw ODB.Fill_NotADODB("adodb"); /* throw later, less code here*/ - - int results = 0; - if (null != recordset) - { - int resultCount = 0; - bool incrementResultCount; - object[] value = new object[1]; - - do - { - string? tmp = null; - if (data is DataSet) - { - tmp = GetSourceTableName(srcTable!, resultCount); - } - results += FillFromRecordset(data, recordset, tmp, out incrementResultCount); - - if (multipleResults) - { - value[0] = DBNull.Value; - - object recordsAffected; - object nextresult; - OleDbHResult hr = ((UnsafeNativeMethods.Recordset15)adodb).NextRecordset(out recordsAffected, out nextresult); - - if (0 > hr) - { - // Current provider does not support returning multiple recordsets from a single execution. - if (ODB.ADODB_NextResultError != (int)hr) - { - IntPtr pErrorInfo; - UnsafeNativeMethods.GetErrorInfo(0, out pErrorInfo); - - string message = string.Empty; - throw new COMException(message, (int)hr); - } - break; - } - adodb = nextresult; - if (null != adodb) - { - recordset = (UnsafeNativeMethods.ADORecordsetConstruction)adodb; - - if (incrementResultCount) - { - resultCount++; - } - continue; - } - } - break; - } while (null != recordset); - - if ((null != recordset) && (closeRecordset || (null == adodb))) - { - FillClose(true, recordset); - } - } - else if (null != record) - { - results = FillFromRecord(data, record, srcTable!); - if (closeRecordset) - { - FillClose(false, record); - } - } - else - { - throw ODB.Fill_NotADODB("adodb"); - } - return results; - } - - private void FillClose(bool isrecordset, object value) - { - OleDbHResult hr; - if (isrecordset) - { - hr = ((UnsafeNativeMethods.Recordset15)value).Close(); - } - else - { - hr = ((UnsafeNativeMethods._ADORecord)value).Close(); - } - if ((0 < (int)hr) && (ODB.ADODB_AlreadyClosedError != (int)hr)) - { - IntPtr pErrorInfo; - UnsafeNativeMethods.GetErrorInfo(0, out pErrorInfo); - string message = string.Empty; - throw new COMException(message, (int)hr); - } - } - } -} diff --git a/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.NoCOMWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.NoCOMWrappers.cs deleted file mode 100644 index d51f2915475b13..00000000000000 --- a/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.NoCOMWrappers.cs +++ /dev/null @@ -1,154 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; -using System.Data.Common; -using System.Diagnostics; -using System.Runtime.InteropServices; - -namespace System.Data.OleDb -{ - public sealed partial class OleDbDataAdapter - { - private int FillFromADODB(object data, object adodb, string? srcTable, bool multipleResults) - { - Debug.Assert(null != data, "FillFromADODB: null data object"); - Debug.Assert(null != adodb, "FillFromADODB: null ADODB"); - Debug.Assert(!(adodb is DataTable), "call Fill( (DataTable) value)"); - Debug.Assert(!(adodb is DataSet), "call Fill( (DataSet) value)"); - - /* - IntPtr adodbptr = ADP.PtrZero; - try { // generate a new COM Callable Wrapper around the user object so they can't ReleaseComObject on us. - adodbptr = Marshal.GetIUnknownForObject(adodb); - adodb = System.Runtime.Remoting.Services.EnterpriseServicesHelper.WrapIUnknownWithComObject(adodbptr); - } - finally { - if (ADP.PtrZero != adodbptr) { - Marshal.Release(adodbptr); - } - } - */ - - bool closeRecordset = multipleResults; - UnsafeNativeMethods.ADORecordsetConstruction? recordset = (adodb as UnsafeNativeMethods.ADORecordsetConstruction); - UnsafeNativeMethods.ADORecordConstruction? record = null; - - if (null != recordset) - { - if (multipleResults) - { - // The NextRecordset method is not available on a disconnected Recordset object, where ActiveConnection has been set to NULL - object activeConnection; - activeConnection = ((UnsafeNativeMethods.Recordset15)adodb).get_ActiveConnection(); - - if (null == activeConnection) - { - multipleResults = false; - } - } - } - else - { - record = (adodb as UnsafeNativeMethods.ADORecordConstruction); - - if (null != record) - { - multipleResults = false; // IRow implies CommandBehavior.SingleRow which implies CommandBehavior.SingleResult - } - } - // else throw ODB.Fill_NotADODB("adodb"); /* throw later, less code here*/ - - int results = 0; - if (null != recordset) - { - int resultCount = 0; - bool incrementResultCount; - object[] value = new object[1]; - - do - { - string? tmp = null; - if (data is DataSet) - { - tmp = GetSourceTableName(srcTable!, resultCount); - } - results += FillFromRecordset(data, recordset, tmp, out incrementResultCount); - - if (multipleResults) - { - value[0] = DBNull.Value; - - object recordsAffected; - object nextresult; - OleDbHResult hr = ((UnsafeNativeMethods.Recordset15)adodb).NextRecordset(out recordsAffected, out nextresult); - - if (0 > hr) - { - // 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); - - string message = string.Empty; - throw new COMException(message, (int)hr); - } - break; - } - adodb = nextresult; - if (null != adodb) - { - recordset = (UnsafeNativeMethods.ADORecordsetConstruction)adodb; - - if (incrementResultCount) - { - resultCount++; - } - continue; - } - } - break; - } while (null != recordset); - - if ((null != recordset) && (closeRecordset || (null == adodb))) - { - FillClose(true, recordset); - } - } - else if (null != record) - { - results = FillFromRecord(data, record, srcTable!); - if (closeRecordset) - { - FillClose(false, record); - } - } - else - { - throw ODB.Fill_NotADODB("adodb"); - } - return results; - } - - private void FillClose(bool isrecordset, object value) - { - OleDbHResult hr; - if (isrecordset) - { - hr = ((UnsafeNativeMethods.Recordset15)value).Close(); - } - else - { - hr = ((UnsafeNativeMethods._ADORecord)value).Close(); - } - if ((0 < (int)hr) && (ODB.ADODB_AlreadyClosedError != (int)hr)) - { - UnsafeNativeMethods.IErrorInfo? errorInfo = null; - UnsafeNativeMethods.GetErrorInfo(0, out errorInfo); - string message = string.Empty; - throw new COMException(message, (int)hr); - } - } - } -} diff --git a/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.cs b/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.cs index 2462a9e80d7b1a..23263a841a1d05 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.cs @@ -180,11 +180,149 @@ public int Fill(DataSet dataSet, object ADODBRecordSet, string srcTable) } return FillFromADODB((object)dataSet, ADODBRecordSet, srcTable, true); } + private int FillFromADODB(object data, object adodb, string? srcTable, bool multipleResults) + { + Debug.Assert(null != data, "FillFromADODB: null data object"); + Debug.Assert(null != adodb, "FillFromADODB: null ADODB"); + Debug.Assert(!(adodb is DataTable), "call Fill( (DataTable) value)"); + Debug.Assert(!(adodb is DataSet), "call Fill( (DataSet) value)"); + + /* + IntPtr adodbptr = ADP.PtrZero; + try { // generate a new COM Callable Wrapper around the user object so they can't ReleaseComObject on us. + adodbptr = Marshal.GetIUnknownForObject(adodb); + adodb = System.Runtime.Remoting.Services.EnterpriseServicesHelper.WrapIUnknownWithComObject(adodbptr); + } + finally { + if (ADP.PtrZero != adodbptr) { + Marshal.Release(adodbptr); + } + } + */ + + bool closeRecordset = multipleResults; + UnsafeNativeMethods.ADORecordsetConstruction? recordset = (adodb as UnsafeNativeMethods.ADORecordsetConstruction); + UnsafeNativeMethods.ADORecordConstruction? record = null; + + if (null != recordset) + { + if (multipleResults) + { + // The NextRecordset method is not available on a disconnected Recordset object, where ActiveConnection has been set to NULL + object activeConnection; + activeConnection = ((UnsafeNativeMethods.Recordset15)adodb).get_ActiveConnection(); + + if (null == activeConnection) + { + multipleResults = false; + } + } + } + else + { + record = (adodb as UnsafeNativeMethods.ADORecordConstruction); + + if (null != record) + { + multipleResults = false; // IRow implies CommandBehavior.SingleRow which implies CommandBehavior.SingleResult + } + } + // else throw ODB.Fill_NotADODB("adodb"); /* throw later, less code here*/ + + int results = 0; + if (null != recordset) + { + int resultCount = 0; + bool incrementResultCount; + object[] value = new object[1]; + + do + { + string? tmp = null; + if (data is DataSet) + { + tmp = GetSourceTableName(srcTable!, resultCount); + } + results += FillFromRecordset(data, recordset, tmp, out incrementResultCount); + + if (multipleResults) + { + value[0] = DBNull.Value; + + object recordsAffected; + object nextresult; + OleDbHResult hr = ((UnsafeNativeMethods.Recordset15)adodb).NextRecordset(out recordsAffected, out nextresult); + + if (0 > hr) + { + // Current provider does not support returning multiple recordsets from a single execution. + if (ODB.ADODB_NextResultError != (int)hr) + { + SafeNativeMethods.Wrapper.ClearErrorInfo(); + + string message = string.Empty; + throw new COMException(message, (int)hr); + } + break; + } + adodb = nextresult; + if (null != adodb) + { + recordset = (UnsafeNativeMethods.ADORecordsetConstruction)adodb; + + if (incrementResultCount) + { + resultCount++; + } + continue; + } + } + break; + } while (null != recordset); + + if ((null != recordset) && (closeRecordset || (null == adodb))) + { + FillClose(true, recordset); + } + } + else if (null != record) + { + results = FillFromRecord(data, record, srcTable!); + if (closeRecordset) + { + FillClose(false, record); + } + } + else + { + throw ODB.Fill_NotADODB("adodb"); + } + return results; + } //protected override int Fill(DataTable dataTable, IDataReader dataReader) { // return base.Fill(dataTable, dataReader); //} + private void FillClose(bool isrecordset, object value) + { + OleDbHResult hr; + if (isrecordset) + { + hr = ((UnsafeNativeMethods.Recordset15)value).Close(); + } + else + { + hr = ((UnsafeNativeMethods._ADORecord)value).Close(); + } + if ((0 < (int)hr) && (ODB.ADODB_AlreadyClosedError != (int)hr)) + { + SafeNativeMethods.Wrapper.ClearErrorInfo(); + string message = string.Empty; + throw new COMException(message, (int)hr); + } + } + private int FillFromRecordset(object data, UnsafeNativeMethods.ADORecordsetConstruction recordset, string? srcTable, out bool incrementResultCount) { incrementResultCount = false; 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 1aee01921331c9..6f6ed8993425c6 100644 --- a/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj +++ b/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj @@ -97,7 +97,6 @@ - @@ -105,7 +104,6 @@ - diff --git a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs index 54a4ac4ae84ee8..ddcc891b80f82c 100644 --- a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs @@ -11,9 +11,9 @@ internal static partial class UnsafeNativeMethods // Oleaut32 // - [DllImport(Interop.Libraries.OleAut32, CharSet = CharSet.Unicode, PreserveSig = true)] + [DllImport(Interop.Libraries.OleAut32, PreserveSig = true)] internal static extern System.Data.OleDb.OleDbHResult GetErrorInfo( - [In] int dwReserved, - [Out] out System.IntPtr ppIErrorInfo); + int dwReserved, + System.IntPtr* ppIErrorInfo); } } From 5b7c9dc1b74f3f226c733dac908937da442de587 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Tue, 29 Jun 2021 13:44:41 +0600 Subject: [PATCH 05/36] Make closer to original --- .../System.Data.OleDb/src/OleDbDataAdapter.cs | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.cs b/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.cs index 23263a841a1d05..5a4e18e76e0bd9 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.cs @@ -10,7 +10,7 @@ namespace System.Data.OleDb { [Designer("Microsoft.VSDesigner.Data.VS.OleDbDataAdapterDesigner, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] [ToolboxItem("Microsoft.VSDesigner.Data.VS.OleDbDataAdapterToolboxItem, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] - public sealed partial class OleDbDataAdapter : DbDataAdapter, IDbDataAdapter, ICloneable + public sealed class OleDbDataAdapter : DbDataAdapter, IDbDataAdapter, ICloneable { private static readonly object EventRowUpdated = new object(); private static readonly object EventRowUpdating = new object(); @@ -304,25 +304,6 @@ record = (adodb as UnsafeNativeMethods.ADORecordConstruction); // return base.Fill(dataTable, dataReader); //} - private void FillClose(bool isrecordset, object value) - { - OleDbHResult hr; - if (isrecordset) - { - hr = ((UnsafeNativeMethods.Recordset15)value).Close(); - } - else - { - hr = ((UnsafeNativeMethods._ADORecord)value).Close(); - } - if ((0 < (int)hr) && (ODB.ADODB_AlreadyClosedError != (int)hr)) - { - SafeNativeMethods.Wrapper.ClearErrorInfo(); - string message = string.Empty; - throw new COMException(message, (int)hr); - } - } - private int FillFromRecordset(object data, UnsafeNativeMethods.ADORecordsetConstruction recordset, string? srcTable, out bool incrementResultCount) { incrementResultCount = false; @@ -384,6 +365,25 @@ private int FillFromRecordset(object data, UnsafeNativeMethods.ADORecordsetConst return 0; } + private void FillClose(bool isrecordset, object value) + { + OleDbHResult hr; + if (isrecordset) + { + hr = ((UnsafeNativeMethods.Recordset15)value).Close(); + } + else + { + hr = ((UnsafeNativeMethods._ADORecord)value).Close(); + } + if ((0 < (int)hr) && (ODB.ADODB_AlreadyClosedError != (int)hr)) + { + SafeNativeMethods.Wrapper.ClearErrorInfo(); + string message = string.Empty; + throw new COMException(message, (int)hr); + } + } + private int FillFromRecord(object data, UnsafeNativeMethods.ADORecordConstruction record, string srcTable) { object? result = null; From 749fee81912a8fb167ba13a6a109ea7722fe609b Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Tue, 29 Jun 2021 13:50:07 +0600 Subject: [PATCH 06/36] One more change --- .../System.Data.OleDb/src/OleDbDataAdapter.cs | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.cs b/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.cs index 5a4e18e76e0bd9..1932ffd77ff263 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbDataAdapter.cs @@ -180,6 +180,7 @@ public int Fill(DataSet dataSet, object ADODBRecordSet, string srcTable) } return FillFromADODB((object)dataSet, ADODBRecordSet, srcTable, true); } + private int FillFromADODB(object data, object adodb, string? srcTable, bool multipleResults) { Debug.Assert(null != data, "FillFromADODB: null data object"); @@ -365,25 +366,6 @@ private int FillFromRecordset(object data, UnsafeNativeMethods.ADORecordsetConst return 0; } - private void FillClose(bool isrecordset, object value) - { - OleDbHResult hr; - if (isrecordset) - { - hr = ((UnsafeNativeMethods.Recordset15)value).Close(); - } - else - { - hr = ((UnsafeNativeMethods._ADORecord)value).Close(); - } - if ((0 < (int)hr) && (ODB.ADODB_AlreadyClosedError != (int)hr)) - { - SafeNativeMethods.Wrapper.ClearErrorInfo(); - string message = string.Empty; - throw new COMException(message, (int)hr); - } - } - private int FillFromRecord(object data, UnsafeNativeMethods.ADORecordConstruction record, string srcTable) { object? result = null; @@ -434,6 +416,25 @@ private int FillFromRecord(object data, UnsafeNativeMethods.ADORecordConstructio return 0; } + private void FillClose(bool isrecordset, object value) + { + OleDbHResult hr; + if (isrecordset) + { + hr = ((UnsafeNativeMethods.Recordset15)value).Close(); + } + else + { + hr = ((UnsafeNativeMethods._ADORecord)value).Close(); + } + if ((0 < (int)hr) && (ODB.ADODB_AlreadyClosedError != (int)hr)) + { + SafeNativeMethods.Wrapper.ClearErrorInfo(); + string message = string.Empty; + throw new COMException(message, (int)hr); + } + } + protected override void OnRowUpdated(RowUpdatedEventArgs value) { OleDbRowUpdatedEventHandler? handler = (OleDbRowUpdatedEventHandler?)Events[EventRowUpdated]; From 505e6f23759b4ca2f6c56f7e34a7b353e5ce983d Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Wed, 30 Jun 2021 10:29:24 +0600 Subject: [PATCH 07/36] Apply PR feedback --- .../src/DbPropSet.COMWrappers.cs | 2 +- .../System.Data.OleDb/src/OleDbComWrappers.cs | 24 +++++++++---------- .../src/OleDbConnection.COMWrappers.cs | 4 ++-- .../src/OleDbException.COMWrappers.cs | 11 +++------ .../src/OleDb_Util.COMWrappers.cs | 2 +- .../src/UnsafeNativeMethods.COMWrappers.cs | 2 +- .../src/UnsafeNativeMethods.cs | 4 ++-- 7 files changed, 21 insertions(+), 28 deletions(-) diff --git a/src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs index b7b6359bee4918..c759d78e5eb045 100644 --- a/src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs @@ -20,7 +20,7 @@ private void SetLastErrorInfo(OleDbHResult lastErrorHr) OleDbHResult errorInfoHr = UnsafeNativeMethods.GetErrorInfo(0, &pErrorInfo); // 0 - IErrorInfo exists, 1 - no IErrorInfo if ((errorInfoHr == OleDbHResult.S_OK) && (pErrorInfo != IntPtr.Zero)) { - using OleDbComWrappers.IErrorInfo errorInfo = (OleDbComWrappers.IErrorInfo)OleDbComWrappers.Instance + using UnsafeNativeMethods.IErrorInfo errorInfo = (UnsafeNativeMethods.IErrorInfo)OleDbComWrappers.Instance .GetOrCreateObjectForComInstance(pErrorInfo, CreateObjectFlags.UniqueInstance);; 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 diff --git a/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs index 60de2735321405..5b80ea5895f7bc 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs @@ -17,6 +17,7 @@ namespace System.Data.OleDb internal unsafe class OleDbComWrappers : ComWrappers { private const int S_OK = (int)Interop.HRESULT.S_OK; + private static readonly Guid IID_IErrorInfo = new Guid(0x1CF2B120, 0x547D, 0x101B, 0x8E, 0xBB, 0x65, 0x08, 0x00, 0x2B, 0x2B, 0xD1, 0x19); internal static OleDbComWrappers Instance { get; } = new OleDbComWrappers(); @@ -31,7 +32,7 @@ protected override object CreateObject(IntPtr externalComObject, CreateObjectFla { Debug.Assert(flags == CreateObjectFlags.UniqueInstance); - Guid errorInfoIID = IErrorInfo.IID; + Guid errorInfoIID = IID_IErrorInfo; int hr = Marshal.QueryInterface(externalComObject, ref errorInfoIID, out IntPtr comObject); if (hr == S_OK) { @@ -46,16 +47,7 @@ protected override void ReleaseObjects(IEnumerable objects) throw new NotImplementedException(); } - internal interface IErrorInfo - { - static readonly Guid IID = new Guid(0x1CF2B120, 0x547D, 0x101B, 0x8E, 0xBB, 0x65, 0x08, 0x00, 0x2B, 0x2B, 0xD1, 0x19); - - System.Data.OleDb.OleDbHResult GetSource(out string source); - - System.Data.OleDb.OleDbHResult GetDescription(out string description); - } - - private class ErrorInfoWrapper : IErrorInfo + private class ErrorInfoWrapper : UnsafeNativeMethods.IErrorInfo { private readonly IntPtr _wrappedInstance; @@ -69,7 +61,13 @@ public void Dispose() Marshal.Release(_wrappedInstance); } - public unsafe System.Data.OleDb.OleDbHResult GetSource(out string source) + [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 */))) @@ -86,7 +84,7 @@ public unsafe System.Data.OleDb.OleDbHResult GetSource(out string source) return (System.Data.OleDb.OleDbHResult)errorCode; } - public unsafe System.Data.OleDb.OleDbHResult GetDescription(out string description) + public unsafe System.Data.OleDb.OleDbHResult GetDescription(out string? description) { IntPtr pDescription; int errorCode = ((delegate* unmanaged)(*(*(void***)_wrappedInstance + 5 /* IErrorInfo.GetDescription slot */))) diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs index bb0c79f9e2130a..41f5f0a3a160da 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs @@ -30,7 +30,7 @@ public sealed partial class OleDbConnection OleDbHResult hr = UnsafeNativeMethods.GetErrorInfo(0, &pErrorInfo); // 0 - IErrorInfo exists, 1 - no IErrorInfo if ((OleDbHResult.S_OK == hr) && (null != errorInfo)) { - using OleDbComWrappers.IErrorInfo errorInfo = (OleDbComWrappers.IErrorInfo)OleDbComWrappers.Instance + using UnsafeNativeMethods.IErrorInfo errorInfo = (UnsafeNativeMethods.IErrorInfo)OleDbComWrappers.Instance .GetOrCreateObjectForComInstance(pErrorInfo, CreateObjectFlags.UniqueInstance);; if (hresult < 0) { @@ -72,7 +72,7 @@ public sealed partial class OleDbConnection return e; } - internal void OnInfoMessage(OleDbComWrappers.IErrorInfo errorInfo, OleDbHResult errorCode) + internal void OnInfoMessage(UnsafeNativeMethods.IErrorInfo errorInfo, OleDbHResult errorCode) { OleDbInfoMessageEventHandler? handler = (OleDbInfoMessageEventHandler?)Events[EventInfoMessage]; if (null != handler) diff --git a/src/libraries/System.Data.OleDb/src/OleDbException.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbException.COMWrappers.cs index 9d48a0be85793b..97e4161f346936 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbException.COMWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbException.COMWrappers.cs @@ -13,19 +13,14 @@ namespace System.Data.OleDb { public sealed partial class OleDbException { - internal static OleDbException CreateException(OleDbComWrappers.IErrorInfo errorInfo, OleDbHResult errorCode, Exception? inner) + internal static OleDbException CreateException(UnsafeNativeMethods.IErrorInfo errorInfo, OleDbHResult errorCode, Exception? inner) { OleDbErrorCollection errors = new OleDbErrorCollection(errorInfo); 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.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDb_Util.COMWrappers.cs index e73512ad0760b2..7dea23cd64c5ec 100644 --- a/src/libraries/System.Data.OleDb/src/OleDb_Util.COMWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/OleDb_Util.COMWrappers.cs @@ -12,7 +12,7 @@ namespace System.Data.OleDb { internal static partial class ODB { - internal static OleDbHResult GetErrorDescription(OleDbComWrappers.IErrorInfo errorInfo, OleDbHResult hresult, out string message) + internal static OleDbHResult GetErrorDescription(UnsafeNativeMethods.IErrorInfo errorInfo, OleDbHResult hresult, out string message) { OleDbHResult hr = errorInfo.GetDescription(out message); if (((int)hr < 0) && ADP.IsEmpty(message)) diff --git a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs index ddcc891b80f82c..23e371783bead0 100644 --- a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs @@ -11,7 +11,7 @@ internal static partial class UnsafeNativeMethods // Oleaut32 // - [DllImport(Interop.Libraries.OleAut32, PreserveSig = true)] + [DllImport(Interop.Libraries.OleAut32)] internal static extern System.Data.OleDb.OleDbHResult GetErrorInfo( int dwReserved, System.IntPtr* ppIErrorInfo); diff --git a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.cs b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.cs index 4415aa87ab1e25..fda384fd221be9 100644 --- a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.cs +++ b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.cs @@ -513,11 +513,11 @@ internal interface IErrorInfo [PreserveSig] System.Data.OleDb.OleDbHResult GetSource( - [Out, MarshalAs(UnmanagedType.BStr)] out string pBstrSource); + [Out, MarshalAs(UnmanagedType.BStr)] out string? pBstrSource); [PreserveSig] System.Data.OleDb.OleDbHResult GetDescription( - [Out, MarshalAs(UnmanagedType.BStr)] out string pBstrDescription); + [Out, MarshalAs(UnmanagedType.BStr)] out string? pBstrDescription); //[ Obsolete("not used", true)] void GetHelpFile(/*deleted parameter signature*/); From db65b0b7dcb45196d26e46d3cfef9ea8d171926b Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Wed, 30 Jun 2021 19:45:53 +0600 Subject: [PATCH 08/36] Update src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj Co-authored-by: Viktor Hofer --- src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 95903999f305ee..0bfb31f88c8716 100644 --- a/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj +++ b/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj @@ -99,7 +99,7 @@ - + From 7e9e9560b51047ca93a675d94fbcbe335ce410fb Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Wed, 30 Jun 2021 19:46:05 +0600 Subject: [PATCH 09/36] Update src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj Co-authored-by: Viktor Hofer --- src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 0bfb31f88c8716..520d265d9db4bd 100644 --- a/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj +++ b/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj @@ -107,7 +107,7 @@ - + From 2cf1788668d225445de67371a4e8797511cb7fd1 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Wed, 30 Jun 2021 20:30:09 +0600 Subject: [PATCH 10/36] Fix compilation errors --- src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs | 3 ++- .../System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs index 5b80ea5895f7bc..ed31c2babd51a6 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs @@ -3,6 +3,7 @@ using System.Collections; using System.Diagnostics; +using System.Data.Common; using System.IO; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -16,7 +17,7 @@ namespace System.Data.OleDb /// internal unsafe class OleDbComWrappers : ComWrappers { - private const int S_OK = (int)Interop.HRESULT.S_OK; + private const int S_OK = (int)OleDbHResult.S_OK; private static readonly Guid IID_IErrorInfo = new Guid(0x1CF2B120, 0x547D, 0x101B, 0x8E, 0xBB, 0x65, 0x08, 0x00, 0x2B, 0x2B, 0xD1, 0x19); internal static OleDbComWrappers Instance { get; } = new OleDbComWrappers(); diff --git a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs index 23e371783bead0..988c1afd544309 100644 --- a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs @@ -12,7 +12,7 @@ internal static partial class UnsafeNativeMethods // [DllImport(Interop.Libraries.OleAut32)] - internal static extern System.Data.OleDb.OleDbHResult GetErrorInfo( + internal unsafe static extern System.Data.OleDb.OleDbHResult GetErrorInfo( int dwReserved, System.IntPtr* ppIErrorInfo); } From b928f03b852000c443334d1f7a59d981fc068e04 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Wed, 30 Jun 2021 21:16:59 +0600 Subject: [PATCH 11/36] Fix errors --- src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs | 2 +- src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs | 2 +- src/libraries/System.Data.OleDb/src/OleDb_Util.COMWrappers.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs index c759d78e5eb045..f33b508eeddd87 100644 --- a/src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs @@ -12,7 +12,7 @@ namespace System.Data.OleDb { internal sealed partial class DBPropSet { - private void SetLastErrorInfo(OleDbHResult lastErrorHr) + private unsafe void SetLastErrorInfo(OleDbHResult lastErrorHr) { // note: OleDbHResult is actually a simple wrapper over HRESULT with OLEDB-specific codes string message = string.Empty; diff --git a/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs index ed31c2babd51a6..3addc96b77acca 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs @@ -18,7 +18,7 @@ namespace System.Data.OleDb internal unsafe class OleDbComWrappers : ComWrappers { private const int S_OK = (int)OleDbHResult.S_OK; - private static readonly Guid IID_IErrorInfo = new Guid(0x1CF2B120, 0x547D, 0x101B, 0x8E, 0xBB, 0x65, 0x08, 0x00, 0x2B, 0x2B, 0xD1, 0x19); + 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(); diff --git a/src/libraries/System.Data.OleDb/src/OleDb_Util.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDb_Util.COMWrappers.cs index 7dea23cd64c5ec..85e17a22d39db2 100644 --- a/src/libraries/System.Data.OleDb/src/OleDb_Util.COMWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/OleDb_Util.COMWrappers.cs @@ -12,7 +12,7 @@ namespace System.Data.OleDb { internal static partial class ODB { - internal static OleDbHResult GetErrorDescription(UnsafeNativeMethods.IErrorInfo errorInfo, OleDbHResult hresult, out string message) + internal unsafe static OleDbHResult GetErrorDescription(UnsafeNativeMethods.IErrorInfo errorInfo, OleDbHResult hresult, out string message) { OleDbHResult hr = errorInfo.GetDescription(out message); if (((int)hr < 0) && ADP.IsEmpty(message)) From 7401706aa8c9273d8b93d5d4cb5f38c136b4430d Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Thu, 1 Jul 2021 09:09:41 +0600 Subject: [PATCH 12/36] Consolidate code --- .../src/OleDbException.COMWrappers.cs | 55 ----------------- .../src/OleDbException.NoCOMWrappers.cs | 60 ------------------- .../System.Data.OleDb/src/OleDbException.cs | 39 ++++++++++++ .../src/OleDb_Util.COMWrappers.cs | 29 --------- .../src/OleDb_Util.NoCOMWrappers.cs | 29 --------- .../System.Data.OleDb/src/OleDb_Util.cs | 16 ++++- 6 files changed, 54 insertions(+), 174 deletions(-) delete mode 100644 src/libraries/System.Data.OleDb/src/OleDbException.COMWrappers.cs delete mode 100644 src/libraries/System.Data.OleDb/src/OleDbException.NoCOMWrappers.cs delete mode 100644 src/libraries/System.Data.OleDb/src/OleDb_Util.COMWrappers.cs delete mode 100644 src/libraries/System.Data.OleDb/src/OleDb_Util.NoCOMWrappers.cs diff --git a/src/libraries/System.Data.OleDb/src/OleDbException.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbException.COMWrappers.cs deleted file mode 100644 index 97e4161f346936..00000000000000 --- a/src/libraries/System.Data.OleDb/src/OleDbException.COMWrappers.cs +++ /dev/null @@ -1,55 +0,0 @@ -// 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.Generic; -using System.ComponentModel; -using System.Data.Common; -using System.Diagnostics; -using System.Globalization; -using System.Runtime.Serialization; -using System.Text; - -namespace System.Data.OleDb -{ - public sealed partial class OleDbException - { - internal static OleDbException CreateException(UnsafeNativeMethods.IErrorInfo errorInfo, OleDbHResult errorCode, Exception? inner) - { - OleDbErrorCollection errors = new OleDbErrorCollection(errorInfo); - string? message = null; - string? source = null; - OleDbHResult hr = 0; - hr = errorInfo.GetDescription(out message); - hr = errorInfo.GetSource(out source); - - int count = errors.Count; - if (0 < errors.Count) - { - StringBuilder builder = new StringBuilder(); - - if ((null != message) && (message != errors[0].Message)) - { - builder.Append(message.TrimEnd(ODB.ErrorTrimCharacters)); - if (1 < count) - { - builder.Append(Environment.NewLine); - } - } - for (int i = 0; i < count; ++i) - { - if (0 < i) - { - builder.Append(Environment.NewLine); - } - builder.Append(errors[i].Message.TrimEnd(ODB.ErrorTrimCharacters)); - } - message = builder.ToString(); - } - if (ADP.IsEmpty(message)) - { - message = ODB.NoErrorMessage(errorCode); - } - return new OleDbException(message, inner, source, errorCode, errors); - } - } -} diff --git a/src/libraries/System.Data.OleDb/src/OleDbException.NoCOMWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbException.NoCOMWrappers.cs deleted file mode 100644 index 7c56157a917098..00000000000000 --- a/src/libraries/System.Data.OleDb/src/OleDbException.NoCOMWrappers.cs +++ /dev/null @@ -1,60 +0,0 @@ -// 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.Generic; -using System.ComponentModel; -using System.Data.Common; -using System.Diagnostics; -using System.Globalization; -using System.Runtime.Serialization; -using System.Text; - -namespace System.Data.OleDb -{ - public sealed partial class OleDbException - { - internal static OleDbException CreateException(UnsafeNativeMethods.IErrorInfo errorInfo, OleDbHResult errorCode, Exception? inner) - { - OleDbErrorCollection errors = new OleDbErrorCollection(errorInfo); - string? message = null; - string? source = null; - OleDbHResult hr = 0; - - if (null != errorInfo) - { - hr = errorInfo.GetDescription(out message); - - hr = errorInfo.GetSource(out source); - } - - int count = errors.Count; - if (0 < errors.Count) - { - StringBuilder builder = new StringBuilder(); - - if ((null != message) && (message != errors[0].Message)) - { - builder.Append(message.TrimEnd(ODB.ErrorTrimCharacters)); - if (1 < count) - { - builder.Append(Environment.NewLine); - } - } - for (int i = 0; i < count; ++i) - { - if (0 < i) - { - builder.Append(Environment.NewLine); - } - builder.Append(errors[i].Message.TrimEnd(ODB.ErrorTrimCharacters)); - } - message = builder.ToString(); - } - if (ADP.IsEmpty(message)) - { - message = ODB.NoErrorMessage(errorCode); - } - return new OleDbException(message, inner, source, errorCode, errors); - } - } -} diff --git a/src/libraries/System.Data.OleDb/src/OleDbException.cs b/src/libraries/System.Data.OleDb/src/OleDbException.cs index b47ec58f9991c8..c0fcf90fd2b0e9 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbException.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbException.cs @@ -64,6 +64,45 @@ public OleDbErrorCollection Errors } } + internal static OleDbException CreateException(UnsafeNativeMethods.IErrorInfo errorInfo, OleDbHResult errorCode, Exception? inner) + { + OleDbErrorCollection errors = new OleDbErrorCollection(errorInfo); + string? message = null; + string? source = null; + OleDbHResult hr = 0; + hr = errorInfo.GetDescription(out message); + hr = errorInfo.GetSource(out source); + + int count = errors.Count; + if (0 < errors.Count) + { + StringBuilder builder = new StringBuilder(); + + if ((null != message) && (message != errors[0].Message)) + { + builder.Append(message.TrimEnd(ODB.ErrorTrimCharacters)); + if (1 < count) + { + builder.Append(Environment.NewLine); + } + } + for (int i = 0; i < count; ++i) + { + if (0 < i) + { + builder.Append(Environment.NewLine); + } + builder.Append(errors[i].Message.TrimEnd(ODB.ErrorTrimCharacters)); + } + message = builder.ToString(); + } + if (ADP.IsEmpty(message)) + { + message = ODB.NoErrorMessage(errorCode); + } + return new OleDbException(message, inner, source, errorCode, errors); + } + internal static OleDbException CombineExceptions(List exceptions) { Debug.Assert(0 < exceptions.Count, "missing exceptions"); diff --git a/src/libraries/System.Data.OleDb/src/OleDb_Util.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDb_Util.COMWrappers.cs deleted file mode 100644 index 85e17a22d39db2..00000000000000 --- a/src/libraries/System.Data.OleDb/src/OleDb_Util.COMWrappers.cs +++ /dev/null @@ -1,29 +0,0 @@ -// 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.Data.Common; -using System.Diagnostics; -using System.Globalization; -using System.Runtime.InteropServices; -using System.Text; - -namespace System.Data.OleDb -{ - internal static partial class ODB - { - internal unsafe static OleDbHResult GetErrorDescription(UnsafeNativeMethods.IErrorInfo errorInfo, OleDbHResult hresult, out string message) - { - OleDbHResult hr = errorInfo.GetDescription(out message); - if (((int)hr < 0) && ADP.IsEmpty(message)) - { - message = FailedGetDescription(hr) + Environment.NewLine + ODB.ELookup(hresult); - } - if (ADP.IsEmpty(message)) - { - message = ODB.ELookup(hresult); - } - return hr; - } - } -} diff --git a/src/libraries/System.Data.OleDb/src/OleDb_Util.NoCOMWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDb_Util.NoCOMWrappers.cs deleted file mode 100644 index 7dea23cd64c5ec..00000000000000 --- a/src/libraries/System.Data.OleDb/src/OleDb_Util.NoCOMWrappers.cs +++ /dev/null @@ -1,29 +0,0 @@ -// 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.Data.Common; -using System.Diagnostics; -using System.Globalization; -using System.Runtime.InteropServices; -using System.Text; - -namespace System.Data.OleDb -{ - internal static partial class ODB - { - internal static OleDbHResult GetErrorDescription(UnsafeNativeMethods.IErrorInfo errorInfo, OleDbHResult hresult, out string message) - { - OleDbHResult hr = errorInfo.GetDescription(out message); - if (((int)hr < 0) && ADP.IsEmpty(message)) - { - message = FailedGetDescription(hr) + Environment.NewLine + ODB.ELookup(hresult); - } - if (ADP.IsEmpty(message)) - { - message = ODB.ELookup(hresult); - } - return hr; - } - } -} diff --git a/src/libraries/System.Data.OleDb/src/OleDb_Util.cs b/src/libraries/System.Data.OleDb/src/OleDb_Util.cs index e7ae36ccfb4254..b0a39dea96c734 100644 --- a/src/libraries/System.Data.OleDb/src/OleDb_Util.cs +++ b/src/libraries/System.Data.OleDb/src/OleDb_Util.cs @@ -10,7 +10,7 @@ namespace System.Data.OleDb { - internal static partial class ODB + internal static class ODB { // OleDbCommand internal static void CommandParameterStatus(StringBuilder builder, int index, DBStatus status) @@ -332,6 +332,20 @@ internal static InvalidOperationException DBBindingGetVector() return ADP.InvalidOperation(SR.Format(SR.OleDb_DBBindingGetVector)); } + internal static OleDbHResult GetErrorDescription(UnsafeNativeMethods.IErrorInfo errorInfo, OleDbHResult hresult, out string message) + { + OleDbHResult hr = errorInfo.GetDescription(out message); + if (((int)hr < 0) && ADP.IsEmpty(message)) + { + message = FailedGetDescription(hr) + Environment.NewLine + ODB.ELookup(hresult); + } + if (ADP.IsEmpty(message)) + { + message = ODB.ELookup(hresult); + } + return hr; + } + // OleDbEnumerator internal static ArgumentException ISourcesRowsetNotSupported() { From 5750c8e4298fe55e65a5ae7a250d715c3505dafb Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Thu, 8 Jul 2021 19:44:08 +0600 Subject: [PATCH 13/36] Fix compilation warnings --- .../src/OleDbConnection.COMWrappers.cs | 46 +++++++++++-------- .../System.Data.OleDb/src/OleDb_Util.cs | 2 +- .../src/System.Data.OleDb.csproj | 4 -- .../src/UnsafeNativeMethods.COMWrappers.cs | 2 +- .../src/UnsafeNativeMethods.NoCOMWrappers.cs | 2 +- 5 files changed, 31 insertions(+), 25 deletions(-) diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs index 41f5f0a3a160da..bc29844c59a2cd 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs @@ -16,7 +16,7 @@ namespace System.Data.OleDb public sealed partial class OleDbConnection { - internal static Exception? ProcessResults(OleDbHResult hresult, OleDbConnection? connection, object? src) + internal static unsafe Exception? ProcessResults(OleDbHResult hresult, OleDbConnection? connection, object? src) { if ((0 <= (int)hresult) && ((null == connection) || (null == connection.Events[EventInfoMessage]))) { @@ -28,31 +28,41 @@ public sealed partial class OleDbConnection Exception? e = null; IntPtr pErrorInfo; OleDbHResult hr = UnsafeNativeMethods.GetErrorInfo(0, &pErrorInfo); // 0 - IErrorInfo exists, 1 - no IErrorInfo - if ((OleDbHResult.S_OK == hr) && (null != errorInfo)) + if ((OleDbHResult.S_OK == hr) && (IntPtr.Zero != pErrorInfo)) { - using UnsafeNativeMethods.IErrorInfo errorInfo = (UnsafeNativeMethods.IErrorInfo)OleDbComWrappers.Instance + UnsafeNativeMethods.IErrorInfo errorInfo = (UnsafeNativeMethods.IErrorInfo)OleDbComWrappers.Instance .GetOrCreateObjectForComInstance(pErrorInfo, CreateObjectFlags.UniqueInstance);; - 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 (hresult < 0) + { + // 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 (OleDbHResult.DB_E_OBJECTOPEN == hresult) + { + e = ADP.OpenReaderExists(e); + } + + ResetState(connection); + } + else if (null != connection) { - e = ADP.OpenReaderExists(e); + connection.OnInfoMessage(errorInfo, hresult); } - - ResetState(connection); } - else if (null != connection) + finally { - connection.OnInfoMessage(errorInfo, hresult); + if (errorInfo is IDisposable disposable) + { + disposable.Dispose(); + } } } else if (0 < hresult) diff --git a/src/libraries/System.Data.OleDb/src/OleDb_Util.cs b/src/libraries/System.Data.OleDb/src/OleDb_Util.cs index b0a39dea96c734..828d829e3a7eda 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 520d265d9db4bd..c0e884841dc632 100644 --- a/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj +++ b/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj @@ -103,16 +103,12 @@ - - - - diff --git a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs index 988c1afd544309..9af6b7b0c2168a 100644 --- a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs @@ -12,7 +12,7 @@ internal static partial class UnsafeNativeMethods // [DllImport(Interop.Libraries.OleAut32)] - internal unsafe static extern System.Data.OleDb.OleDbHResult GetErrorInfo( + internal static unsafe extern System.Data.OleDb.OleDbHResult GetErrorInfo( int dwReserved, System.IntPtr* ppIErrorInfo); } diff --git a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.NoCOMWrappers.cs b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.NoCOMWrappers.cs index b88921b19532dc..adb8f74e0dae3f 100644 --- a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.NoCOMWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.NoCOMWrappers.cs @@ -14,6 +14,6 @@ internal static partial class UnsafeNativeMethods [DllImport(Interop.Libraries.OleAut32, CharSet = CharSet.Unicode, PreserveSig = true)] internal static extern System.Data.OleDb.OleDbHResult GetErrorInfo( [In] int dwReserved, - [Out, MarshalAs(UnmanagedType.Interface)] out IErrorInfo ppIErrorInfo); + [Out, MarshalAs(UnmanagedType.Interface)] out UnsafeNativeMethods.IErrorInfo ppIErrorInfo); } } From c301fb637bec9cc168a71a90195066db6dd3247e Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Thu, 8 Jul 2021 20:18:40 +0600 Subject: [PATCH 14/36] Fix compilation error --- .../src/DbPropSet.COMWrappers.cs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs index f33b508eeddd87..94372917cf636f 100644 --- a/src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs @@ -20,11 +20,22 @@ private unsafe void SetLastErrorInfo(OleDbHResult lastErrorHr) OleDbHResult errorInfoHr = UnsafeNativeMethods.GetErrorInfo(0, &pErrorInfo); // 0 - IErrorInfo exists, 1 - no IErrorInfo if ((errorInfoHr == OleDbHResult.S_OK) && (pErrorInfo != IntPtr.Zero)) { - using UnsafeNativeMethods.IErrorInfo errorInfo = (UnsafeNativeMethods.IErrorInfo)OleDbComWrappers.Instance + UnsafeNativeMethods.IErrorInfo errorInfo = (UnsafeNativeMethods.IErrorInfo)OleDbComWrappers.Instance .GetOrCreateObjectForComInstance(pErrorInfo, CreateObjectFlags.UniqueInstance);; - 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 + { + if (errorInfo is IDisposable disposable) + { + disposable.Dispose(); + } + } } + lastErrorFromProvider = new COMException(message, (int)lastErrorHr); } } From 5d11dea05744af2959faff2f93c16f9c038c73f0 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Fri, 9 Jul 2021 16:17:05 +0600 Subject: [PATCH 15/36] Fix compilation error --- src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 c0e884841dc632..fef12d47d69e70 100644 --- a/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj +++ b/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj @@ -99,13 +99,13 @@ - + - + From a1189fd48e707d45978d0381ca2f9c705b843beb Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Mon, 12 Jul 2021 21:00:22 +0600 Subject: [PATCH 16/36] Address PR feedback --- .../System.Data.OleDb/src/OleDbConnection.COMWrappers.cs | 2 -- .../System.Data.OleDb/src/OleDbConnection.NoCOMWrappers.cs | 2 -- src/libraries/System.Data.OleDb/src/OleDbException.cs | 2 +- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs index bc29844c59a2cd..f637613e6b22f1 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs @@ -12,8 +12,6 @@ namespace System.Data.OleDb { - using SysTx = Transactions; - public sealed partial class OleDbConnection { internal static unsafe Exception? ProcessResults(OleDbHResult hresult, OleDbConnection? connection, object? src) diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnection.NoCOMWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbConnection.NoCOMWrappers.cs index 01c411375064ca..a29d6e9c94c66d 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbConnection.NoCOMWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbConnection.NoCOMWrappers.cs @@ -12,8 +12,6 @@ namespace System.Data.OleDb { - using SysTx = Transactions; - public sealed partial class OleDbConnection { internal static Exception? ProcessResults(OleDbHResult hresult, OleDbConnection? connection, object? src) diff --git a/src/libraries/System.Data.OleDb/src/OleDbException.cs b/src/libraries/System.Data.OleDb/src/OleDbException.cs index c0fcf90fd2b0e9..70d25fa0b14405 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbException.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbException.cs @@ -11,7 +11,7 @@ namespace System.Data.OleDb { - public sealed partial class OleDbException : System.Data.Common.DbException + public sealed class OleDbException : System.Data.Common.DbException { private readonly OleDbErrorCollection oledbErrors; From 0e12c0257c507aeaa444d74a16937a6364fadc66 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Mon, 12 Jul 2021 21:51:34 +0600 Subject: [PATCH 17/36] Update PR feedback --- src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 fef12d47d69e70..89993952638c13 100644 --- a/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj +++ b/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj @@ -99,13 +99,13 @@ - + - + From 0364575d81dd38bbb11536ec187529e2ca5b57f3 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Mon, 19 Jul 2021 19:30:32 +0600 Subject: [PATCH 18/36] Address PR feedback --- src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs | 5 +---- src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs | 4 ++-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs index 94372917cf636f..d1e1423b526fa2 100644 --- a/src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs @@ -29,10 +29,7 @@ private unsafe void SetLastErrorInfo(OleDbHResult lastErrorHr) } finally { - if (errorInfo is IDisposable disposable) - { - disposable.Dispose(); - } + ((IDisposable)errorInfo).Dispose(); } } diff --git a/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs index 3addc96b77acca..a61121498dcc04 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs @@ -73,7 +73,7 @@ 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) + if (pSource == IntPtr.Zero || errorCode < 0) { source = null; } @@ -90,7 +90,7 @@ public unsafe System.Data.OleDb.OleDbHResult GetDescription(out string? descript IntPtr pDescription; int errorCode = ((delegate* unmanaged)(*(*(void***)_wrappedInstance + 5 /* IErrorInfo.GetDescription slot */))) (_wrappedInstance, &pDescription); - if (pDescription == IntPtr.Zero) + if (pDescription == IntPtr.Zero || errorCode < 0) { description = null; } From a2bbb45c2ce5fc5cad22340209d996c62b6c3f1c Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Tue, 20 Jul 2021 00:49:21 +0600 Subject: [PATCH 19/36] Direct cast --- .../System.Data.OleDb/src/OleDbConnection.COMWrappers.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs index f637613e6b22f1..561262336ded6e 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs @@ -57,10 +57,7 @@ public sealed partial class OleDbConnection } finally { - if (errorInfo is IDisposable disposable) - { - disposable.Dispose(); - } + ((IDisposable)errorInfo).Dispose(); } } else if (0 < hresult) From 26859c5e70c89a38b7ac6db2cc929ad374f77692 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Wed, 8 Sep 2021 20:09:43 +0600 Subject: [PATCH 20/36] Ask wrapper to implement IDisposable --- src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs index a61121498dcc04..9377c1d4dc8c06 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs @@ -48,7 +48,7 @@ protected override void ReleaseObjects(IEnumerable objects) throw new NotImplementedException(); } - private class ErrorInfoWrapper : UnsafeNativeMethods.IErrorInfo + private class ErrorInfoWrapper : UnsafeNativeMethods.IErrorInfo, IDisposable { private readonly IntPtr _wrappedInstance; From 0e1177f5a925e63553be24178d1214d034d93a31 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Mon, 20 Sep 2021 22:19:03 +0600 Subject: [PATCH 21/36] Update src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs Co-authored-by: Eric Erhardt --- .../System.Data.OleDb/src/OleDbConnection.COMWrappers.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs index 561262336ded6e..86ee30fe0cba9f 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs @@ -29,7 +29,7 @@ public sealed partial class OleDbConnection if ((OleDbHResult.S_OK == hr) && (IntPtr.Zero != pErrorInfo)) { UnsafeNativeMethods.IErrorInfo errorInfo = (UnsafeNativeMethods.IErrorInfo)OleDbComWrappers.Instance - .GetOrCreateObjectForComInstance(pErrorInfo, CreateObjectFlags.UniqueInstance);; + .GetOrCreateObjectForComInstance(pErrorInfo, CreateObjectFlags.UniqueInstance); try { if (hresult < 0) From 9f3a972bc738090b43b7f14cb8e04fc96f4cd404 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Mon, 20 Sep 2021 22:19:57 +0600 Subject: [PATCH 22/36] Update src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs Co-authored-by: Eric Erhardt --- src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs index 9377c1d4dc8c06..3c98d65237354d 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs @@ -15,7 +15,7 @@ namespace System.Data.OleDb /// /// Supports IErrorInfo COM interface. /// - internal unsafe class OleDbComWrappers : ComWrappers + 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); From f41457fb19d4926250ae4147f5073225f91e788f Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Mon, 20 Sep 2021 22:20:27 +0600 Subject: [PATCH 23/36] Update src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs Co-authored-by: Eric Erhardt --- src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs index 3c98d65237354d..cfbd29e4f5b8bd 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs @@ -87,7 +87,7 @@ public unsafe System.Data.OleDb.OleDbHResult GetSource(out string? source) public unsafe System.Data.OleDb.OleDbHResult GetDescription(out string? description) { - IntPtr pDescription; + IntPtr pDescription = IntPtr.Zero; int errorCode = ((delegate* unmanaged)(*(*(void***)_wrappedInstance + 5 /* IErrorInfo.GetDescription slot */))) (_wrappedInstance, &pDescription); if (pDescription == IntPtr.Zero || errorCode < 0) From dd9e48acf09b328637a9e42576a0154366775ef9 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Mon, 20 Sep 2021 22:20:59 +0600 Subject: [PATCH 24/36] Update src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs Co-authored-by: Eric Erhardt --- src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs index d1e1423b526fa2..7cc7f613fa5683 100644 --- a/src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs @@ -21,7 +21,7 @@ private unsafe void SetLastErrorInfo(OleDbHResult lastErrorHr) if ((errorInfoHr == OleDbHResult.S_OK) && (pErrorInfo != IntPtr.Zero)) { UnsafeNativeMethods.IErrorInfo errorInfo = (UnsafeNativeMethods.IErrorInfo)OleDbComWrappers.Instance - .GetOrCreateObjectForComInstance(pErrorInfo, CreateObjectFlags.UniqueInstance);; + .GetOrCreateObjectForComInstance(pErrorInfo, CreateObjectFlags.UniqueInstance); try { ODB.GetErrorDescription(errorInfo, lastErrorHr, out message); From adf11e56e5c5b44435dcdbedfd3d558bcfbc8f43 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Mon, 20 Sep 2021 23:24:23 +0600 Subject: [PATCH 25/36] Restore changes in OnInfoMessage --- .../src/OleDbConnection.COMWrappers.cs | 24 ------------------- .../src/OleDbConnection.NoCOMWrappers.cs | 24 ------------------- .../System.Data.OleDb/src/OleDbConnection.cs | 24 +++++++++++++++++++ 3 files changed, 24 insertions(+), 48 deletions(-) diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs index 86ee30fe0cba9f..5fffb4736dee8c 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs @@ -76,29 +76,5 @@ public sealed partial class OleDbConnection } return e; } - - internal void OnInfoMessage(UnsafeNativeMethods.IErrorInfo errorInfo, OleDbHResult errorCode) - { - OleDbInfoMessageEventHandler? handler = (OleDbInfoMessageEventHandler?)Events[EventInfoMessage]; - if (null != handler) - { - try - { - OleDbException exception = OleDbException.CreateException(errorInfo, errorCode, null); - OleDbInfoMessageEventArgs e = new OleDbInfoMessageEventArgs(exception); - handler(this, e); - } - catch (Exception e) - { // eat the exception - // UNDONE - should not be catching all exceptions!!! - if (!ADP.IsCatchableOrSecurityExceptionType(e)) - { - throw; - } - - ADP.TraceExceptionWithoutRethrow(e); - } - } - } } } diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnection.NoCOMWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbConnection.NoCOMWrappers.cs index a29d6e9c94c66d..d2b0b98fe38f7d 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbConnection.NoCOMWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbConnection.NoCOMWrappers.cs @@ -71,29 +71,5 @@ public sealed partial class OleDbConnection } return e; } - - internal void OnInfoMessage(UnsafeNativeMethods.IErrorInfo errorInfo, OleDbHResult errorCode) - { - OleDbInfoMessageEventHandler? handler = (OleDbInfoMessageEventHandler?)Events[EventInfoMessage]; - if (null != handler) - { - try - { - OleDbException exception = OleDbException.CreateException(errorInfo, errorCode, null); - OleDbInfoMessageEventArgs e = new OleDbInfoMessageEventArgs(exception); - handler(this, e); - } - catch (Exception e) - { // eat the exception - // UNDONE - should not be catching all exceptions!!! - if (!ADP.IsCatchableOrSecurityExceptionType(e)) - { - throw; - } - - ADP.TraceExceptionWithoutRethrow(e); - } - } - } } } diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnection.cs b/src/libraries/System.Data.OleDb/src/OleDbConnection.cs index 9e91a06c9ace0f..e9621a8ddfac45 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbConnection.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbConnection.cs @@ -488,6 +488,30 @@ internal bool HasLiveReader(OleDbCommand cmd) return result; } + internal void OnInfoMessage(UnsafeNativeMethods.IErrorInfo errorInfo, OleDbHResult errorCode) + { + OleDbInfoMessageEventHandler? handler = (OleDbInfoMessageEventHandler?)Events[EventInfoMessage]; + if (null != handler) + { + try + { + OleDbException exception = OleDbException.CreateException(errorInfo, errorCode, null); + OleDbInfoMessageEventArgs e = new OleDbInfoMessageEventArgs(exception); + handler(this, e); + } + catch (Exception e) + { // eat the exception + // UNDONE - should not be catching all exceptions!!! + if (!ADP.IsCatchableOrSecurityExceptionType(e)) + { + throw; + } + + ADP.TraceExceptionWithoutRethrow(e); + } + } + } + public override void Open() { InnerConnection.OpenConnection(this, ConnectionFactory); From 27a857b66f8342aef99bacff9a512f870a7a7a3a Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Mon, 20 Sep 2021 23:50:26 +0600 Subject: [PATCH 26/36] Consolidate different part of code --- .../src/DbPropSet.COMWrappers.cs | 39 --------- .../src/DbPropSet.NoCOMWrappers.cs | 29 ------- .../System.Data.OleDb/src/DbPropSet.cs | 23 ++++++ .../src/OleDbConnection.COMWrappers.cs | 80 ------------------- .../src/OleDbConnection.NoCOMWrappers.cs | 75 ----------------- .../System.Data.OleDb/src/OleDbConnection.cs | 61 ++++++++++++++ .../src/UnsafeNativeMethods.COMWrappers.cs | 18 +++++ .../src/UnsafeNativeMethods.NoCOMWrappers.cs | 7 +- 8 files changed, 108 insertions(+), 224 deletions(-) delete mode 100644 src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs delete mode 100644 src/libraries/System.Data.OleDb/src/DbPropSet.NoCOMWrappers.cs delete mode 100644 src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs delete mode 100644 src/libraries/System.Data.OleDb/src/OleDbConnection.NoCOMWrappers.cs diff --git a/src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs deleted file mode 100644 index 7cc7f613fa5683..00000000000000 --- a/src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs +++ /dev/null @@ -1,39 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Data.Common; -using System.Diagnostics; -using System.Globalization; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace System.Data.OleDb -{ - internal sealed partial class DBPropSet - { - private unsafe void SetLastErrorInfo(OleDbHResult lastErrorHr) - { - // note: OleDbHResult is actually a simple wrapper over HRESULT with OLEDB-specific codes - string message = string.Empty; - IntPtr pErrorInfo; - OleDbHResult errorInfoHr = UnsafeNativeMethods.GetErrorInfo(0, &pErrorInfo); // 0 - IErrorInfo exists, 1 - no IErrorInfo - if ((errorInfoHr == OleDbHResult.S_OK) && (pErrorInfo != IntPtr.Zero)) - { - UnsafeNativeMethods.IErrorInfo errorInfo = (UnsafeNativeMethods.IErrorInfo)OleDbComWrappers.Instance - .GetOrCreateObjectForComInstance(pErrorInfo, CreateObjectFlags.UniqueInstance); - 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 - { - ((IDisposable)errorInfo).Dispose(); - } - } - - lastErrorFromProvider = new COMException(message, (int)lastErrorHr); - } - } -} diff --git a/src/libraries/System.Data.OleDb/src/DbPropSet.NoCOMWrappers.cs b/src/libraries/System.Data.OleDb/src/DbPropSet.NoCOMWrappers.cs deleted file mode 100644 index e8958298fddd6d..00000000000000 --- a/src/libraries/System.Data.OleDb/src/DbPropSet.NoCOMWrappers.cs +++ /dev/null @@ -1,29 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Data.Common; -using System.Diagnostics; -using System.Globalization; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace System.Data.OleDb -{ - internal sealed partial class DBPropSet - { - private void SetLastErrorInfo(OleDbHResult lastErrorHr) - { - // note: OleDbHResult is actually a simple wrapper over HRESULT with OLEDB-specific codes - UnsafeNativeMethods.IErrorInfo? errorInfo = null; - string message = string.Empty; - - 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 - } - lastErrorFromProvider = new COMException(message, (int)lastErrorHr); - } - } -} diff --git a/src/libraries/System.Data.OleDb/src/DbPropSet.cs b/src/libraries/System.Data.OleDb/src/DbPropSet.cs index af23cca13a6c7b..1fc361e9d79e5f 100644 --- a/src/libraries/System.Data.OleDb/src/DbPropSet.cs +++ b/src/libraries/System.Data.OleDb/src/DbPropSet.cs @@ -96,6 +96,29 @@ internal DBPropSet(UnsafeNativeMethods.ICommandProperties properties, PropertyID } } + private unsafe void SetLastErrorInfo(OleDbHResult lastErrorHr) + { + // note: OleDbHResult is actually a simple wrapper over HRESULT with OLEDB-specific codes + UnsafeNativeMethods.IErrorInfo? errorInfo = null; + string message = string.Empty; + + OleDbHResult errorInfoHr = UnsafeNativeMethods.GetErrorInfo(0, out errorInfo); // 0 - IErrorInfo exists, 1 - no IErrorInfo + if ((errorInfoHr == OleDbHResult.S_OK) && (errorInfo != null)) + { + 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); + } + public override bool IsInvalid { get diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs deleted file mode 100644 index 5fffb4736dee8c..00000000000000 --- a/src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs +++ /dev/null @@ -1,80 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; -using System.Data.Common; -using System.Data.ProviderBase; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Runtime.InteropServices; -using System.Text; - -namespace System.Data.OleDb -{ - public sealed partial class OleDbConnection - { - internal static unsafe Exception? ProcessResults(OleDbHResult hresult, OleDbConnection? connection, object? src) - { - if ((0 <= (int)hresult) && ((null == connection) || (null == connection.Events[EventInfoMessage]))) - { - SafeNativeMethods.Wrapper.ClearErrorInfo(); - return null; - } - - // ErrorInfo object is to be checked regardless the hresult returned by the function called - Exception? e = null; - IntPtr pErrorInfo; - OleDbHResult hr = UnsafeNativeMethods.GetErrorInfo(0, &pErrorInfo); // 0 - IErrorInfo exists, 1 - no IErrorInfo - if ((OleDbHResult.S_OK == hr) && (IntPtr.Zero != pErrorInfo)) - { - UnsafeNativeMethods.IErrorInfo errorInfo = (UnsafeNativeMethods.IErrorInfo)OleDbComWrappers.Instance - .GetOrCreateObjectForComInstance(pErrorInfo, CreateObjectFlags.UniqueInstance); - try - { - if (hresult < 0) - { - // 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); - } - } - finally - { - ((IDisposable)errorInfo).Dispose(); - } - } - else if (0 < hresult) - { - // @devnote: OnInfoMessage with no ErrorInfo - } - else if ((int)hresult < 0) - { - e = ODB.NoErrorInformation((null != connection) ? connection.Provider : null, hresult, null); // OleDbException - - ResetState(connection); - } - if (null != e) - { - ADP.TraceExceptionAsReturnValue(e); - } - return e; - } - } -} diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnection.NoCOMWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbConnection.NoCOMWrappers.cs deleted file mode 100644 index d2b0b98fe38f7d..00000000000000 --- a/src/libraries/System.Data.OleDb/src/OleDbConnection.NoCOMWrappers.cs +++ /dev/null @@ -1,75 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; -using System.Data.Common; -using System.Data.ProviderBase; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Runtime.InteropServices; -using System.Text; - -namespace System.Data.OleDb -{ - public sealed partial class OleDbConnection - { - internal static Exception? ProcessResults(OleDbHResult hresult, OleDbConnection? connection, object? src) - { - if ((0 <= (int)hresult) && ((null == connection) || (null == connection.Events[EventInfoMessage]))) - { - SafeNativeMethods.Wrapper.ClearErrorInfo(); - return null; - } - - // ErrorInfo object is to be checked regardless the hresult returned by the function called - Exception? e = null; - UnsafeNativeMethods.IErrorInfo? errorInfo = null; - OleDbHResult hr = UnsafeNativeMethods.GetErrorInfo(0, out errorInfo); // 0 - IErrorInfo exists, 1 - no IErrorInfo - if ((OleDbHResult.S_OK == hr) && (null != errorInfo)) - { - if (hresult < 0) - { - // 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); - } - else - { - } - Marshal.ReleaseComObject(errorInfo); - } - else if (0 < hresult) - { - // @devnote: OnInfoMessage with no ErrorInfo - } - else if ((int)hresult < 0) - { - e = ODB.NoErrorInformation((null != connection) ? connection.Provider : null, hresult, null); // OleDbException - - ResetState(connection); - } - if (null != e) - { - ADP.TraceExceptionAsReturnValue(e); - } - return e; - } - } -} diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnection.cs b/src/libraries/System.Data.OleDb/src/OleDbConnection.cs index e9621a8ddfac45..a2ca8cbd1f344c 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbConnection.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbConnection.cs @@ -568,6 +568,67 @@ internal bool SupportSchemaRowset(Guid schema) return GetOpenConnection().SupportSchemaRowset(schema); } + internal static unsafe Exception? ProcessResults(OleDbHResult hresult, OleDbConnection? connection, object? src) + { + if ((0 <= (int)hresult) && ((null == connection) || (null == connection.Events[EventInfoMessage]))) + { + SafeNativeMethods.Wrapper.ClearErrorInfo(); + return null; + } + + // ErrorInfo object is to be checked regardless the hresult returned by the function called + Exception? e = null; + UnsafeNativeMethods.IErrorInfo? errorInfo = null; + OleDbHResult hr = UnsafeNativeMethods.GetErrorInfo(0, out errorInfo); // 0 - IErrorInfo exists, 1 - no IErrorInfo + if ((OleDbHResult.S_OK == hr) && (null != errorInfo)) + { + try + { + if (hresult < 0) + { + // 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); + } + } + finally + { + UnsafeNativeMethods.ReleaseErrorInfoObject(errorInfo); + } + } + else if (0 < hresult) + { + // @devnote: OnInfoMessage with no ErrorInfo + } + else if ((int)hresult < 0) + { + e = ODB.NoErrorInformation((null != connection) ? connection.Provider : null, hresult, null); // OleDbException + + ResetState(connection); + } + if (null != e) + { + ADP.TraceExceptionAsReturnValue(e); + } + return e; + } + internal OleDbTransaction? ValidateTransaction(OleDbTransaction? transaction, string method) { return GetOpenConnection().ValidateTransaction(transaction, method); diff --git a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs index 9af6b7b0c2168a..d61ed645e7de6f 100644 --- a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs @@ -15,5 +15,23 @@ internal static partial class UnsafeNativeMethods internal static unsafe extern System.Data.OleDb.OleDbHResult GetErrorInfo( int dwReserved, System.IntPtr* ppIErrorInfo); + + internal static extern System.Data.OleDb.OleDbHResult GetErrorInfo( + int dwReserved, + out UnsafeNativeMethods.IErrorInfo? ppIErrorInfo) + { + ppIErrorInfo = null; + var hr = GetErrorInfo(dwReserved, out IntPtr pErrorInfo); + if (hr == OleDbHResult.S_OK) + { + ppIErrorInfo = (UnsafeNativeMethods.IErrorInfo)OleDbComWrappers.Instance + .GetOrCreateObjectForComInstance(pErrorInfo, CreateObjectFlags.UniqueInstance); + } + } + + internal static void ReleaseErrorInfoObject(UnsafeNativeMethods.IErrorInfo errorInfo) + { + ((IDisposable)errorInfo).Dispose(); + } } } diff --git a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.NoCOMWrappers.cs b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.NoCOMWrappers.cs index adb8f74e0dae3f..48cdce7597bbe4 100644 --- a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.NoCOMWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.NoCOMWrappers.cs @@ -14,6 +14,11 @@ internal static partial class UnsafeNativeMethods [DllImport(Interop.Libraries.OleAut32, CharSet = CharSet.Unicode, PreserveSig = true)] internal static extern System.Data.OleDb.OleDbHResult GetErrorInfo( [In] int dwReserved, - [Out, MarshalAs(UnmanagedType.Interface)] out UnsafeNativeMethods.IErrorInfo ppIErrorInfo); + [Out, MarshalAs(UnmanagedType.Interface)] out UnsafeNativeMethods.IErrorInfo? ppIErrorInfo); + + internal static void ReleaseErrorInfoObject(UnsafeNativeMethods.IErrorInfo errorInfo) + { + Marshal.ReleaseComObject(errorInfo); + } } } From eca9732e4a0a68068eb1d664211de19c7ab488c4 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Mon, 20 Sep 2021 23:52:41 +0600 Subject: [PATCH 27/36] Remove junk (probably from merge) --- src/libraries/System.Data.OleDb/src/OleDbConnection.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnection.cs b/src/libraries/System.Data.OleDb/src/OleDbConnection.cs index a2ca8cbd1f344c..bd357da2db79a1 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbConnection.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbConnection.cs @@ -629,11 +629,6 @@ internal bool SupportSchemaRowset(Guid schema) return e; } - internal OleDbTransaction? ValidateTransaction(OleDbTransaction? transaction, string method) - { - return GetOpenConnection().ValidateTransaction(transaction, method); - } - // @devnote: should be multithread safe public static void ReleaseObjectPool() { From 76b3032c4ded2682bfd8d9e074192372596795ae Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Mon, 20 Sep 2021 23:53:39 +0600 Subject: [PATCH 28/36] Found that last commit was a mess --- src/libraries/System.Data.OleDb/src/OleDbConnection.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnection.cs b/src/libraries/System.Data.OleDb/src/OleDbConnection.cs index bd357da2db79a1..d2786ad0b168e1 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbConnection.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbConnection.cs @@ -568,6 +568,11 @@ internal bool SupportSchemaRowset(Guid schema) return GetOpenConnection().SupportSchemaRowset(schema); } + internal OleDbTransaction? ValidateTransaction(OleDbTransaction? transaction, string method) + { + return GetOpenConnection().ValidateTransaction(transaction, method); + } + internal static unsafe Exception? ProcessResults(OleDbHResult hresult, OleDbConnection? connection, object? src) { if ((0 <= (int)hresult) && ((null == connection) || (null == connection.Events[EventInfoMessage]))) From 75567c22a4d4380d6e2d2524d4b1a35454cd106f Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Mon, 20 Sep 2021 23:55:59 +0600 Subject: [PATCH 29/36] Remove no longer needed annotations --- src/libraries/System.Data.OleDb/src/DbPropSet.cs | 4 ++-- src/libraries/System.Data.OleDb/src/OleDbConnection.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Data.OleDb/src/DbPropSet.cs b/src/libraries/System.Data.OleDb/src/DbPropSet.cs index 1fc361e9d79e5f..0adeb559986882 100644 --- a/src/libraries/System.Data.OleDb/src/DbPropSet.cs +++ b/src/libraries/System.Data.OleDb/src/DbPropSet.cs @@ -9,7 +9,7 @@ namespace System.Data.OleDb { - internal sealed partial class DBPropSet : SafeHandle + internal sealed class DBPropSet : SafeHandle { private readonly int propertySetCount; @@ -96,7 +96,7 @@ internal DBPropSet(UnsafeNativeMethods.ICommandProperties properties, PropertyID } } - private unsafe void SetLastErrorInfo(OleDbHResult lastErrorHr) + private void SetLastErrorInfo(OleDbHResult lastErrorHr) { // note: OleDbHResult is actually a simple wrapper over HRESULT with OLEDB-specific codes UnsafeNativeMethods.IErrorInfo? errorInfo = null; diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnection.cs b/src/libraries/System.Data.OleDb/src/OleDbConnection.cs index d2786ad0b168e1..095495db3816ae 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbConnection.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbConnection.cs @@ -21,7 +21,7 @@ namespace System.Data.OleDb // it won't happen if you directly create the provider and set its properties // 3. First call on IDBInitialize must be Initialize, can't QI for any other interfaces before that [DefaultEvent("InfoMessage")] - public sealed partial class OleDbConnection : DbConnection, ICloneable, IDbConnection + public sealed class OleDbConnection : DbConnection, ICloneable, IDbConnection { private static readonly object EventInfoMessage = new object(); @@ -573,7 +573,7 @@ internal bool SupportSchemaRowset(Guid schema) return GetOpenConnection().ValidateTransaction(transaction, method); } - internal static unsafe Exception? ProcessResults(OleDbHResult hresult, OleDbConnection? connection, object? src) + internal static Exception? ProcessResults(OleDbHResult hresult, OleDbConnection? connection, object? src) { if ((0 <= (int)hresult) && ((null == connection) || (null == connection.Events[EventInfoMessage]))) { From 3c66ce742541eb104543443995c9bc1a638dc332 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Tue, 21 Sep 2021 11:17:15 +0600 Subject: [PATCH 30/36] Apply suggestions from code review Co-authored-by: Aaron Robinson --- .../src/UnsafeNativeMethods.NoCOMWrappers.cs | 4 ++-- src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.NoCOMWrappers.cs b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.NoCOMWrappers.cs index 48cdce7597bbe4..0de48aee45c7f0 100644 --- a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.NoCOMWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.NoCOMWrappers.cs @@ -13,8 +13,8 @@ internal static partial class UnsafeNativeMethods [DllImport(Interop.Libraries.OleAut32, CharSet = CharSet.Unicode, PreserveSig = true)] internal static extern System.Data.OleDb.OleDbHResult GetErrorInfo( - [In] int dwReserved, - [Out, MarshalAs(UnmanagedType.Interface)] out UnsafeNativeMethods.IErrorInfo? ppIErrorInfo); + int dwReserved, + [MarshalAs(UnmanagedType.Interface)] out UnsafeNativeMethods.IErrorInfo? ppIErrorInfo); internal static void ReleaseErrorInfoObject(UnsafeNativeMethods.IErrorInfo errorInfo) { diff --git a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.cs b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.cs index fda384fd221be9..2453d6930a1192 100644 --- a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.cs +++ b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.cs @@ -513,11 +513,11 @@ internal interface IErrorInfo [PreserveSig] System.Data.OleDb.OleDbHResult GetSource( - [Out, MarshalAs(UnmanagedType.BStr)] out string? pBstrSource); + [MarshalAs(UnmanagedType.BStr)] out string? pBstrSource); [PreserveSig] System.Data.OleDb.OleDbHResult GetDescription( - [Out, MarshalAs(UnmanagedType.BStr)] out string? pBstrDescription); + [MarshalAs(UnmanagedType.BStr)] out string? pBstrDescription); //[ Obsolete("not used", true)] void GetHelpFile(/*deleted parameter signature*/); From af6d01e42662e2671700c003f4afa7d193454b32 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Tue, 21 Sep 2021 11:18:03 +0600 Subject: [PATCH 31/36] Update src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs Co-authored-by: Aaron Robinson --- src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs index cfbd29e4f5b8bd..d4666e24521718 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs @@ -48,6 +48,7 @@ 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; From ed5e796927f5227ac8a2157785267b5dceb705f9 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Tue, 21 Sep 2021 11:30:15 +0600 Subject: [PATCH 32/36] Free BSTR --- .../System.Data.OleDb/src/OleDbComWrappers.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs index d4666e24521718..d04d090aa2fd60 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs @@ -83,6 +83,11 @@ public unsafe System.Data.OleDb.OleDbHResult GetSource(out string? source) source = Marshal.PtrToStringBSTR(pSource); } + if (pSource != IntPtr.Zero) + { + Marshal.FreeBSTR(pSource); + } + return (System.Data.OleDb.OleDbHResult)errorCode; } @@ -100,6 +105,11 @@ public unsafe System.Data.OleDb.OleDbHResult GetDescription(out string? descript description = Marshal.PtrToStringBSTR(pDescription); } + if (pSource != IntPtr.Zero) + { + Marshal.FreeBSTR(pDescription); + } + return (System.Data.OleDb.OleDbHResult)errorCode; } } From c897950cc48f6850c676c19d1ffd6105bf25fdab Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Tue, 21 Sep 2021 12:42:23 +0600 Subject: [PATCH 33/36] Remove reference to no longer used files in this PR --- src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj | 4 ---- 1 file changed, 4 deletions(-) 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 46e57aa2f12304..e7b80a71a61c34 100644 --- a/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj +++ b/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj @@ -114,13 +114,9 @@ System.Data.OleDb.OleDbTransaction - - - - From a331a8e7bfdf3f970406312ac5b28fbfd0247215 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Tue, 21 Sep 2021 13:31:51 +0600 Subject: [PATCH 34/36] Add data --- src/libraries/System.Data.OleDb/src/OleDbConnection.cs | 2 +- .../System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnection.cs b/src/libraries/System.Data.OleDb/src/OleDbConnection.cs index 095495db3816ae..7e456b936fba7b 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbConnection.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbConnection.cs @@ -21,7 +21,7 @@ namespace System.Data.OleDb // it won't happen if you directly create the provider and set its properties // 3. First call on IDBInitialize must be Initialize, can't QI for any other interfaces before that [DefaultEvent("InfoMessage")] - public sealed class OleDbConnection : DbConnection, ICloneable, IDbConnection + public sealed partial class OleDbConnection : DbConnection, ICloneable, IDbConnection { private static readonly object EventInfoMessage = new object(); diff --git a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs index d61ed645e7de6f..3e5a10e51dc84f 100644 --- a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs @@ -16,7 +16,7 @@ internal static unsafe extern System.Data.OleDb.OleDbHResult GetErrorInfo( int dwReserved, System.IntPtr* ppIErrorInfo); - internal static extern System.Data.OleDb.OleDbHResult GetErrorInfo( + internal static System.Data.OleDb.OleDbHResult GetErrorInfo( int dwReserved, out UnsafeNativeMethods.IErrorInfo? ppIErrorInfo) { From e6efd5c2d071d42153474ef3bb9721104c1343e4 Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Tue, 21 Sep 2021 15:37:15 +0600 Subject: [PATCH 35/36] Fix compilation errors --- src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs | 2 +- .../src/UnsafeNativeMethods.COMWrappers.cs | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs b/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs index d04d090aa2fd60..92a54fe9e223ed 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs @@ -105,7 +105,7 @@ public unsafe System.Data.OleDb.OleDbHResult GetDescription(out string? descript description = Marshal.PtrToStringBSTR(pDescription); } - if (pSource != IntPtr.Zero) + if (pDescription != IntPtr.Zero) { Marshal.FreeBSTR(pDescription); } diff --git a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs index 3e5a10e51dc84f..51e5ef12cbda1b 100644 --- a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Data.OleDb; using System.Runtime.InteropServices; namespace System.Data.Common @@ -12,16 +13,17 @@ internal static partial class UnsafeNativeMethods // [DllImport(Interop.Libraries.OleAut32)] - internal static unsafe extern System.Data.OleDb.OleDbHResult GetErrorInfo( + internal static unsafe extern OleDbHResult GetErrorInfo( int dwReserved, System.IntPtr* ppIErrorInfo); - internal static System.Data.OleDb.OleDbHResult GetErrorInfo( + internal static unsafe OleDbHResult GetErrorInfo( int dwReserved, out UnsafeNativeMethods.IErrorInfo? ppIErrorInfo) { ppIErrorInfo = null; - var hr = GetErrorInfo(dwReserved, out IntPtr pErrorInfo); + IntPtr pErrorInfo; + var hr = GetErrorInfo(dwReserved, &pErrorInfo); if (hr == OleDbHResult.S_OK) { ppIErrorInfo = (UnsafeNativeMethods.IErrorInfo)OleDbComWrappers.Instance From 93b8fd3842cf9f40f248110b4cdc26aab9f59d7e Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Tue, 21 Sep 2021 16:16:33 +0600 Subject: [PATCH 36/36] Last blow to compiler --- .../System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs index 51e5ef12cbda1b..259b856952d31f 100644 --- a/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs +++ b/src/libraries/System.Data.OleDb/src/UnsafeNativeMethods.COMWrappers.cs @@ -29,6 +29,8 @@ internal static unsafe OleDbHResult GetErrorInfo( ppIErrorInfo = (UnsafeNativeMethods.IErrorInfo)OleDbComWrappers.Instance .GetOrCreateObjectForComInstance(pErrorInfo, CreateObjectFlags.UniqueInstance); } + + return hr; } internal static void ReleaseErrorInfoObject(UnsafeNativeMethods.IErrorInfo errorInfo)