forked from dotnet/runtime
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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 dotnet#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.
- Loading branch information
Showing
21 changed files
with
917 additions
and
333 deletions.
There are no files selected for viewing
31 changes: 31 additions & 0 deletions
31
src/libraries/System.Data.OleDb/src/DbPropSet.COMWrappers.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} | ||
} | ||
} |
29 changes: 29 additions & 0 deletions
29
src/libraries/System.Data.OleDb/src/DbPropSet.NoCOMWrappers.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
108 changes: 108 additions & 0 deletions
108
src/libraries/System.Data.OleDb/src/OleDbComWrappers.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
{ | ||
/// <summary> | ||
/// The ComWrappers implementation for System.Data.OleDb's COM interop usages. | ||
/// | ||
/// Supports IErrorInfo COM interface. | ||
/// </summary> | ||
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<IntPtr, IntPtr*, int>)(*(*(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<IntPtr, IntPtr*, int>)(*(*(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; | ||
} | ||
} | ||
|
||
} | ||
} |
99 changes: 99 additions & 0 deletions
99
src/libraries/System.Data.OleDb/src/OleDbConnection.COMWrappers.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.