From 48ab625f82bc2f147276e02862b47b24f06d576c Mon Sep 17 00:00:00 2001 From: SqlClient DevOps Date: Sat, 4 May 2024 02:08:39 +0000 Subject: [PATCH 01/25] [Scheduled Run] Localized resource files from OneLocBuild --- src/Microsoft.Data.SqlClient/src/Resources/Strings.de.resx | 5 ++++- src/Microsoft.Data.SqlClient/src/Resources/Strings.es.resx | 2 +- src/Microsoft.Data.SqlClient/src/Resources/Strings.fr.resx | 2 +- src/Microsoft.Data.SqlClient/src/Resources/Strings.it.resx | 2 +- src/Microsoft.Data.SqlClient/src/Resources/Strings.ja.resx | 2 +- src/Microsoft.Data.SqlClient/src/Resources/Strings.ko.resx | 2 +- .../src/Resources/Strings.pt-BR.resx | 2 +- src/Microsoft.Data.SqlClient/src/Resources/Strings.ru.resx | 2 +- .../src/Resources/Strings.zh-Hans.resx | 2 +- .../src/Resources/Strings.zh-Hant.resx | 2 +- 10 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.de.resx b/src/Microsoft.Data.SqlClient/src/Resources/Strings.de.resx index 7862b1769c..4a6d349fd8 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.de.resx +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.de.resx @@ -4680,6 +4680,9 @@ Socket hat den erwarteten "{0}" nicht ausgelöst. Fehlercode: "{1}". + + Der Server versucht, ein Feature zu verwenden, das auf dieser Plattform nicht unterstützt wird. + Das Schlüsselwort "{0}" wird auf dieser Plattform nicht unterstützt. @@ -4734,4 +4737,4 @@ Das Zertifikat ist während der Überprüfung des Zertifikats nicht verfügbar. - + \ No newline at end of file diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.es.resx b/src/Microsoft.Data.SqlClient/src/Resources/Strings.es.resx index 028ceeba85..ff71f45c02 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.es.resx +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.es.resx @@ -4737,4 +4737,4 @@ El certificado no está disponible al validar el certificado. - + \ No newline at end of file diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.fr.resx b/src/Microsoft.Data.SqlClient/src/Resources/Strings.fr.resx index 60c04699b7..8b426074c2 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.fr.resx +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.fr.resx @@ -4737,4 +4737,4 @@ Certificat non disponible lors de sa validation. - + \ No newline at end of file diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.it.resx b/src/Microsoft.Data.SqlClient/src/Resources/Strings.it.resx index 01e3a62844..b5cbd33bdd 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.it.resx +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.it.resx @@ -4737,4 +4737,4 @@ Certificato non disponibile durante la convalida del certificato. - + \ No newline at end of file diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.ja.resx b/src/Microsoft.Data.SqlClient/src/Resources/Strings.ja.resx index bd05c52169..de5a1c1830 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.ja.resx +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.ja.resx @@ -4737,4 +4737,4 @@ 証明書の検証中は証明書を使用できません。 - + \ No newline at end of file diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.ko.resx b/src/Microsoft.Data.SqlClient/src/Resources/Strings.ko.resx index e2886df8ff..20db99df33 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.ko.resx +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.ko.resx @@ -4737,4 +4737,4 @@ 인증서의 유효성을 검사하는 동안에는 인증서를 사용할 수 없습니다. - + \ No newline at end of file diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.pt-BR.resx b/src/Microsoft.Data.SqlClient/src/Resources/Strings.pt-BR.resx index 3a7fcbb0f4..911334848e 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.pt-BR.resx +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.pt-BR.resx @@ -4737,4 +4737,4 @@ Certificado não disponível durante a validação do certificado. - + \ No newline at end of file diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.ru.resx b/src/Microsoft.Data.SqlClient/src/Resources/Strings.ru.resx index 3051d03352..cae6234541 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.ru.resx +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.ru.resx @@ -4737,4 +4737,4 @@ Сертификат недоступен при проверке сертификата. - + \ No newline at end of file diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.zh-Hans.resx b/src/Microsoft.Data.SqlClient/src/Resources/Strings.zh-Hans.resx index e24601fb33..2b866bd6ed 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.zh-Hans.resx +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.zh-Hans.resx @@ -4737,4 +4737,4 @@ 验证证书时证书不可用。 - + \ No newline at end of file diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.zh-Hant.resx b/src/Microsoft.Data.SqlClient/src/Resources/Strings.zh-Hant.resx index 3492f58356..404f048cf6 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.zh-Hant.resx +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.zh-Hant.resx @@ -4737,4 +4737,4 @@ 驗證在進行憑證驗證時無法使用。 - + \ No newline at end of file From 55d30c71b9c17b804710b4d7ba83d92f2b2676be Mon Sep 17 00:00:00 2001 From: Javad Rahnama Date: Mon, 6 May 2024 10:58:22 -0700 Subject: [PATCH 02/25] Test | Remove AAS - VBS tests from test pipelines (#2474) --- BUILDGUIDE.md | 1 - .../tests/ManualTests/DataCommon/DataTestUtility.cs | 7 ------- .../Microsoft.Data.SqlClient.ExtUtilities/SqlDbManager.cs | 8 -------- .../Microsoft.Data.SqlClient.TestUtilities/Config.cs | 1 - .../config.default.json | 1 - 5 files changed, 18 deletions(-) diff --git a/BUILDGUIDE.md b/BUILDGUIDE.md index 5f57d70106..d7408fa15e 100644 --- a/BUILDGUIDE.md +++ b/BUILDGUIDE.md @@ -165,7 +165,6 @@ Manual Tests require the below setup to run: |TCPConnectionString | Connection String for a TCP enabled SQL Server instance. | `Server={servername};Database={Database_Name};Trusted_Connection=True;`
OR `Data Source={servername};Initial Catalog={Database_Name};Integrated Security=True;`| |NPConnectionString | Connection String for a Named Pipes enabled SQL Server instance.| `Server=\\{servername}\pipe\sql\query;Database={Database_Name};Trusted_Connection=True;`
OR
`Data Source=np:{servername};Initial Catalog={Database_Name};Integrated Security=True;`| |TCPConnectionStringHGSVBS | (Optional) Connection String for a TCP enabled SQL Server with Host Guardian Service (HGS) attestation protocol configuration. | `Server=tcp:{servername}; Database={Database_Name}; UID={UID}; PWD={PWD}; Attestation Protocol = HGS; Enclave Attestation Url = {AttestationURL};`| - |TCPConnectionStringAASVBS | (Optional) Connection String for a TCP enabled SQL Server with a VBS Enclave and using Microsoft Azure Attestation (AAS) attestation protocol configuration. | `Server=tcp:{servername}; Database={Database_Name}; UID={UID}; PWD={PWD}; Attestation Protocol = AAS; Enclave Attestation Url = {AttestationURL};`| |TCPConnectionStringNoneVBS | (Optional) Connection String for a TCP enabled SQL Server with a VBS Enclave and using None Attestation protocol configuration. | `Server=tcp:{servername}; Database={Database_Name}; UID={UID}; PWD={PWD}; Attestation Protocol = NONE;`| |TCPConnectionStringAASSGX | (Optional) Connection String for a TCP enabled SQL Server with a SGX Enclave and using Microsoft Azure Attestation (AAS) attestation protocol configuration. | `Server=tcp:{servername}; Database={Database_Name}; UID={UID}; PWD={PWD}; Attestation Protocol = AAS; Enclave Attestation Url = {AttestationURL};`| |EnclaveEnabled | Enables tests requiring an enclave-configured server.| diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs index 06209e1ad2..62d4f641ea 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs @@ -32,7 +32,6 @@ public static class DataTestUtility public static readonly string NPConnectionString = null; public static readonly string TCPConnectionString = null; public static readonly string TCPConnectionStringHGSVBS = null; - public static readonly string TCPConnectionStringAASVBS = null; public static readonly string TCPConnectionStringNoneVBS = null; public static readonly string TCPConnectionStringAASSGX = null; public static readonly string AADAuthorityURL = null; @@ -144,7 +143,6 @@ static DataTestUtility() NPConnectionString = c.NPConnectionString; TCPConnectionString = c.TCPConnectionString; TCPConnectionStringHGSVBS = c.TCPConnectionStringHGSVBS; - TCPConnectionStringAASVBS = c.TCPConnectionStringAASVBS; TCPConnectionStringNoneVBS = c.TCPConnectionStringNoneVBS; TCPConnectionStringAASSGX = c.TCPConnectionStringAASSGX; AADAuthorityURL = c.AADAuthorityURL; @@ -203,11 +201,6 @@ static DataTestUtility() AEConnStringsSetup.Add(TCPConnectionStringHGSVBS); } - if (!string.IsNullOrEmpty(TCPConnectionStringAASVBS)) - { - AEConnStrings.Add(TCPConnectionStringAASVBS); - } - if (!string.IsNullOrEmpty(TCPConnectionStringNoneVBS)) { AEConnStrings.Add(TCPConnectionStringNoneVBS); diff --git a/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.ExtUtilities/SqlDbManager.cs b/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.ExtUtilities/SqlDbManager.cs index 6a936ac5a1..52bf5c30f4 100644 --- a/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.ExtUtilities/SqlDbManager.cs +++ b/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.ExtUtilities/SqlDbManager.cs @@ -24,7 +24,6 @@ public static class SqlDbManager private const string TCPConnectionString = "TCPConnectionString"; private const string NPConnectionString = "NPConnectionString"; private const string TCPConnectionStringAASSGX = "TCPConnectionStringAASSGX"; - private const string TCPConnectionStringAASVBS = "TCPConnectionStringAASVBS"; private const string TCPConnectionStringHGSVBS = "TCPConnectionStringHGSVBS"; /// @@ -124,10 +123,6 @@ private static void LoadActiveConnectionStrings() { s_activeConnectionStrings.Add(TCPConnectionStringAASSGX, s_configJson.TCPConnectionStringAASSGX); } - if (!string.IsNullOrEmpty(s_configJson.TCPConnectionStringAASVBS)) - { - s_activeConnectionStrings.Add(TCPConnectionStringAASVBS, s_configJson.TCPConnectionStringAASVBS); - } if (!string.IsNullOrEmpty(s_configJson.TCPConnectionStringHGSVBS)) { s_activeConnectionStrings.Add(TCPConnectionStringHGSVBS, s_configJson.TCPConnectionStringHGSVBS); @@ -148,9 +143,6 @@ private static void UpdateConfig(string key, SqlConnectionStringBuilder builder) case TCPConnectionStringAASSGX: s_configJson.TCPConnectionStringAASSGX = builder.ConnectionString; break; - case TCPConnectionStringAASVBS: - s_configJson.TCPConnectionStringAASVBS = builder.ConnectionString; - break; case TCPConnectionStringHGSVBS: s_configJson.TCPConnectionStringHGSVBS = builder.ConnectionString; break; diff --git a/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Config.cs b/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Config.cs index 14dcd5e086..3fbe8313ee 100644 --- a/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Config.cs +++ b/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Config.cs @@ -13,7 +13,6 @@ public class Config public string TCPConnectionString = null; public string NPConnectionString = null; public string TCPConnectionStringHGSVBS = null; - public string TCPConnectionStringAASVBS = null; public string TCPConnectionStringNoneVBS = null; public string TCPConnectionStringAASSGX = null; public string AADAuthorityURL = null; diff --git a/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/config.default.json b/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/config.default.json index f656c3ae15..d159b7628d 100644 --- a/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/config.default.json +++ b/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/config.default.json @@ -2,7 +2,6 @@ "TCPConnectionString": "Data Source=tcp:localhost;Database=Northwind;Integrated Security=true;Encrypt=false;", "NPConnectionString": "Data Source=np:localhost;Database=Northwind;Integrated Security=true;Encrypt=false;", "TCPConnectionStringHGSVBS": "", - "TCPConnectionStringAASVBS": "", "TCPConnectionStringNoneVBS": "", "TCPConnectionStringAASSGX": "", "EnclaveEnabled": false, From b4f38f50d4fb03e49956b8007496c50c22fbbea2 Mon Sep 17 00:00:00 2001 From: Taylor Southwick Date: Mon, 6 May 2024 16:27:12 -0700 Subject: [PATCH 03/25] Use ReadOnlyMemory in (#2447) --- .../Interop/SNINativeMethodWrapper.Windows.cs | 9 ++++--- .../Microsoft/Data/SqlClient/SNI/SNIProxy.cs | 19 +++++++++++-- .../Interop/SNINativeManagedWrapperARM64.cs | 2 +- .../Interop/SNINativeManagedWrapperX64.cs | 2 +- .../Interop/SNINativeManagedWrapperX86.cs | 2 +- .../Data/Interop/SNINativeMethodWrapper.cs | 27 ++++++++++--------- .../SSPI/ManagedSSPIContextProvider.cs | 5 ++-- .../SSPI/NativeSSPIContextProvider.cs | 4 +-- .../SSPI/NegotiateSSPIContextProvider.cs | 4 +-- .../SqlClient/SSPI/SSPIContextProvider.cs | 10 +++---- .../src/Microsoft/Data/SqlClient/TdsParser.cs | 4 +-- 11 files changed, 53 insertions(+), 35 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Interop/SNINativeMethodWrapper.Windows.cs b/src/Microsoft.Data.SqlClient/netcore/src/Interop/SNINativeMethodWrapper.Windows.cs index c8591a8c11..6f75be4e70 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Interop/SNINativeMethodWrapper.Windows.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Interop/SNINativeMethodWrapper.Windows.cs @@ -315,7 +315,7 @@ private static extern uint SNIOpenWrapper( [DllImport(SNI, CallingConvention = CallingConvention.Cdecl)] private static extern unsafe uint SNISecGenClientContextWrapper( [In] SNIHandle pConn, - [In, Out] byte[] pIn, + [In, Out] byte* pIn, uint cbIn, [In, Out] byte[] pOut, [In] ref uint pcbOut, @@ -471,15 +471,16 @@ internal static unsafe void SNIPacketSetData(SNIPacket packet, byte[] data, int } } - internal static unsafe uint SNISecGenClientContext(SNIHandle pConnectionObject, byte[] inBuff, uint receivedLength, byte[] OutBuff, ref uint sendLength, byte[] serverUserName) + internal static unsafe uint SNISecGenClientContext(SNIHandle pConnectionObject, ReadOnlySpan inBuff, byte[] OutBuff, ref uint sendLength, byte[] serverUserName) { fixed (byte* pin_serverUserName = &serverUserName[0]) + fixed (byte* pInBuff = inBuff) { bool local_fDone; return SNISecGenClientContextWrapper( pConnectionObject, - inBuff, - receivedLength, + pInBuff, + (uint)inBuff.Length, OutBuff, ref sendLength, out local_fDone, diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs index ce3b9dd26b..3276023ef6 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Buffers; using System.Diagnostics; using System.IO; using System.Net; @@ -34,7 +35,21 @@ internal class SNIProxy /// Send buffer /// Service Principal Name buffer /// SNI error code - internal static void GenSspiClientContext(SspiClientContextStatus sspiClientContextStatus, byte[] receivedBuff, ref byte[] sendBuff, byte[][] serverName) + internal static void GenSspiClientContext(SspiClientContextStatus sspiClientContextStatus, ReadOnlyMemory receivedBuff, ref byte[] sendBuff, byte[][] serverName) + { + // TODO: this should use ReadOnlyMemory all the way through + byte[] array = null; + + if (!receivedBuff.IsEmpty) + { + array = new byte[receivedBuff.Length]; + receivedBuff.CopyTo(array); + } + + GenSspiClientContext(sspiClientContextStatus, array, ref sendBuff, serverName); + } + + private static void GenSspiClientContext(SspiClientContextStatus sspiClientContextStatus, byte[] receivedBuff, ref byte[] sendBuff, byte[][] serverName) { SafeDeleteContext securityContext = sspiClientContextStatus.SecurityContext; ContextFlagsPal contextFlags = sspiClientContextStatus.ContextFlags; @@ -189,7 +204,7 @@ internal static SNIHandle CreateConnectionHandle( case DataSource.Protocol.TCP: sniHandle = CreateTcpHandle(details, timeout, parallel, ipPreference, cachedFQDN, ref pendingDNSInfo, tlsFirst, hostNameInCertificate, serverCertificateFilename); - break; + break; case DataSource.Protocol.NP: sniHandle = CreateNpHandle(details, timeout, parallel, tlsFirst); break; diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperARM64.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperARM64.cs index 50552a3fb3..6e9bda11cd 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperARM64.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperARM64.cs @@ -116,7 +116,7 @@ internal static extern uint SNIOpenWrapper( [DllImport(SNI, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SNISecGenClientContextWrapper")] internal static extern unsafe uint SNISecGenClientContextWrapper( [In] SNIHandle pConn, - [In, Out] byte[] pIn, + [In, Out] byte* pIn, uint cbIn, [In, Out] byte[] pOut, [In] ref uint pcbOut, diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperX64.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperX64.cs index f4970e1cda..acb10c8c79 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperX64.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperX64.cs @@ -116,7 +116,7 @@ internal static extern uint SNIOpenWrapper( [DllImport(SNI, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SNISecGenClientContextWrapper")] internal static extern unsafe uint SNISecGenClientContextWrapper( [In] SNIHandle pConn, - [In, Out] byte[] pIn, + [In, Out] byte* pIn, uint cbIn, [In, Out] byte[] pOut, [In] ref uint pcbOut, diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperX86.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperX86.cs index 6e1a0abf5f..c8bb7c0e93 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperX86.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeManagedWrapperX86.cs @@ -116,7 +116,7 @@ internal static extern uint SNIOpenWrapper( [DllImport(SNI, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SNISecGenClientContextWrapper")] internal static extern unsafe uint SNISecGenClientContextWrapper( [In] SNIHandle pConn, - [In, Out] byte[] pIn, + [In, Out] byte* pIn, uint cbIn, [In, Out] byte[] pOut, [In] ref uint pcbOut, diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeMethodWrapper.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeMethodWrapper.cs index b9af5849c4..898fcc6866 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeMethodWrapper.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeMethodWrapper.cs @@ -889,8 +889,7 @@ private static unsafe void SNIPacketSetData(SNIPacket pPacket, [In] byte* pbBuf, private static unsafe uint SNISecGenClientContextWrapper( [In] SNIHandle pConn, - [In, Out] byte[] pIn, - uint cbIn, + [In, Out] ReadOnlySpan pIn, [In, Out] byte[] pOut, [In] ref uint pcbOut, [MarshalAsAttribute(UnmanagedType.Bool)] out bool pfDone, @@ -899,16 +898,19 @@ private static unsafe uint SNISecGenClientContextWrapper( [MarshalAsAttribute(UnmanagedType.LPWStr)] string pwszUserName, [MarshalAsAttribute(UnmanagedType.LPWStr)] string pwszPassword) { - switch (s_architecture) + fixed (byte* pInPtr = pIn) { - case System.Runtime.InteropServices.Architecture.Arm64: - return SNINativeManagedWrapperARM64.SNISecGenClientContextWrapper(pConn, pIn, cbIn, pOut, ref pcbOut, out pfDone, szServerInfo, cbServerInfo, pwszUserName, pwszPassword); - case System.Runtime.InteropServices.Architecture.X64: - return SNINativeManagedWrapperX64.SNISecGenClientContextWrapper(pConn, pIn, cbIn, pOut, ref pcbOut, out pfDone, szServerInfo, cbServerInfo, pwszUserName, pwszPassword); - case System.Runtime.InteropServices.Architecture.X86: - return SNINativeManagedWrapperX86.SNISecGenClientContextWrapper(pConn, pIn, cbIn, pOut, ref pcbOut, out pfDone, szServerInfo, cbServerInfo, pwszUserName, pwszPassword); - default: - throw ADP.SNIPlatformNotSupported(s_architecture.ToString()); + switch (s_architecture) + { + case System.Runtime.InteropServices.Architecture.Arm64: + return SNINativeManagedWrapperARM64.SNISecGenClientContextWrapper(pConn, pInPtr, (uint)pIn.Length, pOut, ref pcbOut, out pfDone, szServerInfo, cbServerInfo, pwszUserName, pwszPassword); + case System.Runtime.InteropServices.Architecture.X64: + return SNINativeManagedWrapperX64.SNISecGenClientContextWrapper(pConn, pInPtr, (uint)pIn.Length, pOut, ref pcbOut, out pfDone, szServerInfo, cbServerInfo, pwszUserName, pwszPassword); + case System.Runtime.InteropServices.Architecture.X86: + return SNINativeManagedWrapperX86.SNISecGenClientContextWrapper(pConn, pInPtr, (uint)pIn.Length, pOut, ref pcbOut, out pfDone, szServerInfo, cbServerInfo, pwszUserName, pwszPassword); + default: + throw ADP.SNIPlatformNotSupported(s_architecture.ToString()); + } } } @@ -1378,7 +1380,7 @@ Int32[] passwordOffsets // Offset into data buffer where the password to be w } } - internal static unsafe uint SNISecGenClientContext(SNIHandle pConnectionObject, byte[] inBuff, uint receivedLength, byte[] OutBuff, ref uint sendLength, byte[] serverUserName) + internal static unsafe uint SNISecGenClientContext(SNIHandle pConnectionObject, ReadOnlySpan inBuff, byte[] OutBuff, ref uint sendLength, byte[] serverUserName) { fixed (byte* pin_serverUserName = &serverUserName[0]) { @@ -1386,7 +1388,6 @@ internal static unsafe uint SNISecGenClientContext(SNIHandle pConnectionObject, return SNISecGenClientContextWrapper( pConnectionObject, inBuff, - receivedLength, OutBuff, ref sendLength, out local_fDone, diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/ManagedSSPIContextProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/ManagedSSPIContextProvider.cs index 25fb2cadae..8395371de7 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/ManagedSSPIContextProvider.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/ManagedSSPIContextProvider.cs @@ -1,5 +1,6 @@ #if !NETFRAMEWORK && !NET7_0_OR_GREATER +using System; using Microsoft.Data.SqlClient.SNI; #nullable enable @@ -10,11 +11,11 @@ internal sealed class ManagedSSPIContextProvider : SSPIContextProvider { private SspiClientContextStatus? _sspiClientContextStatus; - internal override void GenerateSspiClientContext(byte[] receivedBuff, uint receivedLength, ref byte[] sendBuff, ref uint sendLength, byte[][] _sniSpnBuffer) + internal override void GenerateSspiClientContext(ReadOnlyMemory received, ref byte[] sendBuff, ref uint sendLength, byte[][] _sniSpnBuffer) { _sspiClientContextStatus ??= new SspiClientContextStatus(); - SNIProxy.GenSspiClientContext(_sspiClientContextStatus, receivedBuff, ref sendBuff, _sniSpnBuffer); + SNIProxy.GenSspiClientContext(_sspiClientContextStatus, received, ref sendBuff, _sniSpnBuffer); SqlClientEventSource.Log.TryTraceEvent("TdsParserStateObjectManaged.GenerateSspiClientContext | Info | Session Id {0}", _physicalStateObj.SessionId); sendLength = (uint)(sendBuff != null ? sendBuff.Length : 0); } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NativeSSPIContextProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NativeSSPIContextProvider.cs index 718608d136..067682a617 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NativeSSPIContextProvider.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NativeSSPIContextProvider.cs @@ -50,7 +50,7 @@ private void LoadSSPILibrary() } } - internal override void GenerateSspiClientContext(byte[] receivedBuff, uint receivedLength, ref byte[] sendBuff, ref uint sendLength, byte[][] _sniSpnBuffer) + internal override void GenerateSspiClientContext(ReadOnlyMemory receivedBuff, ref byte[] sendBuff, ref uint sendLength, byte[][] _sniSpnBuffer) { #if NETFRAMEWORK SNIHandle handle = _physicalStateObj.Handle; @@ -58,7 +58,7 @@ internal override void GenerateSspiClientContext(byte[] receivedBuff, uint recei Debug.Assert(_physicalStateObj.SessionHandle.Type == SessionHandle.NativeHandleType); SNIHandle handle = _physicalStateObj.SessionHandle.NativeHandle; #endif - if (0 != SNINativeMethodWrapper.SNISecGenClientContext(handle, receivedBuff, receivedLength, sendBuff, ref sendLength, _sniSpnBuffer[0])) + if (0 != SNINativeMethodWrapper.SNISecGenClientContext(handle, receivedBuff.Span, sendBuff, ref sendLength, _sniSpnBuffer[0])) { throw new InvalidOperationException(SQLMessage.SSPIGenerateError()); } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NegotiateSSPIContextProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NegotiateSSPIContextProvider.cs index bc11cf29c9..2d73d28390 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NegotiateSSPIContextProvider.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NegotiateSSPIContextProvider.cs @@ -12,10 +12,10 @@ internal sealed class NegotiateSSPIContextProvider : SSPIContextProvider { private NegotiateAuthentication? _negotiateAuth = null; - internal override void GenerateSspiClientContext(byte[] receivedBuff, uint receivedLength, ref byte[] sendBuff, ref uint sendLength, byte[][] _sniSpnBuffer) + internal override void GenerateSspiClientContext(ReadOnlyMemory received, ref byte[] sendBuff, ref uint sendLength, byte[][] _sniSpnBuffer) { _negotiateAuth ??= new(new NegotiateAuthenticationClientOptions { Package = "Negotiate", TargetName = Encoding.Unicode.GetString(_sniSpnBuffer[0]) }); - sendBuff = _negotiateAuth.GetOutgoingBlob(receivedBuff, out NegotiateAuthenticationStatusCode statusCode)!; + sendBuff = _negotiateAuth.GetOutgoingBlob(received.Span, out NegotiateAuthenticationStatusCode statusCode)!; SqlClientEventSource.Log.TryTraceEvent("TdsParserStateObjectManaged.GenerateSspiClientContext | Info | Session Id {0}, StatusCode={1}", _physicalStateObj.SessionId, statusCode); if (statusCode is not NegotiateAuthenticationStatusCode.Completed and not NegotiateAuthenticationStatusCode.ContinueNeeded) { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/SSPIContextProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/SSPIContextProvider.cs index fa8c27e3ab..256818660e 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/SSPIContextProvider.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/SSPIContextProvider.cs @@ -27,16 +27,16 @@ private protected virtual void Initialize() { } - internal abstract void GenerateSspiClientContext(byte[] receivedBuff, uint receivedLength, ref byte[] sendBuff, ref uint sendLength, byte[][] _sniSpnBuffer); + internal abstract void GenerateSspiClientContext(ReadOnlyMemory input, ref byte[] sendBuff, ref uint sendLength, byte[][] _sniSpnBuffer); - internal void SSPIData(byte[] receivedBuff, UInt32 receivedLength, ref byte[] sendBuff, ref UInt32 sendLength, byte[] sniSpnBuffer) - => SSPIData(receivedBuff, receivedLength, ref sendBuff, ref sendLength, new[] { sniSpnBuffer }); + internal void SSPIData(ReadOnlyMemory receivedBuff, ref byte[] sendBuff, ref UInt32 sendLength, byte[] sniSpnBuffer) + => SSPIData(receivedBuff, ref sendBuff, ref sendLength, new[] { sniSpnBuffer }); - internal void SSPIData(byte[] receivedBuff, UInt32 receivedLength, ref byte[] sendBuff, ref UInt32 sendLength, byte[][] sniSpnBuffer) + internal void SSPIData(ReadOnlyMemory receivedBuff, ref byte[] sendBuff, ref UInt32 sendLength, byte[][] sniSpnBuffer) { try { - GenerateSspiClientContext(receivedBuff, receivedLength, ref sendBuff, ref sendLength, sniSpnBuffer); + GenerateSspiClientContext(receivedBuff, ref sendBuff, ref sendLength, sniSpnBuffer); } catch (Exception e) { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParser.cs index 4366b4665a..8e0569b44b 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -31,7 +31,7 @@ internal void ProcessSSPI(int receivedLength) uint sendLength = _authenticationProvider.MaxSSPILength; // make call for SSPI data - _authenticationProvider.SSPIData(receivedBuff, (uint)receivedLength, ref sendBuff, ref sendLength, _sniSpnBuffer); + _authenticationProvider.SSPIData(receivedBuff.AsMemory(0, receivedLength), ref sendBuff, ref sendLength, _sniSpnBuffer); // DO NOT SEND LENGTH - TDS DOC INCORRECT! JUST SEND SSPI DATA! _physicalStateObj.WriteByteArray(sendBuff, (int)sendLength, 0); @@ -194,7 +194,7 @@ internal void TdsLogin( // byte[] buffer and 0 for the int length. Debug.Assert(SniContext.Snix_Login == _physicalStateObj.SniContext, $"Unexpected SniContext. Expecting Snix_Login, actual value is '{_physicalStateObj.SniContext}'"); _physicalStateObj.SniContext = SniContext.Snix_LoginSspi; - _authenticationProvider.SSPIData(Array.Empty(), 0, ref outSSPIBuff, ref outSSPILength, _sniSpnBuffer); + _authenticationProvider.SSPIData(ReadOnlyMemory.Empty, ref outSSPIBuff, ref outSSPILength, _sniSpnBuffer); if (outSSPILength > int.MaxValue) { From 4c0f013bac63d8bd928c985440acb1e2bc13d3c6 Mon Sep 17 00:00:00 2001 From: Erik Ejlskov Jensen Date: Tue, 7 May 2024 18:02:12 +0200 Subject: [PATCH 04/25] Remove UWP (uap) references and special cased code (#2483) --- .../src/Microsoft.Data.SqlClient.csproj | 41 ++----- .../Data/SqlClient/LocalDBAPI.uap.cs | 14 --- .../Data/SqlClient/SNI/LocalDB.uap.cs | 14 --- .../src/Microsoft/Data/SqlClient/TdsParser.cs | 4 +- .../src/Microsoft/Data/SqlClient/TdsEnums.cs | 45 ------- .../ManualTests/DataCommon/DataTestUtility.cs | 111 +----------------- .../ExceptionTest/ConnectionExceptionTest.cs | 19 --- 7 files changed, 19 insertions(+), 229 deletions(-) delete mode 100644 src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/LocalDBAPI.uap.cs delete mode 100644 src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/LocalDB.uap.cs diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj index 0a0f573333..57497fd2b0 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -726,6 +726,9 @@ Common\Interop\Windows\Kernel32\Interop.IoControlTransferType.cs + + Common\Interop\Windows\kernel32\Interop.LoadLibraryEx.cs + Common\Interop\Windows\NtDll\Interop.FILE_FULL_EA_INFORMATION.cs @@ -826,16 +829,25 @@ Microsoft\Data\Sql\SqlDataSourceEnumerator.Windows.cs + + Microsoft\Data\SqlClient\SSPI\NativeSSPIContextProvider.cs + Microsoft\Data\SqlClient\TdsParserSafeHandles.Windows.cs + + + + + + @@ -894,31 +906,6 @@ - - - - - - - - - - - - - - Common\Interop\Windows\kernel32\Interop.LoadLibraryEx.cs - - - Microsoft\Data\SqlClient\SSPI\NativeSSPIContextProvider.cs - - - - - - - - @@ -947,10 +934,6 @@ - - - - diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/LocalDBAPI.uap.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/LocalDBAPI.uap.cs deleted file mode 100644 index 9ed10f0fcc..0000000000 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/LocalDBAPI.uap.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; - -namespace System.Data -{ - internal static partial class LocalDBAPI - { - private static IntPtr LoadProcAddress() => - throw new PlatformNotSupportedException(Strings.LocalDBNotSupported); // No Registry support on UAP - } -} diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/LocalDB.uap.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/LocalDB.uap.cs deleted file mode 100644 index e764375802..0000000000 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/LocalDB.uap.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Data.SqlClient.SNI -{ - internal class LocalDB - { - internal static string GetLocalDBConnectionString(string localDbInstance) - { - throw new PlatformNotSupportedException(Strings.LocalDBNotSupported); // No Registry support on UAP - } - } -} diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs index 0d3c0a01b5..84b3978bdf 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -1509,9 +1509,7 @@ internal SqlError ProcessSNIError(TdsParserStateObject stateObj) SqlClientEventSource.Log.TryAdvancedTraceEvent(" Empty error message received from SNI. Error Message = {0}", details.errorMessage); } - string sniContextEnumName = TdsEnums.GetSniContextEnumName(stateObj.SniContext); - - string sqlContextInfo = StringsHelper.GetResourceString(sniContextEnumName); + string sqlContextInfo = StringsHelper.GetResourceString(stateObj.SniContext.ToString()); string providerRid = string.Format("SNI_PN{0}", details.provider); string providerName = StringsHelper.GetResourceString(providerRid); Debug.Assert(!string.IsNullOrEmpty(providerName), $"invalid providerResourceId '{providerRid}'"); diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs index c483d8a0f8..8c7119a695 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs @@ -3,11 +3,7 @@ // See the LICENSE file in the project root for more information. using System; -using System.Collections.Generic; -using System.ComponentModel; using System.Data; -using System.Diagnostics; -using Microsoft.Data.Common; namespace Microsoft.Data.SqlClient { @@ -998,47 +994,6 @@ internal enum FedAuthInfoId : byte internal const byte DATA_CLASSIFICATION_VERSION_WITHOUT_RANK_SUPPORT = 0x01; internal const byte DATA_CLASSIFICATION_VERSION_MAX_SUPPORTED = 0x02; - // Needed for UapAot, since we cannot use Enum.GetName() on SniContext. - // Enum.GetName() uses reflection, which is blocked on UapAot for internal types - // like SniContext. - internal static string GetSniContextEnumName(SniContext sniContext) - { - switch (sniContext) - { - case SniContext.Undefined: - return "Undefined"; - case SniContext.Snix_Connect: - return "Snix_Connect"; - case SniContext.Snix_PreLoginBeforeSuccessfulWrite: - return "Snix_PreLoginBeforeSuccessfulWrite"; - case SniContext.Snix_PreLogin: - return "Snix_PreLogin"; - case SniContext.Snix_LoginSspi: - return "Snix_LoginSspi"; - case SniContext.Snix_ProcessSspi: - return "Snix_ProcessSspi"; - case SniContext.Snix_Login: - return "Snix_Login"; - case SniContext.Snix_EnableMars: - return "Snix_EnableMars"; - case SniContext.Snix_AutoEnlist: - return "Snix_AutoEnlist"; - case SniContext.Snix_GetMarsSession: - return "Snix_GetMarsSession"; - case SniContext.Snix_Execute: - return "Snix_Execute"; - case SniContext.Snix_Read: - return "Snix_Read"; - case SniContext.Snix_Close: - return "Snix_Close"; - case SniContext.Snix_SendRows: - return "Snix_SendRows"; - default: - Debug.Fail($"Received unknown SniContext enum. Value: {sniContext}"); - return null; - } - } - // TCE Related constants internal const byte MAX_SUPPORTED_TCE_VERSION = 0x03; // max version internal const byte MIN_TCE_VERSION_WITH_ENCLAVE_SUPPORT = 0x02; // min version with enclave support diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs index 62d4f641ea..e88a72104c 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs @@ -11,19 +11,19 @@ using System.IO; using System.Linq; using System.Net; +using System.Net.NetworkInformation; using System.Net.Sockets; +using System.Runtime.InteropServices; using System.Security; +using System.Security.Principal; +using System.Text; using System.Threading; using System.Threading.Tasks; +using Azure.Core; +using Azure.Identity; using Microsoft.Data.SqlClient.TestUtilities; using Microsoft.Identity.Client; using Xunit; -using System.Net.NetworkInformation; -using System.Text; -using System.Security.Principal; -using System.Runtime.InteropServices; -using Azure.Identity; -using Azure.Core; namespace Microsoft.Data.SqlClient.ManualTesting.Tests { @@ -77,10 +77,6 @@ public static class DataTestUtility public const string AKVEventSourceName = "Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.EventSource"; private const string ManagedNetworkingAppContextSwitch = "Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows"; - // uap constant - const long APPMODEL_ERROR_NO_PACKAGE = 15700L; - public static readonly bool IsRunningAsUWPApp = RunningAsUWPApp(); - private static Dictionary AvailableDatabases; private static BaseEventListener TraceListener; @@ -676,10 +672,6 @@ public static string GetUserIdentityAccessToken() public static bool IsAccessTokenSetup() => !string.IsNullOrEmpty(GetAccessToken()); - public static bool IsSystemIdentityTokenSetup() => !string.IsNullOrEmpty(GetSystemIdentityAccessToken()); - - public static bool IsUserIdentityTokenSetup() => !string.IsNullOrEmpty(GetUserIdentityAccessToken()); - public static bool IsFileStreamSetup() => !string.IsNullOrEmpty(FileStreamDirectory) && IsNotAzureServer() && IsNotAzureSynapse(); private static bool CheckException(Exception ex, string exceptionMessage, bool innerExceptionMustBeNull) where TException : Exception @@ -780,58 +772,6 @@ public static TException ExpectFailure(Action actionThatFails, strin } } - public static TException ExpectFailure(Action actionThatFails, string exceptionMessage = null, string innerExceptionMessage = null, bool innerInnerExceptionMustBeNull = false) where TException : Exception where TInnerException : Exception - { - try - { - actionThatFails(); - Assert.Fail("ERROR: Did not get expected exception"); - return null; - } - catch (Exception ex) - { - if ((CheckException(ex, exceptionMessage, false)) && (CheckException(ex.InnerException, innerExceptionMessage, innerInnerExceptionMustBeNull))) - { - return (ex as TException); - } - else - { - throw; - } - } - } - - public static TException ExpectFailure(Action actionThatFails, string exceptionMessage = null, string innerExceptionMessage = null, string innerInnerExceptionMessage = null, bool innerInnerInnerExceptionMustBeNull = false) where TException : Exception where TInnerException : Exception where TInnerInnerException : Exception - { - try - { - actionThatFails(); - Assert.Fail("ERROR: Did not get expected exception"); - return null; - } - catch (Exception ex) - { - if ((CheckException(ex, exceptionMessage, false)) && (CheckException(ex.InnerException, innerExceptionMessage, false)) && (CheckException(ex.InnerException.InnerException, innerInnerExceptionMessage, innerInnerInnerExceptionMustBeNull))) - { - return (ex as TException); - } - else - { - throw; - } - } - } - - public static void ExpectAsyncFailure(Func actionThatFails, string exceptionMessage = null, bool innerExceptionMustBeNull = false) where TException : Exception - { - ExpectFailure(() => actionThatFails().Wait(), null, exceptionMessage, innerExceptionMustBeNull); - } - - public static void ExpectAsyncFailure(Func actionThatFails, string exceptionMessage = null, string innerExceptionMessage = null, bool innerInnerExceptionMustBeNull = false) where TException : Exception where TInnerException : Exception - { - ExpectFailure(() => actionThatFails().Wait(), null, exceptionMessage, innerExceptionMessage, innerInnerExceptionMustBeNull); - } - public static string GenerateObjectName() { return string.Format("TEST_{0}{1}{2}", Environment.GetEnvironmentVariable("ComputerName"), Environment.TickCount, Guid.NewGuid()).Replace('-', '_'); @@ -1093,44 +1033,5 @@ public static string GetMachineFQDN(string hostname) } return fqdn.ToString(); } - - public static bool IsNotLocalhost() - { - // get the tcp connection string - SqlConnectionStringBuilder builder = new(DataTestUtility.TCPConnectionString); - - string hostname = ""; - - // parse the datasource - ParseDataSource(builder.DataSource, out hostname, out _, out _); - - // hostname must not be localhost, ., 127.0.0.1 nor ::1 - return !(new string[] { "localhost", ".", "127.0.0.1", "::1" }).Contains(hostname.ToLowerInvariant()); - - } - - private static bool RunningAsUWPApp() - { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - return false; - } - else - { - [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] - static extern int GetCurrentPackageFullName(ref int packageFullNameLength, StringBuilder packageFullName); - - { - int length = 0; - StringBuilder sb = new(0); - _ = GetCurrentPackageFullName(ref length, sb); - - sb = new StringBuilder(length); - int result = GetCurrentPackageFullName(ref length, sb); - - return result != APPMODEL_ERROR_NO_PACKAGE; - } - } - } } } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ExceptionTest/ConnectionExceptionTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ExceptionTest/ConnectionExceptionTest.cs index 9b8e7476e4..b1ba557562 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ExceptionTest/ConnectionExceptionTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ExceptionTest/ConnectionExceptionTest.cs @@ -176,25 +176,6 @@ public void NamedPipeInvalidConnStringTest() OpenBadConnection(builder.ConnectionString, invalidConnStringError); } - [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsRunningAsUWPApp))] - public static void LocalDBNotSupportedOnUapTest() - { - SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(@$"server=(localdb)\{DataTestUtility.LocalDbAppName}") - { - IntegratedSecurity = true, - ConnectTimeout = 2 - }; - - Assert.Throws(() => - { - using (SqlConnection conn = new SqlConnection(builder.ConnectionString)) - { - conn.Open(); - } - }); - } - - private void GenerateConnectionException(string connectionString) { using (SqlConnection sqlConnection = new SqlConnection(connectionString)) From 9a71c94c172fd5b231e9673525e95c7079528fa9 Mon Sep 17 00:00:00 2001 From: Saurabh Singh <1623701+saurabh500@users.noreply.github.com> Date: Mon, 13 May 2024 15:37:01 -0700 Subject: [PATCH 05/25] Update build guide for Linux (#2499) Adding the detail about installing powershell on linux to build the driver --- BUILDGUIDE.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/BUILDGUIDE.md b/BUILDGUIDE.md index d7408fa15e..09143c84cf 100644 --- a/BUILDGUIDE.md +++ b/BUILDGUIDE.md @@ -8,6 +8,8 @@ This project should be built with Visual Studio 2019+ for the best compatibility - **Visual Studio 2019** with imported components: [VS19Components](/tools/vsconfig/VS19Components.vsconfig) +- **Powershell**: To build SqlClient on Linux, powershell is needed as well. Follow the distro specific instructions at [Install Powershell on Linux](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-linux?view=powershell-7.4) + Once the environment is setup properly, execute the desired set of commands below from the _root_ folder to perform the respective operations: ## Building the driver From cc6ea2181af5473648d5c7f79b71be30132d0ac0 Mon Sep 17 00:00:00 2001 From: Erik Ejlskov Jensen Date: Tue, 14 May 2024 20:30:08 +0200 Subject: [PATCH 06/25] Streamline conditional compilation symbols (#2486) --- .../netcore/ref/Microsoft.Data.SqlClient.cs | 6 +++--- .../Common/src/Interop/Windows/Interop.Libraries.cs | 2 +- .../src/System/Net/Logging/NetEventSource.Common.cs | 4 ++-- .../Data/ProviderBase/DbConnectionPool.NetCoreApp.cs | 2 +- .../Microsoft/Data/ProviderBase/DbConnectionPool.cs | 2 +- .../src/Microsoft/Data/SqlClient/SNI/SNICommon.cs | 4 ++-- .../src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs | 2 +- .../src/Microsoft/Data/SqlClient/SNI/SNITcpHandle.cs | 2 +- .../src/Microsoft/Data/SqlClient/SqlCommand.cs | 4 ++-- .../SqlConnectionFactory.AssemblyLoadContext.cs | 2 +- .../src/Microsoft/Data/SqlClient/SqlDataReader.cs | 2 +- .../Data/SqlClient/SqlDelegatedTransaction.cs | 8 ++++---- .../Data/SqlClient/SqlInternalConnectionTds.cs | 2 +- .../src/Microsoft/Data/SqlClient/TdsParser.cs | 10 +++++----- .../Data/SqlClient/TdsParserStateObjectManaged.cs | 2 +- .../Data/SqlClient/TdsParserStateObjectNative.cs | 2 +- .../Microsoft/Data/SqlTypes/SqlFileStream.Windows.cs | 4 ++-- .../src/Microsoft/Data/Common/AdapterUtil.Windows.cs | 4 ++-- .../src/Microsoft/Data/Common/AdapterUtil.cs | 2 +- .../DbConnectionPoolAuthenticationContext.cs | 2 +- .../Data/Sql/SqlDataSourceEnumeratorNativeHelper.cs | 6 +++--- .../ActiveDirectoryAuthenticationProvider.cs | 6 ++---- .../Data/SqlClient/LocalAppContextSwitches.cs | 2 +- .../Reliability/SqlConfigurableRetryLogicLoader.cs | 2 +- .../SqlClient/SSPI/ManagedSSPIContextProvider.cs | 2 +- .../SqlClient/SSPI/NegotiateSSPIContextProvider.cs | 2 +- .../Microsoft/Data/SqlClient/Server/ValueUtilsSmi.cs | 6 +++--- .../src/Microsoft/Data/SqlClient/SqlBuffer.cs | 2 +- .../Microsoft/Data/SqlClient/SqlCommandBuilder.cs | 2 -- .../Microsoft/Data/SqlClient/SqlConnectionString.cs | 4 ++-- .../Data/SqlClient/SqlConnectionStringBuilder.cs | 2 +- .../src/Microsoft/Data/SqlClient/SqlDependency.cs | 4 ++-- .../SqlDependencyUtils.AssemblyLoadContext.cs | 2 +- .../Microsoft/Data/SqlClient/SqlDependencyUtils.cs | 2 +- .../Data/SqlClient/SqlInternalConnection.cs | 2 +- .../src/Microsoft/Data/SqlClient/SqlParameter.cs | 2 +- .../Data/SqlClient/TdsParserSafeHandles.Windows.cs | 2 +- .../Microsoft/Data/SqlClient/TdsParserStateObject.cs | 2 +- .../src/Microsoft/Data/SqlClient/TdsValueSetter.cs | 12 ++++++------ .../src/Resources/StringsHelper.cs | 2 +- .../src/System/Diagnostics/CodeAnalysis.cs | 2 +- .../tests/FunctionalTests/SqlErrorTest.cs | 2 +- .../tests/FunctionalTests/SqlExceptionTest.cs | 2 +- .../tests/ManualTests/DataCommon/DataTestUtility.cs | 6 +++--- .../SQL/DataReaderTest/DataReaderStreamsTest.cs | 2 +- .../SQL/InstanceNameTest/InstanceNameTest.cs | 2 +- .../SQL/RetryLogic/RetryLogicConfigHelper.cs | 2 +- .../TransactionTest/DistributedTransactionTest.cs | 2 +- 48 files changed, 75 insertions(+), 79 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs index a0acf34a33..b228b0a137 100644 --- a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs +++ b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs @@ -478,7 +478,7 @@ public static partial class SqlClientMetaDataCollectionNames /// public static readonly string StructuredTypeMembers; } -#if NETCOREAPP +#if NET6_0_OR_GREATER /// public enum SqlConnectionAttestationProtocol { @@ -1017,7 +1017,7 @@ public SqlConnectionStringBuilder(string connectionString) { } [System.ComponentModel.DisplayNameAttribute("Data Source")] [System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)] public string DataSource { get { throw null; } set { } } -#if NETCOREAPP +#if NET6_0_OR_GREATER /// [System.ComponentModel.DisplayNameAttribute("Attestation Protocol")] [System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)] @@ -1444,7 +1444,7 @@ internal SqlException() { } public byte State { get { throw null; } } /// -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK [System.Security.Permissions.SecurityPermissionAttribute(System.Security.Permissions.SecurityAction.LinkDemand, Flags = System.Security.Permissions.SecurityPermissionFlag.SerializationFormatter)] #endif #if NET8_0_OR_GREATER diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/Interop.Libraries.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/Interop.Libraries.cs index 40308195e7..f3c5526e0f 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/Interop.Libraries.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/Interop.Libraries.cs @@ -9,7 +9,7 @@ internal static partial class Libraries internal const string Crypt32 = "crypt32.dll"; internal const string Kernel32 = "kernel32.dll"; internal const string NtDll = "ntdll.dll"; -#if !NET7_0_OR_GREATER +#if !NET8_0_OR_GREATER internal const string SspiCli = "sspicli.dll"; #endif } diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Logging/NetEventSource.Common.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Logging/NetEventSource.Common.cs index 5b908a3b8e..1e56818132 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Logging/NetEventSource.Common.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/System/Net/Logging/NetEventSource.Common.cs @@ -13,7 +13,7 @@ using System.Diagnostics.Tracing; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if net462 +#if NETFRAMEWORK using System.Security; #endif @@ -45,7 +45,7 @@ namespace System.Net // method that takes an object and optionally provides a string representation of it, in case a particular library wants to customize further. /// Provides logging facilities for System.Net libraries. -#if net462 +#if NETFRAMEWORK [SecuritySafeCritical] #endif internal sealed partial class NetEventSource : EventSource diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPool.NetCoreApp.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPool.NetCoreApp.cs index 9f330c3dcc..4a59e0b858 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPool.NetCoreApp.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPool.NetCoreApp.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if NETCOREAPP +#if NET6_0_OR_GREATER using System.Diagnostics; using Microsoft.Data.Common; diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPool.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPool.cs index 7858adc93c..3bf8a9d561 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPool.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/ProviderBase/DbConnectionPool.cs @@ -776,7 +776,7 @@ private DbConnectionInternal CreateObject(DbConnection owningObject, DbConnectio throw; } -#if NETCOREAPP +#if NET6_0_OR_GREATER if (!IsBlockingPeriodEnabled()) { throw; diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNICommon.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNICommon.cs index 9ccc98a779..2e5d3fd815 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNICommon.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNICommon.cs @@ -190,7 +190,7 @@ internal static bool ValidateSslServerCertificate(string targetServerName, X509C if (policyErrors.HasFlag(SslPolicyErrors.RemoteCertificateNameMismatch)) { -#if NET7_0_OR_GREATER +#if NET8_0_OR_GREATER X509Certificate2 cert2 = cert as X509Certificate2; if (!cert2.MatchesHostname(targetServerName)) { @@ -297,7 +297,7 @@ internal static bool ValidateSslServerCertificate(X509Certificate clientCert, X5 if (policyErrors.HasFlag(SslPolicyErrors.RemoteCertificateNameMismatch)) { -#if NET7_0_OR_GREATER +#if NET8_0_OR_GREATER X509Certificate2 s_cert = serverCert as X509Certificate2; X509Certificate2 c_cert = clientCert as X509Certificate2; diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs index 3276023ef6..77b44a1cf5 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs @@ -26,7 +26,7 @@ internal class SNIProxy private static readonly SNIProxy s_singleton = new SNIProxy(); internal static SNIProxy Instance => s_singleton; -#if !NET7_0_OR_GREATER +#if !NET8_0_OR_GREATER /// /// Generate SSPI context /// diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNITcpHandle.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNITcpHandle.cs index d12e91ad62..9d415bcfc8 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNITcpHandle.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNITcpHandle.cs @@ -1008,7 +1008,7 @@ public override void KillConnection() internal static void SetKeepAliveValues(ref Socket socket) { -#if NETCOREAPP +#if NET6_0_OR_GREATER socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true); socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.TcpKeepAliveInterval, 1); socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.TcpKeepAliveTime, 30); diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs index d01c686d04..94325d3c88 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs @@ -3994,7 +3994,7 @@ private SqlDataReader GetParameterEncryptionDataReader(out Task returnTask, Task SqlCommand command = (SqlCommand)state; bool processFinallyBlockAsync = true; bool decrementAsyncCountInFinallyBlockAsync = true; -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK RuntimeHelpers.PrepareConstrainedRegions(); #endif try @@ -4068,7 +4068,7 @@ private SqlDataReader GetParameterEncryptionDataReaderAsync(out Task returnTask, bool processFinallyBlockAsync = true; bool decrementAsyncCountInFinallyBlockAsync = true; -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK RuntimeHelpers.PrepareConstrainedRegions(); #endif try diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionFactory.AssemblyLoadContext.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionFactory.AssemblyLoadContext.cs index 38411594af..230b7ae5fc 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionFactory.AssemblyLoadContext.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionFactory.AssemblyLoadContext.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if NETCOREAPP +#if NET6_0_OR_GREATER using System; using System.Reflection; diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDataReader.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDataReader.cs index 5eb7d7cdeb..c538483fc8 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDataReader.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDataReader.cs @@ -1353,7 +1353,7 @@ override public string GetName(int i) } /// -#if NET7_0_OR_GREATER +#if NET8_0_OR_GREATER [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.PublicFields)] #endif override public Type GetProviderSpecificFieldType(int i) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.cs index 3ed756eef0..2f9e1e8e06 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.cs @@ -81,7 +81,7 @@ public void Initialize() SqlInternalConnection connection = _connection; SqlConnection usersConnection = connection.Connection; SqlClientEventSource.Log.TryTraceEvent("SqlDelegatedTransaction.Initialize | RES | CPOOL | Object Id {0}, Client Connection Id {1}, delegating transaction.", ObjectID, usersConnection?.ClientConnectionId); -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK RuntimeHelpers.PrepareConstrainedRegions(); #endif try @@ -146,7 +146,7 @@ public byte[] Promote() { SqlConnection usersConnection = connection.Connection; SqlClientEventSource.Log.TryTraceEvent("SqlDelegatedTransaction.Promote | RES | CPOOL | Object Id {0}, Client Connection Id {1}, promoting transaction.", ObjectID, usersConnection?.ClientConnectionId); -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK RuntimeHelpers.PrepareConstrainedRegions(); #endif try @@ -256,7 +256,7 @@ public void Rollback(SinglePhaseEnlistment enlistment) { SqlConnection usersConnection = connection.Connection; SqlClientEventSource.Log.TryTraceEvent("SqlDelegatedTransaction.Rollback | RES | CPOOL | Object Id {0}, Client Connection Id {1}, rolling back transaction.", ObjectID, usersConnection?.ClientConnectionId); -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK RuntimeHelpers.PrepareConstrainedRegions(); #endif try @@ -343,7 +343,7 @@ public void SinglePhaseCommit(SinglePhaseEnlistment enlistment) { SqlConnection usersConnection = connection.Connection; SqlClientEventSource.Log.TryTraceEvent("SqlDelegatedTransaction.SinglePhaseCommit | RES | CPOOL | Object Id {0}, Client Connection Id {1}, committing transaction.", ObjectID, usersConnection?.ClientConnectionId); -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK RuntimeHelpers.PrepareConstrainedRegions(); #endif try diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs index dd7043d629..5ef3d781ea 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs @@ -2300,7 +2300,7 @@ internal bool TryGetFedAuthTokenLocked(SqlFedAuthInfo fedAuthInfo, DbConnectionP bool authenticationContextLocked = false; // Prepare CER to ensure the lock on authentication context is released. -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK RuntimeHelpers.PrepareConstrainedRegions(); #endif try diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs index 84b3978bdf..abb16eaebe 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -1774,7 +1774,7 @@ internal void WriteInt(int v, TdsParserStateObject stateObj) internal static void WriteInt(Span buffer, int value) { -#if NETCOREAPP +#if NET6_0_OR_GREATER BinaryPrimitives.TryWriteInt32LittleEndian(buffer, value); #else buffer[0] = (byte)(value & 0xff); @@ -6144,7 +6144,7 @@ internal bool TryReadSqlValue(SqlBuffer value, SqlMetaDataPriv md, int length, T } else { -#if NET7_0_OR_GREATER +#if NET8_0_OR_GREATER value.SqlBinary = SqlBinary.WrapBytes(b); #else value.SqlBinary = SqlTypeWorkarounds.SqlBinaryCtor(b, true); // doesn't copy the byte array @@ -6441,7 +6441,7 @@ internal bool TryReadSqlValueInternal(SqlBuffer value, byte tdsType, int length, { return false; } -#if NET7_0_OR_GREATER +#if NET8_0_OR_GREATER value.SqlBinary = SqlBinary.WrapBytes(b); #else value.SqlBinary = SqlTypeWorkarounds.SqlBinaryCtor(b, true); @@ -7313,7 +7313,7 @@ internal byte[] SerializeSqlDecimal(SqlDecimal d, TdsParserStateObject stateObj) Span data = stackalloc uint[4]; -#if NET7_0_OR_GREATER +#if NET8_0_OR_GREATER d.WriteTdsValue(data); #else SqlTypeWorkarounds.SqlDecimalExtractData(d, out data[0], out data[1], out data[2], out data[3]); @@ -7342,7 +7342,7 @@ internal void WriteSqlDecimal(SqlDecimal d, TdsParserStateObject stateObj) stateObj.WriteByte(0); Span data = stackalloc uint[4]; -#if NET7_0_OR_GREATER +#if NET8_0_OR_GREATER d.WriteTdsValue(data); #else SqlTypeWorkarounds.SqlDecimalExtractData(d, out data[0], out data[1], out data[2], out data[3]); diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectManaged.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectManaged.cs index 7d879ae4d5..b912ea9f09 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectManaged.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectManaged.cs @@ -408,7 +408,7 @@ private SNIHandle GetSessionSNIHandleHandleOrThrow() private void ThrowClosedConnection() => throw ADP.ClosedConnectionError(); internal override SSPIContextProvider CreateSSPIContextProvider() -#if NET7_0_OR_GREATER +#if NET8_0_OR_GREATER => new NegotiateSSPIContextProvider(); #else => new ManagedSSPIContextProvider(); diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.cs index 6f26250072..611a003177 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.cs @@ -409,7 +409,7 @@ internal override uint WaitForSSLHandShakeToComplete(out int protocolVersion) { protocolVersion = (int)SslProtocols.Tls12; } -#if NETCOREAPP +#if NET6_0_OR_GREATER else if (nativeProtocol.HasFlag(NativeProtocols.SP_PROT_TLS1_3_CLIENT) || nativeProtocol.HasFlag(NativeProtocols.SP_PROT_TLS1_3_SERVER)) { /* The SslProtocols.Tls13 is supported by netcoreapp3.1 and later */ diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlTypes/SqlFileStream.Windows.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlTypes/SqlFileStream.Windows.cs index 78682e917f..319e0d0169 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlTypes/SqlFileStream.Windows.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlTypes/SqlFileStream.Windows.cs @@ -297,7 +297,7 @@ public override void Flush() } /// -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK [HostProtection(ExternalThreading = true)] #endif public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) @@ -318,7 +318,7 @@ public override int EndRead(IAsyncResult asyncResult) } /// -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK [HostProtection(ExternalThreading = true)] #endif public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.Windows.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.Windows.cs index abeadf86b7..6fbdfcb343 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.Windows.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.Windows.cs @@ -26,7 +26,7 @@ internal static partial class ADP [ResourceConsumption(ResourceScope.Machine)] internal static object LocalMachineRegistryValue(string subkey, string queryvalue) { // MDAC 77697 -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK (new RegistryPermission(RegistryPermissionAccess.Read, "HKEY_LOCAL_MACHINE\\" + subkey)).Assert(); // MDAC 62028 #endif try @@ -43,7 +43,7 @@ internal static object LocalMachineRegistryValue(string subkey, string queryvalu ADP.TraceExceptionWithoutRethrow(e); return null; } -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK finally { RegistryPermission.RevertAssert(); diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs index 1ded2eef3a..dcbb89a248 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs @@ -668,7 +668,7 @@ private static long TimerToSeconds(long timerValue) /// Note: In Longhorn you'll be able to rename a machine without /// rebooting. Therefore, don't cache this machine name. /// -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK [EnvironmentPermission(SecurityAction.Assert, Read = "COMPUTERNAME")] #endif internal static string MachineName() => Environment.MachineName; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionPoolAuthenticationContext.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionPoolAuthenticationContext.cs index 213f4b8b25..29ac7fee31 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionPoolAuthenticationContext.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionPoolAuthenticationContext.cs @@ -102,7 +102,7 @@ internal bool LockToUpdate() /// /// Release the lock which was obtained through LockToUpdate. /// -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] #endif internal void ReleaseLockToUpdate() diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumeratorNativeHelper.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumeratorNativeHelper.cs index 9118e341af..a236d5645e 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumeratorNativeHelper.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumeratorNativeHelper.cs @@ -25,7 +25,7 @@ internal static class SqlDataSourceEnumeratorNativeHelper /// internal static DataTable GetDataSources() { -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK (new NamedPermissionSet("FullTrust")).Demand(); // SQLBUDT 244304 #endif char[] buffer = null; @@ -37,13 +37,13 @@ internal static DataTable GetDataSources() bool more = true; bool failure = false; IntPtr handle = ADP.s_ptrZero; -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK RuntimeHelpers.PrepareConstrainedRegions(); #endif try { long s_timeoutTime = TdsParserStaticMethods.GetTimeoutSeconds(ADP.DefaultCommandTimeout); -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK RuntimeHelpers.PrepareConstrainedRegions(); #endif try diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ActiveDirectoryAuthenticationProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ActiveDirectoryAuthenticationProvider.cs index 75b55847f7..d40f59c78b 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ActiveDirectoryAuthenticationProvider.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ActiveDirectoryAuthenticationProvider.cs @@ -207,7 +207,7 @@ public override async Task AcquireTokenAsync(SqlAuthenti */ string redirectUri = s_nativeClientRedirectUri; -#if NETCOREAPP +#if NET6_0_OR_GREATER if (parameters.AuthenticationMethod != SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow) { redirectUri = "http://localhost"; @@ -361,7 +361,7 @@ private static async Task AcquireTokenInteractiveDeviceFlo if (authenticationMethod == SqlAuthenticationMethod.ActiveDirectoryInteractive) { CancellationTokenSource ctsInteractive = new CancellationTokenSource(); -#if NETCOREAPP +#if NET6_0_OR_GREATER /* * On .NET Core, MSAL will start the system browser as a separate process. MSAL does not have control over this browser, * but once the user finishes authentication, the web page is redirected in such a way that MSAL can intercept the Uri. @@ -492,8 +492,6 @@ private IPublicClientApplication CreateClientAppInstance(PublicClientAppKey publ .WithParentActivityOrWindow(_iWin32WindowFunc) .Build(); } -#endif -#if !NETCOREAPP else #endif { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs index ed2c4aedf7..5d35159d60 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs @@ -26,7 +26,7 @@ private enum Tristate : byte private static Tristate s_makeReadAsyncBlocking; private static Tristate s_useMinimumLoginTimeout; -#if !NETFRAMEWORK +#if NET6_0_OR_GREATER static LocalAppContextSwitches() { IAppContextSwitchOverridesSection appContextSwitch = AppConfigManager.FetchConfigurationSection(AppContextSwitchOverridesSection.Name); diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Reliability/SqlConfigurableRetryLogicLoader.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Reliability/SqlConfigurableRetryLogicLoader.cs index a4d197d5e2..ab69ed288f 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Reliability/SqlConfigurableRetryLogicLoader.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Reliability/SqlConfigurableRetryLogicLoader.cs @@ -43,7 +43,7 @@ public SqlConfigurableRetryLogicLoader(ISqlConfigurableRetryConnectionSection co string cnnSectionName = SqlConfigurableRetryConnectionSection.Name, string cmdSectionName = SqlConfigurableRetryCommandSection.Name) { -#if !NETFRAMEWORK +#if NET6_0_OR_GREATER // Just only one subscription to this event is required. // This class isn't supposed to be called more than one time; // SqlConfigurableRetryLogicManager manages a single instance of this class. diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/ManagedSSPIContextProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/ManagedSSPIContextProvider.cs index 8395371de7..546ee11366 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/ManagedSSPIContextProvider.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/ManagedSSPIContextProvider.cs @@ -1,4 +1,4 @@ -#if !NETFRAMEWORK && !NET7_0_OR_GREATER +#if NET6_0 using System; using Microsoft.Data.SqlClient.SNI; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NegotiateSSPIContextProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NegotiateSSPIContextProvider.cs index 2d73d28390..2c68839e3f 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NegotiateSSPIContextProvider.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NegotiateSSPIContextProvider.cs @@ -1,4 +1,4 @@ -#if NET7_0_OR_GREATER +#if NET8_0_OR_GREATER using System; using System.Text; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/ValueUtilsSmi.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/ValueUtilsSmi.cs index 4662bc6012..7dd4abd7c1 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/ValueUtilsSmi.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/ValueUtilsSmi.cs @@ -15,7 +15,7 @@ using Microsoft.Data.Common; using Microsoft.Data.SqlTypes; -#if !NETFRAMEWORK +#if NET6_0_OR_GREATER using SmiContext = System.Object; #endif @@ -3174,7 +3174,7 @@ private static SqlMoney GetSqlMoney_Unchecked(SmiEventSink_Default sink, ITypedG long temp = getters.GetInt64(sink, ordinal); sink.ProcessMessagesAndThrow(); -#if NETCOREAPP && NET7_0_OR_GREATER +#if NET8_0_OR_GREATER return SqlMoney.FromTdsValue(temp); #else return SqlTypeWorkarounds.SqlMoneyCtor(temp, 1 /* ignored */ ); @@ -3658,7 +3658,7 @@ private static void SetSqlMoney_Unchecked(SmiEventSink_Default sink, ITypedSette sink.ProcessMessagesAndThrow(); } -#if NET7_0_OR_GREATER +#if NET8_0_OR_GREATER setters.SetInt64(sink, ordinal, value.GetTdsValue()); #else setters.SetInt64(sink, ordinal, SqlTypeWorkarounds.SqlMoneyToSqlInternalRepresentation(value)); diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBuffer.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBuffer.cs index 31678a3107..f28bf6033b 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBuffer.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBuffer.cs @@ -886,7 +886,7 @@ internal SqlMoney SqlMoney { return SqlMoney.Null; } -#if NETCOREAPP && NET7_0_OR_GREATER +#if NET8_0_OR_GREATER return SqlMoney.FromTdsValue(_value._int64); #else return SqlTypeWorkarounds.SqlMoneyCtor(_value._int64, 1/*ignored*/); diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommandBuilder.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommandBuilder.cs index 90546993a6..e256dde95c 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommandBuilder.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommandBuilder.cs @@ -256,8 +256,6 @@ public static void DeriveParameters(SqlCommand command) } #if NETFRAMEWORK TdsParser bestEffortCleanupTarget = null; -#endif -#if !NET6_0_OR_GREATER RuntimeHelpers.PrepareConstrainedRegions(); #endif try diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionString.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionString.cs index 73de1ad4f7..bbcf46d727 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionString.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionString.cs @@ -836,7 +836,7 @@ internal static Dictionary GetParseSynonyms() { int count = SqlConnectionStringBuilder.KeywordsCount + SynonymCount; -#if !NETFRAMEWORK +#if NET6_0_OR_GREATER count += SqlConnectionStringBuilder.DeprecatedKeywordsCount + DeprecatedSynonymCount; #endif synonyms = new Dictionary(count, StringComparer.OrdinalIgnoreCase) @@ -1024,7 +1024,7 @@ internal ApplicationIntent ConvertValueToApplicationIntent() // ArgumentException and other types are raised as is (no wrapping) } -#if NETCOREAPP +#if NET6_0_OR_GREATER internal void ThrowUnsupportedIfKeywordSet(string keyword) { if (ContainsKey(keyword)) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionStringBuilder.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionStringBuilder.cs index c9f9fd2912..3abb275a9f 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionStringBuilder.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionStringBuilder.cs @@ -638,7 +638,7 @@ private void SetPoolBlockingPeriodValue(PoolBlockingPeriod value) private Exception UnsupportedKeyword(string keyword) { -#if !NETFRAMEWORK +#if NET6_0_OR_GREATER for (int index = 0; index < s_notSupportedKeywords.Length; index++) { if (string.Equals(keyword, s_notSupportedKeywords[index], StringComparison.OrdinalIgnoreCase)) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependency.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependency.cs index 401cde2fa2..0b882bc02c 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependency.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependency.cs @@ -629,7 +629,7 @@ internal static bool Start(string connectionString, string queue, bool useDefaul string database = null; string service = null; bool appDomainStart = false; -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK RuntimeHelpers.PrepareConstrainedRegions(); #endif try @@ -775,7 +775,7 @@ internal static bool Stop(string connectionString, string queue, bool useDefault if (useDefaults) { bool appDomainStop = false; -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK RuntimeHelpers.PrepareConstrainedRegions(); #endif try diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependencyUtils.AssemblyLoadContext.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependencyUtils.AssemblyLoadContext.cs index c3f82f0047..34052c3a9d 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependencyUtils.AssemblyLoadContext.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependencyUtils.AssemblyLoadContext.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if NETCOREAPP +#if NET6_0_OR_GREATER using System; using System.Reflection; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependencyUtils.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependencyUtils.cs index 3aa1697d03..c3a0bb1492 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependencyUtils.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDependencyUtils.cs @@ -107,7 +107,7 @@ private SqlDependencyPerAppDomainDispatcher() } } -#if NETCOREAPP +#if NET6_0_OR_GREATER partial void SubscribeToAppDomainUnload(); partial void SubscribeToAssemblyLoadContextUnload(); diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalConnection.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalConnection.cs index 25e1808e56..401815cf94 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalConnection.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalConnection.cs @@ -27,7 +27,7 @@ internal abstract class SqlInternalConnection : DbConnectionInternal private bool _isGlobalTransactionEnabledForServer; // Whether Global Transactions are enabled for this Azure SQL DB Server private static readonly Guid s_globalTransactionTMID = new("1c742caf-6680-40ea-9c26-6b6846079764"); // ID of the Non-MSDTC, Azure SQL DB Transaction Manager -#if NETCOREAPP +#if NET6_0_OR_GREATER internal SqlCommand.ExecuteReaderAsyncCallContext CachedCommandExecuteReaderAsyncContext; internal SqlCommand.ExecuteNonQueryAsyncCallContext CachedCommandExecuteNonQueryAsyncContext; internal SqlCommand.ExecuteXmlReaderAsyncCallContext CachedCommandExecuteXmlReaderAsyncContext; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlParameter.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlParameter.cs index ee3a09c17a..a7c7fa58e1 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlParameter.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlParameter.cs @@ -844,7 +844,7 @@ public override string SourceColumn /// [ResCategory("DataCategory_Update")] -#if !NETFRAMEWORK +#if NET6_0_OR_GREATER [ResDescription(StringsHelper.ResourceNames.SqlParameter_SourceColumnNullMapping)] #endif public override bool SourceColumnNullMapping diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserSafeHandles.Windows.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserSafeHandles.Windows.cs index 8d276cd285..dba1ec788c 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserSafeHandles.Windows.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserSafeHandles.Windows.cs @@ -164,7 +164,7 @@ internal SNIHandle( string hostNameInCertificate) : base(IntPtr.Zero, true) { -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK RuntimeHelpers.PrepareConstrainedRegions(); #endif try diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs index 17729a4cc9..4aadbee4bd 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs @@ -976,7 +976,7 @@ internal bool TryProcessHeader() _inBuff[_inBytesUsed + TdsEnums.HEADER_LEN_FIELD_OFFSET + 1]) - _inputHeaderLen; _spid = _inBuff[_inBytesUsed + TdsEnums.SPID_OFFSET] << 8 | _inBuff[_inBytesUsed + TdsEnums.SPID_OFFSET + 1]; -#if !NETFRAMEWORK +#if NET6_0_OR_GREATER SqlClientEventSource.Log.TryAdvancedTraceEvent("TdsParserStateObject.TryProcessHeader | ADV | State Object Id {0}, Client Connection Id {1}, Server process Id (SPID) {2}", _objectID, _parser?.Connection?.ClientConnectionId, _spid); #endif _inBytesUsed += _inputHeaderLen; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsValueSetter.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsValueSetter.cs index dc797ced8e..6b05698972 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsValueSetter.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsValueSetter.cs @@ -587,7 +587,7 @@ internal void SetDateTime(DateTime value) if (SqlDbType.DateTime2 == _metaData.SqlDbType) { long time = value.TimeOfDay.Ticks / TdsEnums.TICKS_FROM_SCALE[_metaData.Scale]; -#if NETCOREAPP +#if NET6_0_OR_GREATER Span result_time = stackalloc byte[8]; BinaryPrimitives.WriteInt64LittleEndian(result_time, time); _stateObj.WriteByteSpan(result_time.Slice(0, (int)_metaData.MaxLength - 3)); @@ -595,7 +595,7 @@ internal void SetDateTime(DateTime value) _stateObj.WriteByteArray(BitConverter.GetBytes(time), (int)_metaData.MaxLength - 3, 0); #endif } -#if NETCOREAPP +#if NET6_0_OR_GREATER Span result_date = stackalloc byte[4]; BinaryPrimitives.WriteInt32LittleEndian(result_date, days); _stateObj.WriteByteSpan(result_date.Slice(0, 3)); @@ -612,7 +612,7 @@ internal void SetGuid(Guid value) Debug.Assert( SmiXetterAccessMap.IsSetterAccessValid(_metaData, SmiXetterTypeCode.XetGuid)); -#if NETCOREAPP +#if NET6_0_OR_GREATER Span bytes = stackalloc byte[16]; value.TryWriteBytes(bytes); @@ -631,7 +631,7 @@ internal void SetGuid(Guid value) _stateObj.WriteByte((byte)_metaData.MaxLength); } -#if NETCOREAPP +#if NET6_0_OR_GREATER _stateObj.WriteByteSpan(bytes); #else _stateObj.WriteByteArray(bytes, bytes.Length, 0); @@ -659,7 +659,7 @@ internal void SetTimeSpan(TimeSpan value) _stateObj.WriteByte(length); } long time = value.Ticks / TdsEnums.TICKS_FROM_SCALE[scale]; -#if NETCOREAPP +#if NET6_0_OR_GREATER Span result_time = stackalloc byte[8]; BinaryPrimitives.WriteInt64LittleEndian(result_time, time); _stateObj.WriteByteSpan(result_time.Slice(0, length)); @@ -696,7 +696,7 @@ internal void SetDateTimeOffset(DateTimeOffset value) int days = utcDateTime.Subtract(DateTime.MinValue).Days; short offset = (short)value.Offset.TotalMinutes; -#if NETCOREAPP +#if NET6_0_OR_GREATER // In TDS protocol: // https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-tds/786f5b8a-f87d-4980-9070-b9b7274c681d // diff --git a/src/Microsoft.Data.SqlClient/src/Resources/StringsHelper.cs b/src/Microsoft.Data.SqlClient/src/Resources/StringsHelper.cs index 3f003c081c..d1b736f595 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/StringsHelper.cs +++ b/src/Microsoft.Data.SqlClient/src/Resources/StringsHelper.cs @@ -63,7 +63,7 @@ public static string GetString(string res, params object[] args) } } -#if !NETFRAMEWORK +#if NET6_0_OR_GREATER // This method is used to decide if we need to append the exception message parameters to the message when calling Strings.Format. // by default it returns false. // Native code generators can replace the value this returns based on user input at the time of native code generation. diff --git a/src/Microsoft.Data.SqlClient/src/System/Diagnostics/CodeAnalysis.cs b/src/Microsoft.Data.SqlClient/src/System/Diagnostics/CodeAnalysis.cs index 1c021b459a..aaca20a34d 100644 --- a/src/Microsoft.Data.SqlClient/src/System/Diagnostics/CodeAnalysis.cs +++ b/src/Microsoft.Data.SqlClient/src/System/Diagnostics/CodeAnalysis.cs @@ -5,7 +5,7 @@ namespace System.Diagnostics.CodeAnalysis { -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true, Inherited = false)] internal sealed class MemberNotNullAttribute : Attribute { diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlErrorTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlErrorTest.cs index bce79cb6d1..ee05379870 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlErrorTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlErrorTest.cs @@ -16,7 +16,7 @@ public class SqlErrorTest "Connecting to a mirrored SQL Server instance using the MultiSubnetFailover connection option is not supported."; private const byte FATAL_ERROR_CLASS = 20; -#if !NET50_OR_LATER +#if NETFRAMEWORK [Fact] public static void SqlErrorSerializationTest() { diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlExceptionTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlExceptionTest.cs index 204ab379c1..85d3a02fb1 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlExceptionTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlExceptionTest.cs @@ -33,7 +33,7 @@ public void SerializationTest() Assert.Equal(e.StackTrace, sqlEx.StackTrace); } -#if !NET6_0_OR_GREATER +#if NETFRAMEWORK [Fact] [ActiveIssue("12161", TestPlatforms.AnyUnix)] public static void SqlExcpetionSerializationTest() diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs index e88a72104c..34fbacb218 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs @@ -467,7 +467,7 @@ public static bool IsTargetReadyForAeWithKeyStore() public static bool IsSupportingDistributedTransactions() { -#if NET7_0_OR_GREATER +#if NET8_0_OR_GREATER return OperatingSystem.IsWindows() && System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture != System.Runtime.InteropServices.Architecture.X86 && IsNotAzureServer(); #elif NETFRAMEWORK return IsNotAzureServer(); @@ -481,8 +481,8 @@ public static bool IsSupportingDistributedTransactions() public static bool IsNotUsingManagedSNIOnWindows() => !UseManagedSNIOnWindows; public static bool IsUsingNativeSNI() => -#if !NETFRAMEWORK - DataTestUtility.IsNotUsingManagedSNIOnWindows(); +#if NET6_0_OR_GREATER + IsNotUsingManagedSNIOnWindows(); #else true; #endif diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataReaderTest/DataReaderStreamsTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataReaderTest/DataReaderStreamsTest.cs index 3f16a3a138..3902f812fc 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataReaderTest/DataReaderStreamsTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataReaderTest/DataReaderStreamsTest.cs @@ -472,7 +472,7 @@ public static void InvalidCastExceptionStream(CommandBehavior behavior, Accessor } } -#if NETCOREAPP +#if NET6_0_OR_GREATER [ConditionalFact(typeof(DataTestUtility),nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))] public static async void ReadAsyncContentsCompletes() { diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs index aa72bb6f5b..61474ece7f 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/InstanceNameTest/InstanceNameTest.cs @@ -86,7 +86,7 @@ public static void ConnectManagedWithInstanceNameTest(bool useMultiSubnetFailove } } -#if NETCOREAPP +#if NET6_0_OR_GREATER [ActiveIssue("27824")] // When specifying instance name and port number, this method call always returns false [ConditionalFact(nameof(IsSPNPortNumberTestForTCP))] public static void PortNumberInSPNTestForTCP() diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/RetryLogic/RetryLogicConfigHelper.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/RetryLogic/RetryLogicConfigHelper.cs index 7162c4dcaa..21370c08e7 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/RetryLogic/RetryLogicConfigHelper.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/RetryLogic/RetryLogicConfigHelper.cs @@ -73,7 +73,7 @@ public static object CreateLoader(RetryLogicConfigs cnnConfig, RetryLogicConfigs public static void ApplyContextSwitchByManager(string name, bool value) { -#if NETCOREAPP +#if NET6_0_OR_GREATER var appCtxType = s_sqlClientAssembly.GetType(AppCtxCfgTypeName); var appCtxObj = Activator.CreateInstance(appCtxType); SetValue(appCtxObj, appCtxType, "Value", string.Concat(name, "=", value)); diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/TransactionTest/DistributedTransactionTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/TransactionTest/DistributedTransactionTest.cs index dc04ea56ae..658104e193 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/TransactionTest/DistributedTransactionTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/TransactionTest/DistributedTransactionTest.cs @@ -8,7 +8,7 @@ using System.Transactions; using Xunit; -#if NET7_0_OR_GREATER +#if NET8_0_OR_GREATER namespace Microsoft.Data.SqlClient.ManualTesting.Tests { From 5cb73fdc9fa408fcd033510b2e2182085c1f14c9 Mon Sep 17 00:00:00 2001 From: Edward Neal <55035479+edwardneal@users.noreply.github.com> Date: Tue, 14 May 2024 19:31:10 +0100 Subject: [PATCH 07/25] Merged SqlClientFactory between .NET Core and Framework (#2369) --- .../netcore/ref/Microsoft.Data.SqlClient.cs | 30 +++-- .../src/Microsoft.Data.SqlClient.csproj | 5 +- .../SqlClient/SqlClientFactory.NetCoreApp.cs | 24 ---- .../Data/SqlClient/SqlClientFactory.cs | 55 --------- .../netfx/src/Microsoft.Data.SqlClient.csproj | 6 +- .../Data/SqlClient/SqlClientFactory.cs | 98 ---------------- .../Data/SqlClient/SqlClientFactory.cs | 108 ++++++++++++++++++ .../FunctionalTests/SqlClientFactoryTest.cs | 36 +++--- 8 files changed, 149 insertions(+), 213 deletions(-) delete mode 100644 src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientFactory.NetCoreApp.cs delete mode 100644 src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientFactory.cs delete mode 100644 src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlClientFactory.cs create mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlClientFactory.cs diff --git a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs index b228b0a137..72203bb433 100644 --- a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs +++ b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs @@ -189,23 +189,23 @@ public class SqlAuthenticationParameters /// protected SqlAuthenticationParameters(Microsoft.Data.SqlClient.SqlAuthenticationMethod authenticationMethod, string serverName, string databaseName, string resource, string authority, string userId, string password, System.Guid connectionId, int connectionTimeout) { } /// - public Microsoft.Data.SqlClient.SqlAuthenticationMethod AuthenticationMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.Data.SqlClient.SqlAuthenticationMethod AuthenticationMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } /// - public string Authority { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Authority { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } /// - public System.Guid ConnectionId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Guid ConnectionId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } /// - public string DatabaseName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string DatabaseName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } /// - public string Password { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Password { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } /// - public string Resource { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Resource { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } /// - public string ServerName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string ServerName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } /// - public string UserId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string UserId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } /// - public int ConnectionTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public int ConnectionTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } /// public abstract partial class SqlAuthenticationProvider @@ -231,9 +231,9 @@ public partial class SqlAuthenticationToken /// public SqlAuthenticationToken(string accessToken, System.DateTimeOffset expiresOn) { } /// - public string AccessToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string AccessToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } /// - public System.DateTimeOffset ExpiresOn { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.DateTimeOffset ExpiresOn { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } /// public sealed partial class SqlBulkCopy : System.IDisposable @@ -427,6 +427,14 @@ internal SqlClientFactory() { } public override System.Data.Common.DbDataAdapter CreateDataAdapter() { throw null; } /// public override System.Data.Common.DbParameter CreateParameter() { throw null; } + /// + public override System.Data.Common.DbDataSourceEnumerator CreateDataSourceEnumerator() { throw null; } + /// + public override bool CanCreateBatch { get { throw null; } } + /// + public override System.Data.Common.DbBatch CreateBatch() { throw null; } + /// + public override System.Data.Common.DbBatchCommand CreateBatchCommand() { throw null; } } /// public partial class SqlClientLogger diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj index 57497fd2b0..2cd3537ea7 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -383,6 +383,9 @@ Microsoft\Data\SqlClient\SqlClientEventSource.cs + + Microsoft\Data\SqlClient\SqlClientFactory.cs + Microsoft\Data\SqlClient\SqlClientLogger.cs @@ -646,8 +649,6 @@ - - diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientFactory.NetCoreApp.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientFactory.NetCoreApp.cs deleted file mode 100644 index a48179b621..0000000000 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientFactory.NetCoreApp.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -#if NET6_0_OR_GREATER - -using System.Data.Common; - -namespace Microsoft.Data.SqlClient -{ - public sealed partial class SqlClientFactory : DbProviderFactory - { - /// - public override bool CanCreateBatch => true; - - /// - public override DbBatch CreateBatch() => new SqlBatch(); - - /// - public override DbBatchCommand CreateBatchCommand() => new SqlBatchCommand(); - } -} - -#endif diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientFactory.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientFactory.cs deleted file mode 100644 index 2dd3261fe6..0000000000 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientFactory.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. -// See the LICENSE file in the project root for more information. - -using System.Data.Common; - -namespace Microsoft.Data.SqlClient -{ - /// - public sealed partial class SqlClientFactory : DbProviderFactory - { - /// - public static readonly SqlClientFactory Instance = new SqlClientFactory(); - - private SqlClientFactory() - { - } - - /// - public override DbCommand CreateCommand() - { - return new SqlCommand(); - } - - /// - public override DbCommandBuilder CreateCommandBuilder() - { - return new SqlCommandBuilder(); - } - - /// - public override DbConnection CreateConnection() - { - return new SqlConnection(); - } - - /// - public override DbConnectionStringBuilder CreateConnectionStringBuilder() - { - return new SqlConnectionStringBuilder(); - } - - /// - public override DbDataAdapter CreateDataAdapter() - { - return new SqlDataAdapter(); - } - - /// - public override DbParameter CreateParameter() - { - return new SqlParameter(); - } - } -} diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj index 2dd8d69b08..e291206a4a 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj @@ -423,6 +423,9 @@ Microsoft\Data\SqlClient\SqlClientEventSource.cs + + Microsoft\Data\SqlClient\SqlClientFactory.cs + Microsoft\Data\SqlClient\SqlClientLogger.cs @@ -668,7 +671,6 @@ - @@ -766,4 +768,4 @@ - \ No newline at end of file + diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlClientFactory.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlClientFactory.cs deleted file mode 100644 index 3d44d202c0..0000000000 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlClientFactory.cs +++ /dev/null @@ -1,98 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Data.Common; -using System.Data.Sql; -using System.Security; -using System.Security.Permissions; -using Microsoft.Data.Common; - -namespace Microsoft.Data.SqlClient -{ - /// - public sealed class SqlClientFactory : DbProviderFactory, IServiceProvider - { - - /// - public static readonly SqlClientFactory Instance = new SqlClientFactory(); - - private SqlClientFactory() - { - } - - /// - public override bool CanCreateDataSourceEnumerator - { - get - { - return true; - } - } - - /// - public override DbCommand CreateCommand() - { - return new SqlCommand(); - } - - /// - public override DbCommandBuilder CreateCommandBuilder() - { - return new SqlCommandBuilder(); - } - - /// - public override DbConnection CreateConnection() - { - return new SqlConnection(); - } - - /// - public override DbConnectionStringBuilder CreateConnectionStringBuilder() - { - return new SqlConnectionStringBuilder(); - } - - /// - public override DbDataAdapter CreateDataAdapter() - { - return new SqlDataAdapter(); - } - - /// - public override DbParameter CreateParameter() - { - return new SqlParameter(); - } - - /// - public override CodeAccessPermission CreatePermission(PermissionState state) - { - return new SqlClientPermission(state); - } - - /// - public override DbDataSourceEnumerator CreateDataSourceEnumerator() - { - return SqlDataSourceEnumerator.Instance; - } - - /// - /// Extension mechanism for additional services; currently the only service - /// supported is the DbProviderServices - /// - /// requested service provider or null. - object IServiceProvider.GetService(Type serviceType) - { - object result = null; - if (serviceType == GreenMethods.SystemDataCommonDbProviderServices_Type) - { - result = GreenMethods.MicrosoftDataSqlClientSqlProviderServices_Instance(); - } - return result; - } - } -} - diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlClientFactory.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlClientFactory.cs new file mode 100644 index 0000000000..eacf4d6e55 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlClientFactory.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. +// See the LICENSE file in the project root for more information. + +using Microsoft.Data.Sql; +using System; +using System.Data.Common; +using System.Security.Permissions; +using System.Security; +using Microsoft.Data.Common; + +namespace Microsoft.Data.SqlClient +{ + /// + public sealed class SqlClientFactory : DbProviderFactory +#if NETFRAMEWORK + , IServiceProvider +#endif + { + + /// + public static readonly SqlClientFactory Instance = new SqlClientFactory(); + + private SqlClientFactory() + { + } + + /// + public override bool CanCreateDataSourceEnumerator => true; + + /// + public override DbCommand CreateCommand() + { + return new SqlCommand(); + } + + /// + public override DbCommandBuilder CreateCommandBuilder() + { + return new SqlCommandBuilder(); + } + + /// + public override DbConnection CreateConnection() + { + return new SqlConnection(); + } + + /// + public override DbConnectionStringBuilder CreateConnectionStringBuilder() + { + return new SqlConnectionStringBuilder(); + } + + /// + public override DbDataAdapter CreateDataAdapter() + { + return new SqlDataAdapter(); + } + + /// + public override DbParameter CreateParameter() + { + return new SqlParameter(); + } + +#if NETFRAMEWORK + /// + public override CodeAccessPermission CreatePermission(PermissionState state) + { + return new SqlClientPermission(state); + } + + /// + /// Extension mechanism for additional services; currently the only service + /// supported is the DbProviderServices + /// + /// requested service provider or null. + object IServiceProvider.GetService(Type serviceType) + { + object result = null; + if (serviceType == GreenMethods.SystemDataCommonDbProviderServices_Type) + { + result = GreenMethods.MicrosoftDataSqlClientSqlProviderServices_Instance(); + } + return result; + } +#endif + + /// + public override DbDataSourceEnumerator CreateDataSourceEnumerator() + { + return SqlDataSourceEnumerator.Instance; + } + +#if NET6_0_OR_GREATER + /// + public override bool CanCreateBatch => true; + + /// + public override DbBatch CreateBatch() => new SqlBatch(); + + /// + public override DbBatchCommand CreateBatchCommand() => new SqlBatchCommand(); +#endif + + } +} diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlClientFactoryTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlClientFactoryTest.cs index f0e8d39173..b88ae0a260 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlClientFactoryTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlClientFactoryTest.cs @@ -21,40 +21,34 @@ public void InstanceTest() public static readonly object[][] FactoryMethodTestData = { - new object[] { new Func(SqlClientFactory.Instance.CreateCommand), typeof(SqlCommand) }, - new object[] { new Func(SqlClientFactory.Instance.CreateCommandBuilder), typeof(SqlCommandBuilder) }, - new object[] { new Func(SqlClientFactory.Instance.CreateConnection), typeof(SqlConnection) }, - new object[] { new Func(SqlClientFactory.Instance.CreateConnectionStringBuilder), typeof(SqlConnectionStringBuilder) }, - new object[] { new Func(SqlClientFactory.Instance.CreateDataAdapter), typeof(SqlDataAdapter) }, - new object[] { new Func(SqlClientFactory.Instance.CreateParameter), typeof(SqlParameter) }, + new object[] { new Func(SqlClientFactory.Instance.CreateCommand), typeof(SqlCommand), false }, + new object[] { new Func(SqlClientFactory.Instance.CreateCommandBuilder), typeof(SqlCommandBuilder), false }, + new object[] { new Func(SqlClientFactory.Instance.CreateConnection), typeof(SqlConnection), false }, + new object[] { new Func(SqlClientFactory.Instance.CreateConnectionStringBuilder), typeof(SqlConnectionStringBuilder), false }, + new object[] { new Func(SqlClientFactory.Instance.CreateDataAdapter), typeof(SqlDataAdapter), false }, + new object[] { new Func(SqlClientFactory.Instance.CreateParameter), typeof(SqlParameter), false }, + new object[] { new Func(SqlClientFactory.Instance.CreateDataSourceEnumerator), typeof(Microsoft.Data.Sql.SqlDataSourceEnumerator), true }, }; [Theory] [MemberData(nameof(FactoryMethodTestData))] - public void FactoryMethodTest(Func factory, Type expectedType) + public void FactoryMethodTest(Func factory, Type expectedType, bool singleton) { object value1 = factory(); Assert.NotNull(value1); Assert.IsType(expectedType, value1); - object value2 = factory(); - Assert.NotNull(value2); - Assert.IsType(expectedType, value2); + if (!singleton) + { + object value2 = factory(); + Assert.NotNull(value2); + Assert.IsType(expectedType, value2); - Assert.NotSame(value1, value2); + Assert.NotSame(value1, value2); + } } #if NETFRAMEWORK - [Fact] - public void FactoryCreateDataSourceEnumerator() - { - // Unable to cover the in the FactoryMethodTest because the SqlDataSourceEnumerator is a singleton so, it's always the same. - object instance = SqlClientFactory.Instance.CreateDataSourceEnumerator(); - // SqlDataSourceEnumerator is not available for .NET core 3.1 and above, so the type check is only for .NET Framework. - Assert.IsType(instance); - Assert.NotNull(instance); - } - [Fact] public void FactoryGetService() { From cd7a3d10e88a15e6151afca1d0f2b972d6058fcb Mon Sep 17 00:00:00 2001 From: Javad Rahnama Date: Thu, 23 May 2024 09:20:03 -0700 Subject: [PATCH 08/25] Updating Azure.Identity version to 1.11.3 (#2526) --- tools/props/Versions.props | 2 +- tools/specs/Microsoft.Data.SqlClient.nuspec | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/props/Versions.props b/tools/props/Versions.props index 022c9a4c7a..29d1201137 100644 --- a/tools/props/Versions.props +++ b/tools/props/Versions.props @@ -27,7 +27,7 @@ - 1.11.2 + 1.11.3 4.60.3 7.5.0 7.5.0 diff --git a/tools/specs/Microsoft.Data.SqlClient.nuspec b/tools/specs/Microsoft.Data.SqlClient.nuspec index b1666d4459..6bbc961ac7 100644 --- a/tools/specs/Microsoft.Data.SqlClient.nuspec +++ b/tools/specs/Microsoft.Data.SqlClient.nuspec @@ -29,7 +29,7 @@ When using NuGet 3.x this package requires at least version 3.4. - + @@ -40,7 +40,7 @@ When using NuGet 3.x this package requires at least version 3.4. - + @@ -50,7 +50,7 @@ When using NuGet 3.x this package requires at least version 3.4. - + From b178ba5d324cfc77a4ff68cf7c250895f766dbeb Mon Sep 17 00:00:00 2001 From: David Engel Date: Thu, 23 May 2024 12:10:21 -0700 Subject: [PATCH 09/25] Fix | Clone of SqlConnection should include AccessTokenCallback (#2525) --- .../src/Microsoft/Data/SqlClient/SqlConnection.cs | 1 + .../src/Microsoft/Data/SqlClient/SqlConnection.cs | 1 + .../tests/FunctionalTests/CloneTests.cs | 10 ++++++++++ 3 files changed, 12 insertions(+) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs index 4b4e7ccc43..1d044633ec 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs @@ -227,6 +227,7 @@ private SqlConnection(SqlConnection connection) } _accessToken = connection._accessToken; + _accessTokenCallback = connection._accessTokenCallback; CacheConnectionStringProperties(); } diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnection.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnection.cs index b6104b9075..b9d2e32daa 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnection.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnection.cs @@ -429,6 +429,7 @@ private SqlConnection(SqlConnection connection) _credential = new SqlCredential(connection._credential.UserId, password); } _accessToken = connection._accessToken; + _accessTokenCallback = connection._accessTokenCallback; _serverCertificateValidationCallback = connection._serverCertificateValidationCallback; _clientCertificateRetrievalCallback = connection._clientCertificateRetrievalCallback; _originalNetworkAddressInfo = connection._originalNetworkAddressInfo; diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/CloneTests.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/CloneTests.cs index f5deb6c62c..1c8efc4456 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/CloneTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/CloneTests.cs @@ -4,6 +4,7 @@ using System; using System.Data; +using System.Threading.Tasks; using Xunit; namespace Microsoft.Data.SqlClient.Tests @@ -18,10 +19,19 @@ public void CloneSqlConnection() builder.ConnectTimeout = 1; builder.InitialCatalog = "northwinddb"; SqlConnection connection = new SqlConnection(builder.ConnectionString); + connection.AccessToken = Guid.NewGuid().ToString(); SqlConnection clonedConnection = (connection as ICloneable).Clone() as SqlConnection; Assert.Equal(connection.ConnectionString, clonedConnection.ConnectionString); Assert.Equal(connection.ConnectionTimeout, clonedConnection.ConnectionTimeout); + Assert.Equal(connection.AccessToken, clonedConnection.AccessToken); + Assert.NotEqual(connection, clonedConnection); + + connection = new SqlConnection(builder.ConnectionString); + connection.AccessTokenCallback = (ctx, token) => + Task.FromResult(new SqlAuthenticationToken(Guid.NewGuid().ToString(), DateTimeOffset.MaxValue)); + clonedConnection = (connection as ICloneable).Clone() as SqlConnection; + Assert.Equal(connection.AccessTokenCallback, clonedConnection.AccessTokenCallback); Assert.NotEqual(connection, clonedConnection); } From b7c4007d0deb2c2ffa8281f7f731a59f42a5fce1 Mon Sep 17 00:00:00 2001 From: David Engel Date: Fri, 24 May 2024 10:21:39 -0700 Subject: [PATCH 10/25] Enhancement | Add trace logs for packet size (#2522) --- .../netcore/src/Microsoft/Data/SqlClient/TdsParser.cs | 3 +++ .../netfx/src/Microsoft/Data/SqlClient/TdsParser.cs | 3 +++ .../src/Microsoft/Data/SqlClient/TdsParserStateObject.cs | 3 +++ 3 files changed, 9 insertions(+) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs index abb16eaebe..8a5ed05abe 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -2740,6 +2740,9 @@ private bool TryProcessEnvChange(int tokenLength, TdsParserStateObject stateObj, // to MARS initialization! int packetSize = int.Parse(env._newValue, NumberStyles.Integer, CultureInfo.InvariantCulture); + SqlClientEventSource.Log.TryTraceEvent("{0}.{1} | Info | Server sent env packet size change of {2}, ClientConnectionID {3}", + nameof(TdsParser), nameof(TryProcessEnvChange), packetSize, _connHandler._clientConnectionId); + if (_physicalStateObj.SetPacketSize(packetSize)) { // If packet size changed, we need to release our SNIPackets since diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs index 7c8fc724c6..afa5220563 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -3182,6 +3182,9 @@ private bool TryProcessEnvChange(int tokenLength, TdsParserStateObject stateObj, // to MARS initialization! int packetSize = int.Parse(env._newValue, NumberStyles.Integer, CultureInfo.InvariantCulture); + SqlClientEventSource.Log.TryTraceEvent("{0}.{1} | Info | Server sent env packet size change of {2}, ClientConnectionID {3}", + nameof(TdsParser), nameof(TryProcessEnvChange), packetSize, _connHandler._clientConnectionId); + if (_physicalStateObj.SetPacketSize(packetSize)) { // If packet size changed, we need to release our SNIPackets since diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs index 4aadbee4bd..4347d0f2e0 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs @@ -1097,6 +1097,9 @@ internal bool SetPacketSize(int size) (_outBytesUsed == _outputHeaderLen && _outputPacketNumber == 1), "SetPacketSize called with data in the buffer!"); + SqlClientEventSource.Log.TryTraceEvent("{0}.{1} | Info | State Object Id {2}, Setting packet size to {3}", + nameof(TdsParserStateObject), nameof(SetPacketSize), _objectID, size); + if (_inBuff == null || _inBuff.Length != size) { // We only check _inBuff, since two buffers should be consistent. // Allocate or re-allocate _inBuff. From 815e5ab19e9e096bc52f13a82170aa1c5e641826 Mon Sep 17 00:00:00 2001 From: DavoudEshtehari <61173489+DavoudEshtehari@users.noreply.github.com> Date: Tue, 28 May 2024 09:37:31 -0700 Subject: [PATCH 11/25] Doc | Fix SNI dependencies of 5.1 and 5.2 release notes (#2537) --- release-notes/5.1/5.1.0.md | 4 ++-- release-notes/5.1/5.1.1.md | 4 ++-- release-notes/5.1/5.1.2.md | 4 ++-- release-notes/5.1/5.1.3.md | 4 ++-- release-notes/5.1/5.1.4.md | 4 ++-- release-notes/5.1/5.1.5.md | 4 ++-- release-notes/5.2/5.2.0-preview1.md | 4 ++-- release-notes/5.2/5.2.0-preview2.md | 4 ++-- release-notes/5.2/5.2.0-preview3.md | 4 ++-- release-notes/5.2/5.2.0.md | 8 ++++---- 10 files changed, 22 insertions(+), 22 deletions(-) diff --git a/release-notes/5.1/5.1.0.md b/release-notes/5.1/5.1.0.md index e7c4eae495..adbf449e63 100644 --- a/release-notes/5.1/5.1.0.md +++ b/release-notes/5.1/5.1.0.md @@ -79,7 +79,7 @@ The default value of the `ServerCertificate` connection setting is an empty stri #### .NET -- Microsoft.Data.SqlClient.SNI 5.1.0 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.0 - Azure.Identity 1.7.0 - Microsoft.Identity.Client 4.47.2 - Microsoft.IdentityModel.JsonWebTokens 6.24.0 @@ -95,7 +95,7 @@ The default value of the `ServerCertificate` connection setting is an empty stri #### .NET Standard -- Microsoft.Data.SqlClient.SNI 5.1.0 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.0 - Azure.Identity 1.7.0 - Microsoft.Identity.Client 4.47.2 - Microsoft.IdentityModel.Protocols.OpenIdConnect 6.24.0 diff --git a/release-notes/5.1/5.1.1.md b/release-notes/5.1/5.1.1.md index bf40701739..057466a565 100644 --- a/release-notes/5.1/5.1.1.md +++ b/release-notes/5.1/5.1.1.md @@ -37,7 +37,7 @@ Thanks to the following public contributors. Their efforts toward this project a #### .NET -- Microsoft.Data.SqlClient.SNI 5.1.0 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.0 - Azure.Identity 1.7.0 - Microsoft.Identity.Client 4.47.2 - Microsoft.IdentityModel.JsonWebTokens 6.24.0 @@ -53,7 +53,7 @@ Thanks to the following public contributors. Their efforts toward this project a #### .NET Standard -- Microsoft.Data.SqlClient.SNI 5.1.0 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.0 - Azure.Identity 1.7.0 - Microsoft.Identity.Client 4.47.2 - Microsoft.IdentityModel.Protocols.OpenIdConnect 6.24.0 diff --git a/release-notes/5.1/5.1.2.md b/release-notes/5.1/5.1.2.md index 14c4b347ad..cb9ccc5992 100644 --- a/release-notes/5.1/5.1.2.md +++ b/release-notes/5.1/5.1.2.md @@ -45,7 +45,7 @@ Thanks to the following public contributors. Their efforts toward this project a #### .NET -- Microsoft.Data.SqlClient.SNI 5.1.1 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.1 - Azure.Identity 1.7.0 - Microsoft.Identity.Client 4.47.2 - Microsoft.IdentityModel.JsonWebTokens 6.24.0 @@ -61,7 +61,7 @@ Thanks to the following public contributors. Their efforts toward this project a #### .NET Standard -- Microsoft.Data.SqlClient.SNI 5.1.1 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.1 - Azure.Identity 1.7.0 - Microsoft.Identity.Client 4.47.2 - Microsoft.IdentityModel.Protocols.OpenIdConnect 6.24.0 diff --git a/release-notes/5.1/5.1.3.md b/release-notes/5.1/5.1.3.md index 75a3140a6d..7889bf61bb 100644 --- a/release-notes/5.1/5.1.3.md +++ b/release-notes/5.1/5.1.3.md @@ -34,7 +34,7 @@ Thanks to the following public contributors. Their efforts toward this project a #### .NET -- Microsoft.Data.SqlClient.SNI 5.1.1 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.1 - Azure.Identity 1.7.0 - Microsoft.Identity.Client 4.47.2 - Microsoft.IdentityModel.JsonWebTokens 6.24.0 @@ -50,7 +50,7 @@ Thanks to the following public contributors. Their efforts toward this project a #### .NET Standard -- Microsoft.Data.SqlClient.SNI 5.1.1 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.1 - Azure.Identity 1.7.0 - Microsoft.Identity.Client 4.47.2 - Microsoft.IdentityModel.Protocols.OpenIdConnect 6.24.0 diff --git a/release-notes/5.1/5.1.4.md b/release-notes/5.1/5.1.4.md index 3f4e784b75..c1638b1eee 100644 --- a/release-notes/5.1/5.1.4.md +++ b/release-notes/5.1/5.1.4.md @@ -37,7 +37,7 @@ Thanks to the following public contributors. Their efforts toward this project a #### .NET -- Microsoft.Data.SqlClient.SNI 5.1.1 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.1 - Azure.Identity 1.10.3 - Microsoft.Identity.Client 4.56.2 - Microsoft.IdentityModel.JsonWebTokens 6.24.0 @@ -53,7 +53,7 @@ Thanks to the following public contributors. Their efforts toward this project a #### .NET Standard -- Microsoft.Data.SqlClient.SNI 5.1.1 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.1 - Azure.Identity 1.10.3 - Microsoft.Identity.Client 4.56.2 - Microsoft.IdentityModel.Protocols.OpenIdConnect 6.24.0 diff --git a/release-notes/5.1/5.1.5.md b/release-notes/5.1/5.1.5.md index c25672a8d1..e05c26861f 100644 --- a/release-notes/5.1/5.1.5.md +++ b/release-notes/5.1/5.1.5.md @@ -39,7 +39,7 @@ Thanks to the following public contributors. Their efforts toward this project a #### .NET -- Microsoft.Data.SqlClient.SNI 5.1.1 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.1 - Azure.Identity 1.10.3 - Microsoft.Identity.Client 4.56.2 - Microsoft.IdentityModel.JsonWebTokens 6.35.0 @@ -55,7 +55,7 @@ Thanks to the following public contributors. Their efforts toward this project a #### .NET Standard -- Microsoft.Data.SqlClient.SNI 5.1.1 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.1 - Azure.Identity 1.10.3 - Microsoft.Identity.Client 4.56.2 - Microsoft.IdentityModel.Protocols.OpenIdConnect 6.35.0 diff --git a/release-notes/5.2/5.2.0-preview1.md b/release-notes/5.2/5.2.0-preview1.md index 84a4678452..152b3169b8 100644 --- a/release-notes/5.2/5.2.0-preview1.md +++ b/release-notes/5.2/5.2.0-preview1.md @@ -63,7 +63,7 @@ Thanks to the following public contributors. Their efforts toward this project a #### .NET -- Microsoft.Data.SqlClient.SNI 5.1.0 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.0 - Azure.Identity 1.8.0 - Microsoft.Identity.Client 4.47.2 - Microsoft.IdentityModel.JsonWebTokens 6.24.0 @@ -82,7 +82,7 @@ Thanks to the following public contributors. Their efforts toward this project a #### .NET Standard -- Microsoft.Data.SqlClient.SNI 5.1.0 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.0 - Azure.Identity 1.6.0 - Microsoft.Identity.Client 4.47.2 - Microsoft.IdentityModel.Protocols.OpenIdConnect 6.24.0 diff --git a/release-notes/5.2/5.2.0-preview2.md b/release-notes/5.2/5.2.0-preview2.md index 6cfd799f69..360894b93a 100644 --- a/release-notes/5.2/5.2.0-preview2.md +++ b/release-notes/5.2/5.2.0-preview2.md @@ -84,7 +84,7 @@ Example usage: #### .NET -- Microsoft.Data.SqlClient.SNI 5.1.0 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.0 - Azure.Identity 1.8.0 - Microsoft.Identity.Client 4.53.0 - Microsoft.IdentityModel.JsonWebTokens 6.24.0 @@ -103,7 +103,7 @@ Example usage: #### .NET Standard -- Microsoft.Data.SqlClient.SNI 5.1.0 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.0 - Azure.Identity 1.6.0 - Microsoft.Identity.Client 4.53.0 - Microsoft.IdentityModel.Protocols.OpenIdConnect 6.24.0 diff --git a/release-notes/5.2/5.2.0-preview3.md b/release-notes/5.2/5.2.0-preview3.md index 0aa43912d2..82173a5744 100644 --- a/release-notes/5.2/5.2.0-preview3.md +++ b/release-notes/5.2/5.2.0-preview3.md @@ -81,7 +81,7 @@ Example usage: #### .NET -- Microsoft.Data.SqlClient.SNI 5.1.0 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.0 - Azure.Identity 1.8.0 - Microsoft.Identity.Client 4.53.0 - Microsoft.IdentityModel.JsonWebTokens 6.24.0 @@ -100,7 +100,7 @@ Example usage: #### .NET Standard -- Microsoft.Data.SqlClient.SNI 5.1.0 +- Microsoft.Data.SqlClient.SNI.runtime 5.1.0 - Azure.Identity 1.6.0 - Microsoft.Identity.Client 4.53.0 - Microsoft.IdentityModel.Protocols.OpenIdConnect 6.24.0 diff --git a/release-notes/5.2/5.2.0.md b/release-notes/5.2/5.2.0.md index e499e795da..aef0863b6c 100644 --- a/release-notes/5.2/5.2.0.md +++ b/release-notes/5.2/5.2.0.md @@ -216,7 +216,7 @@ Example usage: #### .NET 6 -- Microsoft.Data.SqlClient.SNI 5.2.0 +- Microsoft.Data.SqlClient.SNI.runtime 5.2.0 - Azure.Identity 1.10.3 - Microsoft.Identity.Client 4.56.0 - Microsoft.IdentityModel.Protocols.OpenIdConnect 6.35.0 @@ -228,7 +228,7 @@ Example usage: #### .NET 8 -- Microsoft.Data.SqlClient.SNI 5.2.0 +- Microsoft.Data.SqlClient.SNI.runtime 5.2.0 - Azure.Identity 1.10.3 - Microsoft.Identity.Client 4.56.0 - Microsoft.IdentityModel.Protocols.OpenIdConnect 6.35.0 @@ -240,7 +240,7 @@ Example usage: #### .NET Standard 2.0 -- Microsoft.Data.SqlClient.SNI 5.2.0 +- Microsoft.Data.SqlClient.SNI.runtime 5.2.0 - Azure.Identity 1.10.3 - Microsoft.Identity.Client 4.56.0 - Microsoft.IdentityModel.Protocols.OpenIdConnect 6.35.0 @@ -259,7 +259,7 @@ Example usage: #### .NET Standard 2.1 -- Microsoft.Data.SqlClient.SNI 5.2.0 +- Microsoft.Data.SqlClient.SNI.runtime 5.2.0 - Azure.Identity 1.10.3 - Microsoft.Identity.Client 4.56.0 - Microsoft.IdentityModel.Protocols.OpenIdConnect 6.35.0 From 808d4c3b5a935e6954c96ce02d99c53b624099dc Mon Sep 17 00:00:00 2001 From: Benjamin Russell Date: Wed, 29 May 2024 18:45:55 -0500 Subject: [PATCH 12/25] Change | Separate tests for NetFx and NetCore - NetFx-Only Connection String Properties (#2466) * Adding TransparentNetworkIpResolution to list of unsupported on platform connection string error messages Splitting unit test for netfx-only connection string properties such that test does not fail on netcore * Remove DeprecatedSynonymCount since referencing the unsupported array is not possible --- .../Data/Common/DbConnectionStringCommon.cs | 5 ++- .../Data/SqlClient/SqlConnectionString.cs | 3 +- .../SqlClient/SqlConnectionStringBuilder.cs | 11 ++++--- .../SqlConnectionStringBuilderTest.cs | 33 ++++++++++++++----- 4 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/DbConnectionStringCommon.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/DbConnectionStringCommon.cs index 35aaf412a5..95a54538f9 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/DbConnectionStringCommon.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/DbConnectionStringCommon.cs @@ -1037,7 +1037,6 @@ internal static class DbConnectionStringKeywords internal const string OmitOracleConnectionName = "Omit Oracle Connection Name"; // SqlClient - internal const string TransparentNetworkIPResolution = "Transparent Network IP Resolution"; internal const string Certificate = "Certificate"; #endif // SqlClient @@ -1073,6 +1072,7 @@ internal static class DbConnectionStringKeywords internal const string IPAddressPreference = "IP Address Preference"; internal const string ServerSPN = "Server SPN"; internal const string FailoverPartnerSPN = "Failover Partner SPN"; + internal const string TransparentNetworkIPResolution = "Transparent Network IP Resolution"; // common keywords (OleDb, OracleClient, SqlClient) internal const string DataSource = "Data Source"; @@ -1092,10 +1092,9 @@ internal static class DbConnectionStringKeywords internal static class DbConnectionStringSynonyms { -#if NETFRAMEWORK //internal const string TransparentNetworkIPResolution = TRANSPARENTNETWORKIPRESOLUTION; internal const string TRANSPARENTNETWORKIPRESOLUTION = "transparentnetworkipresolution"; -#endif + //internal const string ApplicationName = APP; internal const string APP = "app"; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionString.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionString.cs index bbcf46d727..243efb3db1 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionString.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionString.cs @@ -233,7 +233,6 @@ internal static class TRANSACTIONBINDING internal const int SynonymCount = 33; #else internal const int SynonymCount = 30; - internal const int DeprecatedSynonymCount = 2; #endif // NETFRAMEWORK private static Dictionary s_sqlClientSynonyms; @@ -837,7 +836,7 @@ internal static Dictionary GetParseSynonyms() int count = SqlConnectionStringBuilder.KeywordsCount + SynonymCount; #if NET6_0_OR_GREATER - count += SqlConnectionStringBuilder.DeprecatedKeywordsCount + DeprecatedSynonymCount; + count += SqlConnectionStringBuilder.DeprecatedKeywordsCount; #endif synonyms = new Dictionary(count, StringComparer.OrdinalIgnoreCase) { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionStringBuilder.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionStringBuilder.cs index 3abb275a9f..de8319c526 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionStringBuilder.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionStringBuilder.cs @@ -139,7 +139,7 @@ private enum Keywords private string _certificate = DbConnectionStringDefaults.Certificate; #endif #else - internal const int DeprecatedKeywordsCount = 3; + internal const int DeprecatedKeywordsCount = 5; #endif #endregion //Fields @@ -363,7 +363,6 @@ private object GetAt(Keywords index) return MinPoolSize; case Keywords.MultiSubnetFailover: return MultiSubnetFailover; - // case Keywords.NamedConnection: return NamedConnection; case Keywords.PacketSize: return PacketSize; case Keywords.Password: @@ -912,17 +911,19 @@ public override StandardValuesCollection GetStandardValues(ITypeDescriptorContex } } #else - private static readonly string[] s_notSupportedKeywords = new string[DeprecatedKeywordsCount] { + private static readonly string[] s_notSupportedKeywords = { DbConnectionStringKeywords.ConnectionReset, DbConnectionStringKeywords.ContextConnection, DbConnectionStringKeywords.TransactionBinding, + DbConnectionStringKeywords.TransparentNetworkIPResolution, + DbConnectionStringSynonyms.TRANSPARENTNETWORKIPRESOLUTION, }; - private static readonly string[] s_notSupportedNetworkLibraryKeywords = new string[] { + private static readonly string[] s_notSupportedNetworkLibraryKeywords = { DbConnectionStringKeywords.NetworkLibrary, DbConnectionStringSynonyms.NET, - DbConnectionStringSynonyms.NETWORK + DbConnectionStringSynonyms.NETWORK, }; #endif #endregion //Private Methods diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionStringBuilderTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionStringBuilderTest.cs index d1c3fd2d34..05b3ca5b48 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionStringBuilderTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionStringBuilderTest.cs @@ -107,19 +107,34 @@ public void ConnectionStringTests(string connectionString) ExecuteConnectionStringTests(connectionString); } + public static readonly IEnumerable ConnectionStringTestsNetFx_TestCases = new[] + { + new object[] { "Connection Reset = false" }, + new object[] { "Context Connection = false" }, + new object[] { "Network Library = dbmssocn" }, + new object[] { "Network = dbnmpntw" }, + new object[] { "Net = dbmsrpcn" }, + new object[] { "TransparentNetworkIPResolution = false" }, + new object[] { "Transparent Network IP Resolution = true" }, + }; + [Theory] - [InlineData("Connection Reset = false")] - [InlineData("Context Connection = false")] - [InlineData("Network Library = dbmssocn")] - [InlineData("Network = dbnmpntw")] - [InlineData("Net = dbmsrpcn")] - [InlineData("TransparentNetworkIPResolution = false")] - [InlineData("Transparent Network IP Resolution = true")] - [SkipOnTargetFramework(~TargetFrameworkMonikers.NetFramework)] - public void ConnectionStringTestsNetFx(string connectionString) + [MemberData(nameof(ConnectionStringTestsNetFx_TestCases))] + #if NETFRAMEWORK + public void ConnectionStringTestsNetFx_OnNetFx_Success(string connectionString) { ExecuteConnectionStringTests(connectionString); } + #else + public void ConnectionStringTestsNetFx_OnNetCore_Throws(string connectionString) + { + // Act + Action action = () => _ = new SqlConnectionStringBuilder(connectionString); + + // Assert + Assert.Throws(action); + } + #endif [Fact] public void SetInvalidApplicationIntent_Throws() From 7af2438ee177738131c6b13dc37743a2dafe6910 Mon Sep 17 00:00:00 2001 From: Aris Rellegue <134557572+arellegue@users.noreply.github.com> Date: Thu, 30 May 2024 12:11:53 -0700 Subject: [PATCH 13/25] Fix | Enhance certificate validation (#2487) --- .../Microsoft/Data/SqlClient/SNI/SNICommon.cs | 256 +++++++---------- .../Data/SqlClient/SNI/SNINpHandle.cs | 16 +- .../Microsoft/Data/SqlClient/SNI/SNIProxy.cs | 10 +- .../Data/SqlClient/SNI/SNITcpHandle.cs | 28 +- .../src/Resources/Strings.Designer.cs | 9 + .../src/Resources/Strings.resx | 3 + .../SqlConnectionBasicTests.cs | 1 + .../tests/FunctionalTests/TestTdsServer.cs | 1 - .../DataCommon/ConnectionTestParameters.cs | 40 +++ .../ConnectionTestParametersData.cs | 85 ++++++ ....Data.SqlClient.ManualTesting.Tests.csproj | 12 + .../CertificateTest.cs | 2 +- .../CertificateTestWithTdsServer.cs | 269 ++++++++++++++++++ .../ManualTests/TracingTests/TestTdsServer.cs | 52 +++- .../tests/ManualTests/makepfxcert.ps1 | 158 ++++++++++ .../tests/ManualTests/mismatchedcert.cer | Bin 0 -> 919 bytes .../tests/ManualTests/removecert.ps1 | 21 ++ .../tests/tools/TDS/TDS/TDSStream.cs | 4 + 18 files changed, 771 insertions(+), 196 deletions(-) create mode 100644 src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/ConnectionTestParameters.cs create mode 100644 src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/ConnectionTestParametersData.cs create mode 100644 src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectionTestWithSSLCert/CertificateTestWithTdsServer.cs create mode 100644 src/Microsoft.Data.SqlClient/tests/ManualTests/makepfxcert.ps1 create mode 100644 src/Microsoft.Data.SqlClient/tests/ManualTests/mismatchedcert.cer create mode 100644 src/Microsoft.Data.SqlClient/tests/ManualTests/removecert.ps1 diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNICommon.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNICommon.cs index 2e5d3fd815..f8f2facb59 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNICommon.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNICommon.cs @@ -138,196 +138,154 @@ internal class SNICommon internal const int LocalDBBadRuntime = 57; /// - /// We only validate Server name in Certificate to match with "targetServerName". + /// We either validate that the provided 'validationCert' matches the 'serverCert', or we validate that the server name in the 'serverCert' matches 'targetServerName'. /// Certificate validation and chain trust validations are done by SSLStream class [System.Net.Security.SecureChannel.VerifyRemoteCertificate method] /// This method is called as a result of callback for SSL Stream Certificate validation. /// + /// Connection ID/GUID for tracing /// Server that client is expecting to connect to - /// X.509 certificate + /// Optional hostname to use for server certificate validation + /// X.509 certificate from the server + /// Path to an X.509 certificate file from the application to compare with the serverCert /// Policy errors /// True if certificate is valid - internal static bool ValidateSslServerCertificate(string targetServerName, X509Certificate cert, SslPolicyErrors policyErrors) + internal static bool ValidateSslServerCertificate(Guid connectionId, string targetServerName, string hostNameInCertificate, X509Certificate serverCert, string validationCertFileName, SslPolicyErrors policyErrors) { using (TrySNIEventScope.Create("SNICommon.ValidateSslServerCertificate | SNI | SCOPE | INFO | Entering Scope {0} ")) { if (policyErrors == SslPolicyErrors.None) { - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.INFO, "targetServerName {0}, SSL Server certificate not validated as PolicyErrors set to None.", args0: targetServerName); + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.INFO, "Connection Id {0}, targetServerName {1}, SSL Server certificate not validated as PolicyErrors set to None.", args0: connectionId, args1: targetServerName); return true; } - // If we get to this point then there is a ssl policy flag. - StringBuilder messageBuilder = new(); - if (policyErrors.HasFlag(SslPolicyErrors.RemoteCertificateChainErrors)) + string serverNameToValidate; + X509Certificate validationCertificate = null; + if (!string.IsNullOrEmpty(hostNameInCertificate)) { - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "targetServerName {0}, SslPolicyError {1}, SSL Policy certificate chain has errors.", args0: targetServerName, args1: policyErrors); + serverNameToValidate = hostNameInCertificate; + } + else + { + serverNameToValidate = targetServerName; + } - // get the chain status from the certificate - X509Certificate2 cert2 = cert as X509Certificate2; - X509Chain chain = new(); - chain.ChainPolicy.RevocationMode = X509RevocationMode.Offline; - StringBuilder chainStatusInformation = new(); - bool chainIsValid = chain.Build(cert2); - Debug.Assert(!chainIsValid, "RemoteCertificateChainError flag is detected, but certificate chain is valid."); - if (!chainIsValid) + if (!string.IsNullOrEmpty(validationCertFileName)) + { + try { - foreach (X509ChainStatus chainStatus in chain.ChainStatus) - { - chainStatusInformation.Append($"{chainStatus.StatusInformation}, [Status: {chainStatus.Status}]"); - chainStatusInformation.AppendLine(); - } + validationCertificate = new X509Certificate(validationCertFileName); + } + catch (Exception e) + { + // if this fails, then fall back to the HostNameInCertificate or TargetServer validation. + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNITCPHandle), EventType.INFO, "Connection Id {0}, Exception occurred loading specified ServerCertificate: {1}, treating it as if ServerCertificate has not been specified.", args0: connectionId, args1: e.Message); } - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "targetServerName {0}, SslPolicyError {1}, SSL Policy certificate chain has errors. ChainStatus {2}", args0: targetServerName, args1: policyErrors, args2: chainStatusInformation); - messageBuilder.AppendFormat(Strings.SQL_RemoteCertificateChainErrors, chainStatusInformation); - messageBuilder.AppendLine(); } - if (policyErrors.HasFlag(SslPolicyErrors.RemoteCertificateNotAvailable)) + if (validationCertificate != null) { - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "targetServerName {0}, SSL Policy invalidated certificate.", args0: targetServerName); - messageBuilder.AppendLine(Strings.SQL_RemoteCertificateNotAvailable); + if (serverCert.GetRawCertData().AsSpan().SequenceEqual(validationCertificate.GetRawCertData().AsSpan())) + { + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.INFO, "Connection Id {0}, ServerCertificate matches the certificate provided by the server. Certificate validation passed.", args0: connectionId); + return true; + } + else + { + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.INFO, "Connection Id {0}, ServerCertificate doesn't match the certificate provided by the server. Certificate validation failed.", args0: connectionId); + throw ADP.SSLCertificateAuthenticationException(Strings.SQL_RemoteCertificateDoesNotMatchServerCertificate); + } } - - if (policyErrors.HasFlag(SslPolicyErrors.RemoteCertificateNameMismatch)) + else { -#if NET8_0_OR_GREATER - X509Certificate2 cert2 = cert as X509Certificate2; - if (!cert2.MatchesHostname(targetServerName)) + // If we get to this point then there is a ssl policy flag. + StringBuilder messageBuilder = new(); + if (policyErrors.HasFlag(SslPolicyErrors.RemoteCertificateNotAvailable)) { - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "targetServerName {0}, Target Server name or HNIC does not match the Subject/SAN in Certificate.", args0: targetServerName); - messageBuilder.AppendLine(Strings.SQL_RemoteCertificateNameMismatch); + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "Connection Id {0}, targetServerName {1}, SSL Server certificate not validated as PolicyErrors set to RemoteCertificateNotAvailable.", args0: connectionId, args1: targetServerName); + messageBuilder.AppendLine(Strings.SQL_RemoteCertificateNotAvailable); } -#else - // To Do: include certificate SAN (Subject Alternative Name) check. - string certServerName = cert.Subject.Substring(cert.Subject.IndexOf('=') + 1); - // Verify that target server name matches subject in the certificate - if (targetServerName.Length > certServerName.Length) - { - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "targetServerName {0}, Target Server name is of greater length than Subject in Certificate.", args0: targetServerName); - messageBuilder.AppendLine(Strings.SQL_RemoteCertificateNameMismatch); - } - else if (targetServerName.Length == certServerName.Length) + if (policyErrors.HasFlag(SslPolicyErrors.RemoteCertificateChainErrors)) { - // Both strings have the same length, so targetServerName must be a FQDN - if (!targetServerName.Equals(certServerName, StringComparison.OrdinalIgnoreCase)) + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "Connection Id {0}, targetServerName {0}, SslPolicyError {1}, SSL Policy certificate chain has errors.", args0: connectionId, args1: targetServerName, args2: policyErrors); + + // get the chain status from the certificate + X509Certificate2 cert2 = serverCert as X509Certificate2; + X509Chain chain = new(); + chain.ChainPolicy.RevocationMode = X509RevocationMode.Offline; + StringBuilder chainStatusInformation = new(); + bool chainIsValid = chain.Build(cert2); + Debug.Assert(!chainIsValid, "RemoteCertificateChainError flag is detected, but certificate chain is valid."); + if (!chainIsValid) { - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "targetServerName {0}, Target Server name does not match Subject in Certificate.", args0: targetServerName); - messageBuilder.AppendLine(Strings.SQL_RemoteCertificateNameMismatch); + foreach (X509ChainStatus chainStatus in chain.ChainStatus) + { + chainStatusInformation.Append($"{chainStatus.StatusInformation}, [Status: {chainStatus.Status}]"); + chainStatusInformation.AppendLine(); + } } + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "Connection Id {0}, targetServerName {1}, SslPolicyError {2}, SSL Policy certificate chain has errors. ChainStatus {3}", args0: connectionId, args1: targetServerName, args2: policyErrors, args3: chainStatusInformation); + messageBuilder.AppendFormat(Strings.SQL_RemoteCertificateChainErrors, chainStatusInformation); + messageBuilder.AppendLine(); } - else + + if (policyErrors.HasFlag(SslPolicyErrors.RemoteCertificateNameMismatch)) { - if (string.Compare(targetServerName, 0, certServerName, 0, targetServerName.Length, StringComparison.OrdinalIgnoreCase) != 0) +#if NET8_0_OR_GREATER + X509Certificate2 cert2 = serverCert as X509Certificate2; + if (!cert2.MatchesHostname(serverNameToValidate)) { - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "targetServerName {0}, Target Server name does not match Subject in Certificate.", args0: targetServerName); + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "Connection Id {0}, serverNameToValidate {1}, Target Server name or HNIC does not match the Subject/SAN in Certificate.", args0: connectionId, args1: serverNameToValidate); messageBuilder.AppendLine(Strings.SQL_RemoteCertificateNameMismatch); } +#else + // To Do: include certificate SAN (Subject Alternative Name) check. + string certServerName = serverCert.Subject.Substring(serverCert.Subject.IndexOf('=') + 1); - // Server name matches cert name for its whole length, so ensure that the - // character following the server name is a '.'. This will avoid - // having server name "ab" match "abc.corp.company.com" - // (Names have different lengths, so the target server can't be a FQDN.) - if (certServerName[targetServerName.Length] != '.') + // Verify that target server name matches subject in the certificate + if (serverNameToValidate.Length > certServerName.Length) { - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "targetServerName {0}, Target Server name does not match Subject in Certificate.", args0: targetServerName); + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "Connection Id {0}, serverNameToValidate {1}, Target Server name is of greater length than Subject in Certificate.", args0: connectionId, args1: serverNameToValidate); messageBuilder.AppendLine(Strings.SQL_RemoteCertificateNameMismatch); } - } -#endif - } - - if (messageBuilder.Length > 0) - { - throw ADP.SSLCertificateAuthenticationException(messageBuilder.ToString()); - } - - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.INFO, " Remote certificate with subject: {0}, validated successfully.", args0: cert.Subject); - return true; - } - } - - /// - /// We validate the provided certificate provided by the client with the one from the server to see if it matches. - /// Certificate validation and chain trust validations are done by SSLStream class [System.Net.Security.SecureChannel.VerifyRemoteCertificate method] - /// This method is called as a result of callback for SSL Stream Certificate validation. - /// - /// X.509 certificate provided by the client - /// X.509 certificate provided by the server - /// Policy errors - /// True if certificate is valid - internal static bool ValidateSslServerCertificate(X509Certificate clientCert, X509Certificate serverCert, SslPolicyErrors policyErrors) - { - using (TrySNIEventScope.Create("SNICommon.ValidateSslServerCertificate | SNI | SCOPE | INFO | Entering Scope {0} ")) - { - if (policyErrors == SslPolicyErrors.None) - { - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.INFO, "serverCert {0}, SSL Server certificate not validated as PolicyErrors set to None.", args0: clientCert.Subject); - return true; - } - - StringBuilder messageBuilder = new(); - if (policyErrors.HasFlag(SslPolicyErrors.RemoteCertificateNotAvailable)) - { - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "serverCert {0}, SSL Server certificate not validated as PolicyErrors set to RemoteCertificateNotAvailable.", args0: clientCert.Subject); - messageBuilder.AppendLine(Strings.SQL_RemoteCertificateNotAvailable); - } - - if (policyErrors.HasFlag(SslPolicyErrors.RemoteCertificateChainErrors)) - { - // get the chain status from the server certificate - X509Certificate2 cert2 = serverCert as X509Certificate2; - X509Chain chain = new(); - chain.ChainPolicy.RevocationMode = X509RevocationMode.Offline; - StringBuilder chainStatusInformation = new(); - bool chainIsValid = chain.Build(cert2); - Debug.Assert(!chainIsValid, "RemoteCertificateChainError flag is detected, but certificate chain is valid."); - if (!chainIsValid) - { - foreach (X509ChainStatus chainStatus in chain.ChainStatus) + else if (serverNameToValidate.Length == certServerName.Length) { - chainStatusInformation.Append($"{chainStatus.StatusInformation}, [Status: {chainStatus.Status}]"); - chainStatusInformation.AppendLine(); + // Both strings have the same length, so serverNameToValidate must be a FQDN + if (!serverNameToValidate.Equals(certServerName, StringComparison.OrdinalIgnoreCase)) + { + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "Connection Id {0}, serverNameToValidate {1}, Target Server name does not match Subject in Certificate.", args0: connectionId, args1: serverNameToValidate); + messageBuilder.AppendLine(Strings.SQL_RemoteCertificateNameMismatch); + } } - } - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "certificate subject from server is {0}, and does not match with the certificate provided client.", args0: cert2.SubjectName.Name); - messageBuilder.AppendFormat(Strings.SQL_RemoteCertificateChainErrors, chainStatusInformation); - messageBuilder.AppendLine(); - } - - if (policyErrors.HasFlag(SslPolicyErrors.RemoteCertificateNameMismatch)) - { -#if NET8_0_OR_GREATER - X509Certificate2 s_cert = serverCert as X509Certificate2; - X509Certificate2 c_cert = clientCert as X509Certificate2; - - if (!s_cert.MatchesHostname(c_cert.SubjectName.Name)) - { - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "certificate from server does not match with the certificate provided client.", args0: s_cert.Subject); - messageBuilder.AppendLine(Strings.SQL_RemoteCertificateNameMismatch); - } -#else - // Verify that subject name matches - if (serverCert.Subject != clientCert.Subject) - { - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "certificate subject from server is {0}, and does not match with the certificate provided client.", args0: serverCert.Subject); - messageBuilder.AppendLine(Strings.SQL_RemoteCertificateNameMismatch); + else + { + if (string.Compare(serverNameToValidate, 0, certServerName, 0, serverNameToValidate.Length, StringComparison.OrdinalIgnoreCase) != 0) + { + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "Connection Id {0}, serverNameToValidate {1}, Target Server name does not match Subject in Certificate.", args0: connectionId, args1: serverNameToValidate); + messageBuilder.AppendLine(Strings.SQL_RemoteCertificateNameMismatch); + } + + // Server name matches cert name for its whole length, so ensure that the + // character following the server name is a '.'. This will avoid + // having server name "ab" match "abc.corp.company.com" + // (Names have different lengths, so the target server can't be a FQDN.) + if (certServerName[serverNameToValidate.Length] != '.') + { + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "Connection Id {0}, serverNameToValidate {1}, Target Server name does not match Subject in Certificate.", args0: connectionId, args1: serverNameToValidate); + messageBuilder.AppendLine(Strings.SQL_RemoteCertificateNameMismatch); + } + } +#endif } - if (!serverCert.Equals(clientCert)) + if (messageBuilder.Length > 0) { - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.ERR, "certificate from server does not match with the certificate provided client.", args0: serverCert.Subject); - messageBuilder.AppendLine(Strings.SQL_RemoteCertificateNameMismatch); + throw ADP.SSLCertificateAuthenticationException(messageBuilder.ToString()); } -#endif } - if (messageBuilder.Length > 0) - { - throw ADP.SSLCertificateAuthenticationException(messageBuilder.ToString()); - } - - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.INFO, "certificate subject {0}, Client certificate validated successfully.", args0: clientCert.Subject); + SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.INFO, "Connection Id {0}, certificate with subject: {1}, validated successfully.", args0: connectionId, args1: serverCert.Subject); return true; } } @@ -342,11 +300,11 @@ internal static IPAddress[] GetDnsIpAddresses(string serverName, TimeoutTimer ti args0: serverName, args1: remainingTimeout); using CancellationTokenSource cts = new CancellationTokenSource(remainingTimeout); - - return Dns.GetHostAddressesAsync(serverName, cts.Token) - .ConfigureAwait(false) - .GetAwaiter() - .GetResult(); + // using this overload to support netstandard + Task task = Dns.GetHostAddressesAsync(serverName); + task.ConfigureAwait(false); + task.Wait(cts.Token); + return task.Result; } } diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNINpHandle.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNINpHandle.cs index 2889ce6bb4..8f8af57f58 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNINpHandle.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNINpHandle.cs @@ -24,6 +24,8 @@ internal sealed class SNINpHandle : SNIPhysicalHandle private readonly string _targetServer; private readonly object _sendSync; + private readonly string _hostNameInCertificate; + private readonly string _serverCertificateFilename; private readonly bool _tlsFirst; private Stream _stream; private NamedPipeClientStream _pipeStream; @@ -38,7 +40,7 @@ internal sealed class SNINpHandle : SNIPhysicalHandle private int _bufferSize = TdsEnums.DEFAULT_LOGIN_PACKET_SIZE; private readonly Guid _connectionId = Guid.NewGuid(); - public SNINpHandle(string serverName, string pipeName, TimeoutTimer timeout, bool tlsFirst) + public SNINpHandle(string serverName, string pipeName, TimeoutTimer timeout, bool tlsFirst, string hostNameInCertificate, string serverCertificateFilename) { using (TrySNIEventScope.Create(nameof(SNINpHandle))) { @@ -47,6 +49,8 @@ public SNINpHandle(string serverName, string pipeName, TimeoutTimer timeout, boo _sendSync = new object(); _targetServer = serverName; _tlsFirst = tlsFirst; + _hostNameInCertificate = hostNameInCertificate; + _serverCertificateFilename = serverCertificateFilename; try { _pipeStream = new NamedPipeClientStream( @@ -369,14 +373,14 @@ public override void DisableSsl() /// Validate server certificate /// /// Sender object - /// X.509 certificate + /// X.509 certificate /// X.509 chain /// Policy errors /// true if valid - private bool ValidateServerCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors policyErrors) + private bool ValidateServerCertificate(object sender, X509Certificate serverCertificate, X509Chain chain, SslPolicyErrors policyErrors) { using (TrySNIEventScope.Create(nameof(SNINpHandle))) - { + { if (!_validateCert) { SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNINpHandle), EventType.INFO, "Connection Id {0}, Certificate validation not requested.", args0: ConnectionId); @@ -384,8 +388,8 @@ private bool ValidateServerCertificate(object sender, X509Certificate cert, X509 } SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNINpHandle), EventType.INFO, "Connection Id {0}, Proceeding to SSL certificate validation.", args0: ConnectionId); - return SNICommon.ValidateSslServerCertificate(_targetServer, cert, policyErrors); - } + return SNICommon.ValidateSslServerCertificate(_connectionId, _targetServer, _hostNameInCertificate, serverCertificate, _serverCertificateFilename, policyErrors); + } } /// diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs index 77b44a1cf5..0ee31e5f46 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs @@ -206,7 +206,7 @@ internal static SNIHandle CreateConnectionHandle( tlsFirst, hostNameInCertificate, serverCertificateFilename); break; case DataSource.Protocol.NP: - sniHandle = CreateNpHandle(details, timeout, parallel, tlsFirst); + sniHandle = CreateNpHandle(details, timeout, parallel, tlsFirst, hostNameInCertificate, serverCertificateFilename); break; default: Debug.Fail($"Unexpected connection protocol: {details._connectionProtocol}"); @@ -362,8 +362,10 @@ private static SNITCPHandle CreateTcpHandle( /// Timer expiration /// Should MultiSubnetFailover be used. Only returns an error for named pipes. /// + /// Host name in certificate + /// Used for the path to the Server Certificate /// SNINpHandle - private static SNINpHandle CreateNpHandle(DataSource details, TimeoutTimer timeout, bool parallel, bool tlsFirst) + private static SNINpHandle CreateNpHandle(DataSource details, TimeoutTimer timeout, bool parallel, bool tlsFirst, string hostNameInCertificate, string serverCertificateFilename) { if (parallel) { @@ -371,7 +373,7 @@ private static SNINpHandle CreateNpHandle(DataSource details, TimeoutTimer timeo SNICommon.ReportSNIError(SNIProviders.NP_PROV, 0, SNICommon.MultiSubnetFailoverWithNonTcpProtocol, Strings.SNI_ERROR_49); return null; } - return new SNINpHandle(details.PipeHostName, details.PipeName, timeout, tlsFirst); + return new SNINpHandle(details.PipeHostName, details.PipeName, timeout, tlsFirst, hostNameInCertificate, serverCertificateFilename); } /// @@ -539,8 +541,10 @@ private void PopulateProtocol() internal static string GetLocalDBInstance(string dataSource, out bool error) { string instanceName = null; + // ReadOnlySpan is not supported in netstandard 2.0, but installing System.Memory solves the issue ReadOnlySpan input = dataSource.AsSpan().TrimStart(); error = false; + // NetStandard 2.0 does not support passing a string to ReadOnlySpan int index = input.IndexOf(LocalDbHost.AsSpan().Trim(), StringComparison.InvariantCultureIgnoreCase); if (input.StartsWith(LocalDbHost_NP.AsSpan().Trim(), StringComparison.InvariantCultureIgnoreCase)) { diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNITcpHandle.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNITcpHandle.cs index 9d415bcfc8..2791de17a4 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNITcpHandle.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNITcpHandle.cs @@ -644,7 +644,6 @@ public override uint EnableSsl(uint options) } else { - // TODO: Resolve whether to send _serverNameIndication or _targetServer. _serverNameIndication currently results in error. Why? _sslStream.AuthenticateAsClient(_targetServer, null, s_supportedProtocols, false); } if (_sslOverTdsStream is not null) @@ -698,33 +697,8 @@ private bool ValidateServerCertificate(object sender, X509Certificate serverCert return true; } - string serverNameToValidate; - if (!string.IsNullOrEmpty(_hostNameInCertificate)) - { - serverNameToValidate = _hostNameInCertificate; - } - else - { - serverNameToValidate = _targetServer; - } - - if (!string.IsNullOrEmpty(_serverCertificateFilename)) - { - X509Certificate clientCertificate = null; - try - { - clientCertificate = new X509Certificate(_serverCertificateFilename); - return SNICommon.ValidateSslServerCertificate(clientCertificate, serverCertificate, policyErrors); - } - catch (Exception e) - { - // if this fails, then fall back to the HostNameInCertificate or TargetServer validation. - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNITCPHandle), EventType.INFO, "Connection Id {0}, IOException occurred: {1}", args0: _connectionId, args1: e.Message); - } - } - SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNITCPHandle), EventType.INFO, "Connection Id {0}, Certificate will be validated for Target Server name", args0: _connectionId); - return SNICommon.ValidateSslServerCertificate(serverNameToValidate, serverCertificate, policyErrors); + return SNICommon.ValidateSslServerCertificate(_connectionId, _targetServer, _hostNameInCertificate, serverCertificate, _serverCertificateFilename, policyErrors); } /// diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.Designer.cs b/src/Microsoft.Data.SqlClient/src/Resources/Strings.Designer.cs index 533ffa86ad..a685787e9e 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.Designer.cs +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.Designer.cs @@ -10215,6 +10215,15 @@ internal static string SQL_RemoteCertificateChainErrors { } } + /// + /// Looks up a localized string similar to The certificate provided by the server does not match the certificate provided by the ServerCertificate option.. + /// + internal static string SQL_RemoteCertificateDoesNotMatchServerCertificate { + get { + return ResourceManager.GetString("SQL_RemoteCertificateDoesNotMatchServerCertificate", resourceCulture); + } + } + /// /// Looks up a localized string similar to Certificate name mismatch. The provided 'DataSource' or 'HostNameInCertificate' does not match the name in the certificate.. /// diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.resx b/src/Microsoft.Data.SqlClient/src/Resources/Strings.resx index 3fb2e0a74a..c2dd68b867 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.resx +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.resx @@ -4737,4 +4737,7 @@ Certificate not available while validating the certificate. + + The certificate provided by the server does not match the certificate provided by the ServerCertificate option. + diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs index 8f16c09aa3..a164149a60 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs @@ -12,6 +12,7 @@ using System.Security; using System.Threading; using System.Threading.Tasks; +using Microsoft.SqlServer.TDS.PreLogin; using Microsoft.SqlServer.TDS.Servers; using Xunit; diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/TestTdsServer.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/TestTdsServer.cs index 1ead74f58d..ef45bdbc7a 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/TestTdsServer.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/TestTdsServer.cs @@ -65,6 +65,5 @@ public static TestTdsServer StartTestServer(bool enableFedAuth = false, bool ena public void Dispose() => _endpoint?.Stop(); public string ConnectionString { get; private set; } - } } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/ConnectionTestParameters.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/ConnectionTestParameters.cs new file mode 100644 index 0000000000..4b6e7b087b --- /dev/null +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/ConnectionTestParameters.cs @@ -0,0 +1,40 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.SqlServer.TDS.PreLogin; + +namespace Microsoft.Data.SqlClient.ManualTesting.Tests.DataCommon +{ + public class ConnectionTestParameters + { + private SqlConnectionEncryptOption _encryptionOption; + private TDSPreLoginTokenEncryptionType _encryptionType; + private string _hnic; + private string _cert; + private bool _result; + private bool _trustServerCert; + + public SqlConnectionEncryptOption Encrypt => _encryptionOption; + public bool TrustServerCertificate => _trustServerCert; + public string Certificate => _cert; + public string HostNameInCertificate => _hnic; + public bool TestResult => _result; + public TDSPreLoginTokenEncryptionType TdsEncryptionType => _encryptionType; + + public ConnectionTestParameters(TDSPreLoginTokenEncryptionType tdsEncryptionType, SqlConnectionEncryptOption encryptOption, bool trustServerCert, string cert, string hnic, bool result) + { + _encryptionOption = encryptOption; + _trustServerCert = trustServerCert; + _cert = cert; + _hnic = hnic; + _result = result; + _encryptionType = tdsEncryptionType; + } + } +} diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/ConnectionTestParametersData.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/ConnectionTestParametersData.cs new file mode 100644 index 0000000000..5a2e01a77c --- /dev/null +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/ConnectionTestParametersData.cs @@ -0,0 +1,85 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.IO; +using Microsoft.SqlServer.TDS.PreLogin; + +namespace Microsoft.Data.SqlClient.ManualTesting.Tests.DataCommon +{ + public class ConnectionTestParametersData + { + private const int CASES = 30; + private string _empty = string.Empty; + // It was advised to store the client certificate in its own folder. + private static readonly string s_fullPathToCer = Path.Combine(Directory.GetCurrentDirectory(), "clientcert", "localhostcert.cer"); + private static readonly string s_mismatchedcert = Path.Combine(Directory.GetCurrentDirectory(), "clientcert", "mismatchedcert.cer"); + + private static readonly string s_hostName = System.Net.Dns.GetHostName(); + public static ConnectionTestParametersData Data { get; } = new ConnectionTestParametersData(); + public List ConnectionTestParametersList { get; set; } + + public static IEnumerable GetConnectionTestParameters() + { + for (int i = 0; i < CASES; i++) + { + yield return new object[] { Data.ConnectionTestParametersList[i] }; + } + } + + public ConnectionTestParametersData() + { + // Test cases possible field values for connection parameters: + // These combinations are based on the possible values of Encrypt, TrustServerCertificate, Certificate, HostNameInCertificate + /* + * TDSEncryption | Encrypt | TrustServerCertificate | Certificate | HNIC | TestResults + * ---------------------------------------------------------------------------------------------- + * Off | Optional | true | valid | valid name | true + * On | Mandatory | false | mismatched | empty | false + * Required | | x | ChainError? | wrong name? | + */ + ConnectionTestParametersList = new List + { + // TDSPreLoginTokenEncryptionType.Off + new(TDSPreLoginTokenEncryptionType.Off, SqlConnectionEncryptOption.Optional, false, _empty, _empty, true), + new(TDSPreLoginTokenEncryptionType.Off, SqlConnectionEncryptOption.Mandatory, false, _empty, _empty, false), + new(TDSPreLoginTokenEncryptionType.Off, SqlConnectionEncryptOption.Optional, true, _empty, _empty, true), + new(TDSPreLoginTokenEncryptionType.Off, SqlConnectionEncryptOption.Mandatory, true, _empty, _empty, true), + new(TDSPreLoginTokenEncryptionType.Off, SqlConnectionEncryptOption.Mandatory, false, s_fullPathToCer, _empty, true), + new(TDSPreLoginTokenEncryptionType.Off, SqlConnectionEncryptOption.Mandatory, true, s_fullPathToCer, _empty, true), + new(TDSPreLoginTokenEncryptionType.Off, SqlConnectionEncryptOption.Mandatory, false, _empty, s_hostName, false), + new(TDSPreLoginTokenEncryptionType.Off, SqlConnectionEncryptOption.Mandatory, true, _empty, s_hostName, true), + + // TDSPreLoginTokenEncryptionType.On + new(TDSPreLoginTokenEncryptionType.On, SqlConnectionEncryptOption.Optional, false, _empty, _empty, false), + new(TDSPreLoginTokenEncryptionType.On, SqlConnectionEncryptOption.Mandatory, false, _empty, _empty, false), + new(TDSPreLoginTokenEncryptionType.On, SqlConnectionEncryptOption.Optional, true, _empty, _empty, true), + new(TDSPreLoginTokenEncryptionType.On, SqlConnectionEncryptOption.Mandatory, true, _empty, _empty, true), + new(TDSPreLoginTokenEncryptionType.On, SqlConnectionEncryptOption.Mandatory, false, s_fullPathToCer, _empty, true), + new(TDSPreLoginTokenEncryptionType.On, SqlConnectionEncryptOption.Mandatory, true, s_fullPathToCer, _empty, true), + new(TDSPreLoginTokenEncryptionType.On, SqlConnectionEncryptOption.Mandatory, false, _empty, s_hostName, false), + new(TDSPreLoginTokenEncryptionType.On, SqlConnectionEncryptOption.Mandatory, true, _empty, s_hostName, true), + + // TDSPreLoginTokenEncryptionType.Required + new(TDSPreLoginTokenEncryptionType.Required, SqlConnectionEncryptOption.Optional, false, _empty, _empty, false), + new(TDSPreLoginTokenEncryptionType.Required, SqlConnectionEncryptOption.Mandatory, false, _empty, _empty, false), + new(TDSPreLoginTokenEncryptionType.Required, SqlConnectionEncryptOption.Optional, true, _empty, _empty, true), + new(TDSPreLoginTokenEncryptionType.Required, SqlConnectionEncryptOption.Mandatory, true, _empty, _empty, true), + new(TDSPreLoginTokenEncryptionType.Required, SqlConnectionEncryptOption.Mandatory, false, s_fullPathToCer, _empty, true), + new(TDSPreLoginTokenEncryptionType.Required, SqlConnectionEncryptOption.Mandatory, true, s_fullPathToCer, _empty, true), + new(TDSPreLoginTokenEncryptionType.Required, SqlConnectionEncryptOption.Mandatory, false, _empty, s_hostName, false), + new(TDSPreLoginTokenEncryptionType.Required, SqlConnectionEncryptOption.Mandatory, true, _empty, s_hostName, true), + + // Mismatched certificate test + new(TDSPreLoginTokenEncryptionType.Off, SqlConnectionEncryptOption.Mandatory, false, s_mismatchedcert, _empty, false), + new(TDSPreLoginTokenEncryptionType.Off, SqlConnectionEncryptOption.Mandatory, true, s_mismatchedcert, _empty, false), + new(TDSPreLoginTokenEncryptionType.Off, SqlConnectionEncryptOption.Mandatory, true, s_mismatchedcert, _empty, true), + new(TDSPreLoginTokenEncryptionType.On, SqlConnectionEncryptOption.Mandatory, false, s_mismatchedcert, _empty, false), + new(TDSPreLoginTokenEncryptionType.On, SqlConnectionEncryptOption.Mandatory, true, s_mismatchedcert, _empty, true), + new(TDSPreLoginTokenEncryptionType.Required, SqlConnectionEncryptOption.Mandatory, false, s_mismatchedcert, _empty, false), + new(TDSPreLoginTokenEncryptionType.Required, SqlConnectionEncryptOption.Mandatory, true, s_mismatchedcert, _empty, true), + }; + } + } +} diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj index f75aef8edb..8962d5ab15 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj @@ -270,6 +270,8 @@ + + @@ -287,6 +289,7 @@ + @@ -354,6 +357,15 @@ + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + Always diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectionTestWithSSLCert/CertificateTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectionTestWithSSLCert/CertificateTest.cs index fc358acb05..d8a402236e 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectionTestWithSSLCert/CertificateTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectionTestWithSSLCert/CertificateTest.cs @@ -32,7 +32,7 @@ public class CertificateTest : IDisposable // InstanceName will get replaced with an instance name in the connection string private static string InstanceName = "MSSQLSERVER"; - // InstanceNamePrefix will get replaced with MSSQL$ is there is an instance name in connection string + // s_instanceNamePrefix will get replaced with MSSQL$ is there is an instance name in connection string private static string InstanceNamePrefix = ""; // SlashInstance is used to override IPV4 and IPV6 defined about so it includes an instance name diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectionTestWithSSLCert/CertificateTestWithTdsServer.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectionTestWithSSLCert/CertificateTestWithTdsServer.cs new file mode 100644 index 0000000000..9cfc1c71bb --- /dev/null +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectionTestWithSSLCert/CertificateTestWithTdsServer.cs @@ -0,0 +1,269 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Data; +using System.Diagnostics; +using System.IO; +using System.Runtime.InteropServices; +using System.Security.Cryptography.X509Certificates; +using System.Security.Principal; +using System.ServiceProcess; +using System.Text; +using Microsoft.Data.SqlClient.ManualTesting.Tests.DataCommon; +using Microsoft.Win32; +using Xunit; + +namespace Microsoft.Data.SqlClient.ManualTesting.Tests +{ + public class CertificateTestWithTdsServer : IDisposable + { + private static readonly string s_fullPathToPowershellScript = Path.Combine(Directory.GetCurrentDirectory(), "makepfxcert.ps1"); + private static readonly string s_fullPathToCleanupPowershellScript = Path.Combine(Directory.GetCurrentDirectory(), "removecert.ps1"); + private static readonly string s_fullPathToPfx = Path.Combine(Directory.GetCurrentDirectory(), "localhostcert.pfx"); + private static readonly string s_fullPathTothumbprint = Path.Combine(Directory.GetCurrentDirectory(), "thumbprint.txt"); + private static readonly string s_fullPathToClientCert = Path.Combine(Directory.GetCurrentDirectory(), "clientcert"); + private static bool s_windowsAdmin = true; + private static string s_instanceName = "MSSQLSERVER"; + // s_instanceNamePrefix will get replaced with MSSQL$ is there is an instance name in the connection string + private static string s_instanceNamePrefix = ""; + private const string LocalHost = "localhost"; + + public CertificateTestWithTdsServer() + { + SqlConnectionStringBuilder builder = new(DataTestUtility.TCPConnectionString); + Assert.True(DataTestUtility.ParseDataSource(builder.DataSource, out string hostname, out _, out string instanceName)); + + if (!string.IsNullOrEmpty(instanceName)) + { + s_instanceName = instanceName; + s_instanceNamePrefix = "MSSQL$"; + } + + // Confirm that user has elevated access on Windows + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + using WindowsIdentity identity = WindowsIdentity.GetCurrent(); + WindowsPrincipal principal = new(identity); + if (principal.IsInRole(WindowsBuiltInRole.Administrator)) + s_windowsAdmin = true; + else + s_windowsAdmin = false; + } + + if (!Directory.Exists(s_fullPathToClientCert)) + { + Directory.CreateDirectory(s_fullPathToClientCert); + } + + RunPowershellScript(s_fullPathToPowershellScript); + } + + private static bool IsLocalHost() + { + SqlConnectionStringBuilder builder = new(DataTestUtility.TCPConnectionString); + Assert.True(DataTestUtility.ParseDataSource(builder.DataSource, out string hostname, out _, out _)); + return LocalHost.Equals(hostname, StringComparison.OrdinalIgnoreCase); + } + + private static bool AreConnStringsSetup() => DataTestUtility.AreConnStringsSetup(); + private static bool IsNotAzureServer() => DataTestUtility.IsNotAzureServer(); + private static bool UseManagedSNIOnWindows() => DataTestUtility.UseManagedSNIOnWindows; + + private static string ForceEncryptionRegistryPath + { + get + { + if (DataTestUtility.IsSQL2022()) + { + return $@"SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL16.{s_instanceName}\MSSQLSERVER\SuperSocketNetLib"; + } + if (DataTestUtility.IsSQL2019()) + { + return $@"SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL15.{s_instanceName}\MSSQLSERVER\SuperSocketNetLib"; + } + if (DataTestUtility.IsSQL2016()) + { + return $@"SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL14.{s_instanceName}\MSSQLSERVER\SuperSocketNetLib"; + } + return string.Empty; + } + } + + [ConditionalTheory(nameof(AreConnStringsSetup), nameof(IsNotAzureServer), nameof(IsLocalHost))] + [MemberData(nameof(ConnectionTestParametersData.GetConnectionTestParameters), MemberType = typeof(ConnectionTestParametersData))] + [PlatformSpecific(TestPlatforms.Windows)] + public void BeginWindowsConnectionTest(ConnectionTestParameters connectionTestParameters) + { + if (!s_windowsAdmin) + { + Assert.Fail("User needs to have elevated access for these set of tests"); + } + + ConnectionTest(connectionTestParameters); + } + + [ConditionalTheory(nameof(AreConnStringsSetup), nameof(IsNotAzureServer), nameof(IsLocalHost))] + [MemberData(nameof(ConnectionTestParametersData.GetConnectionTestParameters), MemberType = typeof(ConnectionTestParametersData))] + [PlatformSpecific(TestPlatforms.Linux)] + public void BeginLinuxConnectionTest(ConnectionTestParameters connectionTestParameters) + { + ConnectionTest(connectionTestParameters); + } + + private void ConnectionTest(ConnectionTestParameters connectionTestParameters) + { + SqlConnectionStringBuilder builder = new(DataTestUtility.TCPConnectionString); + + // The TestTdsServer does not validate the user name and password, so we can use any value if they are not defined. + string userId = string.IsNullOrWhiteSpace(builder.UserID) ? "user" : builder.UserID; + string password = string.IsNullOrWhiteSpace(builder.Password) ? "password" : builder.Password; + + using TestTdsServer server = TestTdsServer.StartTestServer(enableFedAuth: false, enableLog: false, connectionTimeout: 15, + methodName: "", new X509Certificate2(s_fullPathToPfx, "nopassword", X509KeyStorageFlags.UserKeySet), + encryptionType: connectionTestParameters.TdsEncryptionType); + + builder = new(server.ConnectionString) + { + UserID = userId, + Password = password, + TrustServerCertificate = connectionTestParameters.TrustServerCertificate, + Encrypt = connectionTestParameters.Encrypt, + }; + + if (!string.IsNullOrEmpty(connectionTestParameters.Certificate)) + { + builder.ServerCertificate = connectionTestParameters.Certificate; + } + + if (!string.IsNullOrEmpty(connectionTestParameters.HostNameInCertificate)) + { + builder.HostNameInCertificate = connectionTestParameters.HostNameInCertificate; + } + + using SqlConnection connection = new(builder.ConnectionString); + try + { + connection.Open(); + Assert.Equal(connectionTestParameters.TestResult, (connection.State == ConnectionState.Open)); + } + catch (Exception) + { + Assert.False(connectionTestParameters.TestResult); + } + } + + private static void RunPowershellScript(string script) + { + string currentDirectory = Directory.GetCurrentDirectory(); + string powerShellCommand = "powershell.exe"; + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + powerShellCommand = "pwsh"; + } + + if (File.Exists(script)) + { + StringBuilder output = new(); + Process proc = new() + { + StartInfo = + { + FileName = powerShellCommand, + RedirectStandardError = true, + RedirectStandardOutput = true, + UseShellExecute = false, + Arguments = $"{script} -OutDir {currentDirectory} > result.txt", + CreateNoWindow = false, + Verb = "runas" + } + }; + + proc.EnableRaisingEvents = true; + + proc.OutputDataReceived += new DataReceivedEventHandler((sender, e) => + { + if (e.Data != null) + { + output.AppendLine(e.Data); + } + }); + + proc.ErrorDataReceived += new DataReceivedEventHandler((sender, e) => + { + if (e.Data != null) + { + output.AppendLine(e.Data); + } + }); + + proc.Start(); + + proc.BeginOutputReadLine(); + proc.BeginErrorReadLine(); + + if (!proc.WaitForExit(60000)) + { + proc.Kill(); + proc.WaitForExit(2000); + throw new Exception($"Could not generate certificate. Error output: {output}"); + } + } + else + { + throw new Exception($"Could not find makepfxcert.ps1"); + } + } + + private void RemoveCertificate() + { + string thumbprint = File.ReadAllText(s_fullPathTothumbprint); + using X509Store certStore = new(StoreName.Root, StoreLocation.LocalMachine); + certStore.Open(OpenFlags.ReadWrite); + X509Certificate2Collection certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false); + if (certCollection.Count > 0) + { + certStore.Remove(certCollection[0]); + } + certStore.Close(); + + File.Delete(s_fullPathTothumbprint); + Directory.Delete(s_fullPathToClientCert, true); + } + + private static void RemoveForceEncryptionFromRegistryPath(string registryPath) + { + RegistryKey key = Registry.LocalMachine.OpenSubKey(registryPath, true); + key?.SetValue("ForceEncryption", 0, RegistryValueKind.DWord); + key?.SetValue("Certificate", "", RegistryValueKind.String); + ServiceController sc = new($"{s_instanceNamePrefix}{s_instanceName}"); + sc.Stop(); + sc.WaitForStatus(ServiceControllerStatus.Stopped); + sc.Start(); + sc.WaitForStatus(ServiceControllerStatus.Running); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + if (disposing && !string.IsNullOrEmpty(s_fullPathTothumbprint)) + { + RemoveCertificate(); + RemoveForceEncryptionFromRegistryPath(ForceEncryptionRegistryPath); + } + } + else + { + RunPowershellScript(s_fullPathToCleanupPowershellScript); + } + } + } +} diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/TestTdsServer.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/TestTdsServer.cs index 3552204886..a4557d72b6 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/TestTdsServer.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/TestTdsServer.cs @@ -3,27 +3,35 @@ // See the LICENSE file in the project root for more information. using System; +using System.Linq; using System.Net; +using System.Net.Sockets; using System.Runtime.CompilerServices; +using System.Security.Cryptography.X509Certificates; using Microsoft.SqlServer.TDS.EndPoint; +using Microsoft.SqlServer.TDS.PreLogin; using Microsoft.SqlServer.TDS.Servers; namespace Microsoft.Data.SqlClient.ManualTesting.Tests { internal class TestTdsServer : GenericTDSServer, IDisposable { + private const int DefaultConnectionTimeout = 5; + private TDSServerEndPoint _endpoint = null; - private SqlConnectionStringBuilder connectionStringBuilder; + private SqlConnectionStringBuilder _connectionStringBuilder; public TestTdsServer(TDSServerArguments args) : base(args) { } public TestTdsServer(QueryEngine engine, TDSServerArguments args) : base(args) { - this.Engine = engine; + Engine = engine; } - public static TestTdsServer StartServerWithQueryEngine(QueryEngine engine, bool enableFedAuth = false, bool enableLog = false, [CallerMemberName] string methodName = "") + public static TestTdsServer StartServerWithQueryEngine(QueryEngine engine, bool enableFedAuth = false, bool enableLog = false, + int connectionTimeout = DefaultConnectionTimeout, [CallerMemberName] string methodName = "", + X509Certificate2 encryptionCertificate = null, TDSPreLoginTokenEncryptionType encryptionType = TDSPreLoginTokenEncryptionType.NotSupported) { TDSServerArguments args = new TDSServerArguments() { @@ -32,10 +40,18 @@ public static TestTdsServer StartServerWithQueryEngine(QueryEngine engine, bool if (enableFedAuth) { - args.FedAuthRequiredPreLoginOption = Microsoft.SqlServer.TDS.PreLogin.TdsPreLoginFedAuthRequiredOption.FedAuthRequired; + args.FedAuthRequiredPreLoginOption = SqlServer.TDS.PreLogin.TdsPreLoginFedAuthRequiredOption.FedAuthRequired; + } + + if (encryptionCertificate != null) + { + args.EncryptionCertificate = encryptionCertificate; } + args.Encryption = encryptionType; + TestTdsServer server = engine == null ? new TestTdsServer(args) : new TestTdsServer(engine, args); + server._endpoint = new TDSServerEndPoint(server) { ServerEndPoint = new IPEndPoint(IPAddress.Any, 0) }; server._endpoint.EndpointName = methodName; // The server EventLog should be enabled as it logs the exceptions. @@ -43,19 +59,37 @@ public static TestTdsServer StartServerWithQueryEngine(QueryEngine engine, bool server._endpoint.Start(); int port = server._endpoint.ServerEndPoint.Port; - server.connectionStringBuilder = new SqlConnectionStringBuilder() { DataSource = "localhost," + port, ConnectTimeout = 5, Encrypt = SqlConnectionEncryptOption.Optional }; - server.ConnectionString = server.connectionStringBuilder.ConnectionString; + + server._connectionStringBuilder = new SqlConnectionStringBuilder() + { + DataSource = "localhost," + port, + ConnectTimeout = connectionTimeout, + }; + + if (encryptionType == TDSPreLoginTokenEncryptionType.Off || + encryptionType == TDSPreLoginTokenEncryptionType.None || + encryptionType == TDSPreLoginTokenEncryptionType.NotSupported) + { + server._connectionStringBuilder.Encrypt = SqlConnectionEncryptOption.Optional; + } + else + { + server._connectionStringBuilder.Encrypt = SqlConnectionEncryptOption.Mandatory; + } + + server.ConnectionString = server._connectionStringBuilder.ConnectionString; return server; } - public static TestTdsServer StartTestServer(bool enableFedAuth = false, bool enableLog = false, [CallerMemberName] string methodName = "") + public static TestTdsServer StartTestServer(bool enableFedAuth = false, bool enableLog = false, + int connectionTimeout = DefaultConnectionTimeout, [CallerMemberName] string methodName = "", + X509Certificate2 encryptionCertificate = null, TDSPreLoginTokenEncryptionType encryptionType = TDSPreLoginTokenEncryptionType.NotSupported) { - return StartServerWithQueryEngine(null, false, false, methodName); + return StartServerWithQueryEngine(null, enableFedAuth, enableLog, connectionTimeout, methodName, encryptionCertificate, encryptionType); } public void Dispose() => _endpoint?.Stop(); public string ConnectionString { get; private set; } - } } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/makepfxcert.ps1 b/src/Microsoft.Data.SqlClient/tests/ManualTests/makepfxcert.ps1 new file mode 100644 index 0000000000..02d558d77b --- /dev/null +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/makepfxcert.ps1 @@ -0,0 +1,158 @@ +# Licensed to the .NET Foundation under one or more agreements. +# The .NET Foundation licenses this file to you under the MIT license. +# See the LICENSE file in the project root for more information. +# Script: Invoke-SqlServerCertificateCommand# +# Author: SqlClient Team +# Date: March 20, 2024 +# Comments: This scripts creates SSL Self-Signed Certificate for TestTdsServer in pfx format. +# This script is not intended to be used in any production environments. + +param ($OutDir) + +function Invoke-SqlServerCertificateCommand { + [CmdletBinding()] + param( + [Parameter(Mandatory = $false)] + [string] $certificateName = "localhostcert.cer", + [string] $myCertStoreLocation = "Cert:\LocalMachine\My", + [string] $rootCertStoreLocation = "Cert:\LocalMachine\Root", + [string] $sqlAliasName = "SQLAliasName", + [string] $localhost = "localhost", + [string] $LoopBackIPV4 = "127.0.0.1", + [string] $LoopBackIPV6 = "::1" + ) + Write-Output "Certificate generation started..." + + # Change directory to where the tests are + Write-Output "Change directory to $OutDir ..." + cd $OutDir + pwd + + try { + # Get FQDN of the machine + Write-Output "Get FQDN of the machine..." + $fqdn = [System.Net.Dns]::GetHostByName(($env:computerName)).HostName + Write-Output "FQDN = $fqdn" + + $OS = [System.Environment]::OSVersion.Platform + Write-Output "Operating System is $OS" + + # Create a self-signed certificate + if ($OS -eq "Unix") { + chmod 777 $OutDir + # Install OpenSSL module + Install-Module -Name OpenSSL -Repository PSGallery -Force + # Show version of OpenSSL just to make sure it is installed + openssl version + + # Create self signed certificate using openssl + Write-Output "Creating certificate for linux..." + if ($fqdn.length -gt 64) { + $machineId = $fqdn.Substring(0,15) + openssl req -x509 -newkey rsa:4096 -sha256 -days 1095 -nodes -keyout $OutDir/localhostcert.key -out $OutDir/localhostcert.cer -subj "/CN=$machineId" -addext "subjectAltName=DNS:$fqdn,DNS:localhost,IP:127.0.0.1,IP:::1" + } + else { + openssl req -x509 -newkey rsa:4096 -sha256 -days 1095 -nodes -keyout $OutDir/localhostcert.key -out $OutDir/localhostcert.cer -subj "/CN=$fqdn" -addext "subjectAltName=DNS:$fqdn,DNS:localhost,IP:127.0.0.1,IP:::1" + } + chmod 777 $OutDir/localhostcert.key $OutDir/localhostcert.cer + # Copy the certificate to the clientcert folder + cp $OutDir/localhostcert.cer $OutDir/clientcert/ + # Export the certificate to pfx + Write-Output "Exporting certificate to pfx..." + openssl pkcs12 -export -in $OutDir/localhostcert.cer -inkey $OutDir/localhostcert.key -out $OutDir/localhostcert.pfx -password pass:nopassword + chmod 777 $OutDir/localhostcert.pfx + + Write-Output "Converting certificate to pem..." + # Create pem from cer + cp $OutDir/localhostcert.cer $OutDir/localhostcert.pem + chmod 777 $OutDir/localhostcert.pem + + # Add trust to the pem certificate + Write-Output "Adding trust to pem certificate..." + openssl x509 -trustout -addtrust "serverAuth" -in $OutDir/localhostcert.pem + + # Import the certificate to the Root store ------------------------------------------------------------------------------ + # NOTE: The process must have root privileges to add the certificate to the Root store. If not, then use + # "chmod 777 /usr/local/share/ca-certificates" to give read, write and execute privileges to anyone on that folder + # Copy the certificate to /usr/local/share/ca-certificates folder while changing the extension to "crt". + # Only certificates with extension "crt" gets added for some reason. + Write-Output "Copy the pem certificate to /usr/local/share/ca-certificates folder..." + cp $OutDir/localhostcert.pem /usr/local/share/ca-certificates/localhostcert.crt + + # Add trust to the mismatched certificate as well + $ openssl x509 -in $OutDir/mismatchedcert.cer -inform der -out $OutDir/mismatchedcert.pem + # Copy the mismatched certificate to the clientcert folder + cp $OutDir/mismatchedcert.cer $OutDir/clientcert/ + openssl x509 -trustout -addtrust "serverAuth" -in $OutDir/mismatchedcert.pem + cp $OutDir/mismatchedcert.pem /usr/local/share/ca-certificates/mismatchedcert.crt + + # enable certificate as CA certificate + dpkg-reconfigure ca-certificates -f noninteractive -p critical + + # Update the certificates store + Write-Output "Updating the certificates store..." + update-ca-certificates -v + } else { + Write-Output "Creating a self-signed certificate..." + $params = @{ + Type = "SSLServerAuthentication" + Subject = "CN=$fqdn" + KeyAlgorithm = "RSA" + KeyLength = 4096 + HashAlgorithm = "SHA256" + TextExtension = "2.5.29.37={text}1.3.6.1.5.5.7.3.1", "2.5.29.17={text}DNS=$fqdn&DNS=$localhost&IPAddress=$LoopBackIPV4&DNS=$sqlAliasName&IPAddress=$LoopBackIPV6" + NotAfter = (Get-Date).AddMonths(36) + KeySpec = "KeyExchange" + Provider = "Microsoft RSA SChannel Cryptographic Provider" + CertStoreLocation = $myCertStoreLocation + FriendlyName = "TestTDSServerCertificate" + } + + $certificate = New-SelfSignedCertificate @params + Write-Output "Certificate created successfully" + Write-Output "Certificate Thumbprint: $($certificate.Thumbprint)" + + # Export the certificate to a file + Write-Output "Exporting the certificate to a file..." + Export-Certificate -Cert $certificate -FilePath "$OutDir/$certificateName" -Type CERT + + # Copy the certificate to the clientcert folder + copy $OutDir/$certificateName $OutDir/clientcert/ + copy $OutDir/mismatchedcert.cer $OutDir/clientcert/ + + # Import the certificate to the Root store + Write-Output "Importing the certificate to the Root store..." + $params = @{ + FilePath = "$OutDir/$certificateName" + CertStoreLocation = $rootCertStoreLocation + } + Import-Certificate @params + + Write-Output "Converting certificate to pfx..." + Write-Output "Cert:\LocalMachine\my\$($certificate.Thumbprint)" + + $pwd = ConvertTo-SecureString -String 'nopassword' -Force -AsPlainText + # Export the certificate to a pfx format + Export-PfxCertificate -Password $pwd -FilePath "$OutDir\localhostcert.pfx" -Cert "Cert:\LocalMachine\my\$($certificate.Thumbprint)" + + # Write the certificate thumbprint to a file + echo $certificate.Thumbprint | Out-File -FilePath "$OutDir\thumbprint.txt" -Encoding ascii + } + + Write-Output "Done creating pfx certificate..." + } + catch { + $e = $_.Exception + $msg = $e.Message + while ($e.InnerException) { + $e = $e.InnerException + $msg += "`n" + $e.Message + } + + Write-Output "Certificate generation was not successfull. $msg" + } + + Write-Output "Certificate generation task completed." +} + +Invoke-SqlServerCertificateCommand diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/mismatchedcert.cer b/src/Microsoft.Data.SqlClient/tests/ManualTests/mismatchedcert.cer new file mode 100644 index 0000000000000000000000000000000000000000..6b35e97a5534ea4c218c4df7c8874906248ae967 GIT binary patch literal 919 zcmXqLVxDZ!#8kb2nTe5!Ngy^P*GyUZ-a7B}EvW(eTUiWv**LY@JlekVGBR?rG8h;d z>Ko{?F^94+^Qak_8JJiZrx;jRS)`h$SfwT#SQ(m_8e18r7@1flCmUN>85@~f7|4n9 z8kqn!8X6cFTN)We0lB6St|^F1j*(4_O2`glWMyD(V&rEqXkz4IYGPz$SbOK-j9&TV zEgRNvuu-@i@;fWtudU~!iqntVJ}2GYS=8;|itsC3$D4V?#`L7UfI4%*`2waxd(+vv zwAKfR|GZieThy9zBSOKIcfrM1o{y6F51ib|vG?(Dm`V_WUN%W?Dgiha#mwg;~^ExIkpuww6)OtVU-e`1>ssRvbcEU%ki z6UxNQ$iTR`ahXBmVgo*4Y{~L7GX7^_VP;}oU?2JvoW%=vNJQmS&Rn3 zAZbAs9|Nx@ejmqx5dQ$(0ArtEcRw%7c9wbu2F7*)22{YfK%R{YXc7x!leq{J^8!I0 zbd3-@`B=nQL^y+2NAGaD968U_Qe$GxadoS&C635Z2~1O`5AbNofAd?B{41$IBVlICa^LjYly7sGdwi`9u_UiCKQD5n`kU%biB%6K zG7HaTx-9W^-7y(^MURXQ0RwqnQJ!|eUA)t#967$F!8L8O@b3I|J?9b_clWAgr!M-u zvew4PMd)Fq!`f(_%*i70JT=lsrmwd=D9=~Kc&=09-9cv0ywC0J+{> literal 0 HcmV?d00001 diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/removecert.ps1 b/src/Microsoft.Data.SqlClient/tests/ManualTests/removecert.ps1 new file mode 100644 index 0000000000..14b944de80 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/removecert.ps1 @@ -0,0 +1,21 @@ +# Licensed to the .NET Foundation under one or more agreements. +# The .NET Foundation licenses this file to you under the MIT license. +# See the LICENSE file in the project root for more information. +# Script: removecert.ps1 +# Author: SqlClient Team +# Date: May 24, 2024 +# Comments: This script deletes the SSL Self-Signed Certificate from Linux certificate store. +# This script is not intended to be used in any production environments. + +param ($OutDir) + +# Delete all certificates +rm $OutDir/clientcer/*.cer +rm $OutDir/localhostcert.pem +rm $OutDir/mismatchedcert.pem +rm /usr/local/share/ca-certificates/localhostcert.crt +rm /usr/local/share/ca-certificates/mismatchedcert.crt + +# Update the certificates store +Write-Output "Updating the certificates store..." +update-ca-certificates -v diff --git a/src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS/TDSStream.cs b/src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS/TDSStream.cs index 94abbf5818..80d8633501 100644 --- a/src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS/TDSStream.cs +++ b/src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS/TDSStream.cs @@ -264,6 +264,10 @@ public override int Read(byte[] buffer, int offset, int count) // Calculate how much data can be read until the end of the packet is reached long packetDataAvailable = IncomingPacketHeader.Length - IncomingPacketPosition; + // Set count to actual size of data to be read from the buffer so this loop can exit + if (packetDataAvailable < count) + count = (int)packetDataAvailable; + // Check how much data we should give back in the current iteration int packetDataToRead = Math.Min((int)packetDataAvailable, count - bufferReadPosition); From 42e9f08f91a3e1a1602d6b632df00f89abe04760 Mon Sep 17 00:00:00 2001 From: dauinsight <145612907+dauinsight@users.noreply.github.com> Date: Fri, 31 May 2024 14:57:21 -0700 Subject: [PATCH 14/25] Hotfix v5.2.1 Release notes (#2534) --- CHANGELOG.md | 18 +++++++ release-notes/5.2/5.2.1.md | 99 +++++++++++++++++++++++++++++++++++++ release-notes/5.2/5.2.md | 1 + release-notes/5.2/README.md | 1 + 4 files changed, 119 insertions(+) create mode 100644 release-notes/5.2/5.2.1.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 29c1c394af..1b8d651ebf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,24 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) +## [Stable release 5.2.1] - 2024-05-31 + +This update brings the below changes over the previous release: + +### Changed + +- Upgraded `Azure.Identity` version from 1.10.3 to 1.11.3 [#2492](https://github.com/dotnet/SqlClient/pull/2492), [#2528](https://github.com/dotnet/SqlClient/pull/2528) +- Upgraded `Microsoft.Identity.Client` version from 4.56.0 to 4.60.3 [#2492](https://github.com/dotnet/SqlClient/pull/2492) +- Code Health improvements: [#2467](https://github.com/dotnet/SqlClient/pull/2467) + +### Fixed + +- Fixed connection errors on Linux when Data Source property contains both named instance and port [#2436](https://github.com/dotnet/SqlClient/pull/2436) +- Fixed `SqlConnection.FireInfoMessageEventOnUserErrors` when set to true throws an exception [#2505](https://github.com/dotnet/SqlClient/pull/2505) +- Fixed exception when using `DATETIMEOFFSET(n)` in a TVP if `n` is 1, 2, 3, or 4 [#2506](https://github.com/dotnet/SqlClient/pull/2506) +- Reverted PR [#1983](https://github.com/dotnet/SqlClient/pull/1938) which caused connection failure delays when using `OpenAsync` [#2507](https://github.com/dotnet/SqlClient/pull/2507) +- Fixed `SqlConnection.Clone()` to include `AccessTokenCallback` [#2527](https://github.com/dotnet/SqlClient/pull/2527) + ## [Stable release 5.2.0] - 2024-02-28 ### Added diff --git a/release-notes/5.2/5.2.1.md b/release-notes/5.2/5.2.1.md new file mode 100644 index 0000000000..9922998d9d --- /dev/null +++ b/release-notes/5.2/5.2.1.md @@ -0,0 +1,99 @@ +# Release Notes + +## [Stable release 5.2.1] - 2024-05-31 + +This update brings the below changes over the previous release: + +### Changed + +- Upgraded `Azure.Identity` version from 1.10.3 to 1.11.3 [#2492](https://github.com/dotnet/SqlClient/pull/2492), [#2528](https://github.com/dotnet/SqlClient/pull/2528) +- Upgraded `Microsoft.Identity.Client` version from 4.56.0 to 4.60.3 [#2492](https://github.com/dotnet/SqlClient/pull/2492) +- Code Health improvements: [#2467](https://github.com/dotnet/SqlClient/pull/2467) + +### Fixed + +- Fixed connection errors on Linux when Data Source property contains both named instance and port [#2436](https://github.com/dotnet/SqlClient/pull/2436) +- Fixed `SqlConnection.FireInfoMessageEventOnUserErrors` when set to true throws an exception [#2505](https://github.com/dotnet/SqlClient/pull/2505) +- Fixed exception when using `DATETIMEOFFSET(n)` in a TVP if `n` is 1, 2, 3, or 4 [#2506](https://github.com/dotnet/SqlClient/pull/2506) +- Reverted PR [#1983](https://github.com/dotnet/SqlClient/pull/1938) which caused connection failure delays when using `OpenAsync` [#2507](https://github.com/dotnet/SqlClient/pull/2507) +- Fixed `SqlConnection.Clone()` to include `AccessTokenCallback` [#2527](https://github.com/dotnet/SqlClient/pull/2527) + +## Target Platform Support + +- .NET Framework 4.6.2+ (Windows x86, Windows x64) +- .NET 6.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS) +- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS) + +### Dependencies + +#### .NET Framework + +- Microsoft.Data.SqlClient.SNI 5.2.0 +- Azure.Identity 1.11.3 +- Microsoft.Identity.Client 4.60.3 +- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.35.0 +- Microsoft.IdentityModel.JsonWebTokens 6.35.0 +- System.Buffers 4.5.1 +- System.Configuration.ConfigurationManager 6.0.1 +- System.Runtime.InteropServices.RuntimeInformation 4.3.0 +- System.Text.Encoding.Web 6.0.0 + +#### .NET 6 + +- Microsoft.Data.SqlClient.SNI.runtime 5.2.0 +- Azure.Identity 1.11.3 +- Microsoft.Identity.Client 4.60.3 +- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.35.0 +- Microsoft.IdentityModel.JsonWebTokens 6.35.0 +- Microsoft.SqlServer.Server 1.0.0 +- System.Configuration.ConfigurationManager 6.0.1 +- System.Runtime.Caching 6.0.0 + +#### .NET 8 + +- Microsoft.Data.SqlClient.SNI.runtime 5.2.0 +- Azure.Identity 1.11.3 +- Microsoft.Identity.Client 4.60.3 +- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.35.0 +- Microsoft.IdentityModel.JsonWebTokens 6.35.0 +- Microsoft.SqlServer.Server 1.0.0 +- System.Configuration.ConfigurationManager 8.0.0 +- System.Runtime.Caching 8.0.0 + +#### .NET Standard 2.0 + +- Microsoft.Data.SqlClient.SNI.runtime 5.2.0 +- Azure.Identity 1.11.3 +- Microsoft.Identity.Client 4.60.3 +- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.35.0 +- Microsoft.IdentityModel.JsonWebTokens 6.35.0 +- Microsoft.SqlServer.Server 1.0.0 +- Microsoft.Win32.Registry 5.0.0 +- System.Buffers 4.5.1 +- System.Configuration.ConfigurationManager 6.0.1 +- System.Diagnostics.DiagnosticSource 6.0.1 +- System.Runtime.Caching 6.0.0 +- System.Text.Encoding.CodePages 6.0.0 +- System.Text.Encodings.Web 6.0.0 +- System.Runtime.Loader 4.3.0 +- System.Security.Cryptography.Cng 5.0.0 +- System.Security.Principal.Windows 5.0.0 + +#### .NET Standard 2.1 + +- Microsoft.Data.SqlClient.SNI.runtime 5.2.0 +- Azure.Identity 1.11.3 +- Microsoft.Identity.Client 4.60.3 +- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.35.0 +- Microsoft.IdentityModel.JsonWebTokens 6.35.0 +- Microsoft.SqlServer.Server 1.0.0 +- Microsoft.Win32.Registry 5.0.0 +- System.Configuration.ConfigurationManager 6.0.1 +- System.Diagnostics.DiagnosticSource 6.0.1 +- System.Runtime.Caching 6.0.0 +- System.Text.Encoding.CodePages 6.0.0 +- System.Text.Encodings.Web 6.0.0 +- System.Runtime.Loader 4.3.0 +- System.Security.Cryptography.Cng 5.0.0 +- System.Security.Principal.Windows 5.0.0 + diff --git a/release-notes/5.2/5.2.md b/release-notes/5.2/5.2.md index 8193904e37..18473289b3 100644 --- a/release-notes/5.2/5.2.md +++ b/release-notes/5.2/5.2.md @@ -4,6 +4,7 @@ The following Microsoft.Data.SqlClient 5.2 stable releases have been shipped: | Release Date | Version | Notes | | :-- | :-- | :--: | +| 2024/05/31 | 5.2.1 | [release notes](5.2.1.md) | | 2024/02/28 | 5.2.0 | [release notes](5.2.0.md) | The following Microsoft.Data.SqlClient 5.2 preview releases have been shipped: diff --git a/release-notes/5.2/README.md b/release-notes/5.2/README.md index a311f99484..1d5a27bb00 100644 --- a/release-notes/5.2/README.md +++ b/release-notes/5.2/README.md @@ -4,6 +4,7 @@ The following Microsoft.Data.SqlClient 5.2 stable releases have been shipped: | Release Date | Version | Notes | | :-- | :-- | :--: | +| 2024/05/31 | 5.2.1 | [release notes](5.2.1.md) | | 2024/02/28 | 5.2.0 | [release notes](5.2.0.md) | The following Microsoft.Data.SqlClient 5.2 preview releases have been shipped: From 348ae2ee13ddccd64fe5fe4220ff22ba04ef9a4b Mon Sep 17 00:00:00 2001 From: Scott Addie <10702007+scottaddie@users.noreply.github.com> Date: Fri, 31 May 2024 17:07:36 -0500 Subject: [PATCH 15/25] Improve AccessTokenCallback sample code (#2543) --- doc/samples/SqlConnection_AccessTokenCallback.cs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/doc/samples/SqlConnection_AccessTokenCallback.cs b/doc/samples/SqlConnection_AccessTokenCallback.cs index c761f640fd..3d9422f7d4 100644 --- a/doc/samples/SqlConnection_AccessTokenCallback.cs +++ b/doc/samples/SqlConnection_AccessTokenCallback.cs @@ -14,14 +14,21 @@ static void Main() private static void OpenSqlConnection() { + const string defaultScopeSuffix = "/.default"; string connectionString = GetConnectionString(); - using (SqlConnection connection = new SqlConnection("Data Source=contoso.database.windows.net;Initial Catalog=AdventureWorks;") + DefaultAzureCredential credential = new(); + + using (SqlConnection connection = new(connectionString) { AccessTokenCallback = async (authParams, cancellationToken) => { - var cred = new DefaultAzureCredential(); - string scope = authParams.Resource.EndsWith(s_defaultScopeSuffix) ? authParams.Resource : authParams.Resource + s_defaultScopeSuffix; - var token = await cred.GetTokenAsync(new TokenRequestContext(new[] { scope }), cancellationToken); + string scope = authParams.Resource.EndsWith(defaultScopeSuffix) + ? authParams.Resource + : $"{authParams.Resource}{defaultScopeSuffix}"; + AccessToken token = await credential.GetTokenAsync( + new TokenRequestContext([scope]), + cancellationToken); + return new SqlAuthenticationToken(token.Token, token.ExpiresOn); } }) From f7ab11591d6fe736f26e1d21756e29e2a2d259d2 Mon Sep 17 00:00:00 2001 From: Javad Rahnama Date: Sat, 8 Jun 2024 10:44:31 -0700 Subject: [PATCH 16/25] Fix | Adjust path for .AssemblyAttributes in obj folder (#2550) --- src/Microsoft.Data.SqlClient/add-ons/Directory.Build.props | 2 +- .../netcore/src/Microsoft.Data.SqlClient.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/add-ons/Directory.Build.props b/src/Microsoft.Data.SqlClient/add-ons/Directory.Build.props index 4ec39ed694..d0bf4f7757 100644 --- a/src/Microsoft.Data.SqlClient/add-ons/Directory.Build.props +++ b/src/Microsoft.Data.SqlClient/add-ons/Directory.Build.props @@ -11,7 +11,7 @@ Project $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb true - $([System.IO.Path]::Combine('$(IntermediateOutputPath)','$(TargetFrameworkMoniker).AssemblyAttributes$(DefaultLanguageSourceExtension)')) + $([System.IO.Path]::Combine('$(IntermediateOutputPath)','$(TargetFramework)','$(TargetFrameworkMoniker).AssemblyAttributes$(DefaultLanguageSourceExtension)')) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj index 2cd3537ea7..7cf0b1e619 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -20,7 +20,7 @@ $(NoWarn);IL2026;IL2057;IL2072;IL2075 - $([System.IO.Path]::Combine('$(IntermediateOutputPath)','$(TargetFrameworkMoniker).AssemblyAttributes$(DefaultLanguageSourceExtension)')) + $([System.IO.Path]::Combine('$(IntermediateOutputPath)','$(TargetFramework)','$(TargetFrameworkMoniker).AssemblyAttributes$(DefaultLanguageSourceExtension)')) From 3f0c4b1a706136e417efa3a49bc168342470513e Mon Sep 17 00:00:00 2001 From: Aris Rellegue <134557572+arellegue@users.noreply.github.com> Date: Tue, 11 Jun 2024 19:14:48 +0000 Subject: [PATCH 17/25] Fix | Fixed GenerateSspiClientContext to retry negotiation with default port (#2559) --- .../SSPI/NegotiateSSPIContextProvider.cs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NegotiateSSPIContextProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NegotiateSSPIContextProvider.cs index 2c68839e3f..21ab4a15b7 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NegotiateSSPIContextProvider.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NegotiateSSPIContextProvider.cs @@ -14,13 +14,25 @@ internal sealed class NegotiateSSPIContextProvider : SSPIContextProvider internal override void GenerateSspiClientContext(ReadOnlyMemory received, ref byte[] sendBuff, ref uint sendLength, byte[][] _sniSpnBuffer) { - _negotiateAuth ??= new(new NegotiateAuthenticationClientOptions { Package = "Negotiate", TargetName = Encoding.Unicode.GetString(_sniSpnBuffer[0]) }); - sendBuff = _negotiateAuth.GetOutgoingBlob(received.Span, out NegotiateAuthenticationStatusCode statusCode)!; - SqlClientEventSource.Log.TryTraceEvent("TdsParserStateObjectManaged.GenerateSspiClientContext | Info | Session Id {0}, StatusCode={1}", _physicalStateObj.SessionId, statusCode); + NegotiateAuthenticationStatusCode statusCode = NegotiateAuthenticationStatusCode.UnknownCredentials; + + for (int i = 0; i < _sniSpnBuffer.Length; i++) + { + _negotiateAuth ??= new(new NegotiateAuthenticationClientOptions { Package = "Negotiate", TargetName = Encoding.Unicode.GetString(_sniSpnBuffer[i]) }); + sendBuff = _negotiateAuth.GetOutgoingBlob(received.Span, out statusCode)!; + // Log session id, status code and the actual SPN used in the negotiation + SqlClientEventSource.Log.TryTraceEvent("TdsParserStateObjectManaged.GenerateSspiClientContext | Info | Session Id {0}, StatusCode={1}, SPN={2}", _physicalStateObj.SessionId, statusCode, _negotiateAuth.TargetName); + if (statusCode == NegotiateAuthenticationStatusCode.Completed || statusCode == NegotiateAuthenticationStatusCode.ContinueNeeded) + break; // Successful case, exit the loop with current SPN. + else + _negotiateAuth = null; // Reset _negotiateAuth to be generated again for next SPN. + } + if (statusCode is not NegotiateAuthenticationStatusCode.Completed and not NegotiateAuthenticationStatusCode.ContinueNeeded) { throw new InvalidOperationException(SQLMessage.SSPIGenerateError() + Environment.NewLine + statusCode); } + sendLength = (uint)(sendBuff != null ? sendBuff.Length : 0); } } From ffd8771a599f90557facdebd983cd4e60dbb6f83 Mon Sep 17 00:00:00 2001 From: Wraith Date: Tue, 11 Jun 2024 21:46:23 +0100 Subject: [PATCH 18/25] Strong typed diagnostics (#2226) --- .../SqlClientDiagnostic.xml | 312 ++++++ src/Microsoft.Data.SqlClient.sln | 1 + .../netcore/ref/Microsoft.Data.SqlClient.cs | 312 ++++++ .../src/Microsoft.Data.SqlClient.csproj | 1 + .../Data/SqlClient/SqlClientDiagnostic.cs | 970 ++++++++++++++++++ .../SqlClientDiagnosticListenerExtensions.cs | 380 +++---- .../Microsoft/Data/SqlClient/SqlCommand.cs | 3 +- .../Microsoft/Data/SqlClient/SqlConnection.cs | 11 +- 8 files changed, 1795 insertions(+), 195 deletions(-) create mode 100644 doc/snippets/Microsoft.Data.SqlClient/SqlClientDiagnostic.xml create mode 100644 src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientDiagnostic.cs diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlClientDiagnostic.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlClientDiagnostic.xml new file mode 100644 index 0000000000..3711bbb7f7 --- /dev/null +++ b/doc/snippets/Microsoft.Data.SqlClient/SqlClientDiagnostic.xml @@ -0,0 +1,312 @@ + + + + + A guid value used to correlate before, after and error events. + + + The name of the operation. + + + The timestamp of the event. + + + + Gets the element at the specified index in the read-only list. + + The zero-based index of the element to get. + The element at the specified index in the read-only list. + + + + Gets the number of elements in the collection. + The number of elements in the collection. + + + Returns an enumerator that iterates through the collection. + An enumerator that can be used to iterate through the collection. + + + + + Contains diagnostic information emitted before a command is executed. + + + The name of the event that needs to be enabled for the event to be raised. + + + A nullable guid uniquely identifying the connection that the xommand is being executed on. + + + A nullable long uniquely identifying the transaction that the command enrolled in if it is enrolled in one. + + + The command object that is executing. + + + + + Contains diagnostic information emitted after a command is successfully executed. + + + The name of the event that needs to be enabled for the event to be raised. + + + A nullable guid uniquely identifying the connection that the command is being executed on. + + + A nullable long uniquely identifying the transaction that the command is enrolled in if it is enrolled in one, or null. + + + The command object that is executing. + + + An IDictionary of statistic information about the event that has completed. + + + + + Contains diagnostic information emitted after a command execution fails with an exception. + + + The name of the event that needs to be enabled for the event to be raised. + + + A nullable guid uniquely identifying the connection that the command is being executed on. + + + A nullable long uniquely identifying the transaction that the command is enrolled in if it is enrolled in one, or null. + + + The command object that is executing. + + + The exception object that caused the command execution to fail. + + + + + Contains diagnostic information emitted before a connection is opened. + + + The name of the event that needs to be enabled for the event to be raised. + + + The connection object that is being opened. + + + The version of the SqlClient library. + + + + + Contains diagnostic information emitted after a connection has been successfully opened. + + + The name of the event that needs to be enabled for the event to be raised. + + + The connection object that has been opened. + + + The version of the SqlClient library. + + + The unique guid assigned to the connection. + + + An IDictionary of statistic information about the event that has completed. + + + + + Contains diagnostic information emitted after a connection open fails with an exception. + + + The name of the event that needs to be enabled for the event to be raised. + + + The connection object that has been opened. + + + The version of the SqlClient library. + + + The unique guid assigned to the connection. + + + The exception object that caused the command execution to fail. + + + + + Contains diagnostic information emitted before a connection is closed. + + + The name of the event that needs to be enabled for the event to be raised. + + + The connection object that is being closed. + + + The unique guid assigned to the connection. + + + An IDictionary of statistic information about the connection. + + + + + Contains diagnostic information emitted after a connection has been successfully closed. + + + The name of the event that needs to be enabled for the event to be raised. + + + The connection object that has been closed. + + + The unique guid assigned to the connection. + + + An IDictionary of statistic information about the connection. + + + + + Contains diagnostic information emitted after a connection close fails with an exception. + + + The name of the event that needs to be enabled for the event to be raised. + + + The connection object that has been closed. + + + The unique guid assigned to the connection. + + + An IDictionary of statistic information about the connection. + + + The exception object that caused the command execution to fail. + + + + + Contains diagnostic information emitted before a transaction is opened. + + + The name of the event that needs to be enabled for the event to be raised. + + + The connection object that the transaction belongs to. + + + The IsolationLevel of the transaction. + + + A nullable long uniquely identifying the transaction that the command is enrolled in if it is enrolled in one, or null. + + + + + Contains diagnostic information emitted after a transaction is successfully committed. + + + The name of the event that needs to be enabled for the event to be raised. + + + The connection object that the transaction belongs to. + + + The IsolationLevel of the transaction. + + + A nullable long uniquely identifying the transaction that the command is enrolled in if it is enrolled in one, or null. + + + + + Contains diagnostic information emitted after a transaction commit fails with an exception. + + + The name of the event that needs to be enabled for the event to be raised. + + + The connection object that the transaction belongs to. + + + The IsolationLevel of the transaction. + + + A nullable long uniquely identifying the transaction that the command is enrolled in if it is enrolled in one, or null. + + + The exception object that caused the command execution to fail. + + + + + Contains diagnostic information emitted before a transaction rollback is rolled back. + + + The name of the event that needs to be enabled for the event to be raised. + + + The connection object that the transaction belongs to. + + + The IsolationLevel of the transaction. + + + A nullable long uniquely identifying the transaction that the command is enrolled in if it is enrolled in one, or null. + + + The name of the transaction which is being rolled back. + + + + + Contains diagnostic information emitted after a transaction is rolled back successfully. + + + The name of the event that needs to be enabled for the event to be raised. + + + The connection object that the transaction belongs to. + + + The IsolationLevel of the transaction. + + + A nullable long uniquely identifying the transaction, or null. + + + The name of the transaction which is being rolled back. + + + + + Contains diagnostic information emitted after a transaction roll back failes with an exception. + + + The name of the event that needs to be enabled for the event to be raised. + + + The connection object that the transaction belongs to. + + + The IsolationLevel of the transaction. + + + A nullable long uniquely identifying the transaction , or null. + + + The name of the transaction which is being rolled back. + + + The exception object that caused the command execution to fail. + + + diff --git a/src/Microsoft.Data.SqlClient.sln b/src/Microsoft.Data.SqlClient.sln index 04668c8f81..9ab18e4989 100644 --- a/src/Microsoft.Data.SqlClient.sln +++ b/src/Microsoft.Data.SqlClient.sln @@ -100,6 +100,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft.Data.SqlClient", ..\doc\snippets\Microsoft.Data.SqlClient\SqlBulkCopyColumnMapping.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlBulkCopyColumnMapping.xml ..\doc\snippets\Microsoft.Data.SqlClient\SqlBulkCopyColumnMappingCollection.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlBulkCopyColumnMappingCollection.xml ..\doc\snippets\Microsoft.Data.SqlClient\SqlBulkCopyOptions.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlBulkCopyOptions.xml + ..\doc\snippets\Microsoft.Data.SqlClient\SqlClientDiagnostic.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlClientDiagnostic.xml ..\doc\snippets\Microsoft.Data.SqlClient\SqlClientFactory.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlClientFactory.xml ..\doc\snippets\Microsoft.Data.SqlClient\SqlClientLogger.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlClientLogger.xml ..\doc\snippets\Microsoft.Data.SqlClient\SqlClientMetaDataCollectionNames.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlClientMetaDataCollectionNames.xml diff --git a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs index 72203bb433..5dfbf8af3f 100644 --- a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs +++ b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs @@ -5,6 +5,8 @@ // NOTE: The current Microsoft.VSDesigner editor attributes are implemented for System.Data.SqlClient, and are not publicly available. // New attributes that are designed to work with Microsoft.Data.SqlClient and are publicly documented should be included in future. +using System; + [assembly: System.CLSCompliant(true)] namespace Microsoft.Data { @@ -1908,6 +1910,316 @@ public sealed class SqlConfigurableRetryFactory public static SqlRetryLogicBaseProvider CreateNoneRetryProvider() { throw null; } } } +namespace Microsoft.Data.SqlClient.Diagnostics +{ + /// + public abstract class SqlClientDiagnostic : System.Collections.Generic.IReadOnlyList> + { + internal SqlClientDiagnostic() { } + /// + protected const int CommonPropertyCount = 3; + /// + protected SqlClientDiagnostic(System.Guid operationId, string operation, long timestamp) { } + /// + public System.Guid OperationId => throw null; + /// + public string Operation => throw null; + /// + public long Timestamp => throw null; + /// > + public int Count => CommonPropertyCount + GetDerivedCount(); + /// > + public System.Collections.Generic.KeyValuePair this[int index] => throw null; + /// > + public System.Collections.Generic.IEnumerator> GetEnumerator() => throw null; + /// > + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator(); + /// + protected bool TryGetCommonProperty(int index, out System.Collections.Generic.KeyValuePair property) => throw null; + /// + protected abstract int GetDerivedCount(); + /// + protected abstract System.Collections.Generic.KeyValuePair GetDerivedProperty(int index); + } + + /// + public sealed class SqlClientCommandBefore : SqlClientDiagnostic + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteCommandBefore"; + /// + public System.Guid? ConnectionId => throw null; + /// + public long? TransactionId => throw null; + /// + public SqlCommand Command => throw null; + /// > + protected sealed override int GetDerivedCount() => 3; + /// > + protected sealed override System.Collections.Generic.KeyValuePair GetDerivedProperty(int index) => throw null; + } + + /// + public sealed class SqlClientCommandAfter : SqlClientDiagnostic + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteCommandAfter"; + /// + public System.Guid? ConnectionId => throw null; + /// + public long? TransactionId => throw null; + /// + public SqlCommand Command => throw null; + /// + public System.Collections.IDictionary Statistics => throw null; + /// > + protected sealed override int GetDerivedCount() => 4; + /// > + protected sealed override System.Collections.Generic.KeyValuePair GetDerivedProperty(int index) => throw null; + } + + /// + public sealed class SqlClientCommandError : SqlClientDiagnostic + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteCommandError"; + /// + public System.Guid? ConnectionId => throw null; + /// + public long? TransactionId => throw null; + /// + public SqlCommand Command => throw null; + /// + public System.Exception Exception { get; } + /// > + protected sealed override int GetDerivedCount() => 4; + /// > + protected sealed override System.Collections.Generic.KeyValuePair GetDerivedProperty(int index) => throw null; + } + + /// + public sealed class SqlClientConnectionOpenBefore : SqlClientDiagnostic + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteConnectionOpenBefore"; + /// + public SqlConnection Connection => throw null; + /// + public string ClientVersion => throw null; + /// > + protected override int GetDerivedCount() => 2; + /// > + protected sealed override System.Collections.Generic.KeyValuePair GetDerivedProperty(int index) => throw null; + } + + /// + public sealed class SqlClientConnectionOpenAfter : SqlClientDiagnostic + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteConnectionOpenAfter"; + /// + public System.Guid ConnectionId => throw null; + /// + public SqlConnection Connection => throw null; + /// + public string ClientVersion => throw null; + /// + public System.Collections.IDictionary Statistics => throw null; + /// > + protected override int GetDerivedCount() => 4; + /// > + protected sealed override System.Collections.Generic.KeyValuePair GetDerivedProperty(int index) => throw null; + } + + /// + public sealed class SqlClientConnectionOpenError : SqlClientDiagnostic + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteConnectionOpenError"; + /// + public System.Guid ConnectionId => throw null; + /// + public SqlConnection Connection => throw null; + /// + public string ClientVersion => throw null; + /// + public System.Exception Exception => throw null; + /// > + protected override int GetDerivedCount() => 4; + /// > + protected sealed override System.Collections.Generic.KeyValuePair GetDerivedProperty(int index) => throw null; + } + + /// + public sealed class SqlClientConnectionCloseBefore : SqlClientDiagnostic + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteConnectionCloseBefore"; + /// + public System.Guid? ConnectionId => throw null; + /// + public SqlConnection Connection => throw null; + /// + public System.Collections.IDictionary Statistics => throw null; + /// > + protected sealed override int GetDerivedCount() => 3; + /// > + protected sealed override System.Collections.Generic.KeyValuePair GetDerivedProperty(int index) => throw null; + } + + /// + public sealed class SqlClientConnectionCloseAfter : SqlClientDiagnostic + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteConnectionCloseAfter"; + + /// + public System.Guid? ConnectionId => throw null; + + /// + public SqlConnection Connection => throw null; + + /// + public System.Collections.IDictionary Statistics => throw null; + + /// > + protected sealed override int GetDerivedCount() => 3; + + /// > + protected sealed override System.Collections.Generic.KeyValuePair GetDerivedProperty(int index) => throw null; + } + + /// + public sealed class SqlClientConnectionCloseError : SqlClientDiagnostic + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteConnectionCloseError"; + /// + public System.Guid? ConnectionId => throw null; + /// + public SqlConnection Connection => throw null; + /// + public System.Collections.IDictionary Statistics => throw null; + /// + public System.Exception Exception => throw null; + /// > + protected sealed override int GetDerivedCount() => 4; + /// > + protected sealed override System.Collections.Generic.KeyValuePair GetDerivedProperty(int index) => throw null; + } + + /// + public sealed class SqlClientTransactionCommitBefore : SqlClientDiagnostic + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteTransactionCommitBefore"; + /// + public System.Data.IsolationLevel IsolationLevel => throw null; + /// + public SqlConnection Connection => throw null; + /// + public long? TransactionId => throw null; + /// > + protected sealed override int GetDerivedCount() => 3; + /// > + protected sealed override System.Collections.Generic.KeyValuePair GetDerivedProperty(int index) => throw null; + } + + /// + public sealed class SqlClientTransactionCommitAfter : SqlClientDiagnostic + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteTransactionCommitAfter"; + /// + public System.Data.IsolationLevel IsolationLevel => throw null; + /// + public SqlConnection Connection => throw null; + /// + public long? TransactionId => throw null; + /// > + protected sealed override int GetDerivedCount() => 3; + /// > + protected sealed override System.Collections.Generic.KeyValuePair GetDerivedProperty(int index) => throw null; + } + + /// + public sealed class SqlClientTransactionCommitError : SqlClientDiagnostic + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteTransactionCommitError"; + /// + public System.Data.IsolationLevel IsolationLevel => throw null; + /// + public SqlConnection Connection => throw null; + /// + public long? TransactionId => throw null; + /// + public System.Exception Exception => throw null; + /// > + protected sealed override int GetDerivedCount() => 4; + /// > + protected sealed override System.Collections.Generic.KeyValuePair GetDerivedProperty(int index) => throw null; + } + + /// + public sealed class SqlClientTransactionRollbackBefore : SqlClientDiagnostic + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteTransactionRollbackBefore"; + /// + public System.Data.IsolationLevel IsolationLevel => throw null; + /// + public SqlConnection Connection => throw null; + /// + public long? TransactionId => throw null; + /// + public string TransactionName => throw null; + /// > + protected sealed override int GetDerivedCount() => 4; + /// > + protected sealed override System.Collections.Generic.KeyValuePair GetDerivedProperty(int index) => throw null; + } + + /// + public sealed class SqlClientTransactionRollbackAfter : SqlClientDiagnostic + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteTransactionRollbackAfter"; + /// + public System.Data.IsolationLevel IsolationLevel => throw null; + /// + public SqlConnection Connection => throw null; + /// + public long? TransactionId => throw null; + /// + public string TransactionName => throw null; + /// > + protected sealed override int GetDerivedCount() => 4; + /// > + protected sealed override System.Collections.Generic.KeyValuePair GetDerivedProperty(int index) => throw null; + } + + /// + public sealed class SqlClientTransactionRollbackError : SqlClientDiagnostic + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteTransactionRollbackError"; + /// + public System.Data.IsolationLevel IsolationLevel => throw null; + /// + public SqlConnection Connection => throw null; + /// + public long? TransactionId => throw null; + /// + public string TransactionName => throw null; + /// + public System.Exception Exception => throw null; + /// > + protected sealed override int GetDerivedCount() => 5; + /// > + protected sealed override System.Collections.Generic.KeyValuePair GetDerivedProperty(int index) => throw null; + } +} namespace Microsoft.Data.SqlClient.Server { /// diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj index 7cf0b1e619..46a77d5373 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -647,6 +647,7 @@ + diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientDiagnostic.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientDiagnostic.cs new file mode 100644 index 0000000000..51a2f8f0ba --- /dev/null +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientDiagnostic.cs @@ -0,0 +1,970 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; + +namespace Microsoft.Data.SqlClient.Diagnostics +{ + /// + public sealed class SqlClientCommandBefore : IReadOnlyList> + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteCommandBefore"; + + internal SqlClientCommandBefore(Guid operationId, string operation, long timestamp, Guid? connectionId, long? transactionId, SqlCommand command) + { + OperationId = operationId; + Operation = operation; + Timestamp = timestamp; + ConnectionId = connectionId; + TransactionId = transactionId; + Command = command; + } + + /// + public Guid OperationId { get; } + /// + public string Operation { get; } + /// + public long Timestamp { get; } + /// + public Guid? ConnectionId { get; } + /// + public long? TransactionId { get; } + /// + public SqlCommand Command { get; } + + /// + public int Count => 3 + 3; + + /// + public KeyValuePair this[int index] + { + get => index switch + { + 0 => new KeyValuePair(nameof(OperationId), OperationId), + 1 => new KeyValuePair(nameof(Operation), Operation), + 2 => new KeyValuePair(nameof(Timestamp), Timestamp), + 3 => new KeyValuePair(nameof(ConnectionId), ConnectionId), + 4 => new KeyValuePair(nameof(TransactionId), TransactionId), + 5 => new KeyValuePair(nameof(Command), Command), + _ => throw new IndexOutOfRangeException(nameof(index)), + }; + } + + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator> GetEnumerator() + { + int count = Count; + for (int index = 0; index < count; index++) + { + yield return this[index]; + } + } + } + + /// + public sealed class SqlClientCommandAfter : IReadOnlyList> + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteCommandAfter"; + + internal SqlClientCommandAfter(Guid operationId, string operation, long timestamp, Guid? connectionId, long? transactionId, SqlCommand command, IDictionary statistics) + { + OperationId = operationId; + Operation = operation; + Timestamp = timestamp; + ConnectionId = connectionId; + TransactionId = transactionId; + Command = command; + Statistics = statistics; + } + + /// + public Guid OperationId { get; } + /// + public string Operation { get; } + /// + public long Timestamp { get; } + /// + public Guid? ConnectionId { get; } + /// + public long? TransactionId { get; } + /// + public SqlCommand Command { get; } + /// + public IDictionary Statistics { get; } + + /// + public int Count => 3 + 4; + + /// + public KeyValuePair this[int index] + { + get => index switch + { + 0 => new KeyValuePair(nameof(OperationId), OperationId), + 1 => new KeyValuePair(nameof(Operation), Operation), + 2 => new KeyValuePair(nameof(Timestamp), Timestamp), + 3 => new KeyValuePair(nameof(ConnectionId), ConnectionId), + 4 => new KeyValuePair(nameof(TransactionId), TransactionId), + 5 => new KeyValuePair(nameof(Command), Command), + 6 => new KeyValuePair(nameof(Statistics), Statistics), + _ => throw new IndexOutOfRangeException(nameof(index)), + }; + } + + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator> GetEnumerator() + { + int count = Count; + for (int index = 0; index < count; index++) + { + yield return this[index]; + } + } + } + + /// + public sealed class SqlClientCommandError : IReadOnlyList> + { + /// + + public const string Name = "Microsoft.Data.SqlClient.WriteCommandError"; + + internal SqlClientCommandError(Guid operationId, string operation, long timestamp, Guid? connectionId, long? transactionId, SqlCommand command, Exception exception) + { + OperationId = operationId; + Operation = operation; + Timestamp = timestamp; + ConnectionId = connectionId; + TransactionId = transactionId; + Command = command; + Exception = exception; + } + /// + public Guid OperationId { get; } + /// + public string Operation { get; } + /// + public long Timestamp { get; } + /// + public Guid? ConnectionId { get; } + /// + public long? TransactionId { get; } + /// + public SqlCommand Command { get; } + /// + public Exception Exception { get; } + + /// + public int Count => 3 + 4; + + /// + public KeyValuePair this[int index] + { + get => index switch + { + 0 => new KeyValuePair(nameof(OperationId), OperationId), + 1 => new KeyValuePair(nameof(Operation), Operation), + 2 => new KeyValuePair(nameof(Timestamp), Timestamp), + 3 => new KeyValuePair(nameof(ConnectionId), ConnectionId), + 4 => new KeyValuePair(nameof(TransactionId), TransactionId), + 5 => new KeyValuePair(nameof(Command), Command), + 6 => new KeyValuePair(nameof(Exception), Exception), + _ => throw new IndexOutOfRangeException(nameof(index)), + }; + } + + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator> GetEnumerator() + { + int count = Count; + for (int index = 0; index < count; index++) + { + yield return this[index]; + } + } + } + + /// + public sealed class SqlClientConnectionOpenBefore : IReadOnlyList> + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteConnectionOpenBefore"; + + internal SqlClientConnectionOpenBefore(Guid operationId, string operation, long timestamp, SqlConnection connection, string clientVersion) + { + OperationId = operationId; + Operation = operation; + Timestamp = timestamp; + Connection = connection; + ClientVersion = clientVersion; + } + + /// + public Guid OperationId { get; } + /// + public string Operation { get; } + /// + public long Timestamp { get; } + /// + public SqlConnection Connection { get; } + /// + public string ClientVersion { get; } + + /// + public int Count => 3 + 2; + + /// + public KeyValuePair this[int index] + { + get => index switch + { + 0 => new KeyValuePair(nameof(OperationId), OperationId), + 1 => new KeyValuePair(nameof(Operation), Operation), + 2 => new KeyValuePair(nameof(Timestamp), Timestamp), + 3 => new KeyValuePair(nameof(Connection), Connection), + 4 => new KeyValuePair(nameof(ClientVersion), ClientVersion), + _ => throw new IndexOutOfRangeException(nameof(index)), + }; + } + + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator> GetEnumerator() + { + int count = Count; + for (int index = 0; index < count; index++) + { + yield return this[index]; + } + } + } + + /// + public sealed class SqlClientConnectionOpenAfter : IReadOnlyList> + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteConnectionOpenAfter"; + + internal SqlClientConnectionOpenAfter(Guid operationId, string operation, long timestamp, Guid connectionId, SqlConnection connection, string clientVersion, IDictionary statistics) + { + OperationId = operationId; + Operation = operation; + Timestamp = timestamp; + ConnectionId = connectionId; + Connection = connection; + ClientVersion = clientVersion; + Statistics = statistics; + } + + /// + public Guid OperationId { get; } + /// + public string Operation { get; } + /// + public long Timestamp { get; } + /// + public Guid ConnectionId { get; } + /// + public SqlConnection Connection { get; } + /// + public string ClientVersion { get; } + /// + public IDictionary Statistics { get; } + + /// + public int Count => 3 + 4; + + /// + public KeyValuePair this[int index] + { + get => index switch + { + 0 => new KeyValuePair(nameof(OperationId), OperationId), + 1 => new KeyValuePair(nameof(Operation), Operation), + 2 => new KeyValuePair(nameof(Timestamp), Timestamp), + 3 => new KeyValuePair(nameof(ConnectionId), ConnectionId), + 4 => new KeyValuePair(nameof(Connection), Connection), + 5 => new KeyValuePair(nameof(ClientVersion), ClientVersion), + 6 => new KeyValuePair(nameof(Statistics), Statistics), + _ => throw new IndexOutOfRangeException(nameof(index)), + }; + } + + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator> GetEnumerator() + { + int count = Count; + for (int index = 0; index < count; index++) + { + yield return this[index]; + } + } + } + + /// + public sealed class SqlClientConnectionOpenError : IReadOnlyList> + { + /// + + public const string Name = "Microsoft.Data.SqlClient.WriteConnectionOpenError"; + + internal SqlClientConnectionOpenError(Guid operationId, string operation, long timestamp, Guid connectionId, SqlConnection connection, string clientVersion, Exception exception) + { + OperationId = operationId; + Operation = operation; + Timestamp = timestamp; + ConnectionId = connectionId; + Connection = connection; + ClientVersion = clientVersion; + Exception = exception; + } + + /// + public Guid OperationId { get; } + /// + public string Operation { get; } + /// + public long Timestamp { get; } + + /// + public Guid ConnectionId { get; } + /// + public SqlConnection Connection { get; } + /// + public string ClientVersion { get; } + /// + public Exception Exception { get; } + + /// + public int Count => 3 + 4; + + /// + public KeyValuePair this[int index] + { + get => index switch + { + 0 => new KeyValuePair(nameof(OperationId), OperationId), + 1 => new KeyValuePair(nameof(Operation), Operation), + 2 => new KeyValuePair(nameof(Timestamp), Timestamp), + 3 => new KeyValuePair(nameof(ConnectionId), ConnectionId), + 4 => new KeyValuePair(nameof(Connection), Connection), + 5 => new KeyValuePair(nameof(ClientVersion), ClientVersion), + 6 => new KeyValuePair(nameof(Exception), Exception), + _ => throw new IndexOutOfRangeException(nameof(index)), + }; + } + + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator> GetEnumerator() + { + int count = Count; + for (int index = 0; index < count; index++) + { + yield return this[index]; + } + } + } + + /// + public sealed class SqlClientConnectionCloseBefore : IReadOnlyList> + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteConnectionCloseBefore"; + + internal SqlClientConnectionCloseBefore(Guid operationId, string operation, long timestamp, Guid? connectionId, SqlConnection connection, IDictionary statistics) + { + OperationId = operationId; + Operation = operation; + Timestamp = timestamp; + ConnectionId = connectionId; + Connection = connection; + Statistics = statistics; + } + + /// + public Guid OperationId { get; } + /// + public string Operation { get; } + /// + public long Timestamp { get; } + /// + public Guid? ConnectionId { get; } + /// + public SqlConnection Connection { get; } + /// + public IDictionary Statistics { get; } + + /// + public int Count => 3 + 3; + + /// + public KeyValuePair this[int index] + { + get => index switch + { + 0 => new KeyValuePair(nameof(OperationId), OperationId), + 1 => new KeyValuePair(nameof(Operation), Operation), + 2 => new KeyValuePair(nameof(Timestamp), Timestamp), + 3 => new KeyValuePair(nameof(ConnectionId), ConnectionId), + 4 => new KeyValuePair(nameof(Connection), Connection), + 5 => new KeyValuePair(nameof(Statistics), Statistics), + _ => throw new IndexOutOfRangeException(nameof(index)), + }; + } + + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator> GetEnumerator() + { + int count = Count; + for (int index = 0; index < count; index++) + { + yield return this[index]; + } + } + } + + /// + public sealed class SqlClientConnectionCloseAfter : IReadOnlyList> + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteConnectionCloseAfter"; + + internal SqlClientConnectionCloseAfter(Guid operationId, string operation, long timestamp, Guid? connectionId, SqlConnection connection, IDictionary statistics) + { + OperationId = operationId; + Operation = operation; + Timestamp = timestamp; + ConnectionId = connectionId; + Connection = connection; + Statistics = statistics; + } + + /// + public Guid OperationId { get; } + /// + public string Operation { get; } + /// + public long Timestamp { get; } + /// + public Guid? ConnectionId { get; } + /// + public SqlConnection Connection { get; } + /// + public IDictionary Statistics { get; } + + /// + public int Count => 3 + 3; + + /// + public KeyValuePair this[int index] + { + get => index switch + { + 0 => new KeyValuePair(nameof(OperationId), OperationId), + 1 => new KeyValuePair(nameof(Operation), Operation), + 2 => new KeyValuePair(nameof(Timestamp), Timestamp), + 3 => new KeyValuePair(nameof(ConnectionId), ConnectionId), + 4 => new KeyValuePair(nameof(Connection), Connection), + 5 => new KeyValuePair(nameof(Statistics), Statistics), + _ => throw new IndexOutOfRangeException(nameof(index)), + }; + } + + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator> GetEnumerator() + { + int count = Count; + for (int index = 0; index < count; index++) + { + yield return this[index]; + } + } + } + + /// + public sealed class SqlClientConnectionCloseError : IReadOnlyList> + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteConnectionCloseError"; + + internal SqlClientConnectionCloseError(Guid operationId, string operation, long timestamp, Guid? connectionId, SqlConnection connection, IDictionary statistics, Exception ex) + { + OperationId = operationId; + Operation = operation; + Timestamp = timestamp; + ConnectionId = connectionId; + Connection = connection; + Statistics = statistics; + Exception = ex; + } + + /// + public Guid OperationId { get; } + /// + public string Operation { get; } + /// + public long Timestamp { get; } + + /// + public Guid? ConnectionId { get; } + /// + public SqlConnection Connection { get; } + /// + public IDictionary Statistics { get; } + + /// + public Exception Exception { get; } + + /// + public int Count => 3 + 4; + + /// + public KeyValuePair this[int index] + { + get => index switch + { + 0 => new KeyValuePair(nameof(OperationId), OperationId), + 1 => new KeyValuePair(nameof(Operation), Operation), + 2 => new KeyValuePair(nameof(Timestamp), Timestamp), + 3 => new KeyValuePair(nameof(ConnectionId), ConnectionId), + 4 => new KeyValuePair(nameof(Connection), Connection), + 5 => new KeyValuePair(nameof(Statistics), Statistics), + 6 => new KeyValuePair(nameof(Exception), Exception), + _ => throw new IndexOutOfRangeException(nameof(index)), + }; + } + + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator> GetEnumerator() + { + int count = Count; + for (int index = 0; index < count; index++) + { + yield return this[index]; + } + } + } + + /// + public sealed class SqlClientTransactionCommitBefore : IReadOnlyList> + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteTransactionCommitBefore"; + + internal SqlClientTransactionCommitBefore(Guid operationId, string operation, long timestamp, IsolationLevel isolationLevel, SqlConnection connection, long? transactionId) + { + OperationId = operationId; + Operation = operation; + Timestamp = timestamp; + IsolationLevel = isolationLevel; + Connection = connection; + TransactionId = transactionId; + } + + /// + public Guid OperationId { get; } + /// + public string Operation { get; } + /// + public long Timestamp { get; } + /// + public IsolationLevel IsolationLevel { get; } + /// + public SqlConnection Connection { get; } + /// + public long? TransactionId { get; } + + /// + public int Count => 3 + 3; + + /// + public KeyValuePair this[int index] + { + get => index switch + { + 0 => new KeyValuePair(nameof(OperationId), OperationId), + 1 => new KeyValuePair(nameof(Operation), Operation), + 2 => new KeyValuePair(nameof(Timestamp), Timestamp), + 3 => new KeyValuePair(nameof(IsolationLevel), IsolationLevel), + 4 => new KeyValuePair(nameof(Connection), Connection), + 5 => new KeyValuePair(nameof(TransactionId), TransactionId), + _ => throw new IndexOutOfRangeException(nameof(index)), + }; + } + + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator> GetEnumerator() + { + int count = Count; + for (int index = 0; index < count; index++) + { + yield return this[index]; + } + } + } + + /// + public sealed class SqlClientTransactionCommitAfter : IReadOnlyList> + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteTransactionCommitAfter"; + + internal SqlClientTransactionCommitAfter(Guid operationId, string operation, long timestamp, IsolationLevel isolationLevel, SqlConnection connection, long? transactionId) + { + OperationId = operationId; + Operation = operation; + Timestamp = timestamp; + IsolationLevel = isolationLevel; + Connection = connection; + TransactionId = transactionId; + } + + /// + public Guid OperationId { get; } + /// + public string Operation { get; } + /// + public long Timestamp { get; } + + /// + public IsolationLevel IsolationLevel { get; } + /// + public SqlConnection Connection { get; } + /// + public long? TransactionId { get; } + + /// + public int Count => 3 + 3; + + /// + public KeyValuePair this[int index] + { + get => index switch + { + 0 => new KeyValuePair(nameof(OperationId), OperationId), + 1 => new KeyValuePair(nameof(Operation), Operation), + 2 => new KeyValuePair(nameof(Timestamp), Timestamp), + 3 => new KeyValuePair(nameof(IsolationLevel), IsolationLevel), + 4 => new KeyValuePair(nameof(Connection), Connection), + 5 => new KeyValuePair(nameof(TransactionId), TransactionId), + _ => throw new IndexOutOfRangeException(nameof(index)), + }; + } + + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator> GetEnumerator() + { + int count = Count; + for (int index = 0; index < count; index++) + { + yield return this[index]; + } + } + } + + /// + public sealed class SqlClientTransactionCommitError : IReadOnlyList> + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteTransactionCommitError"; + + internal SqlClientTransactionCommitError(Guid operationId, string operation, long timestamp, IsolationLevel isolationLevel, SqlConnection connection, long? transactionId, Exception ex) + { + OperationId = operationId; + Operation = operation; + Timestamp = timestamp; + IsolationLevel = isolationLevel; + Connection = connection; + TransactionId = transactionId; + Exception = ex; + } + + /// + public Guid OperationId { get; } + /// + public string Operation { get; } + /// + public long Timestamp { get; } + + /// + public IsolationLevel IsolationLevel { get; } + /// + public SqlConnection Connection { get; } + /// + public long? TransactionId { get; } + /// + public Exception Exception { get; } + + /// + public int Count => 3 + 4; + + /// + public KeyValuePair this[int index] + { + get => index switch + { + 0 => new KeyValuePair(nameof(OperationId), OperationId), + 1 => new KeyValuePair(nameof(Operation), Operation), + 2 => new KeyValuePair(nameof(Timestamp), Timestamp), + 3 => new KeyValuePair(nameof(IsolationLevel), IsolationLevel), + 4 => new KeyValuePair(nameof(Connection), Connection), + 5 => new KeyValuePair(nameof(TransactionId), TransactionId), + 6 => new KeyValuePair(nameof(Exception), Exception), + _ => throw new IndexOutOfRangeException(nameof(index)), + }; + } + + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator> GetEnumerator() + { + int count = Count; + for (int index = 0; index < count; index++) + { + yield return this[index]; + } + } + } + + /// + public sealed class SqlClientTransactionRollbackBefore : IReadOnlyList> + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteTransactionRollbackBefore"; + + internal SqlClientTransactionRollbackBefore(Guid operationId, string operation, long timestamp, IsolationLevel isolationLevel, SqlConnection connection, long? transactionId, string transactionName) + { + OperationId = operationId; + Operation = operation; + Timestamp = timestamp; + IsolationLevel = isolationLevel; + Connection = connection; + TransactionId = transactionId; + TransactionName = transactionName; + } + + /// + public Guid OperationId { get; } + /// + public string Operation { get; } + /// + public long Timestamp { get; } + + /// + public IsolationLevel IsolationLevel { get; } + /// + public SqlConnection Connection { get; } + /// + public long? TransactionId { get; } + /// + public string TransactionName { get; } + + /// + public int Count => 3 + 4; + + /// + public KeyValuePair this[int index] + { + get => index switch + { + 0 => new KeyValuePair(nameof(OperationId), OperationId), + 1 => new KeyValuePair(nameof(Operation), Operation), + 2 => new KeyValuePair(nameof(Timestamp), Timestamp), + 3 => new KeyValuePair(nameof(IsolationLevel), IsolationLevel), + 4 => new KeyValuePair(nameof(Connection), Connection), + 5 => new KeyValuePair(nameof(TransactionId), TransactionId), + 6 => new KeyValuePair(nameof(TransactionName), TransactionName), + _ => throw new IndexOutOfRangeException(nameof(index)), + }; + } + + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator> GetEnumerator() + { + int count = Count; + for (int index = 0; index < count; index++) + { + yield return this[index]; + } + } + } + + /// + public sealed class SqlClientTransactionRollbackAfter : IReadOnlyList> + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteTransactionRollbackAfter"; + + internal SqlClientTransactionRollbackAfter(Guid operationId, string operation, long timestamp, IsolationLevel isolationLevel, SqlConnection connection, long? transactionId, string transactionName) + { + OperationId = operationId; + Operation = operation; + Timestamp = timestamp; + IsolationLevel = isolationLevel; + Connection = connection; + TransactionId = transactionId; + TransactionName = transactionName; + } + + /// + public Guid OperationId { get; } + /// + public string Operation { get; } + /// + public long Timestamp { get; } + /// + public IsolationLevel IsolationLevel { get; } + /// + public SqlConnection Connection { get; } + /// + public long? TransactionId { get; } + /// + public string TransactionName { get; } + + /// + public int Count => 3 + 4; + + /// + public KeyValuePair this[int index] + { + get => index switch + { + 0 => new KeyValuePair(nameof(OperationId), OperationId), + 1 => new KeyValuePair(nameof(Operation), Operation), + 2 => new KeyValuePair(nameof(Timestamp), Timestamp), + 3 => new KeyValuePair(nameof(IsolationLevel), IsolationLevel), + 4 => new KeyValuePair(nameof(Connection), Connection), + 5 => new KeyValuePair(nameof(TransactionId), TransactionId), + 6 => new KeyValuePair(nameof(TransactionName), TransactionName), + _ => throw new IndexOutOfRangeException(nameof(index)), + }; + } + + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator> GetEnumerator() + { + int count = Count; + for (int index = 0; index < count; index++) + { + yield return this[index]; + } + } + } + + /// + public sealed class SqlClientTransactionRollbackError : IReadOnlyList> + { + /// + public const string Name = "Microsoft.Data.SqlClient.WriteTransactionRollbackError"; + + internal SqlClientTransactionRollbackError(Guid operationId, string operation, long timestamp, IsolationLevel isolationLevel, SqlConnection connection, long? transactionId, string transactionName, Exception ex) + { + OperationId = operationId; + Operation = operation; + Timestamp = timestamp; + IsolationLevel = isolationLevel; + Connection = connection; + TransactionId = transactionId; + TransactionName = transactionName; + Exception = ex; + } + + + /// + public Guid OperationId { get; } + /// + public string Operation { get; } + /// + public long Timestamp { get; } + /// + public IsolationLevel IsolationLevel { get; } + /// + public SqlConnection Connection { get; } + /// + public long? TransactionId { get; } + /// + public string TransactionName { get; } + /// + public Exception Exception { get; } + + /// + public int Count => 3 + 5; + + /// + public KeyValuePair this[int index] + { + get => index switch + { + 0 => new KeyValuePair(nameof(OperationId), OperationId), + 1 => new KeyValuePair(nameof(Operation), Operation), + 2 => new KeyValuePair(nameof(Timestamp), Timestamp), + 3 => new KeyValuePair(nameof(IsolationLevel), IsolationLevel), + 4 => new KeyValuePair(nameof(Connection), Connection), + 5 => new KeyValuePair(nameof(TransactionId), TransactionId), + 6 => new KeyValuePair(nameof(TransactionName), TransactionName), + 7 => new KeyValuePair(nameof(Exception), Exception), + _ => throw new IndexOutOfRangeException(nameof(index)), + }; + } + + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator> GetEnumerator() + { + int count = Count; + for (int index = 0; index < count; index++) + { + yield return this[index]; + } + } + } +} diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientDiagnosticListenerExtensions.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientDiagnosticListenerExtensions.cs index 1d955b8c47..9f63cbaba8 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientDiagnosticListenerExtensions.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlClientDiagnosticListenerExtensions.cs @@ -3,9 +3,12 @@ // See the LICENSE file in the project root for more information. using System; +using System.Collections; +using System.Collections.Generic; using System.Data; using System.Diagnostics; using System.Runtime.CompilerServices; +using Microsoft.Data.SqlClient.Diagnostics; namespace Microsoft.Data.SqlClient { @@ -16,168 +19,155 @@ internal static class SqlClientDiagnosticListenerExtensions { public const string DiagnosticListenerName = "SqlClientDiagnosticListener"; - private const string SqlClientPrefix = "Microsoft.Data.SqlClient."; - - public const string SqlBeforeExecuteCommand = SqlClientPrefix + nameof(WriteCommandBefore); - public const string SqlAfterExecuteCommand = SqlClientPrefix + nameof(WriteCommandAfter); - public const string SqlErrorExecuteCommand = SqlClientPrefix + nameof(WriteCommandError); - - public const string SqlBeforeOpenConnection = SqlClientPrefix + nameof(WriteConnectionOpenBefore); - public const string SqlAfterOpenConnection = SqlClientPrefix + nameof(WriteConnectionOpenAfter); - public const string SqlErrorOpenConnection = SqlClientPrefix + nameof(WriteConnectionOpenError); - - public const string SqlBeforeCloseConnection = SqlClientPrefix + nameof(WriteConnectionCloseBefore); - public const string SqlAfterCloseConnection = SqlClientPrefix + nameof(WriteConnectionCloseAfter); - public const string SqlErrorCloseConnection = SqlClientPrefix + nameof(WriteConnectionCloseError); - - public const string SqlBeforeCommitTransaction = SqlClientPrefix + nameof(WriteTransactionCommitBefore); - public const string SqlAfterCommitTransaction = SqlClientPrefix + nameof(WriteTransactionCommitAfter); - public const string SqlErrorCommitTransaction = SqlClientPrefix + nameof(WriteTransactionCommitError); - - public const string SqlBeforeRollbackTransaction = SqlClientPrefix + nameof(WriteTransactionRollbackBefore); - public const string SqlAfterRollbackTransaction = SqlClientPrefix + nameof(WriteTransactionRollbackAfter); - public const string SqlErrorRollbackTransaction = SqlClientPrefix + nameof(WriteTransactionRollbackError); - public static Guid WriteCommandBefore(this SqlDiagnosticListener @this, SqlCommand sqlCommand, SqlTransaction transaction, [CallerMemberName] string operation = "") { - if (@this.IsEnabled(SqlBeforeExecuteCommand)) + if (@this.IsEnabled(SqlClientCommandBefore.Name)) { Guid operationId = Guid.NewGuid(); @this.Write( - SqlBeforeExecuteCommand, - new - { - OperationId = operationId, - Operation = operation, - ConnectionId = sqlCommand.Connection?.ClientConnectionId, - Command = sqlCommand, + SqlClientCommandBefore.Name, + new SqlClientCommandBefore( + operationId, + operation, + Stopwatch.GetTimestamp(), + sqlCommand.Connection?.ClientConnectionId, transaction?.InternalTransaction?.TransactionId, - Timestamp = Stopwatch.GetTimestamp() - }); + sqlCommand + ) + ); return operationId; } else + { return Guid.Empty; + } } public static void WriteCommandAfter(this SqlDiagnosticListener @this, Guid operationId, SqlCommand sqlCommand, SqlTransaction transaction, [CallerMemberName] string operation = "") { - if (@this.IsEnabled(SqlAfterExecuteCommand)) + if (@this.IsEnabled(SqlClientCommandAfter.Name)) { @this.Write( - SqlAfterExecuteCommand, - new - { - OperationId = operationId, - Operation = operation, - ConnectionId = sqlCommand.Connection?.ClientConnectionId, - Command = sqlCommand, + SqlClientCommandAfter.Name, + new SqlClientCommandAfter( + operationId, + operation, + Stopwatch.GetTimestamp(), + sqlCommand.Connection?.ClientConnectionId, transaction?.InternalTransaction?.TransactionId, - Statistics = sqlCommand.Statistics?.GetDictionary(), - Timestamp = Stopwatch.GetTimestamp() - }); + sqlCommand, + sqlCommand.Statistics?.GetDictionary() + ) + ); } } public static void WriteCommandError(this SqlDiagnosticListener @this, Guid operationId, SqlCommand sqlCommand, SqlTransaction transaction, Exception ex, [CallerMemberName] string operation = "") { - if (@this.IsEnabled(SqlErrorExecuteCommand)) + if (@this.IsEnabled(SqlClientCommandError.Name)) { @this.Write( - SqlErrorExecuteCommand, - new - { - OperationId = operationId, - Operation = operation, - ConnectionId = sqlCommand.Connection?.ClientConnectionId, - Command = sqlCommand, + SqlClientCommandError.Name, + new SqlClientCommandError + ( + operationId, + operation, + Stopwatch.GetTimestamp(), + sqlCommand.Connection?.ClientConnectionId, transaction?.InternalTransaction?.TransactionId, - Exception = ex, - Timestamp = Stopwatch.GetTimestamp() - }); + sqlCommand, + ex + ) + ); } } public static Guid WriteConnectionOpenBefore(this SqlDiagnosticListener @this, SqlConnection sqlConnection, [CallerMemberName] string operation = "") { - if (@this.IsEnabled(SqlBeforeOpenConnection)) + if (@this.IsEnabled(SqlClientConnectionOpenBefore.Name)) { Guid operationId = Guid.NewGuid(); @this.Write( - SqlBeforeOpenConnection, - new - { - OperationId = operationId, - Operation = operation, - Connection = sqlConnection, - ClientVersion = ThisAssembly.InformationalVersion, - Timestamp = Stopwatch.GetTimestamp() - }); + SqlClientConnectionOpenBefore.Name, + new SqlClientConnectionOpenBefore + ( + operationId, + operation, + Stopwatch.GetTimestamp(), + sqlConnection, + ThisAssembly.InformationalVersion + ) + ); return operationId; } else + { return Guid.Empty; + } } public static void WriteConnectionOpenAfter(this SqlDiagnosticListener @this, Guid operationId, SqlConnection sqlConnection, [CallerMemberName] string operation = "") { - if (@this.IsEnabled(SqlAfterOpenConnection)) + if (@this.IsEnabled(SqlClientConnectionOpenAfter.Name)) { @this.Write( - SqlAfterOpenConnection, - new - { - OperationId = operationId, - Operation = operation, - ConnectionId = sqlConnection.ClientConnectionId, - Connection = sqlConnection, - ClientVersion = ThisAssembly.InformationalVersion, - Statistics = sqlConnection.Statistics?.GetDictionary(), - Timestamp = Stopwatch.GetTimestamp() - }); + SqlClientConnectionOpenAfter.Name, + new SqlClientConnectionOpenAfter + ( + operationId, + operation, + Stopwatch.GetTimestamp(), + sqlConnection.ClientConnectionId, + sqlConnection, + ThisAssembly.InformationalVersion, + sqlConnection.Statistics?.GetDictionary() + ) + ); } } public static void WriteConnectionOpenError(this SqlDiagnosticListener @this, Guid operationId, SqlConnection sqlConnection, Exception ex, [CallerMemberName] string operation = "") { - if (@this.IsEnabled(SqlErrorOpenConnection)) + if (@this.IsEnabled(SqlClientConnectionOpenError.Name)) { @this.Write( - SqlErrorOpenConnection, - new - { - OperationId = operationId, - Operation = operation, - ConnectionId = sqlConnection.ClientConnectionId, - Connection = sqlConnection, - ClientVersion = ThisAssembly.InformationalVersion, - Exception = ex, - Timestamp = Stopwatch.GetTimestamp() - }); + SqlClientConnectionOpenError.Name, + new SqlClientConnectionOpenError + ( + operationId, + operation, + Stopwatch.GetTimestamp(), + sqlConnection.ClientConnectionId, + sqlConnection, + ThisAssembly.InformationalVersion, + ex + ) + ); } } public static Guid WriteConnectionCloseBefore(this SqlDiagnosticListener @this, SqlConnection sqlConnection, [CallerMemberName] string operation = "") { - if (@this.IsEnabled(SqlBeforeCloseConnection)) + if (@this.IsEnabled(SqlClientConnectionCloseBefore.Name)) { Guid operationId = Guid.NewGuid(); @this.Write( - SqlBeforeCloseConnection, - new - { - OperationId = operationId, - Operation = operation, - ConnectionId = sqlConnection.ClientConnectionId, - Connection = sqlConnection, - Statistics = sqlConnection.Statistics?.GetDictionary(), - Timestamp = Stopwatch.GetTimestamp() - }); + SqlClientConnectionCloseBefore.Name, + new SqlClientConnectionCloseBefore + ( + operationId, + operation, + Stopwatch.GetTimestamp(), + sqlConnection.ClientConnectionId, + sqlConnection, + sqlConnection.Statistics?.GetDictionary() + ) + ); return operationId; } @@ -187,163 +177,175 @@ public static Guid WriteConnectionCloseBefore(this SqlDiagnosticListener @this, public static void WriteConnectionCloseAfter(this SqlDiagnosticListener @this, Guid operationId, Guid clientConnectionId, SqlConnection sqlConnection, [CallerMemberName] string operation = "") { - if (@this.IsEnabled(SqlAfterCloseConnection)) + if (@this.IsEnabled(SqlClientConnectionCloseAfter.Name)) { @this.Write( - SqlAfterCloseConnection, - new - { - OperationId = operationId, - Operation = operation, - ConnectionId = clientConnectionId, - Connection = sqlConnection, - Statistics = sqlConnection.Statistics?.GetDictionary(), - Timestamp = Stopwatch.GetTimestamp() - }); + SqlClientConnectionCloseAfter.Name, + new SqlClientConnectionCloseAfter + ( + operationId, + operation, + Stopwatch.GetTimestamp(), + clientConnectionId, + sqlConnection, + sqlConnection.Statistics?.GetDictionary() + ) + ); } } public static void WriteConnectionCloseError(this SqlDiagnosticListener @this, Guid operationId, Guid clientConnectionId, SqlConnection sqlConnection, Exception ex, [CallerMemberName] string operation = "") { - if (@this.IsEnabled(SqlErrorCloseConnection)) + if (@this.IsEnabled(SqlClientConnectionCloseError.Name)) { @this.Write( - SqlErrorCloseConnection, - new - { - OperationId = operationId, - Operation = operation, - ConnectionId = clientConnectionId, - Connection = sqlConnection, - Statistics = sqlConnection.Statistics?.GetDictionary(), - Exception = ex, - Timestamp = Stopwatch.GetTimestamp() - }); + SqlClientConnectionCloseError.Name, + new SqlClientConnectionCloseError + ( + operationId, + operation, + Stopwatch.GetTimestamp(), + clientConnectionId, + sqlConnection, + sqlConnection.Statistics?.GetDictionary(), + ex + ) + ); } } public static Guid WriteTransactionCommitBefore(this SqlDiagnosticListener @this, IsolationLevel isolationLevel, SqlConnection connection, SqlInternalTransaction transaction, [CallerMemberName] string operation = "") { - if (@this.IsEnabled(SqlBeforeCommitTransaction)) + if (@this.IsEnabled(SqlClientTransactionCommitBefore.Name)) { Guid operationId = Guid.NewGuid(); @this.Write( - SqlBeforeCommitTransaction, - new - { - OperationId = operationId, - Operation = operation, - IsolationLevel = isolationLevel, - Connection = connection, - transaction?.TransactionId, - Timestamp = Stopwatch.GetTimestamp() - }); + SqlClientTransactionCommitBefore.Name, + new SqlClientTransactionCommitBefore + ( + operationId, + operation, + Stopwatch.GetTimestamp(), + isolationLevel, + connection, + transaction?.TransactionId + ) + ); return operationId; } else + { return Guid.Empty; + } } public static void WriteTransactionCommitAfter(this SqlDiagnosticListener @this, Guid operationId, IsolationLevel isolationLevel, SqlConnection connection, SqlInternalTransaction transaction, [CallerMemberName] string operation = "") { - if (@this.IsEnabled(SqlAfterCommitTransaction)) + if (@this.IsEnabled(SqlClientTransactionCommitAfter.Name)) { @this.Write( - SqlAfterCommitTransaction, - new - { - OperationId = operationId, - Operation = operation, - IsolationLevel = isolationLevel, - Connection = connection, - transaction?.TransactionId, - Timestamp = Stopwatch.GetTimestamp() - }); + SqlClientTransactionCommitAfter.Name, + new SqlClientTransactionCommitAfter + ( + operationId, + operation, + Stopwatch.GetTimestamp(), + isolationLevel, + connection, + transaction?.TransactionId + ) + ); } } public static void WriteTransactionCommitError(this SqlDiagnosticListener @this, Guid operationId, IsolationLevel isolationLevel, SqlConnection connection, SqlInternalTransaction transaction, Exception ex, [CallerMemberName] string operation = "") { - if (@this.IsEnabled(SqlErrorCommitTransaction)) + if (@this.IsEnabled(SqlClientTransactionCommitError.Name)) { @this.Write( - SqlErrorCommitTransaction, - new - { - OperationId = operationId, - Operation = operation, - IsolationLevel = isolationLevel, - Connection = connection, + SqlClientTransactionCommitError.Name, + new SqlClientTransactionCommitError + ( + operationId, + operation, + Stopwatch.GetTimestamp(), + isolationLevel, + connection, transaction?.TransactionId, - Exception = ex, - Timestamp = Stopwatch.GetTimestamp() - }); + ex + ) + ); } } public static Guid WriteTransactionRollbackBefore(this SqlDiagnosticListener @this, IsolationLevel isolationLevel, SqlConnection connection, SqlInternalTransaction transaction, string transactionName = null, [CallerMemberName] string operation = "") { - if (@this.IsEnabled(SqlBeforeRollbackTransaction)) + if (@this.IsEnabled(SqlClientTransactionRollbackBefore.Name)) { Guid operationId = Guid.NewGuid(); @this.Write( - SqlBeforeRollbackTransaction, - new - { - OperationId = operationId, - Operation = operation, - IsolationLevel = isolationLevel, - Connection = connection, + SqlClientTransactionRollbackBefore.Name, + new SqlClientTransactionRollbackBefore + ( + operationId, + operation, + Stopwatch.GetTimestamp(), + isolationLevel, + connection, transaction?.TransactionId, - TransactionName = transactionName, - Timestamp = Stopwatch.GetTimestamp() - }); + transactionName + ) + ); return operationId; } else + { return Guid.Empty; + } } public static void WriteTransactionRollbackAfter(this SqlDiagnosticListener @this, Guid operationId, IsolationLevel isolationLevel, SqlConnection connection, SqlInternalTransaction transaction, string transactionName = null, [CallerMemberName] string operation = "") { - if (@this.IsEnabled(SqlAfterRollbackTransaction)) + if (@this.IsEnabled(SqlClientTransactionRollbackAfter.Name)) { @this.Write( - SqlAfterRollbackTransaction, - new - { - OperationId = operationId, - Operation = operation, - IsolationLevel = isolationLevel, - Connection = connection, + SqlClientTransactionRollbackAfter.Name, + new SqlClientTransactionRollbackAfter + ( + operationId, + operation, + Stopwatch.GetTimestamp(), + isolationLevel, + connection, transaction?.TransactionId, - TransactionName = transactionName, - Timestamp = Stopwatch.GetTimestamp() - }); + transactionName + ) + ); } } public static void WriteTransactionRollbackError(this SqlDiagnosticListener @this, Guid operationId, IsolationLevel isolationLevel, SqlConnection connection, SqlInternalTransaction transaction, Exception ex, string transactionName = null, [CallerMemberName] string operation = "") { - if (@this.IsEnabled(SqlErrorRollbackTransaction)) + if (@this.IsEnabled(SqlClientTransactionRollbackError.Name)) { @this.Write( - SqlErrorRollbackTransaction, - new - { - OperationId = operationId, - Operation = operation, - IsolationLevel = isolationLevel, - Connection = connection, + SqlClientTransactionRollbackError.Name, + new SqlClientTransactionRollbackError + ( + operationId, + operation, + Stopwatch.GetTimestamp(), + isolationLevel, + connection, transaction?.TransactionId, - TransactionName = transactionName, - Exception = ex, - Timestamp = Stopwatch.GetTimestamp() - }); + transactionName, + ex + ) + ); } } diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs index 94325d3c88..9b484fc96f 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs @@ -19,6 +19,7 @@ using System.Xml; using Microsoft.Data.Common; using Microsoft.Data.Sql; +using Microsoft.Data.SqlClient.Diagnostics; using Microsoft.Data.SqlClient.Server; // NOTE: The current Microsoft.VSDesigner editor attributes are implemented for System.Data.SqlClient, and are not publicly available. @@ -596,7 +597,7 @@ internal SqlStatistics Statistics if (null != _activeConnection) { if (_activeConnection.StatisticsEnabled || - s_diagnosticListener.IsEnabled(SqlClientDiagnosticListenerExtensions.SqlAfterExecuteCommand)) + s_diagnosticListener.IsEnabled(SqlClientCommandAfter.Name)) { return _activeConnection.Statistics; } diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs index 1d044633ec..697315abc9 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs @@ -19,6 +19,7 @@ using System.Threading.Tasks; using Microsoft.Data.Common; using Microsoft.Data.ProviderBase; +using Microsoft.Data.SqlClient.Diagnostics; using Microsoft.SqlServer.Server; namespace Microsoft.Data.SqlClient @@ -1689,8 +1690,8 @@ private Task InternalOpenAsync(CancellationToken cancellationToken) TaskCompletionSource completion = new TaskCompletionSource(transaction); TaskCompletionSource result = new TaskCompletionSource(state: this); - if (s_diagnosticListener.IsEnabled(SqlClientDiagnosticListenerExtensions.SqlAfterOpenConnection) || - s_diagnosticListener.IsEnabled(SqlClientDiagnosticListenerExtensions.SqlErrorOpenConnection)) + if (s_diagnosticListener.IsEnabled(SqlClientConnectionOpenAfter.Name) || + s_diagnosticListener.IsEnabled(SqlClientConnectionOpenError.Name)) { result.Task.ContinueWith( continuationAction: s_openAsyncComplete, @@ -1879,8 +1880,8 @@ internal void Retry(Task retryTask) private void PrepareStatisticsForNewConnection() { if (StatisticsEnabled || - s_diagnosticListener.IsEnabled(SqlClientDiagnosticListenerExtensions.SqlAfterExecuteCommand) || - s_diagnosticListener.IsEnabled(SqlClientDiagnosticListenerExtensions.SqlAfterOpenConnection)) + s_diagnosticListener.IsEnabled(SqlClientCommandAfter.Name) || + s_diagnosticListener.IsEnabled(SqlClientConnectionOpenAfter.Name)) { if (null == _statistics) { @@ -1985,7 +1986,7 @@ private bool TryOpen(TaskCompletionSource retry, SqlConnec // The _statistics can change with StatisticsEnabled. Copying to a local variable before checking for a null value. SqlStatistics statistics = _statistics; if (StatisticsEnabled || - (s_diagnosticListener.IsEnabled(SqlClientDiagnosticListenerExtensions.SqlAfterExecuteCommand) && statistics != null)) + (s_diagnosticListener.IsEnabled(SqlClientCommandAfter.Name) && statistics != null)) { _statistics._openTimestamp = ADP.TimerCurrent(); tdsInnerConnection.Parser.Statistics = _statistics; From 689cc257fa250d42728c5d240b888b1f151cfd7c Mon Sep 17 00:00:00 2001 From: Aris Rellegue <134557572+arellegue@users.noreply.github.com> Date: Tue, 11 Jun 2024 21:05:07 +0000 Subject: [PATCH 19/25] Fix | Replaced System.Runtime.Caching with Microsoft.Extensions.Caching.Memory (#2493) --- .../ref/Microsoft.Data.SqlClient.csproj | 1 + .../src/Microsoft.Data.SqlClient.csproj | 2 +- .../netfx/ref/Microsoft.Data.SqlClient.csproj | 1 + .../netfx/src/Microsoft.Data.SqlClient.csproj | 1 + .../ActiveDirectoryAuthenticationProvider.cs | 12 +++---- .../AzureAttestationBasedEnclaveProvider.cs | 12 ++++--- .../Data/SqlClient/EnclaveProviderBase.cs | 12 ++++--- .../Data/SqlClient/EnclaveSessionCache.cs | 20 +++++++---- .../SqlClient/SignatureVerificationCache.cs | 23 ++++++------ .../Data/SqlClient/SqlQueryMetadataCache.cs | 20 ++++++----- .../Data/SqlClient/SqlSecurityUtility.cs | 6 ++-- .../Data/SqlClient/SqlSymmetricKeyCache.cs | 14 +++++--- .../VirtualSecureModeEnclaveProviderBase.cs | 14 +++++--- .../Microsoft.Data.SqlClient.Tests.csproj | 8 ++--- .../AlwaysEncrypted/ConversionTests.cs | 1 - .../TestFixtures/Setup/CertificateUtility.cs | 36 ++++++++++++++----- ....Data.SqlClient.ManualTesting.Tests.csproj | 10 +++--- tools/specs/Microsoft.Data.SqlClient.nuspec | 4 +-- 18 files changed, 125 insertions(+), 72 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.csproj index 498849102a..7190117fa2 100644 --- a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.csproj @@ -17,6 +17,7 @@ + diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj index 46a77d5373..8711b8a8ed 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -938,10 +938,10 @@ - + diff --git a/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.csproj index 19e1e5c7b6..0b43452f7f 100644 --- a/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.csproj @@ -16,6 +16,7 @@ + diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj index e291206a4a..46a34e75d5 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj @@ -740,6 +740,7 @@ + $(SystemTextEncodingsWebVersion) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ActiveDirectoryAuthenticationProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ActiveDirectoryAuthenticationProvider.cs index d40f59c78b..768a8cfe45 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ActiveDirectoryAuthenticationProvider.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ActiveDirectoryAuthenticationProvider.cs @@ -5,13 +5,13 @@ using System; using System.Collections.Concurrent; using System.Linq; -using System.Runtime.Caching; using System.Security.Cryptography; using System.Text; using System.Threading; using System.Threading.Tasks; using Azure.Core; using Azure.Identity; +using Microsoft.Extensions.Caching.Memory; using Microsoft.Identity.Client; using Microsoft.Identity.Client.Extensibility; @@ -27,7 +27,7 @@ public sealed class ActiveDirectoryAuthenticationProvider : SqlAuthenticationPro /// private static ConcurrentDictionary s_pcaMap = new ConcurrentDictionary(); - private static readonly MemoryCache s_accountPwCache = new(nameof(ActiveDirectoryAuthenticationProvider)); + private static readonly MemoryCache s_accountPwCache = new MemoryCache(new MemoryCacheOptions()); private static readonly int s_accountPwCacheTtlInHours = 2; private static readonly string s_nativeClientRedirectUri = "https://login.microsoftonline.com/common/oauth2/nativeclient"; private static readonly string s_defaultScopeSuffix = "/.default"; @@ -270,11 +270,11 @@ previousPw is byte[] previousPwBytes && // We cache the password hash to ensure future connection requests include a validated password // when we check for a cached MSAL account. Otherwise, a connection request with the same username // against the same tenant could succeed with an invalid password when we re-use the cached token. - if (!s_accountPwCache.Add(pwCacheKey, GetHash(parameters.Password), DateTime.UtcNow.AddHours(s_accountPwCacheTtlInHours))) + using (ICacheEntry entry = s_accountPwCache.CreateEntry(pwCacheKey)) { - s_accountPwCache.Remove(pwCacheKey); - s_accountPwCache.Add(pwCacheKey, GetHash(parameters.Password), DateTime.UtcNow.AddHours(s_accountPwCacheTtlInHours)); - } + entry.Value = GetHash(parameters.Password); + entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(s_accountPwCacheTtlInHours); + }; SqlClientEventSource.Log.TryTraceEvent("AcquireTokenAsync | Acquired access token for Active Directory Password auth mode. Expiry Time: {0}", result?.ExpiresOn); } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AzureAttestationBasedEnclaveProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AzureAttestationBasedEnclaveProvider.cs index 7b1b2bf2e4..3c51716828 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AzureAttestationBasedEnclaveProvider.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AzureAttestationBasedEnclaveProvider.cs @@ -6,11 +6,11 @@ using System.Collections.Generic; using System.Diagnostics; using System.IdentityModel.Tokens.Jwt; -using System.Runtime.Caching; using System.Security.Claims; using System.Security.Cryptography; using System.Text; using System.Threading; +using Microsoft.Extensions.Caching.Memory; using Microsoft.IdentityModel.JsonWebTokens; using Microsoft.IdentityModel.Logging; using Microsoft.IdentityModel.Protocols; @@ -59,7 +59,7 @@ internal class AzureAttestationEnclaveProvider : EnclaveProviderBase // such as https://sql.azure.attest.com/.well-known/openid-configuration private const string AttestationUrlSuffix = @"/.well-known/openid-configuration"; - private static readonly MemoryCache OpenIdConnectConfigurationCache = new MemoryCache("OpenIdConnectConfigurationCache"); + private static readonly MemoryCache OpenIdConnectConfigurationCache = new MemoryCache(new MemoryCacheOptions()); #endregion #region Internal methods @@ -332,7 +332,7 @@ private static string GetInnerMostExceptionMessage(Exception exception) // It also caches that information for 1 day to avoid DDOS attacks. private OpenIdConnectConfiguration GetOpenIdConfigForSigningKeys(string url, bool forceUpdate) { - OpenIdConnectConfiguration openIdConnectConfig = OpenIdConnectConfigurationCache[url] as OpenIdConnectConfiguration; + OpenIdConnectConfiguration openIdConnectConfig = OpenIdConnectConfigurationCache.Get(url); if (forceUpdate || openIdConnectConfig == null) { // Compute the meta data endpoint @@ -348,7 +348,11 @@ private OpenIdConnectConfiguration GetOpenIdConfigForSigningKeys(string url, boo throw SQL.AttestationFailed(string.Format(Strings.GetAttestationTokenSigningKeysFailed, GetInnerMostExceptionMessage(exception)), exception); } - OpenIdConnectConfigurationCache.Add(url, openIdConnectConfig, DateTime.UtcNow.AddDays(1)); + MemoryCacheEntryOptions options = new MemoryCacheEntryOptions + { + AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(1) + }; + OpenIdConnectConfigurationCache.Set(url, openIdConnectConfig, options); } return openIdConnectConfig; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveProviderBase.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveProviderBase.cs index b8a52b9e4b..b666819dde 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveProviderBase.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveProviderBase.cs @@ -3,9 +3,9 @@ // See the LICENSE file in the project root for more information. using System; -using System.Runtime.Caching; using System.Security.Cryptography; using System.Threading; +using Microsoft.Extensions.Caching.Memory; // Enclave session locking model // 1. For doing the enclave attestation, driver makes either 1, 2 or 3 API calls(in order) @@ -84,7 +84,7 @@ internal abstract class EnclaveProviderBase : SqlColumnEncryptionEnclaveProvider private static readonly Object lockUpdateSessionLock = new Object(); // It is used to save the attestation url and nonce value across API calls - protected static readonly MemoryCache ThreadRetryCache = new MemoryCache("ThreadRetryCache"); + protected static readonly MemoryCache ThreadRetryCache = new MemoryCache(new MemoryCacheOptions()); #endregion #region protected methods @@ -102,7 +102,7 @@ protected void GetEnclaveSessionHelper(EnclaveSessionParameters enclaveSessionPa // In case if on some thread we are running SQL workload which don't require attestation, then in those cases we don't want same thread to wait for event to be signaled. // hence skipping it - string retryThreadID = ThreadRetryCache[Thread.CurrentThread.ManagedThreadId.ToString()] as string; + string retryThreadID = ThreadRetryCache.Get(Thread.CurrentThread.ManagedThreadId.ToString()); if (!string.IsNullOrEmpty(retryThreadID)) { sameThreadRetry = true; @@ -167,7 +167,11 @@ protected void GetEnclaveSessionHelper(EnclaveSessionParameters enclaveSessionPa retryThreadID = Thread.CurrentThread.ManagedThreadId.ToString(); } - ThreadRetryCache.Set(Thread.CurrentThread.ManagedThreadId.ToString(), retryThreadID, DateTime.UtcNow.AddMinutes(ThreadRetryCacheTimeoutInMinutes)); + MemoryCacheEntryOptions options = new MemoryCacheEntryOptions + { + AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(ThreadRetryCacheTimeoutInMinutes) + }; + ThreadRetryCache.Set(Thread.CurrentThread.ManagedThreadId.ToString(), retryThreadID, options); } } } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveSessionCache.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveSessionCache.cs index 2cc34eeeb5..5673395e11 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveSessionCache.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveSessionCache.cs @@ -3,7 +3,7 @@ // See the LICENSE file in the project root for more information. using System; -using System.Runtime.Caching; +using Microsoft.Extensions.Caching.Memory; using System.Threading; namespace Microsoft.Data.SqlClient @@ -11,7 +11,7 @@ namespace Microsoft.Data.SqlClient // Maintains a cache of SqlEnclaveSession instances internal class EnclaveSessionCache { - private readonly MemoryCache enclaveMemoryCache = new MemoryCache("EnclaveMemoryCache"); + private readonly MemoryCache enclaveMemoryCache = new MemoryCache(new MemoryCacheOptions()); private readonly object enclaveCacheLock = new object(); // Nonce for each message sent by the client to the server to prevent replay attacks by the server, @@ -25,7 +25,7 @@ internal class EnclaveSessionCache internal SqlEnclaveSession GetEnclaveSession(EnclaveSessionParameters enclaveSessionParameters, out long counter) { string cacheKey = GenerateCacheKey(enclaveSessionParameters); - SqlEnclaveSession enclaveSession = enclaveMemoryCache[cacheKey] as SqlEnclaveSession; + SqlEnclaveSession enclaveSession = enclaveMemoryCache.Get(cacheKey); counter = Interlocked.Increment(ref _counter); return enclaveSession; } @@ -41,8 +41,12 @@ internal void InvalidateSession(EnclaveSessionParameters enclaveSessionParameter if (enclaveSession != null && enclaveSession.SessionId == enclaveSessionToInvalidate.SessionId) { - SqlEnclaveSession enclaveSessionRemoved = enclaveMemoryCache.Remove(cacheKey) as SqlEnclaveSession; - if (enclaveSessionRemoved == null) + enclaveMemoryCache.TryGetValue(cacheKey, out SqlEnclaveSession enclaveSessionToRemove); + if (enclaveSessionToRemove != null) + { + enclaveMemoryCache.Remove(cacheKey); + } + else { throw new InvalidOperationException(Strings.EnclaveSessionInvalidationFailed); } @@ -58,7 +62,11 @@ internal SqlEnclaveSession CreateSession(EnclaveSessionParameters enclaveSession lock (enclaveCacheLock) { enclaveSession = new SqlEnclaveSession(sharedSecret, sessionId); - enclaveMemoryCache.Add(cacheKey, enclaveSession, DateTime.UtcNow.AddHours(enclaveCacheTimeOutInHours)); + MemoryCacheEntryOptions options = new MemoryCacheEntryOptions + { + AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(enclaveCacheTimeOutInHours) + }; + enclaveMemoryCache.Set(cacheKey, enclaveSession, options); counter = Interlocked.Increment(ref _counter); } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SignatureVerificationCache.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SignatureVerificationCache.cs index c181637c4b..e54e88f23e 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SignatureVerificationCache.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SignatureVerificationCache.cs @@ -3,9 +3,9 @@ // See the LICENSE file in the project root for more information. using System; -using System.Runtime.Caching; using System.Text; using System.Threading; +using Microsoft.Extensions.Caching.Memory; namespace Microsoft.Data.SqlClient { @@ -35,7 +35,7 @@ internal class ColumnMasterKeyMetadataSignatureVerificationCache private ColumnMasterKeyMetadataSignatureVerificationCache() { - _cache = new MemoryCache(_className); + _cache = new MemoryCache(new MemoryCacheOptions()); _inTrim = 0; } @@ -46,17 +46,15 @@ private ColumnMasterKeyMetadataSignatureVerificationCache() /// Key Path for CMK /// boolean indicating whether the key can be sent to enclave /// Signature for the CMK metadata - /// null if the data is not found in cache otherwise returns true/false indicating signature verification success/failure - internal bool? GetSignatureVerificationResult(string keyStoreName, string masterKeyPath, bool allowEnclaveComputations, byte[] signature) + internal bool GetSignatureVerificationResult(string keyStoreName, string masterKeyPath, bool allowEnclaveComputations, byte[] signature) { - ValidateStringArgumentNotNullOrEmpty(masterKeyPath, _masterkeypathArgumentName, _getSignatureVerificationResultMethodName); ValidateStringArgumentNotNullOrEmpty(keyStoreName, _keyStoreNameArgumentName, _getSignatureVerificationResultMethodName); ValidateSignatureNotNullOrEmpty(signature, _getSignatureVerificationResultMethodName); string cacheLookupKey = GetCacheLookupKey(masterKeyPath, allowEnclaveComputations, signature, keyStoreName); - return _cache.Get(cacheLookupKey) as bool?; + return _cache.TryGetValue(cacheLookupKey, out bool value); } /// @@ -69,7 +67,6 @@ private ColumnMasterKeyMetadataSignatureVerificationCache() /// result indicating signature verification success/failure internal void AddSignatureVerificationResult(string keyStoreName, string masterKeyPath, bool allowEnclaveComputations, byte[] signature, bool result) { - ValidateStringArgumentNotNullOrEmpty(masterKeyPath, _masterkeypathArgumentName, _addSignatureVerificationResultMethodName); ValidateStringArgumentNotNullOrEmpty(keyStoreName, _keyStoreNameArgumentName, _addSignatureVerificationResultMethodName); ValidateSignatureNotNullOrEmpty(signature, _addSignatureVerificationResultMethodName); @@ -79,7 +76,11 @@ internal void AddSignatureVerificationResult(string keyStoreName, string masterK TrimCacheIfNeeded(); // By default evict after 10 days. - _cache.Set(cacheLookupKey, result, DateTimeOffset.UtcNow.AddDays(10)); + MemoryCacheEntryOptions options = new MemoryCacheEntryOptions + { + AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(10) + }; + _cache.Set(cacheLookupKey, result, options); } private void ValidateSignatureNotNullOrEmpty(byte[] signature, string methodName) @@ -115,15 +116,17 @@ private void ValidateStringArgumentNotNullOrEmpty(string stringArgValue, string private void TrimCacheIfNeeded() { // If the size of the cache exceeds the threshold, set that we are in trimming and trim the cache accordingly. - long currentCacheSize = _cache.GetCount(); + long currentCacheSize = _cache.Count; if ((currentCacheSize > _cacheSize + _cacheTrimThreshold) && (0 == Interlocked.CompareExchange(ref _inTrim, 1, 0))) { try { - _cache.Trim((int)(((double)(currentCacheSize - _cacheSize) / (double)currentCacheSize) * 100)); + // Example: 2301 - 2000 = 301; 301 / 2301 = 0.1308 * 100 = 13% compacting + _cache.Compact((((double)(currentCacheSize - _cacheSize) / (double)currentCacheSize) * 100)); } finally { + // Reset _inTrim flag Interlocked.CompareExchange(ref _inTrim, 0, 1); } } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlQueryMetadataCache.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlQueryMetadataCache.cs index 5475eb5a0c..964e46aca3 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlQueryMetadataCache.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlQueryMetadataCache.cs @@ -7,9 +7,9 @@ using System.Collections.Generic; using System.Data; using System.Diagnostics; -using System.Runtime.Caching; using System.Text; using System.Threading; +using Microsoft.Extensions.Caching.Memory; namespace Microsoft.Data.SqlClient { @@ -34,7 +34,7 @@ sealed internal class SqlQueryMetadataCache private SqlQueryMetadataCache() { - _cache = new MemoryCache("SqlQueryMetadataCache"); + _cache = new MemoryCache(new MemoryCacheOptions()); } internal static SqlQueryMetadataCache GetInstance() @@ -61,7 +61,7 @@ internal bool GetQueryMetadataIfExists(SqlCommand sqlCommand) return false; } - Dictionary cipherMetadataDictionary = _cache.Get(cacheLookupKey) as Dictionary; + Dictionary cipherMetadataDictionary = _cache.Get>(cacheLookupKey); // If we had a cache miss just return false. if (cipherMetadataDictionary is null) @@ -144,7 +144,7 @@ internal bool GetQueryMetadataIfExists(SqlCommand sqlCommand) } ConcurrentDictionary enclaveKeys = - _cache.Get(enclaveLookupKey) as ConcurrentDictionary; + _cache.Get>(enclaveLookupKey); if (enclaveKeys is not null) { sqlCommand.keysToBeSentToEnclave = CreateCopyOfEnclaveKeys(enclaveKeys); @@ -215,7 +215,7 @@ internal void AddQueryMetadata(SqlCommand sqlCommand, bool ignoreQueriesWithRetu } // If the size of the cache exceeds the threshold, set that we are in trimming and trim the cache accordingly. - long currentCacheSize = _cache.GetCount(); + long currentCacheSize = _cache.Count; if ((currentCacheSize > CacheSize + CacheTrimThreshold) && (0 == Interlocked.CompareExchange(ref _inTrim, 1, 0))) { try @@ -226,7 +226,7 @@ internal void AddQueryMetadata(SqlCommand sqlCommand, bool ignoreQueriesWithRetu Thread.Sleep(TimeSpan.FromSeconds(10)); } #endif - _cache.Trim((int)(((double)(currentCacheSize - CacheSize) / (double)currentCacheSize) * 100)); + _cache.Compact((int)(((double)(currentCacheSize - CacheSize) / (double)currentCacheSize) * 100)); } finally { @@ -235,11 +235,15 @@ internal void AddQueryMetadata(SqlCommand sqlCommand, bool ignoreQueriesWithRetu } // By default evict after 10 hours. - _cache.Set(cacheLookupKey, cipherMetadataDictionary, DateTimeOffset.UtcNow.AddHours(10)); + MemoryCacheEntryOptions options = new MemoryCacheEntryOptions + { + AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(10) + }; + _cache.Set>(cacheLookupKey, cipherMetadataDictionary, options); if (sqlCommand.requiresEnclaveComputations) { ConcurrentDictionary keysToBeCached = CreateCopyOfEnclaveKeys(sqlCommand.keysToBeSentToEnclave); - _cache.Set(enclaveLookupKey, keysToBeCached, DateTimeOffset.UtcNow.AddHours(10)); + _cache.Set>(enclaveLookupKey, keysToBeCached, options); } } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlSecurityUtility.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlSecurityUtility.cs index d9fea6b211..01d2d1bc61 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlSecurityUtility.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlSecurityUtility.cs @@ -374,8 +374,8 @@ internal static void VerifyColumnMasterKeySignature(string keyStoreName, string } else { - bool? signatureVerificationResult = ColumnMasterKeyMetadataSignatureVerificationCache.GetSignatureVerificationResult(keyStoreName, keyPath, isEnclaveEnabled, CMKSignature); - if (signatureVerificationResult is null) + bool signatureVerificationResult = ColumnMasterKeyMetadataSignatureVerificationCache.GetSignatureVerificationResult(keyStoreName, keyPath, isEnclaveEnabled, CMKSignature); + if (signatureVerificationResult == false) { // We will simply bubble up the exception from VerifyColumnMasterKeyMetadata function. isValidSignature = provider.VerifyColumnMasterKeyMetadata(keyPath, isEnclaveEnabled, @@ -385,7 +385,7 @@ internal static void VerifyColumnMasterKeySignature(string keyStoreName, string } else { - isValidSignature = signatureVerificationResult.Value; + isValidSignature = signatureVerificationResult; } } } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlSymmetricKeyCache.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlSymmetricKeyCache.cs index 663116ed59..fb9ea2997d 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlSymmetricKeyCache.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlSymmetricKeyCache.cs @@ -4,8 +4,8 @@ using System; using System.Diagnostics; -using System.Runtime.Caching; using System.Text; +using Microsoft.Extensions.Caching.Memory; namespace Microsoft.Data.SqlClient { @@ -20,7 +20,7 @@ sealed internal class SqlSymmetricKeyCache private SqlSymmetricKeyCache() { - _cache = new MemoryCache("ColumnEncryptionKeyCache"); + _cache = new MemoryCache(new MemoryCacheOptions()); } internal static SqlSymmetricKeyCache GetInstance() @@ -53,7 +53,8 @@ internal SqlClientSymmetricKey GetKey(SqlEncryptionKeyInfo keyInfo, SqlConnectio #endif //DEBUG // Lookup the key in cache - if (!(_cache.Get(cacheLookupKey) is SqlClientSymmetricKey encryptionKey)) + SqlClientSymmetricKey encryptionKey; + if (!(_cache.TryGetValue(cacheLookupKey, out encryptionKey))) { Debug.Assert(SqlConnection.ColumnEncryptionTrustedMasterKeyPaths is not null, @"SqlConnection.ColumnEncryptionTrustedMasterKeyPaths should not be null"); @@ -90,8 +91,11 @@ internal SqlClientSymmetricKey GetKey(SqlEncryptionKeyInfo keyInfo, SqlConnectio { // In case multiple threads reach here at the same time, the first one wins. // The allocated memory will be reclaimed by Garbage Collector. - DateTimeOffset expirationTime = DateTimeOffset.UtcNow.Add(SqlConnection.ColumnEncryptionKeyCacheTtl); - _cache.Add(cacheLookupKey, encryptionKey, expirationTime); + MemoryCacheEntryOptions options = new MemoryCacheEntryOptions + { + AbsoluteExpirationRelativeToNow = SqlConnection.ColumnEncryptionKeyCacheTtl + }; + _cache.Set(cacheLookupKey, encryptionKey, options); } } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs index cfbe531e82..ab327aa689 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs @@ -3,10 +3,10 @@ // See the LICENSE file in the project root for more information. using System; -using System.Runtime.Caching; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Threading; +using Microsoft.Extensions.Caching.Memory; namespace Microsoft.Data.SqlClient { @@ -14,7 +14,7 @@ internal abstract class VirtualizationBasedSecurityEnclaveProviderBase : Enclave { #region Members - private static readonly MemoryCache rootSigningCertificateCache = new MemoryCache("RootSigningCertificateCache"); + private static readonly MemoryCache rootSigningCertificateCache = new MemoryCache(new MemoryCacheOptions()); #endregion @@ -192,7 +192,7 @@ private void VerifyAttestationInfo(string attestationUrl, HealthReport healthRep private X509Certificate2Collection GetSigningCertificate(string attestationUrl, bool forceUpdate) { attestationUrl = GetAttestationUrl(attestationUrl); - X509Certificate2Collection signingCertificates = (X509Certificate2Collection)rootSigningCertificateCache[attestationUrl]; + X509Certificate2Collection signingCertificates = rootSigningCertificateCache.Get(attestationUrl); if (forceUpdate || signingCertificates == null || AnyCertificatesExpired(signingCertificates)) { byte[] data = MakeRequest(attestationUrl); @@ -207,10 +207,14 @@ private X509Certificate2Collection GetSigningCertificate(string attestationUrl, throw SQL.AttestationFailed(string.Format(Strings.GetAttestationSigningCertificateFailedInvalidCertificate, attestationUrl), exception); } - rootSigningCertificateCache.Add(attestationUrl, certificateCollection, DateTime.Now.AddDays(1)); + MemoryCacheEntryOptions options = new MemoryCacheEntryOptions + { + AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(1) + }; + rootSigningCertificateCache.Set(attestationUrl, certificateCollection, options); } - return (X509Certificate2Collection)rootSigningCertificateCache[attestationUrl]; + return rootSigningCertificateCache.Get(attestationUrl); } // Return the endpoint for given attestation url diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj index b5ac559337..15249ba3cd 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj @@ -123,10 +123,10 @@ - - PreserveNewest - %(Filename)%(Extension) - + + PreserveNewest + %(Filename)%(Extension) + diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/ConversionTests.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/ConversionTests.cs index d0b1bfd076..8e62ee95fc 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/ConversionTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/ConversionTests.cs @@ -1449,5 +1449,4 @@ public IEnumerator GetEnumerator() IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); } - } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/Setup/CertificateUtility.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/Setup/CertificateUtility.cs index 3d3c717b31..d695c2c9dd 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/Setup/CertificateUtility.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/Setup/CertificateUtility.cs @@ -3,17 +3,18 @@ // See the LICENSE file in the project root for more information. using System; +using System.Collections; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; -using System.Runtime.Caching; -using System.Runtime.CompilerServices; -using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Threading.Tasks; using Azure; using Azure.Identity; using Azure.Security.KeyVault.Keys; +using Microsoft.Extensions.Caching.Memory; + namespace Microsoft.Data.SqlClient.ManualTesting.Tests.AlwaysEncrypted { class CertificateUtility @@ -98,11 +99,7 @@ internal static void CleanSqlClientCache() { object sqlSymmetricKeyCache = SqlSymmetricKeyCacheGetInstance.Invoke(null, null); MemoryCache cache = SqlSymmetricKeyCacheFieldCache.GetValue(sqlSymmetricKeyCache) as MemoryCache; - - foreach (KeyValuePair item in cache) - { - cache.Remove(item.Key); - } + ClearCache(cache); } /// @@ -308,5 +305,28 @@ public static void ChangeServerTceSetting(bool fEnable, SqlConnectionStringBuild } } } + + private static void ClearCache(MemoryCache cache) + { + // Get the Clear method of the cache and use it if available. This is available in Microsoft.Extensions.Caching 8.0 + MethodInfo clearMethod = cache.GetType().GetMethod("Clear", BindingFlags.Instance | BindingFlags.Public); + if (clearMethod != null) + { + clearMethod.Invoke(cache, null); + } + else + { + // Otherwise, use the Remove function to remove all entries using all keys in the cache gathered using reflection. + PropertyInfo cacheEntriesCollectionDefinition = typeof(MemoryCache).GetProperty("EntriesCollection", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); + ICollection cacheEntriesCollection = (ICollection)cacheEntriesCollectionDefinition.GetValue(cache); + List cacheCollectionValues = new List(); + + foreach (object cacheItem in cacheEntriesCollection) + { + ICacheEntry cacheItemValue = (ICacheEntry)cacheItem.GetType().GetProperty("Value").GetValue(cacheItem, null); + cache.Remove(cacheItemValue.Key); + } + } + } } } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj index 8962d5ab15..fdf6096d7d 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj @@ -315,6 +315,7 @@ + @@ -343,7 +344,6 @@ - @@ -351,10 +351,10 @@ - - PreserveNewest - %(Filename)%(Extension) - + + PreserveNewest + %(Filename)%(Extension) + diff --git a/tools/specs/Microsoft.Data.SqlClient.nuspec b/tools/specs/Microsoft.Data.SqlClient.nuspec index 6bbc961ac7..62dea30d5c 100644 --- a/tools/specs/Microsoft.Data.SqlClient.nuspec +++ b/tools/specs/Microsoft.Data.SqlClient.nuspec @@ -46,7 +46,7 @@ When using NuGet 3.x this package requires at least version 3.4. - + @@ -56,7 +56,7 @@ When using NuGet 3.x this package requires at least version 3.4. - + From a7405ded70a0139a41e97c2ace76977b3a5260a4 Mon Sep 17 00:00:00 2001 From: Javad Rahnama Date: Tue, 11 Jun 2024 14:53:27 -0700 Subject: [PATCH 20/25] Add | Add SourceLink translation (#2552) --- build.proj | 3 ++ src/Directory.Build.props | 8 ++---- tools/targets/RepositoryInfo.targets | 41 ++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 tools/targets/RepositoryInfo.targets diff --git a/build.proj b/build.proj index 89b46fb761..7014ea77b2 100644 --- a/build.proj +++ b/build.proj @@ -6,6 +6,9 @@ + + false + src\NuGet.config Debug AnyCPU diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 1fa393eccb..b1d427fd7b 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -80,12 +80,7 @@ true - - - - - - + @@ -95,6 +90,7 @@ + diff --git a/tools/targets/RepositoryInfo.targets b/tools/targets/RepositoryInfo.targets new file mode 100644 index 0000000000..c62efed34a --- /dev/null +++ b/tools/targets/RepositoryInfo.targets @@ -0,0 +1,41 @@ + + + + + + false + false + false + + + + + + + + true + <_TranslateUrlPattern>https://[^/]+/ADO.Net/_git/([^/-]+)-(.+) + <_TranslateUrlReplacement>https://github.com/dotnet/SqlClient + + + + + + $([System.Text.RegularExpressions.Regex]::Replace($(ScmRepositoryUrl), $(_TranslateUrlPattern), $(_TranslateUrlReplacement))) + + + + + + + $([System.Text.RegularExpressions.Regex]::Replace(%(SourceRoot.ScmRepositoryUrl), + $(_TranslateUrlPattern), $(_TranslateUrlReplacement))) + + + + + From 080e66950d9d0b6d113c8eae3a2056372159f258 Mon Sep 17 00:00:00 2001 From: David Engel Date: Wed, 12 Jun 2024 09:20:14 -0700 Subject: [PATCH 21/25] Add | Cache TokenCredential objects to take advantage of token caching (#2380) --- .../ActiveDirectoryAuthenticationProvider.cs | 249 ++++++++++++++---- 1 file changed, 204 insertions(+), 45 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ActiveDirectoryAuthenticationProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ActiveDirectoryAuthenticationProvider.cs index 768a8cfe45..d9ceb49c2d 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ActiveDirectoryAuthenticationProvider.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ActiveDirectoryAuthenticationProvider.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Concurrent; -using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading; @@ -25,14 +24,16 @@ public sealed class ActiveDirectoryAuthenticationProvider : SqlAuthenticationPro /// The purpose of this cache is to allow re-use of Access Tokens fetched for a user interactively or with any other mode /// to avoid interactive authentication request every-time, within application scope making use of MSAL's userTokenCache. /// - private static ConcurrentDictionary s_pcaMap - = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary s_pcaMap = new(); + private static readonly ConcurrentDictionary s_tokenCredentialMap = new(); + private static SemaphoreSlim s_pcaMapModifierSemaphore = new(1, 1); + private static SemaphoreSlim s_tokenCredentialMapModifierSemaphore = new(1, 1); private static readonly MemoryCache s_accountPwCache = new MemoryCache(new MemoryCacheOptions()); private static readonly int s_accountPwCacheTtlInHours = 2; private static readonly string s_nativeClientRedirectUri = "https://login.microsoftonline.com/common/oauth2/nativeclient"; private static readonly string s_defaultScopeSuffix = "/.default"; private readonly string _type = typeof(ActiveDirectoryAuthenticationProvider).Name; - private readonly SqlClientLogger _logger = new SqlClientLogger(); + private readonly SqlClientLogger _logger = new(); private Func _deviceCodeFlowCallback; private ICustomWebUi _customWebUI = null; private readonly string _applicationClientId = ActiveDirectoryAuthentication.AdoClientId; @@ -66,6 +67,11 @@ public static void ClearUserTokenCache() { s_pcaMap.Clear(); } + + if (!s_tokenCredentialMap.IsEmpty) + { + s_tokenCredentialMap.Clear(); + } } /// @@ -135,65 +141,47 @@ public override async Task AcquireTokenAsync(SqlAuthenti * More information: https://docs.microsoft.com/azure/active-directory/develop/msal-client-application-configuration **/ - int seperatorIndex = parameters.Authority.LastIndexOf('/'); - string authority = parameters.Authority.Remove(seperatorIndex + 1); - string audience = parameters.Authority.Substring(seperatorIndex + 1); + int separatorIndex = parameters.Authority.LastIndexOf('/'); + string authority = parameters.Authority.Remove(separatorIndex + 1); + string audience = parameters.Authority.Substring(separatorIndex + 1); string clientId = string.IsNullOrWhiteSpace(parameters.UserId) ? null : parameters.UserId; if (parameters.AuthenticationMethod == SqlAuthenticationMethod.ActiveDirectoryDefault) { - DefaultAzureCredentialOptions defaultAzureCredentialOptions = new() - { - AuthorityHost = new Uri(authority), - SharedTokenCacheTenantId = audience, - VisualStudioCodeTenantId = audience, - VisualStudioTenantId = audience, - ExcludeInteractiveBrowserCredential = true // Force disabled, even though it's disabled by default to respect driver specifications. - }; - - // Optionally set clientId when available - if (clientId is not null) - { - defaultAzureCredentialOptions.ManagedIdentityClientId = clientId; - defaultAzureCredentialOptions.SharedTokenCacheUsername = clientId; - defaultAzureCredentialOptions.WorkloadIdentityClientId = clientId; - } - AccessToken accessToken = await new DefaultAzureCredential(defaultAzureCredentialOptions).GetTokenAsync(tokenRequestContext, cts.Token).ConfigureAwait(false); + // Cache DefaultAzureCredenial based on scope, authority, audience, and clientId + TokenCredentialKey tokenCredentialKey = new(typeof(DefaultAzureCredential), authority, scope, audience, clientId); + AccessToken accessToken = await GetTokenAsync(tokenCredentialKey, string.Empty, tokenRequestContext, cts.Token).ConfigureAwait(false); SqlClientEventSource.Log.TryTraceEvent("AcquireTokenAsync | Acquired access token for Default auth mode. Expiry Time: {0}", accessToken.ExpiresOn); return new SqlAuthenticationToken(accessToken.Token, accessToken.ExpiresOn); } - TokenCredentialOptions tokenCredentialOptions = new TokenCredentialOptions() { AuthorityHost = new Uri(authority) }; + TokenCredentialOptions tokenCredentialOptions = new() { AuthorityHost = new Uri(authority) }; if (parameters.AuthenticationMethod == SqlAuthenticationMethod.ActiveDirectoryManagedIdentity || parameters.AuthenticationMethod == SqlAuthenticationMethod.ActiveDirectoryMSI) { - AccessToken accessToken = await new ManagedIdentityCredential(clientId, tokenCredentialOptions).GetTokenAsync(tokenRequestContext, cts.Token).ConfigureAwait(false); + // Cache ManagedIdentityCredential based on scope, authority, and clientId + TokenCredentialKey tokenCredentialKey = new(typeof(ManagedIdentityCredential), authority, scope, string.Empty, clientId); + AccessToken accessToken = await GetTokenAsync(tokenCredentialKey, string.Empty, tokenRequestContext, cts.Token).ConfigureAwait(false); SqlClientEventSource.Log.TryTraceEvent("AcquireTokenAsync | Acquired access token for Managed Identity auth mode. Expiry Time: {0}", accessToken.ExpiresOn); return new SqlAuthenticationToken(accessToken.Token, accessToken.ExpiresOn); } if (parameters.AuthenticationMethod == SqlAuthenticationMethod.ActiveDirectoryServicePrincipal) { - AccessToken accessToken = await new ClientSecretCredential(audience, parameters.UserId, parameters.Password, tokenCredentialOptions).GetTokenAsync(tokenRequestContext, cts.Token).ConfigureAwait(false); + // Cache ClientSecretCredential based on scope, authority, audience, and clientId + TokenCredentialKey tokenCredentialKey = new(typeof(ClientSecretCredential), authority, scope, audience, clientId); + AccessToken accessToken = await GetTokenAsync(tokenCredentialKey, parameters.Password, tokenRequestContext, cts.Token).ConfigureAwait(false); SqlClientEventSource.Log.TryTraceEvent("AcquireTokenAsync | Acquired access token for Active Directory Service Principal auth mode. Expiry Time: {0}", accessToken.ExpiresOn); return new SqlAuthenticationToken(accessToken.Token, accessToken.ExpiresOn); } if (parameters.AuthenticationMethod == SqlAuthenticationMethod.ActiveDirectoryWorkloadIdentity) { - // The WorkloadIdentityCredentialOptions object initialization populates its instance members - // from the environment variables AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_FEDERATED_TOKEN_FILE, - // and AZURE_ADDITIONALLY_ALLOWED_TENANTS. AZURE_CLIENT_ID may be overridden by the User Id. - WorkloadIdentityCredentialOptions options = new() { AuthorityHost = new Uri(authority) }; - - if (clientId is not null) - { - options.ClientId = clientId; - } - + // Cache WorkloadIdentityCredential based on authority and clientId + TokenCredentialKey tokenCredentialKey = new(typeof(WorkloadIdentityCredential), authority, string.Empty, string.Empty, clientId); // If either tenant id, client id, or the token file path are not specified when fetching the token, // a CredentialUnavailableException will be thrown instead - AccessToken accessToken = await new WorkloadIdentityCredential(options).GetTokenAsync(tokenRequestContext, cts.Token).ConfigureAwait(false); + AccessToken accessToken = await GetTokenAsync(tokenCredentialKey, string.Empty, tokenRequestContext, cts.Token).ConfigureAwait(false); SqlClientEventSource.Log.TryTraceEvent("AcquireTokenAsync | Acquired access token for Workload Identity auth mode. Expiry Time: {0}", accessToken.ExpiresOn); return new SqlAuthenticationToken(accessToken.Token, accessToken.ExpiresOn); } @@ -213,14 +201,14 @@ public override async Task AcquireTokenAsync(SqlAuthenti redirectUri = "http://localhost"; } #endif - PublicClientAppKey pcaKey = new PublicClientAppKey(parameters.Authority, redirectUri, _applicationClientId + PublicClientAppKey pcaKey = new(parameters.Authority, redirectUri, _applicationClientId #if NETFRAMEWORK , _iWin32WindowFunc #endif ); AuthenticationResult result = null; - IPublicClientApplication app = GetPublicClientAppInstance(pcaKey); + IPublicClientApplication app = await GetPublicClientAppInstanceAsync(pcaKey, cts.Token).ConfigureAwait(false); if (parameters.AuthenticationMethod == SqlAuthenticationMethod.ActiveDirectoryIntegrated) { @@ -255,7 +243,7 @@ public override async Task AcquireTokenAsync(SqlAuthenti if (null != previousPw && previousPw is byte[] previousPwBytes && // Only get the cached token if the current password hash matches the previously used password hash - currPwHash.SequenceEqual(previousPwBytes)) + AreEqual(currPwHash, previousPwBytes)) { result = await TryAcquireTokenSilent(app, parameters, scopes, cts).ConfigureAwait(false); } @@ -360,7 +348,7 @@ private static async Task AcquireTokenInteractiveDeviceFlo { if (authenticationMethod == SqlAuthenticationMethod.ActiveDirectoryInteractive) { - CancellationTokenSource ctsInteractive = new CancellationTokenSource(); + CancellationTokenSource ctsInteractive = new(); #if NET6_0_OR_GREATER /* * On .NET Core, MSAL will start the system browser as a separate process. MSAL does not have control over this browser, @@ -454,16 +442,69 @@ public Task AcquireAuthorizationCodeAsync(Uri authorizationUri, Uri redirec => _acquireAuthorizationCodeAsyncCallback.Invoke(authorizationUri, redirectUri, cancellationToken); } - private IPublicClientApplication GetPublicClientAppInstance(PublicClientAppKey publicClientAppKey) + private async Task GetPublicClientAppInstanceAsync(PublicClientAppKey publicClientAppKey, CancellationToken cancellationToken) { if (!s_pcaMap.TryGetValue(publicClientAppKey, out IPublicClientApplication clientApplicationInstance)) { - clientApplicationInstance = CreateClientAppInstance(publicClientAppKey); - s_pcaMap.TryAdd(publicClientAppKey, clientApplicationInstance); + await s_pcaMapModifierSemaphore.WaitAsync(cancellationToken); + try + { + // Double-check in case another thread added it while we waited for the semaphore + if (!s_pcaMap.TryGetValue(publicClientAppKey, out clientApplicationInstance)) + { + clientApplicationInstance = CreateClientAppInstance(publicClientAppKey); + s_pcaMap.TryAdd(publicClientAppKey, clientApplicationInstance); + } + } + finally + { + s_pcaMapModifierSemaphore.Release(); + } } + return clientApplicationInstance; } + private static async Task GetTokenAsync(TokenCredentialKey tokenCredentialKey, string secret, + TokenRequestContext tokenRequestContext, CancellationToken cancellationToken) + { + if (!s_tokenCredentialMap.TryGetValue(tokenCredentialKey, out TokenCredentialData tokenCredentialInstance)) + { + await s_tokenCredentialMapModifierSemaphore.WaitAsync(cancellationToken); + try + { + // Double-check in case another thread added it while we waited for the semaphore + if (!s_tokenCredentialMap.TryGetValue(tokenCredentialKey, out tokenCredentialInstance)) + { + tokenCredentialInstance = CreateTokenCredentialInstance(tokenCredentialKey, secret); + s_tokenCredentialMap.TryAdd(tokenCredentialKey, tokenCredentialInstance); + } + } + finally + { + s_tokenCredentialMapModifierSemaphore.Release(); + } + } + + if (!AreEqual(tokenCredentialInstance._secretHash, GetHash(secret))) + { + // If the secret hash has changed, we need to remove the old token credential instance and create a new one. + await s_tokenCredentialMapModifierSemaphore.WaitAsync(cancellationToken); + try + { + s_tokenCredentialMap.TryRemove(tokenCredentialKey, out _); + tokenCredentialInstance = CreateTokenCredentialInstance(tokenCredentialKey, secret); + s_tokenCredentialMap.TryAdd(tokenCredentialKey, tokenCredentialInstance); + } + finally + { + s_tokenCredentialMapModifierSemaphore.Release(); + } + } + + return await tokenCredentialInstance._tokenCredential.GetTokenAsync(tokenRequestContext, cancellationToken); + } + private static string GetAccountPwCacheKey(SqlAuthenticationParameters parameters) { return parameters.Authority + "+" + parameters.UserId; @@ -477,6 +518,24 @@ private static byte[] GetHash(string input) return hashedBytes; } + private static bool AreEqual(byte[] a1, byte[] a2) + { + if (ReferenceEquals(a1, a2)) + { + return true; + } + else if (a1 is null || a2 is null) + { + return false; + } + else if (a1.Length != a2.Length) + { + return false; + } + + return a1.AsSpan().SequenceEqual(a2.AsSpan()); + } + private IPublicClientApplication CreateClientAppInstance(PublicClientAppKey publicClientAppKey) { IPublicClientApplication publicClientApplication; @@ -506,6 +565,59 @@ private IPublicClientApplication CreateClientAppInstance(PublicClientAppKey publ return publicClientApplication; } + private static TokenCredentialData CreateTokenCredentialInstance(TokenCredentialKey tokenCredentialKey, string secret) + { + if (tokenCredentialKey._tokenCredentialType == typeof(DefaultAzureCredential)) + { + DefaultAzureCredentialOptions defaultAzureCredentialOptions = new() + { + AuthorityHost = new Uri(tokenCredentialKey._authority), + SharedTokenCacheTenantId = tokenCredentialKey._audience, + VisualStudioCodeTenantId = tokenCredentialKey._audience, + VisualStudioTenantId = tokenCredentialKey._audience, + ExcludeInteractiveBrowserCredential = true // Force disabled, even though it's disabled by default to respect driver specifications. + }; + + // Optionally set clientId when available + if (tokenCredentialKey._clientId is not null) + { + defaultAzureCredentialOptions.ManagedIdentityClientId = tokenCredentialKey._clientId; + defaultAzureCredentialOptions.SharedTokenCacheUsername = tokenCredentialKey._clientId; + defaultAzureCredentialOptions.WorkloadIdentityClientId = tokenCredentialKey._clientId; + } + + return new TokenCredentialData(new DefaultAzureCredential(defaultAzureCredentialOptions), GetHash(secret)); + } + + TokenCredentialOptions tokenCredentialOptions = new() { AuthorityHost = new Uri(tokenCredentialKey._authority) }; + + if (tokenCredentialKey._tokenCredentialType == typeof(ManagedIdentityCredential)) + { + return new TokenCredentialData(new ManagedIdentityCredential(tokenCredentialKey._clientId, tokenCredentialOptions), GetHash(secret)); + } + else if (tokenCredentialKey._tokenCredentialType == typeof(ClientSecretCredential)) + { + return new TokenCredentialData(new ClientSecretCredential(tokenCredentialKey._audience, tokenCredentialKey._clientId, secret, tokenCredentialOptions), GetHash(secret)); + } + else if (tokenCredentialKey._tokenCredentialType == typeof(WorkloadIdentityCredential)) + { + // The WorkloadIdentityCredentialOptions object initialization populates its instance members + // from the environment variables AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_FEDERATED_TOKEN_FILE, + // and AZURE_ADDITIONALLY_ALLOWED_TENANTS. AZURE_CLIENT_ID may be overridden by the User Id. + WorkloadIdentityCredentialOptions options = new() { AuthorityHost = new Uri(tokenCredentialKey._authority) }; + + if (tokenCredentialKey._clientId is not null) + { + options.ClientId = tokenCredentialKey._clientId; + } + + return new TokenCredentialData(new WorkloadIdentityCredential(options), GetHash(secret)); + } + + // This should never be reached, but if it is, throw an exception that will be noticed during development + throw new ArgumentException(nameof(ActiveDirectoryAuthenticationProvider)); + } + internal class PublicClientAppKey { public readonly string _authority; @@ -550,5 +662,52 @@ public override int GetHashCode() => Tuple.Create(_authority, _redirectUri, _app #endif ).GetHashCode(); } + + internal class TokenCredentialData + { + public TokenCredential _tokenCredential; + public byte[] _secretHash; + + public TokenCredentialData(TokenCredential tokenCredential, byte[] secretHash) + { + _tokenCredential = tokenCredential; + _secretHash = secretHash; + } + } + + internal class TokenCredentialKey + { + public readonly Type _tokenCredentialType; + public readonly string _authority; + public readonly string _scope; + public readonly string _audience; + public readonly string _clientId; + + public TokenCredentialKey(Type tokenCredentialType, string authority, string scope, string audience, string clientId) + { + _tokenCredentialType = tokenCredentialType; + _authority = authority; + _scope = scope; + _audience = audience; + _clientId = clientId; + } + + public override bool Equals(object obj) + { + if (obj != null && obj is TokenCredentialKey tcKey) + { + return string.CompareOrdinal(nameof(_tokenCredentialType), nameof(tcKey._tokenCredentialType)) == 0 + && string.CompareOrdinal(_authority, tcKey._authority) == 0 + && string.CompareOrdinal(_scope, tcKey._scope) == 0 + && string.CompareOrdinal(_audience, tcKey._audience) == 0 + && string.CompareOrdinal(_clientId, tcKey._clientId) == 0 + ; + } + return false; + } + + public override int GetHashCode() => Tuple.Create(_tokenCredentialType, _authority, _scope, _audience, _clientId).GetHashCode(); + } + } } From c822b6917da7e38445777869acdaf13634a826f8 Mon Sep 17 00:00:00 2001 From: Aris Rellegue <134557572+arellegue@users.noreply.github.com> Date: Wed, 12 Jun 2024 17:16:35 +0000 Subject: [PATCH 22/25] Merged common code base for SqlUtil.cs (#2533) --- .../src/Microsoft.Data.SqlClient.csproj | 1 - .../src/Microsoft/Data/SqlClient/SqlUtil.cs | 2218 ------------- .../netfx/src/Microsoft.Data.SqlClient.csproj | 1 - .../src/Microsoft/Data/SqlClient/SqlUtil.cs | 2677 ---------------- .../src/Microsoft/Data/SqlClient/SqlUtil.cs | 2796 ++++++++++++++++- 5 files changed, 2794 insertions(+), 4899 deletions(-) delete mode 100644 src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlUtil.cs delete mode 100644 src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlUtil.cs diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj index 8711b8a8ed..c6676e1cf3 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -664,7 +664,6 @@ - diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlUtil.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlUtil.cs deleted file mode 100644 index 3583310717..0000000000 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlUtil.cs +++ /dev/null @@ -1,2218 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Data; -using System.Diagnostics; -using System.Globalization; -using System.Net; -using System.Net.Sockets; -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.ExceptionServices; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using System.Transactions; -using Microsoft.Data.Common; - -namespace Microsoft.Data.SqlClient -{ - internal static class AsyncHelper - { - internal static Task CreateContinuationTask(Task task, Action onSuccess, Action onFailure = null) - { - if (task == null) - { - onSuccess(); - return null; - } - else - { - TaskCompletionSource completion = new TaskCompletionSource(); - ContinueTaskWithState(task, completion, - state: Tuple.Create(onSuccess, onFailure, completion), - onSuccess: static (object state) => - { - var parameters = (Tuple, TaskCompletionSource>)state; - Action success = parameters.Item1; - TaskCompletionSource taskCompletionSource = parameters.Item3; - success(); - taskCompletionSource.SetResult(null); - }, - onFailure: static (Exception exception, object state) => - { - var parameters = (Tuple, TaskCompletionSource>)state; - Action failure = parameters.Item2; - failure?.Invoke(exception); - } - ); - return completion.Task; - } - } - - internal static Task CreateContinuationTaskWithState(Task task, object state, Action onSuccess, Action onFailure = null) - { - if (task == null) - { - onSuccess(state); - return null; - } - else - { - var completion = new TaskCompletionSource(); - ContinueTaskWithState(task, completion, state, - onSuccess: (object continueState) => - { - onSuccess(continueState); - completion.SetResult(null); - }, - onFailure: onFailure - ); - return completion.Task; - } - } - - internal static Task CreateContinuationTask(Task task, Action onSuccess, T1 arg1, T2 arg2, SqlInternalConnectionTds connectionToDoom = null, Action onFailure = null) - { - return CreateContinuationTask(task, () => onSuccess(arg1, arg2), onFailure); - } - - internal static void ContinueTask(Task task, - TaskCompletionSource completion, - Action onSuccess, - Action onFailure = null, - Action onCancellation = null, - Func exceptionConverter = null - ) - { - task.ContinueWith( - tsk => - { - if (tsk.Exception != null) - { - Exception exc = tsk.Exception.InnerException; - if (exceptionConverter != null) - { - exc = exceptionConverter(exc); - } - try - { - onFailure?.Invoke(exc); - } - finally - { - completion.TrySetException(exc); - } - } - else if (tsk.IsCanceled) - { - try - { - onCancellation?.Invoke(); - } - finally - { - completion.TrySetCanceled(); - } - } - else - { - try - { - onSuccess(); - } - catch (Exception e) - { - completion.SetException(e); - } - } - }, TaskScheduler.Default - ); - } - - // the same logic as ContinueTask but with an added state parameter to allow the caller to avoid the use of a closure - // the parameter allocation cannot be avoided here and using closure names is clearer than Tuple numbered properties - internal static void ContinueTaskWithState(Task task, - TaskCompletionSource completion, - object state, - Action onSuccess, - Action onFailure = null, - Action onCancellation = null, - Func exceptionConverter = null - ) - { - task.ContinueWith( - (Task tsk, object state2) => - { - if (tsk.Exception != null) - { - Exception exc = tsk.Exception.InnerException; - if (exceptionConverter != null) - { - exc = exceptionConverter(exc); - } - try - { - onFailure?.Invoke(exc, state2); - } - finally - { - completion.TrySetException(exc); - } - } - else if (tsk.IsCanceled) - { - try - { - onCancellation?.Invoke(state2); - } - finally - { - completion.TrySetCanceled(); - } - } - else - { - try - { - onSuccess(state2); - } - catch (Exception e) - { - completion.SetException(e); - } - } - }, - state: state, - scheduler: TaskScheduler.Default - ); - } - - internal static void WaitForCompletion(Task task, int timeout, Action onTimeout = null, bool rethrowExceptions = true) - { - try - { - task.Wait(timeout > 0 ? (1000 * timeout) : Timeout.Infinite); - } - catch (AggregateException ae) - { - if (rethrowExceptions) - { - Debug.Assert(ae.InnerExceptions.Count == 1, "There is more than one exception in AggregateException"); - ExceptionDispatchInfo.Capture(ae.InnerException).Throw(); - } - } - if (!task.IsCompleted) - { - task.ContinueWith(static t => { var ignored = t.Exception; }); //Ensure the task does not leave an unobserved exception - onTimeout?.Invoke(); - } - } - - internal static void SetTimeoutException(TaskCompletionSource completion, int timeout, Func onFailure, CancellationToken ctoken) - { - if (timeout > 0) - { - Task.Delay(timeout * 1000, ctoken).ContinueWith( - (Task task) => - { - if (!task.IsCanceled && !completion.Task.IsCompleted) - { - completion.TrySetException(onFailure()); - } - } - ); - } - } - - internal static void SetTimeoutExceptionWithState(TaskCompletionSource completion, int timeout, object state, Func onFailure, CancellationToken cancellationToken) - { - if (timeout > 0) - { - Task.Delay(timeout * 1000, cancellationToken).ContinueWith( - (Task task, object state) => - { - if (!task.IsCanceled && !completion.Task.IsCompleted) - { - completion.TrySetException(onFailure(state)); - } - }, - state: state, - cancellationToken: CancellationToken.None - ); - } - } - } - - internal static class SQL - { - // The class SQL defines the exceptions that are specific to the SQL Adapter. - // The class contains functions that take the proper informational variables and then construct - // the appropriate exception with an error string obtained from the resource Framework.txt. - // The exception is then returned to the caller, so that the caller may then throw from its - // location so that the catcher of the exception will have the appropriate call stack. - // This class is used so that there will be compile time checking of error - // messages. The resource Framework.txt will ensure proper string text based on the appropriate - // locale. - - // - // SQL specific exceptions - // - - // - // SQL.Connection - // - internal static Exception CannotGetDTCAddress() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_CannotGetDTCAddress)); - } - - internal static Exception InvalidInternalPacketSize(string str) - { - return ADP.ArgumentOutOfRange(str); - } - internal static Exception InvalidPacketSize() - { - return ADP.ArgumentOutOfRange(StringsHelper.GetString(Strings.SQL_InvalidTDSPacketSize)); - } - internal static Exception InvalidPacketSizeValue() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_InvalidPacketSizeValue)); - } - internal static Exception InvalidSSPIPacketSize() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_InvalidSSPIPacketSize)); - } - internal static Exception AuthenticationAndIntegratedSecurity() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_AuthenticationAndIntegratedSecurity)); - } - internal static Exception IntegratedWithPassword() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_IntegratedWithPassword)); - } - internal static Exception InteractiveWithPassword() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_InteractiveWithPassword)); - } - internal static Exception DeviceFlowWithUsernamePassword() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_DeviceFlowWithUsernamePassword)); - } - internal static Exception NonInteractiveWithPassword(string authenticationMode) - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_NonInteractiveWithPassword, authenticationMode)); - } - static internal Exception SettingIntegratedWithCredential() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SettingIntegratedWithCredential)); - } - static internal Exception SettingInteractiveWithCredential() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SettingInteractiveWithCredential)); - } - static internal Exception SettingDeviceFlowWithCredential() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SettingDeviceFlowWithCredential)); - } - static internal Exception SettingNonInteractiveWithCredential(string authenticationMode) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SettingNonInteractiveWithCredential, authenticationMode)); - } - static internal Exception SettingCredentialWithIntegratedArgument() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_SettingCredentialWithIntegrated)); - } - static internal Exception SettingCredentialWithInteractiveArgument() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_SettingCredentialWithInteractive)); - } - static internal Exception SettingCredentialWithDeviceFlowArgument() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_SettingCredentialWithDeviceFlow)); - } - static internal Exception SettingCredentialWithNonInteractiveArgument(string authenticationMode) - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_SettingCredentialWithNonInteractive, authenticationMode)); - } - static internal Exception SettingCredentialWithIntegratedInvalid() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SettingCredentialWithIntegrated)); - } - static internal Exception SettingCredentialWithInteractiveInvalid() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SettingCredentialWithInteractive)); - } - static internal Exception SettingCredentialWithDeviceFlowInvalid() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SettingCredentialWithDeviceFlow)); - } - static internal Exception SettingCredentialWithNonInteractiveInvalid(string authenticationMode) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SettingCredentialWithNonInteractive, authenticationMode)); - } - internal static Exception NullEmptyTransactionName() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_NullEmptyTransactionName)); - } - internal static Exception UserInstanceFailoverNotCompatible() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_UserInstanceFailoverNotCompatible)); - } - internal static Exception CredentialsNotProvided(SqlAuthenticationMethod auth) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_CredentialsNotProvided, DbConnectionStringBuilderUtil.AuthenticationTypeToString(auth))); - } - internal static Exception ParsingErrorLibraryType(ParsingErrorState state, int libraryType) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParsingErrorAuthLibraryType, ((int)state).ToString(CultureInfo.InvariantCulture), libraryType)); - } - internal static Exception InvalidSQLServerVersionUnknown() - { - return ADP.DataAdapter(StringsHelper.GetString(Strings.SQL_InvalidSQLServerVersionUnknown)); - } - internal static Exception SynchronousCallMayNotPend() - { - return new Exception(StringsHelper.GetString(Strings.Sql_InternalError)); - } - internal static Exception SocketDidNotThrow() - { - return new InternalException(StringsHelper.GetString(Strings.SQL_SocketDidNotThrow, nameof(SocketException), nameof(SocketError.WouldBlock))); - } - internal static Exception ConnectionLockedForBcpEvent() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ConnectionLockedForBcpEvent)); - } - internal static Exception InstanceFailure() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_InstanceFailure)); - } - internal static Exception ChangePasswordArgumentMissing(string argumentName) - { - return ADP.ArgumentNull(StringsHelper.GetString(Strings.SQL_ChangePasswordArgumentMissing, argumentName)); - } - internal static Exception ChangePasswordConflictsWithSSPI() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_ChangePasswordConflictsWithSSPI)); - } - internal static Exception ChangePasswordRequires2005() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ChangePasswordRequiresYukon)); - } - internal static Exception ChangePasswordUseOfUnallowedKey(string key) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ChangePasswordUseOfUnallowedKey, key)); - } - internal static Exception GlobalizationInvariantModeNotSupported() - { - return ADP.NotSupported(StringsHelper.GetString(Strings.SQL_GlobalizationInvariantModeNotSupported)); - } - - // - // Global Transactions. - // - internal static Exception GlobalTransactionsNotEnabled() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.GT_Disabled)); - } - internal static Exception UnknownSysTxIsolationLevel(System.Transactions.IsolationLevel isolationLevel) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_UnknownSysTxIsolationLevel, isolationLevel.ToString())); - } - - - internal static Exception InvalidPartnerConfiguration(string server, string database) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_InvalidPartnerConfiguration, server, database)); - } - - internal static Exception BatchedUpdateColumnEncryptionSettingMismatch() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_BatchedUpdateColumnEncryptionSettingMismatch, "SqlCommandColumnEncryptionSetting", "SelectCommand", "InsertCommand", "UpdateCommand", "DeleteCommand")); - } - internal static Exception MARSUnsupportedOnConnection() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_MarsUnsupportedOnConnection)); - } - - internal static Exception CannotModifyPropertyAsyncOperationInProgress([CallerMemberName] string property = "") - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_CannotModifyPropertyAsyncOperationInProgress, property)); - } - internal static Exception NonLocalSSEInstance() - { - return ADP.NotSupported(StringsHelper.GetString(Strings.SQL_NonLocalSSEInstance)); - } - - // SQL.ActiveDirectoryAuth - // - internal static Exception UnsupportedAuthentication(string authentication) - { - return ADP.NotSupported(StringsHelper.GetString(Strings.SQL_UnsupportedAuthentication, authentication)); - } - - internal static Exception UnsupportedSqlAuthenticationMethod(SqlAuthenticationMethod authentication) - { - return ADP.NotSupported(StringsHelper.GetString(Strings.SQL_UnsupportedSqlAuthenticationMethod, authentication)); - } - - internal static Exception UnsupportedAuthenticationSpecified(SqlAuthenticationMethod authentication) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_UnsupportedAuthenticationSpecified, authentication)); - } - - internal static Exception CannotCreateAuthProvider(string authentication, string type, Exception e) - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_CannotCreateAuthProvider, authentication, type), e); - } - - internal static Exception CannotCreateSqlAuthInitializer(string type, Exception e) - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_CannotCreateAuthInitializer, type), e); - } - - internal static Exception CannotInitializeAuthProvider(string type, Exception e) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_CannotInitializeAuthProvider, type), e); - } - - internal static Exception UnsupportedAuthenticationByProvider(string authentication, string type) - { - return ADP.NotSupported(StringsHelper.GetString(Strings.SQL_UnsupportedAuthenticationByProvider, type, authentication)); - } - - internal static Exception CannotFindAuthProvider(string authentication) - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_CannotFindAuthProvider, authentication)); - } - - internal static Exception CannotGetAuthProviderConfig(Exception e) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_CannotGetAuthProviderConfig), e); - } - - internal static Exception ParameterCannotBeEmpty(string paramName) - { - return ADP.ArgumentNull(StringsHelper.GetString(Strings.SQL_ParameterCannotBeEmpty, paramName)); - } - - internal static Exception ParameterDirectionInvalidForOptimizedBinding(string paramName) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParameterDirectionInvalidForOptimizedBinding, paramName)); - } - - internal static Exception ActiveDirectoryInteractiveTimeout() - { - return ADP.TimeoutException(Strings.SQL_Timeout_Active_Directory_Interactive_Authentication); - } - - internal static Exception ActiveDirectoryDeviceFlowTimeout() - { - return ADP.TimeoutException(Strings.SQL_Timeout_Active_Directory_DeviceFlow_Authentication); - } - - internal static Exception ActiveDirectoryTokenRetrievingTimeout(string authenticaton, string errorCode, Exception exception) - { - return ADP.TimeoutException(StringsHelper.GetString(Strings.AAD_Token_Retrieving_Timeout, authenticaton, errorCode, exception?.Message), exception); - } - - // - // SQL.DataCommand - // - - internal static ArgumentOutOfRangeException NotSupportedEnumerationValue(Type type, int value) - { - return ADP.ArgumentOutOfRange(StringsHelper.GetString(Strings.SQL_NotSupportedEnumerationValue, type.Name, value.ToString(System.Globalization.CultureInfo.InvariantCulture)), type.Name); - } - - internal static ArgumentOutOfRangeException NotSupportedCommandType(CommandType value) - { -#if DEBUG - switch (value) - { - case CommandType.Text: - case CommandType.StoredProcedure: - Debug.Fail("valid CommandType " + value.ToString()); - break; - case CommandType.TableDirect: - break; - default: - Debug.Fail("invalid CommandType " + value.ToString()); - break; - } -#endif - return NotSupportedEnumerationValue(typeof(CommandType), (int)value); - } - internal static ArgumentOutOfRangeException NotSupportedIsolationLevel(System.Data.IsolationLevel value) - { -#if DEBUG - switch (value) - { - case System.Data.IsolationLevel.Unspecified: - case System.Data.IsolationLevel.ReadCommitted: - case System.Data.IsolationLevel.ReadUncommitted: - case System.Data.IsolationLevel.RepeatableRead: - case System.Data.IsolationLevel.Serializable: - case System.Data.IsolationLevel.Snapshot: - Debug.Fail("valid IsolationLevel " + value.ToString()); - break; - case System.Data.IsolationLevel.Chaos: - break; - default: - Debug.Fail("invalid IsolationLevel " + value.ToString()); - break; - } -#endif - return NotSupportedEnumerationValue(typeof(System.Data.IsolationLevel), (int)value); - } - - internal static Exception OperationCancelled() - { - Exception exception = ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_OperationCancelled)); - return exception; - } - - internal static Exception PendingBeginXXXExists() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_PendingBeginXXXExists)); - } - - internal static ArgumentOutOfRangeException InvalidSqlDependencyTimeout(string param) - { - return ADP.ArgumentOutOfRange(StringsHelper.GetString(Strings.SqlDependency_InvalidTimeout), param); - } - - internal static Exception NonXmlResult() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_NonXmlResult)); - } - - // - // SQL.DataParameter - // - internal static Exception InvalidUdt3PartNameFormat() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_InvalidUdt3PartNameFormat)); - } - internal static Exception InvalidParameterTypeNameFormat() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_InvalidParameterTypeNameFormat)); - } - internal static Exception InvalidParameterNameLength(string value) - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_InvalidParameterNameLength, value)); - } - internal static Exception PrecisionValueOutOfRange(byte precision) - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_PrecisionValueOutOfRange, precision.ToString(CultureInfo.InvariantCulture))); - } - internal static Exception ScaleValueOutOfRange(byte scale) - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_ScaleValueOutOfRange, scale.ToString(CultureInfo.InvariantCulture))); - } - internal static Exception TimeScaleValueOutOfRange(byte scale) - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_TimeScaleValueOutOfRange, scale.ToString(CultureInfo.InvariantCulture))); - } - internal static Exception InvalidSqlDbType(SqlDbType value) - { - return ADP.InvalidEnumerationValue(typeof(SqlDbType), (int)value); - } - internal static Exception UnsupportedTVPOutputParameter(ParameterDirection direction, string paramName) - { - return ADP.NotSupported(StringsHelper.GetString(Strings.SqlParameter_UnsupportedTVPOutputParameter, - direction.ToString(), paramName)); - } - internal static Exception DBNullNotSupportedForTVPValues(string paramName) - { - return ADP.NotSupported(StringsHelper.GetString(Strings.SqlParameter_DBNullNotSupportedForTVP, paramName)); - } - internal static Exception UnexpectedTypeNameForNonStructParams(string paramName) - { - return ADP.NotSupported(StringsHelper.GetString(Strings.SqlParameter_UnexpectedTypeNameForNonStruct, paramName)); - } - internal static Exception ParameterInvalidVariant(string paramName) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParameterInvalidVariant, paramName)); - } - - internal static Exception MustSetTypeNameForParam(string paramType, string paramName) - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_ParameterTypeNameRequired, paramType, paramName)); - } - internal static Exception NullSchemaTableDataTypeNotSupported(string columnName) - { - return ADP.Argument(StringsHelper.GetString(Strings.NullSchemaTableDataTypeNotSupported, columnName)); - } - internal static Exception InvalidSchemaTableOrdinals() - { - return ADP.Argument(StringsHelper.GetString(Strings.InvalidSchemaTableOrdinals)); - } - internal static Exception EnumeratedRecordMetaDataChanged(string fieldName, int recordNumber) - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_EnumeratedRecordMetaDataChanged, fieldName, recordNumber)); - } - internal static Exception EnumeratedRecordFieldCountChanged(int recordNumber) - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_EnumeratedRecordFieldCountChanged, recordNumber)); - } - - // - // SQL.SqlDataAdapter - // - - // - // SQL.TDSParser - // - internal static Exception InvalidTDSVersion() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_InvalidTDSVersion)); - } - internal static Exception ParsingError() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParsingError)); - } - internal static Exception ParsingError(ParsingErrorState state) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParsingErrorWithState, ((int)state).ToString(CultureInfo.InvariantCulture))); - } - internal static Exception ParsingError(ParsingErrorState state, Exception innerException) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParsingErrorWithState, ((int)state).ToString(CultureInfo.InvariantCulture)), innerException); - } - internal static Exception ParsingErrorValue(ParsingErrorState state, int value) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParsingErrorValue, ((int)state).ToString(CultureInfo.InvariantCulture), value)); - } - internal static Exception ParsingErrorFeatureId(ParsingErrorState state, int featureId) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParsingErrorFeatureId, ((int)state).ToString(CultureInfo.InvariantCulture), featureId)); - } - internal static Exception ParsingErrorToken(ParsingErrorState state, int token) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParsingErrorToken, ((int)state).ToString(CultureInfo.InvariantCulture), token)); - } - internal static Exception ParsingErrorLength(ParsingErrorState state, int length) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParsingErrorLength, ((int)state).ToString(CultureInfo.InvariantCulture), length)); - } - internal static Exception ParsingErrorStatus(ParsingErrorState state, int status) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParsingErrorStatus, ((int)state).ToString(CultureInfo.InvariantCulture), status)); - } - internal static Exception ParsingErrorOffset(ParsingErrorState state, int offset) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParsingErrorOffset, ((int)state).ToString(CultureInfo.InvariantCulture), offset)); - } - internal static Exception MoneyOverflow(string moneyValue) - { - return ADP.Overflow(StringsHelper.GetString(Strings.SQL_MoneyOverflow, moneyValue)); - } - internal static Exception SmallDateTimeOverflow(string datetime) - { - return ADP.Overflow(StringsHelper.GetString(Strings.SQL_SmallDateTimeOverflow, datetime)); - } - internal static Exception SNIPacketAllocationFailure() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SNIPacketAllocationFailure)); - } - internal static Exception TimeOverflow(string time) - { - return ADP.Overflow(StringsHelper.GetString(Strings.SQL_TimeOverflow, time)); - } - - // - // SQL.SqlDataReader - // - internal static Exception InvalidRead() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_InvalidRead)); - } - - internal static Exception NonBlobColumn(string columnName) - { - return ADP.InvalidCast(StringsHelper.GetString(Strings.SQL_NonBlobColumn, columnName)); - } - - internal static Exception NonCharColumn(string columnName) - { - return ADP.InvalidCast(StringsHelper.GetString(Strings.SQL_NonCharColumn, columnName)); - } - - internal static Exception StreamNotSupportOnColumnType(string columnName) - { - return ADP.InvalidCast(StringsHelper.GetString(Strings.SQL_StreamNotSupportOnColumnType, columnName)); - } - - internal static Exception StreamNotSupportOnEncryptedColumn(string columnName) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_StreamNotSupportOnEncryptedColumn, columnName, "Stream")); - } - - internal static Exception SequentialAccessNotSupportedOnEncryptedColumn(string columnName) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_SequentialAccessNotSupportedOnEncryptedColumn, columnName, "CommandBehavior=SequentialAccess")); - } - - internal static Exception TextReaderNotSupportOnColumnType(string columnName) - { - return ADP.InvalidCast(StringsHelper.GetString(Strings.SQL_TextReaderNotSupportOnColumnType, columnName)); - } - - internal static Exception XmlReaderNotSupportOnColumnType(string columnName) - { - return ADP.InvalidCast(StringsHelper.GetString(Strings.SQL_XmlReaderNotSupportOnColumnType, columnName)); - } - - internal static Exception UDTUnexpectedResult(string exceptionText) - { - return ADP.TypeLoad(StringsHelper.GetString(Strings.SQLUDT_Unexpected, exceptionText)); - } - - internal static Exception DateTimeOverflow() - { - return new OverflowException(SqlTypes.SQLResource.DateTimeOverflowMessage); - } - - // - // SQL.SqlDependency - // - internal static Exception SqlCommandHasExistingSqlNotificationRequest() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQLNotify_AlreadyHasCommand)); - } - - internal static Exception SqlDepDefaultOptionsButNoStart() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlDependency_DefaultOptionsButNoStart)); - } - - internal static Exception SqlDependencyDatabaseBrokerDisabled() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlDependency_DatabaseBrokerDisabled)); - } - - internal static Exception SqlDependencyEventNoDuplicate() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlDependency_EventNoDuplicate)); - } - - internal static Exception SqlDependencyDuplicateStart() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlDependency_DuplicateStart)); - } - - internal static Exception SqlDependencyIdMismatch() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlDependency_IdMismatch)); - } - - internal static Exception SqlDependencyNoMatchingServerStart() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlDependency_NoMatchingServerStart)); - } - - internal static Exception SqlDependencyNoMatchingServerDatabaseStart() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlDependency_NoMatchingServerDatabaseStart)); - } - - // - // SQL.SqlDelegatedTransaction - // - static internal Exception CannotCompleteDelegatedTransactionWithOpenResults(SqlInternalConnectionTds internalConnection, bool marsOn) - { - SqlErrorCollection errors = new SqlErrorCollection(); - errors.Add(new SqlError(TdsEnums.TIMEOUT_EXPIRED, (byte)0x00, TdsEnums.MIN_ERROR_CLASS, null, (StringsHelper.GetString(Strings.ADP_OpenReaderExists, marsOn ? ADP.Command : ADP.Connection)), "", 0, TdsEnums.SNI_WAIT_TIMEOUT)); - return SqlException.CreateException(errors, null, internalConnection, innerException: null, batchCommand: null); - } - - internal static TransactionPromotionException PromotionFailed(Exception inner) - { - TransactionPromotionException e = new TransactionPromotionException(StringsHelper.GetString(Strings.SqlDelegatedTransaction_PromotionFailed), inner); - ADP.TraceExceptionAsReturnValue(e); - return e; - } - //Failure while attempting to promote transaction. - - // - // SQL.SqlMetaData - // - internal static Exception UnexpectedUdtTypeNameForNonUdtParams() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQLUDT_UnexpectedUdtTypeName)); - } - internal static Exception MustSetUdtTypeNameForUdtParams() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQLUDT_InvalidUdtTypeName)); - } - internal static Exception UDTInvalidSqlType(string typeName) - { - return ADP.Argument(StringsHelper.GetString(Strings.SQLUDT_InvalidSqlType, typeName)); - } - - internal static Exception UDTInvalidSize(int maxSize, int maxSupportedSize) - { - throw ADP.ArgumentOutOfRange(StringsHelper.GetString(Strings.SQLUDT_InvalidSize, maxSize, maxSupportedSize)); - } - - internal static Exception InvalidSqlDbTypeForConstructor(SqlDbType type) - { - return ADP.Argument(StringsHelper.GetString(Strings.SqlMetaData_InvalidSqlDbTypeForConstructorFormat, type.ToString())); - } - - internal static Exception NameTooLong(string parameterName) - { - return ADP.Argument(StringsHelper.GetString(Strings.SqlMetaData_NameTooLong), parameterName); - } - - internal static Exception InvalidSortOrder(SortOrder order) - { - return ADP.InvalidEnumerationValue(typeof(SortOrder), (int)order); - } - - internal static Exception MustSpecifyBothSortOrderAndOrdinal(SortOrder order, int ordinal) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlMetaData_SpecifyBothSortOrderAndOrdinal, order.ToString(), ordinal)); - } - - internal static Exception UnsupportedColumnTypeForSqlProvider(string columnName, string typeName) - { - return ADP.Argument(StringsHelper.GetString(Strings.SqlProvider_InvalidDataColumnType, columnName, typeName)); - } - internal static Exception InvalidColumnMaxLength(string columnName, long maxLength) - { - return ADP.Argument(StringsHelper.GetString(Strings.SqlProvider_InvalidDataColumnMaxLength, columnName, maxLength)); - } - internal static Exception InvalidColumnPrecScale() - { - return ADP.Argument(StringsHelper.GetString(Strings.SqlMisc_InvalidPrecScaleMessage)); - } - internal static Exception NotEnoughColumnsInStructuredType() - { - return ADP.Argument(StringsHelper.GetString(Strings.SqlProvider_NotEnoughColumnsInStructuredType)); - } - internal static Exception DuplicateSortOrdinal(int sortOrdinal) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlProvider_DuplicateSortOrdinal, sortOrdinal)); - } - internal static Exception MissingSortOrdinal(int sortOrdinal) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlProvider_MissingSortOrdinal, sortOrdinal)); - } - internal static Exception SortOrdinalGreaterThanFieldCount(int columnOrdinal, int sortOrdinal) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlProvider_SortOrdinalGreaterThanFieldCount, sortOrdinal, columnOrdinal)); - } - internal static Exception IEnumerableOfSqlDataRecordHasNoRows() - { - return ADP.Argument(StringsHelper.GetString(Strings.IEnumerableOfSqlDataRecordHasNoRows)); - } - - - - - // - // SQL.BulkLoad - // - internal static Exception BulkLoadMappingInaccessible() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadMappingInaccessible)); - } - internal static Exception BulkLoadMappingsNamesOrOrdinalsOnly() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadMappingsNamesOrOrdinalsOnly)); - } - internal static Exception BulkLoadCannotConvertValue(Type sourcetype, MetaType metatype, int ordinal, int rowNumber, bool isEncrypted, string columnName, string value, Exception e) - { - string quotedValue = string.Empty; - if (!isEncrypted) - { - quotedValue = string.Format(" '{0}'", (value.Length > 100 ? value.Substring(0, 100) : value)); - } - if (rowNumber == -1) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadCannotConvertValueWithoutRowNo, quotedValue, sourcetype.Name, metatype.TypeName, ordinal, columnName), e); - } - else - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadCannotConvertValue, quotedValue, sourcetype.Name, metatype.TypeName, ordinal, columnName, rowNumber), e); - } - } - internal static Exception BulkLoadNonMatchingColumnMapping() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadNonMatchingColumnMapping)); - } - internal static Exception BulkLoadNonMatchingColumnName(string columnName) - { - return BulkLoadNonMatchingColumnName(columnName, null); - } - internal static Exception BulkLoadNonMatchingColumnName(string columnName, Exception e) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadNonMatchingColumnName, columnName), e); - } - internal static Exception BulkLoadNullEmptyColumnName(string paramName) - { - return ADP.Argument(string.Format(StringsHelper.GetString(Strings.SQL_ParameterCannotBeEmpty), paramName)); - } - internal static Exception BulkLoadUnspecifiedSortOrder() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_BulkLoadUnspecifiedSortOrder)); - } - internal static Exception BulkLoadInvalidOrderHint() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_BulkLoadInvalidOrderHint)); - } - internal static Exception BulkLoadOrderHintInvalidColumn(string columnName) - { - return ADP.InvalidOperation(string.Format(StringsHelper.GetString(Strings.SQL_BulkLoadOrderHintInvalidColumn), columnName)); - } - internal static Exception BulkLoadOrderHintDuplicateColumn(string columnName) - { - return ADP.InvalidOperation(string.Format(StringsHelper.GetString(Strings.SQL_BulkLoadOrderHintDuplicateColumn), columnName)); - } - internal static Exception BulkLoadStringTooLong(string tableName, string columnName, string truncatedValue) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadStringTooLong, tableName, columnName, truncatedValue)); - } - internal static Exception BulkLoadInvalidVariantValue() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadInvalidVariantValue)); - } - internal static Exception BulkLoadInvalidTimeout(int timeout) - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_BulkLoadInvalidTimeout, timeout.ToString(CultureInfo.InvariantCulture))); - } - internal static Exception BulkLoadExistingTransaction() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadExistingTransaction)); - } - internal static Exception BulkLoadNoCollation() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadNoCollation)); - } - internal static Exception BulkLoadConflictingTransactionOption() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_BulkLoadConflictingTransactionOption)); - } - internal static Exception BulkLoadLcidMismatch(int sourceLcid, string sourceColumnName, int destinationLcid, string destinationColumnName) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.Sql_BulkLoadLcidMismatch, sourceLcid, sourceColumnName, destinationLcid, destinationColumnName)); - } - internal static Exception InvalidOperationInsideEvent() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadInvalidOperationInsideEvent)); - } - internal static Exception BulkLoadMissingDestinationTable() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadMissingDestinationTable)); - } - internal static Exception BulkLoadInvalidDestinationTable(string tableName, Exception inner) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadInvalidDestinationTable, tableName), inner); - } - internal static Exception BulkLoadBulkLoadNotAllowDBNull(string columnName) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadNotAllowDBNull, columnName)); - } - internal static Exception BulkLoadPendingOperation() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadPendingOperation)); - } - internal static Exception InvalidTableDerivedPrecisionForTvp(string columnName, byte precision) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlParameter_InvalidTableDerivedPrecisionForTvp, precision, columnName, System.Data.SqlTypes.SqlDecimal.MaxPrecision)); - } - - // - // transactions. - // - internal static Exception ConnectionDoomed() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ConnectionDoomed)); - } - - internal static Exception OpenResultCountExceeded() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_OpenResultCountExceeded)); - } - - internal static Exception UnsupportedSysTxForGlobalTransactions() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_UnsupportedSysTxVersion)); - } - - internal static readonly byte[] AttentionHeader = new byte[] { - TdsEnums.MT_ATTN, // Message Type - TdsEnums.ST_EOM, // Status - TdsEnums.HEADER_LEN >> 8, // length - upper byte - TdsEnums.HEADER_LEN & 0xff, // length - lower byte - 0, // spid - 0, // spid - 0, // packet (out of band) - 0 // window - }; - - // - // MultiSubnetFailover - // - - /// - /// used to block two scenarios if MultiSubnetFailover is true: - /// * server-provided failover partner - raising SqlException in this case - /// * connection string with failover partner and MultiSubnetFailover=true - raising argument one in this case with the same message - /// - internal static Exception MultiSubnetFailoverWithFailoverPartner(bool serverProvidedFailoverPartner, SqlInternalConnectionTds internalConnection) - { - string msg = StringsHelper.GetString(Strings.SQLMSF_FailoverPartnerNotSupported); - if (serverProvidedFailoverPartner) - { - // Replacing InvalidOperation with SQL exception - SqlErrorCollection errors = new SqlErrorCollection(); - errors.Add(new SqlError(0, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, null, msg, "", 0)); - SqlException exc = SqlException.CreateException(errors, null, internalConnection, innerException: null, batchCommand: null); - exc._doNotReconnect = true; // disable open retry logic on this error - return exc; - } - else - { - return ADP.Argument(msg); - } - } - - internal static Exception MultiSubnetFailoverWithMoreThan64IPs() - { - string msg = GetSNIErrorMessage((int)SNINativeMethodWrapper.SniSpecialErrors.MultiSubnetFailoverWithMoreThan64IPs); - return ADP.InvalidOperation(msg); - } - - internal static Exception MultiSubnetFailoverWithInstanceSpecified() - { - string msg = GetSNIErrorMessage((int)SNINativeMethodWrapper.SniSpecialErrors.MultiSubnetFailoverWithInstanceSpecified); - return ADP.Argument(msg); - } - - internal static Exception MultiSubnetFailoverWithNonTcpProtocol() - { - string msg = GetSNIErrorMessage((int)SNINativeMethodWrapper.SniSpecialErrors.MultiSubnetFailoverWithNonTcpProtocol); - return ADP.Argument(msg); - } - - // - // Read-only routing - // - - internal static Exception ROR_FailoverNotSupportedConnString() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQLROR_FailoverNotSupported)); - } - - internal static Exception ROR_FailoverNotSupportedServer(SqlInternalConnectionTds internalConnection) - { - SqlErrorCollection errors = new SqlErrorCollection(); - errors.Add(new SqlError(0, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, null, (StringsHelper.GetString(Strings.SQLROR_FailoverNotSupported)), "", 0)); - SqlException exc = SqlException.CreateException(errors, null, internalConnection, innerException: null, batchCommand: null); - exc._doNotReconnect = true; - return exc; - } - - internal static Exception ROR_RecursiveRoutingNotSupported(SqlInternalConnectionTds internalConnection) - { - SqlErrorCollection errors = new SqlErrorCollection(); - errors.Add(new SqlError(0, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, null, (StringsHelper.GetString(Strings.SQLROR_RecursiveRoutingNotSupported)), "", 0)); - SqlException exc = SqlException.CreateException(errors, null, internalConnection, innerException: null, batchCommand: null); - exc._doNotReconnect = true; - return exc; - } - - internal static Exception ROR_UnexpectedRoutingInfo(SqlInternalConnectionTds internalConnection) - { - SqlErrorCollection errors = new SqlErrorCollection(); - errors.Add(new SqlError(0, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, null, (StringsHelper.GetString(Strings.SQLROR_UnexpectedRoutingInfo)), "", 0)); - SqlException exc = SqlException.CreateException(errors, null, internalConnection, innerException: null, batchCommand: null); - exc._doNotReconnect = true; - return exc; - } - - internal static Exception ROR_InvalidRoutingInfo(SqlInternalConnectionTds internalConnection) - { - SqlErrorCollection errors = new SqlErrorCollection(); - errors.Add(new SqlError(0, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, null, (StringsHelper.GetString(Strings.SQLROR_InvalidRoutingInfo)), "", 0)); - SqlException exc = SqlException.CreateException(errors, null, internalConnection, innerException: null, batchCommand: null); - exc._doNotReconnect = true; - return exc; - } - - internal static Exception ROR_TimeoutAfterRoutingInfo(SqlInternalConnectionTds internalConnection) - { - SqlErrorCollection errors = new SqlErrorCollection(); - errors.Add(new SqlError(0, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, null, (StringsHelper.GetString(Strings.SQLROR_TimeoutAfterRoutingInfo)), "", 0)); - SqlException exc = SqlException.CreateException(errors, null, internalConnection, innerException: null, batchCommand: null); - exc._doNotReconnect = true; - return exc; - } - - // - // Connection resiliency - // - internal static SqlException CR_ReconnectTimeout() - { - SqlErrorCollection errors = new SqlErrorCollection(); - errors.Add(new SqlError(TdsEnums.TIMEOUT_EXPIRED, (byte)0x00, TdsEnums.MIN_ERROR_CLASS, null, SQLMessage.Timeout(), "", 0, TdsEnums.SNI_WAIT_TIMEOUT)); - SqlException exc = SqlException.CreateException(errors, ""); - return exc; - } - - internal static SqlException CR_ReconnectionCancelled() - { - SqlErrorCollection errors = new SqlErrorCollection(); - errors.Add(new SqlError(0, 0, TdsEnums.MIN_ERROR_CLASS, null, SQLMessage.OperationCancelled(), "", 0)); - SqlException exc = SqlException.CreateException(errors, ""); - return exc; - } - - internal static Exception CR_NextAttemptWillExceedQueryTimeout(SqlException innerException, Guid connectionId) - { - SqlErrorCollection errors = new SqlErrorCollection(); - errors.Add(new SqlError(0, 0, TdsEnums.MIN_ERROR_CLASS, null, StringsHelper.GetString(Strings.SQLCR_NextAttemptWillExceedQueryTimeout), "", 0)); - SqlException exc = SqlException.CreateException(errors, "", connectionId, innerException); - return exc; - } - - internal static Exception CR_EncryptionChanged(SqlInternalConnectionTds internalConnection) - { - SqlErrorCollection errors = new SqlErrorCollection(); - errors.Add(new SqlError(0, 0, TdsEnums.FATAL_ERROR_CLASS, null, StringsHelper.GetString(Strings.SQLCR_EncryptionChanged), "", 0)); - SqlException exc = SqlException.CreateException(errors, "", internalConnection, innerException: null, batchCommand: null); - return exc; - } - - internal static SqlException CR_AllAttemptsFailed(SqlException innerException, Guid connectionId) - { - SqlErrorCollection errors = new SqlErrorCollection(); - errors.Add(new SqlError(0, 0, TdsEnums.MIN_ERROR_CLASS, null, StringsHelper.GetString(Strings.SQLCR_AllAttemptsFailed), "", 0)); - SqlException exc = SqlException.CreateException(errors, "", connectionId, innerException, batchCommand: null); - return exc; - } - - internal static SqlException CR_NoCRAckAtReconnection(SqlInternalConnectionTds internalConnection) - { - SqlErrorCollection errors = new SqlErrorCollection(); - errors.Add(new SqlError(0, 0, TdsEnums.FATAL_ERROR_CLASS, null, StringsHelper.GetString(Strings.SQLCR_NoCRAckAtReconnection), "", 0)); - SqlException exc = SqlException.CreateException(errors, "", internalConnection, innerException: null, batchCommand: null); - return exc; - } - - internal static SqlException CR_TDSVersionNotPreserved(SqlInternalConnectionTds internalConnection) - { - SqlErrorCollection errors = new SqlErrorCollection(); - errors.Add(new SqlError(0, 0, TdsEnums.FATAL_ERROR_CLASS, null, StringsHelper.GetString(Strings.SQLCR_TDSVestionNotPreserved), "", 0)); - SqlException exc = SqlException.CreateException(errors, "", internalConnection, innerException: null, batchCommand: null); - return exc; - } - - internal static SqlException CR_UnrecoverableServer(Guid connectionId) - { - SqlErrorCollection errors = new SqlErrorCollection(); - errors.Add(new SqlError(0, 0, TdsEnums.FATAL_ERROR_CLASS, null, StringsHelper.GetString(Strings.SQLCR_UnrecoverableServer), "", 0)); - SqlException exc = SqlException.CreateException(errors, "", connectionId, innerException: null, batchCommand: null); - return exc; - } - - internal static SqlException CR_UnrecoverableClient(Guid connectionId) - { - SqlErrorCollection errors = new SqlErrorCollection(); - errors.Add(new SqlError(0, 0, TdsEnums.FATAL_ERROR_CLASS, null, StringsHelper.GetString(Strings.SQLCR_UnrecoverableClient), "", 0)); - SqlException exc = SqlException.CreateException(errors, "", connectionId, innerException: null, batchCommand: null); - return exc; - } - - internal static Exception StreamWriteNotSupported() - { - return ADP.NotSupported(StringsHelper.GetString(Strings.SQL_StreamWriteNotSupported)); - } - internal static Exception StreamReadNotSupported() - { - return ADP.NotSupported(StringsHelper.GetString(Strings.SQL_StreamReadNotSupported)); - } - internal static Exception StreamSeekNotSupported() - { - return ADP.NotSupported(StringsHelper.GetString(Strings.SQL_StreamSeekNotSupported)); - } - internal static System.Data.SqlTypes.SqlNullValueException SqlNullValue() - { - System.Data.SqlTypes.SqlNullValueException e = new System.Data.SqlTypes.SqlNullValueException(); - return e; - } - internal static Exception SubclassMustOverride() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlMisc_SubclassMustOverride)); - } - - // ProjectK\CoreCLR specific errors - internal static Exception UnsupportedKeyword(string keyword) - { - return ADP.NotSupported(StringsHelper.GetString(Strings.SQL_UnsupportedKeyword, keyword)); - } - internal static Exception NetworkLibraryKeywordNotSupported() - { - return ADP.NotSupported(StringsHelper.GetString(Strings.SQL_NetworkLibraryNotSupported)); - } - internal static Exception UnsupportedFeatureAndToken(SqlInternalConnectionTds internalConnection, string token) - { - var innerException = ADP.NotSupported(StringsHelper.GetString(Strings.SQL_UnsupportedToken, token)); - - SqlErrorCollection errors = new SqlErrorCollection(); - errors.Add(new SqlError(0, 0, TdsEnums.FATAL_ERROR_CLASS, null, StringsHelper.GetString(Strings.SQL_UnsupportedFeature), "", 0)); - SqlException exc = SqlException.CreateException(errors, "", internalConnection, innerException); - return exc; - } - - internal static Exception BatchedUpdatesNotAvailableOnContextConnection() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BatchedUpdatesNotAvailableOnContextConnection)); - } - internal static Exception Azure_ManagedIdentityException(string msg) - { - SqlErrorCollection errors = new SqlErrorCollection - { - new SqlError(0, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, null, msg, "", 0) - }; - SqlException exc = SqlException.CreateException(errors, null); - exc._doNotReconnect = true; // disable open retry logic on this error - return exc; - } - - #region Always Encrypted Errors - - #region Always Encrypted - Certificate Store Provider Errors - internal static Exception InvalidKeyEncryptionAlgorithm(string encryptionAlgorithm, string validEncryptionAlgorithm, bool isSystemOp) - { - string message = isSystemOp ? Strings.TCE_InvalidKeyEncryptionAlgorithmSysErr : Strings.TCE_InvalidKeyEncryptionAlgorithm; - return ADP.Argument(StringsHelper.GetString(message, encryptionAlgorithm, validEncryptionAlgorithm), TdsEnums.TCE_PARAM_ENCRYPTION_ALGORITHM); - } - - internal static Exception NullKeyEncryptionAlgorithm(bool isSystemOp) - { - string message = isSystemOp ? Strings.TCE_NullKeyEncryptionAlgorithmSysErr : Strings.TCE_NullKeyEncryptionAlgorithm; - return ADP.ArgumentNull(TdsEnums.TCE_PARAM_ENCRYPTION_ALGORITHM, StringsHelper.GetString(message)); - } - - internal static Exception EmptyColumnEncryptionKey() - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_EmptyColumnEncryptionKey), TdsEnums.TCE_PARAM_COLUMNENCRYPTION_KEY); - } - - internal static Exception NullColumnEncryptionKey() - { - return ADP.ArgumentNull(TdsEnums.TCE_PARAM_COLUMNENCRYPTION_KEY, StringsHelper.GetString(Strings.TCE_NullColumnEncryptionKey)); - } - - internal static Exception EmptyEncryptedColumnEncryptionKey() - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_EmptyEncryptedColumnEncryptionKey), TdsEnums.TCE_PARAM_ENCRYPTED_CEK); - } - - internal static Exception NullEncryptedColumnEncryptionKey() - { - return ADP.ArgumentNull(TdsEnums.TCE_PARAM_ENCRYPTED_CEK, StringsHelper.GetString(Strings.TCE_NullEncryptedColumnEncryptionKey)); - } - - internal static Exception LargeCertificatePathLength(int actualLength, int maxLength, bool isSystemOp) - { - string message = isSystemOp ? Strings.TCE_LargeCertificatePathLengthSysErr : Strings.TCE_LargeCertificatePathLength; - return ADP.Argument(StringsHelper.GetString(message, actualLength, maxLength), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - - } - - internal static Exception NullCertificatePath(string[] validLocations, bool isSystemOp) - { - Debug.Assert(2 == validLocations.Length); - string message = isSystemOp ? Strings.TCE_NullCertificatePathSysErr : Strings.TCE_NullCertificatePath; - return ADP.ArgumentNull(TdsEnums.TCE_PARAM_MASTERKEY_PATH, StringsHelper.GetString(message, validLocations[0], validLocations[1], @"/")); - } - - internal static Exception NullCspKeyPath(bool isSystemOp) - { - string message = isSystemOp ? Strings.TCE_NullCspPathSysErr : Strings.TCE_NullCspPath; - return ADP.ArgumentNull(TdsEnums.TCE_PARAM_MASTERKEY_PATH, StringsHelper.GetString(message, @"/")); - } - - internal static Exception NullCngKeyPath(bool isSystemOp) - { - string message = isSystemOp ? Strings.TCE_NullCngPathSysErr : Strings.TCE_NullCngPath; - return ADP.ArgumentNull(TdsEnums.TCE_PARAM_MASTERKEY_PATH, StringsHelper.GetString(message, @"/")); - } - - internal static Exception InvalidCertificatePath(string actualCertificatePath, string[] validLocations, bool isSystemOp) - { - Debug.Assert(2 == validLocations.Length); - string message = isSystemOp ? Strings.TCE_InvalidCertificatePathSysErr : Strings.TCE_InvalidCertificatePath; - return ADP.Argument(StringsHelper.GetString(message, actualCertificatePath, validLocations[0], validLocations[1], @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - - internal static Exception InvalidCspPath(string masterKeyPath, bool isSystemOp) - { - string message = isSystemOp ? Strings.TCE_InvalidCspPathSysErr : Strings.TCE_InvalidCspPath; - return ADP.Argument(StringsHelper.GetString(message, masterKeyPath, @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - - internal static Exception InvalidCngPath(string masterKeyPath, bool isSystemOp) - { - string message = isSystemOp ? Strings.TCE_InvalidCngPathSysErr : Strings.TCE_InvalidCngPath; - return ADP.Argument(StringsHelper.GetString(message, masterKeyPath, @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - - internal static Exception EmptyCspName(string masterKeyPath, bool isSystemOp) - { - string message = isSystemOp ? Strings.TCE_EmptyCspNameSysErr : Strings.TCE_EmptyCspName; - return ADP.Argument(StringsHelper.GetString(message, masterKeyPath, @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - - internal static Exception EmptyCngName(string masterKeyPath, bool isSystemOp) - { - string message = isSystemOp ? Strings.TCE_EmptyCngNameSysErr : Strings.TCE_EmptyCngName; - return ADP.Argument(StringsHelper.GetString(message, masterKeyPath, @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - - internal static Exception EmptyCspKeyId(string masterKeyPath, bool isSystemOp) - { - string message = isSystemOp ? Strings.TCE_EmptyCspKeyIdSysErr : Strings.TCE_EmptyCspKeyId; - return ADP.Argument(StringsHelper.GetString(message, masterKeyPath, @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - - internal static Exception EmptyCngKeyId(string masterKeyPath, bool isSystemOp) - { - string message = isSystemOp ? Strings.TCE_EmptyCngKeyIdSysErr : Strings.TCE_EmptyCngKeyId; - return ADP.Argument(StringsHelper.GetString(message, masterKeyPath, @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - - internal static Exception InvalidCspName(string cspName, string masterKeyPath, bool isSystemOp) - { - string message = isSystemOp ? Strings.TCE_InvalidCspNameSysErr : Strings.TCE_InvalidCspName; - return ADP.Argument(StringsHelper.GetString(message, cspName, masterKeyPath), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - - internal static Exception InvalidCspKeyIdentifier(string keyIdentifier, string masterKeyPath, bool isSystemOp) - { - string message = isSystemOp ? Strings.TCE_InvalidCspKeyIdSysErr : Strings.TCE_InvalidCspKeyId; - return ADP.Argument(StringsHelper.GetString(message, keyIdentifier, masterKeyPath), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - - internal static Exception InvalidCngKey(string masterKeyPath, string cngProviderName, string keyIdentifier, bool isSystemOp) - { - string message = isSystemOp ? Strings.TCE_InvalidCngKeySysErr : Strings.TCE_InvalidCngKey; - return ADP.Argument(StringsHelper.GetString(message, masterKeyPath, cngProviderName, keyIdentifier), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - - internal static Exception InvalidCertificateLocation(string certificateLocation, string certificatePath, string[] validLocations, bool isSystemOp) - { - string message = isSystemOp ? Strings.TCE_InvalidCertificateLocationSysErr : Strings.TCE_InvalidCertificateLocation; - return ADP.Argument(StringsHelper.GetString(message, certificateLocation, certificatePath, validLocations[0], validLocations[1], @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - - internal static Exception InvalidCertificateStore(string certificateStore, string certificatePath, string validCertificateStore, bool isSystemOp) - { - string message = isSystemOp ? Strings.TCE_InvalidCertificateStoreSysErr : Strings.TCE_InvalidCertificateStore; - return ADP.Argument(StringsHelper.GetString(message, certificateStore, certificatePath, validCertificateStore), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - - internal static Exception EmptyCertificateThumbprint(string certificatePath, bool isSystemOp) - { - string message = isSystemOp ? Strings.TCE_EmptyCertificateThumbprintSysErr : Strings.TCE_EmptyCertificateThumbprint; - return ADP.Argument(StringsHelper.GetString(message, certificatePath), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - - internal static Exception CertificateNotFound(string thumbprint, string certificateLocation, string certificateStore, bool isSystemOp) - { - string message = isSystemOp ? Strings.TCE_CertificateNotFoundSysErr : Strings.TCE_CertificateNotFound; - return ADP.Argument(StringsHelper.GetString(message, thumbprint, certificateLocation, certificateStore), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - - internal static Exception InvalidAlgorithmVersionInEncryptedCEK(byte actual, byte expected) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidAlgorithmVersionInEncryptedCEK, actual.ToString(@"X2"), expected.ToString(@"X2")), TdsEnums.TCE_PARAM_ENCRYPTED_CEK); - } - - internal static Exception InvalidCiphertextLengthInEncryptedCEK(int actual, int expected, string certificateName) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCiphertextLengthInEncryptedCEK, actual, expected, certificateName), TdsEnums.TCE_PARAM_ENCRYPTED_CEK); - } - - internal static Exception InvalidCiphertextLengthInEncryptedCEKCsp(int actual, int expected, string masterKeyPath) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCiphertextLengthInEncryptedCEKCsp, actual, expected, masterKeyPath), TdsEnums.TCE_PARAM_ENCRYPTED_CEK); - } - - internal static Exception InvalidCiphertextLengthInEncryptedCEKCng(int actual, int expected, string masterKeyPath) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCiphertextLengthInEncryptedCEKCng, actual, expected, masterKeyPath), TdsEnums.TCE_PARAM_ENCRYPTED_CEK); - } - - internal static Exception InvalidSignatureInEncryptedCEK(int actual, int expected, string masterKeyPath) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidSignatureInEncryptedCEK, actual, expected, masterKeyPath), TdsEnums.TCE_PARAM_ENCRYPTED_CEK); - } - - internal static Exception InvalidSignatureInEncryptedCEKCsp(int actual, int expected, string masterKeyPath) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidSignatureInEncryptedCEKCsp, actual, expected, masterKeyPath), TdsEnums.TCE_PARAM_ENCRYPTED_CEK); - } - - internal static Exception InvalidSignatureInEncryptedCEKCng(int actual, int expected, string masterKeyPath) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidSignatureInEncryptedCEKCng, actual, expected, masterKeyPath), TdsEnums.TCE_PARAM_ENCRYPTED_CEK); - } - - internal static Exception InvalidCertificateSignature(string certificatePath) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCertificateSignature, certificatePath), TdsEnums.TCE_PARAM_ENCRYPTED_CEK); - } - - internal static Exception InvalidSignature(string masterKeyPath) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidSignature, masterKeyPath), TdsEnums.TCE_PARAM_ENCRYPTED_CEK); - } - - internal static Exception CertificateWithNoPrivateKey(string keyPath, bool isSystemOp) - { - string message = isSystemOp ? Strings.TCE_CertificateWithNoPrivateKeySysErr : Strings.TCE_CertificateWithNoPrivateKey; - return ADP.Argument(StringsHelper.GetString(message, keyPath), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - #endregion Always Encrypted - Certificate Store Provider Errors - - #region Always Encrypted - Cryptographic Algorithms Error messages - internal static Exception NullPlainText() - { - return ADP.ArgumentNull(StringsHelper.GetString(Strings.TCE_NullPlainText)); - } - - internal static Exception NullCipherText() - { - return ADP.ArgumentNull(StringsHelper.GetString(Strings.TCE_NullCipherText)); - } - - internal static Exception NullColumnEncryptionAlgorithm(string supportedAlgorithms) - { - return ADP.ArgumentNull(TdsEnums.TCE_PARAM_ENCRYPTION_ALGORITHM, StringsHelper.GetString(Strings.TCE_NullColumnEncryptionAlgorithm, supportedAlgorithms)); - } - - internal static Exception NullColumnEncryptionKeySysErr() - { - return ADP.ArgumentNull(TdsEnums.TCE_PARAM_ENCRYPTIONKEY, StringsHelper.GetString(Strings.TCE_NullColumnEncryptionKeySysErr)); - } - - internal static Exception InvalidKeySize(string algorithmName, int actualKeylength, int expectedLength) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidKeySize, algorithmName, actualKeylength, expectedLength), TdsEnums.TCE_PARAM_ENCRYPTIONKEY); - } - - internal static Exception InvalidEncryptionType(string algorithmName, SqlClientEncryptionType encryptionType, params SqlClientEncryptionType[] validEncryptionTypes) - { - const string valueSeparator = @", "; - return ADP.Argument( - StringsHelper.GetString( - Strings.TCE_InvalidEncryptionType, - algorithmName, - encryptionType.ToString(), - string.Join(valueSeparator, Map(validEncryptionTypes, static validEncryptionType => $"'{validEncryptionType:G}'")) - ), - TdsEnums.TCE_PARAM_ENCRYPTIONTYPE - ); - } - - internal static Exception InvalidCipherTextSize(int actualSize, int minimumSize) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCipherTextSize, actualSize, minimumSize), TdsEnums.TCE_PARAM_CIPHERTEXT); - } - - internal static Exception InvalidAlgorithmVersion(byte actual, byte expected) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidAlgorithmVersion, actual.ToString(@"X2"), expected.ToString(@"X2")), TdsEnums.TCE_PARAM_CIPHERTEXT); - } - - internal static Exception InvalidAuthenticationTag() - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidAuthenticationTag), TdsEnums.TCE_PARAM_CIPHERTEXT); - } - #endregion Always Encrypted - Cryptographic Algorithms Error messages - - #region Always Encrypted - Errors from sp_describe_parameter_encryption - internal static Exception UnexpectedDescribeParamFormatParameterMetadata() - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_UnexpectedDescribeParamFormatParameterMetadata, "sp_describe_parameter_encryption")); - } - - internal static Exception UnexpectedDescribeParamFormatAttestationInfo(string enclaveType) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_UnexpectedDescribeParamFormatAttestationInfo, "sp_describe_parameter_encryption", enclaveType)); - } - - internal static Exception InvalidEncryptionKeyOrdinalEnclaveMetadata(int ordinal, int maxOrdinal) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_InvalidEncryptionKeyOrdinalEnclaveMetadata, ordinal, maxOrdinal)); - } - - internal static Exception InvalidEncryptionKeyOrdinalParameterMetadata(int ordinal, int maxOrdinal) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_InvalidEncryptionKeyOrdinalParameterMetadata, ordinal, maxOrdinal)); - } - - public static Exception MultipleRowsReturnedForAttestationInfo() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_MultipleRowsReturnedForAttestationInfo, "sp_describe_parameter_encryption")); - } - - internal static Exception ParamEncryptionMetadataMissing(string paramName, string procedureName) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_ParamEncryptionMetaDataMissing, "sp_describe_parameter_encryption", paramName, procedureName)); - } - - internal static Exception ProcEncryptionMetadataMissing(string procedureName) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_ProcEncryptionMetaDataMissing, "sp_describe_parameter_encryption", procedureName)); - } - - internal static Exception UnableToVerifyColumnMasterKeySignature(Exception innerException) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_UnableToVerifyColumnMasterKeySignature, innerException.Message), innerException); - } - - internal static Exception ColumnMasterKeySignatureVerificationFailed(string cmkPath) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_ColumnMasterKeySignatureVerificationFailed, cmkPath)); - } - - internal static Exception InvalidKeyStoreProviderName(string providerName, List systemProviders, List customProviders) - { - const string valueSeparator = @", "; - string systemProviderStr = string.Join(valueSeparator, Map(systemProviders, static provider => $"'{provider}'")); - string customProviderStr = string.Join(valueSeparator, Map(customProviders, static provider => $"'{provider}'")); - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidKeyStoreProviderName, providerName, systemProviderStr, customProviderStr)); - } - - internal static Exception ParamInvalidForceColumnEncryptionSetting(string paramName, string procedureName) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_ParamInvalidForceColumnEncryptionSetting, TdsEnums.TCE_PARAM_FORCE_COLUMN_ENCRYPTION, paramName, procedureName, "SqlParameter")); - } - - internal static Exception ParamUnExpectedEncryptionMetadata(string paramName, string procedureName) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_ParamUnExpectedEncryptionMetadata, paramName, procedureName, TdsEnums.TCE_PARAM_FORCE_COLUMN_ENCRYPTION, "SqlParameter")); - } - - internal static Exception ColumnMasterKeySignatureNotFound(string cmkPath) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_ColumnMasterKeySignatureNotFound, cmkPath)); - } - #endregion Always Encrypted - Errors from sp_describe_parameter_encryption - - #region Always Encrypted - Errors from secure channel Communication - - internal static Exception ExceptionWhenGeneratingEnclavePackage(Exception innerException) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_ExceptionWhenGeneratingEnclavePackage, innerException.Message), innerException); - } - - internal static Exception FailedToEncryptRegisterRulesBytePackage(Exception innerException) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_FailedToEncryptRegisterRulesBytePackage, innerException.Message), innerException); - } - - internal static Exception InvalidKeyIdUnableToCastToUnsignedShort(int keyId, Exception innerException) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidKeyIdUnableToCastToUnsignedShort, keyId, innerException.Message), innerException); - } - - internal static Exception InvalidDatabaseIdUnableToCastToUnsignedInt(int databaseId, Exception innerException) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidDatabaseIdUnableToCastToUnsignedInt, databaseId, innerException.Message), innerException); - } - - internal static Exception InvalidAttestationParameterUnableToConvertToUnsignedInt(string variableName, int intValue, string enclaveType, Exception innerException) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidAttestationParameterUnableToConvertToUnsignedInt, enclaveType, intValue, variableName, innerException.Message), innerException); - } - - internal static Exception OffsetOutOfBounds(string argument, string type, string method) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_OffsetOutOfBounds, type, method)); - } - - internal static Exception InsufficientBuffer(string argument, string type, string method) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InsufficientBuffer, argument, type, method)); - } - - internal static Exception ColumnEncryptionKeysNotFound() - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_ColumnEncryptionKeysNotFound)); - } - - #endregion Always Encrypted - Errors from secure channel Communication - - #region Always Encrypted - Errors when performing attestation - internal static Exception AttestationInfoNotReturnedFromSqlServer(string enclaveType, string enclaveAttestationUrl) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_AttestationInfoNotReturnedFromSQLServer, enclaveType, enclaveAttestationUrl)); - } - - internal static SqlException AttestationFailed(string errorMessage, Exception innerException = null) - { - SqlErrorCollection errors = new(); - errors.Add(new SqlError( - infoNumber: 0, - errorState: 0, - errorClass: 0, - server: null, - errorMessage, - procedure: string.Empty, - lineNumber: 0)); - return SqlException.CreateException(errors, serverVersion: string.Empty, Guid.Empty, innerException); - } - - #endregion Always Encrypted - Errors when performing attestation - - #region Always Encrypted - Errors when establishing secure channel - internal static Exception NullArgumentInConstructorInternal(string argumentName, string objectUnderConstruction) - { - return ADP.ArgumentNull(argumentName, StringsHelper.GetString(Strings.TCE_NullArgumentInConstructorInternal, argumentName, objectUnderConstruction)); - } - - internal static Exception EmptyArgumentInConstructorInternal(string argumentName, string objectUnderConstruction) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_EmptyArgumentInConstructorInternal, argumentName, objectUnderConstruction)); - } - - internal static Exception NullArgumentInternal(string argumentName, string type, string method) - { - return ADP.ArgumentNull(argumentName, StringsHelper.GetString(Strings.TCE_NullArgumentInternal, argumentName, type, method)); - } - - internal static Exception EmptyArgumentInternal(string argumentName, string type, string method) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_EmptyArgumentInternal, argumentName, type, method)); - } - #endregion Always Encrypted - Errors when establishing secure channel - - #region Always Encrypted - Enclave provider/configuration errors - - internal static Exception CannotGetSqlColumnEncryptionEnclaveProviderConfig(Exception innerException) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_CannotGetSqlColumnEncryptionEnclaveProviderConfig, innerException.Message), innerException); - } - - internal static Exception CannotCreateSqlColumnEncryptionEnclaveProvider(string providerName, string type, Exception innerException) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_CannotCreateSqlColumnEncryptionEnclaveProvider, providerName, type, innerException.Message), innerException); - } - - internal static Exception SqlColumnEncryptionEnclaveProviderNameCannotBeEmpty() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_SqlColumnEncryptionEnclaveProviderNameCannotBeEmpty)); - } - - internal static Exception NoAttestationUrlSpecifiedForEnclaveBasedQuerySpDescribe(string enclaveType) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_NoAttestationUrlSpecifiedForEnclaveBasedQuerySpDescribe, "sp_describe_parameter_encryption", enclaveType)); - } - - internal static Exception NoAttestationUrlSpecifiedForEnclaveBasedQueryGeneratingEnclavePackage(string enclaveType) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_NoAttestationUrlSpecifiedForEnclaveBasedQueryGeneratingEnclavePackage, enclaveType)); - } - - internal static Exception EnclaveTypeNullForEnclaveBasedQuery() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_EnclaveTypeNullForEnclaveBasedQuery)); - } - - internal static Exception EnclaveProvidersNotConfiguredForEnclaveBasedQuery() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_EnclaveProvidersNotConfiguredForEnclaveBasedQuery)); - } - - internal static Exception EnclaveProviderNotFound(string enclaveType) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_EnclaveProviderNotFound, enclaveType)); - } - - internal static Exception NullEnclaveSessionReturnedFromProvider(string enclaveType, string attestationUrl) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_NullEnclaveSessionReturnedFromProvider, enclaveType, attestationUrl)); - } - - #endregion Always Encrypted - Enclave provider/configuration errors - - #region Always Encrypted - Generic toplevel failures - - internal static Exception GetExceptionArray(string serverName, string errorMessage, Exception e) - { - // Create and throw an exception array - SqlErrorCollection sqlErs = new SqlErrorCollection(); - Exception exceptionToInclude = (null != e.InnerException) ? e.InnerException : e; - sqlErs.Add(new SqlError(infoNumber: 0, errorState: (byte)0x00, errorClass: (byte)TdsEnums.MIN_ERROR_CLASS, server: serverName, errorMessage: errorMessage, procedure: null, lineNumber: 0)); - - if (e is SqlException) - { - SqlException exThrown = (SqlException)e; - SqlErrorCollection errorList = exThrown.Errors; - for (int i = 0; i < exThrown.Errors.Count; i++) - { - sqlErs.Add(errorList[i]); - } - } - else - { - sqlErs.Add(new SqlError(infoNumber: 0, errorState: (byte)0x00, errorClass: (byte)TdsEnums.MIN_ERROR_CLASS, server: serverName, errorMessage: e.Message, procedure: null, lineNumber: 0)); - } - - return SqlException.CreateException(sqlErs, "", null, exceptionToInclude); - } - - internal static Exception ColumnDecryptionFailed(string columnName, string serverName, Exception e) - { - return GetExceptionArray(serverName, StringsHelper.GetString(Strings.TCE_ColumnDecryptionFailed, columnName), e); - } - - internal static Exception ParamEncryptionFailed(string paramName, string serverName, Exception e) - { - return GetExceptionArray(serverName, StringsHelper.GetString(Strings.TCE_ParamEncryptionFailed, paramName), e); - } - - internal static Exception ParamDecryptionFailed(string paramName, string serverName, Exception e) - { - return GetExceptionArray(serverName, StringsHelper.GetString(Strings.TCE_ParamDecryptionFailed, paramName), e); - } - #endregion Always Encrypted - Generic toplevel failures - - #region Always Encrypted - Client side query processing errors - - internal static Exception UnknownColumnEncryptionAlgorithm(string algorithmName, string supportedAlgorithms) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_UnknownColumnEncryptionAlgorithm, algorithmName, supportedAlgorithms)); - } - - internal static Exception UnknownColumnEncryptionAlgorithmId(int algoId, string supportAlgorithmIds) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_UnknownColumnEncryptionAlgorithmId, algoId, supportAlgorithmIds), TdsEnums.TCE_PARAM_CIPHER_ALGORITHM_ID); - } - - internal static Exception UnsupportedNormalizationVersion(byte version) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_UnsupportedNormalizationVersion, version, "'1'", "SQL Server")); - } - - internal static Exception UnrecognizedKeyStoreProviderName(string providerName, List systemProviders, List customProviders) - { - const string valueSeparator = @", "; - string systemProviderStr = string.Join(valueSeparator, Map(systemProviders, static provider => @"'" + provider + @"'")); - string customProviderStr = string.Join(valueSeparator, Map(customProviders, static provider => @"'" + provider + @"'")); - return ADP.Argument(StringsHelper.GetString(Strings.TCE_UnrecognizedKeyStoreProviderName, providerName, systemProviderStr, customProviderStr)); - } - - internal static Exception InvalidDataTypeForEncryptedParameter(string parameterName, int actualDataType, int expectedDataType) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_NullProviderValue, parameterName, actualDataType, expectedDataType)); - } - - internal static Exception KeyDecryptionFailed(string providerName, string keyHex, Exception e) - { - - if (providerName.Equals(SqlColumnEncryptionCertificateStoreProvider.ProviderName)) - { - return GetExceptionArray(null, StringsHelper.GetString(Strings.TCE_KeyDecryptionFailedCertStore, providerName, keyHex), e); - } - else - { - return GetExceptionArray(null, StringsHelper.GetString(Strings.TCE_KeyDecryptionFailed, providerName, keyHex), e); - } - } - - internal static Exception UntrustedKeyPath(string keyPath, string serverName) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_UntrustedKeyPath, keyPath, serverName)); - } - - internal static Exception UnsupportedDatatypeEncryption(string dataType) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_UnsupportedDatatype, dataType)); - } - - internal static Exception ThrowDecryptionFailed(string keyStr, string valStr, Exception e) - { - return GetExceptionArray(null, StringsHelper.GetString(Strings.TCE_DecryptionFailed, keyStr, valStr), e); - } - - internal static Exception NullEnclaveSessionDuringQueryExecution(string enclaveType, string enclaveAttestationUrl) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_NullEnclaveSessionDuringQueryExecution, enclaveType, enclaveAttestationUrl)); - } - - internal static Exception NullEnclavePackageForEnclaveBasedQuery(string enclaveType, string enclaveAttestationUrl) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_NullEnclavePackageForEnclaveBasedQuery, enclaveType, enclaveAttestationUrl)); - } - - internal static Exception EnclaveProviderNotFound(string enclaveType, string attestationProtocol) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_EnclaveProviderNotFound, enclaveType, attestationProtocol)); - } - - internal static Exception EnclaveTypeNotSupported(string enclaveType) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_EnclaveTypeNotSupported, enclaveType)); - } - - internal static Exception AttestationProtocolNotSupportEnclaveType(string attestationProtocolStr, string enclaveType) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_AttestationProtocolNotSupportEnclaveType, attestationProtocolStr, enclaveType)); - } - - internal static Exception AttestationProtocolNotSpecifiedForGeneratingEnclavePackage() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_AttestationProtocolNotSpecifiedForGeneratingEnclavePackage)); - } - - #endregion Always Encrypted - Client side query processing errors - - #region Always Encrypted - SQL connection related error messages - - internal static Exception TceNotSupported() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_NotSupportedByServer, "SQL Server")); - } - - internal static Exception EnclaveComputationsNotSupported() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_EnclaveComputationsNotSupported)); - } - - internal static Exception AttestationURLNotSupported() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_AttestationURLNotSupported)); - } - - internal static Exception AttestationProtocolNotSupported() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_AttestationProtocolNotSupported)); - } - - internal static Exception EnclaveTypeNotReturned() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_EnclaveTypeNotReturned)); - } - #endregion Always Encrypted - SQL connection related error messages - - #region Always Encrypted - Extensibility related error messages - - internal static Exception CanOnlyCallOnce() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_CanOnlyCallOnce)); - } - - internal static Exception NullCustomKeyStoreProviderDictionary() - { - return ADP.ArgumentNull(TdsEnums.TCE_PARAM_CLIENT_KEYSTORE_PROVIDERS, StringsHelper.GetString(Strings.TCE_NullCustomKeyStoreProviderDictionary)); - } - - internal static Exception InvalidCustomKeyStoreProviderName(string providerName, string prefix) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCustomKeyStoreProviderName, providerName, prefix), TdsEnums.TCE_PARAM_CLIENT_KEYSTORE_PROVIDERS); - } - - internal static Exception NullProviderValue(string providerName) - { - return ADP.ArgumentNull(TdsEnums.TCE_PARAM_CLIENT_KEYSTORE_PROVIDERS, StringsHelper.GetString(Strings.TCE_NullProviderValue, providerName)); - } - - internal static Exception EmptyProviderName() - { - return ADP.ArgumentNull(TdsEnums.TCE_PARAM_CLIENT_KEYSTORE_PROVIDERS, StringsHelper.GetString(Strings.TCE_EmptyProviderName)); - } - #endregion Always Encrypted - Extensibility related error messages - - #endregion Always Encrypted Errors - - /// - /// gets a message for SNI error (sniError must be valid, non-zero error code) - /// - internal static string GetSNIErrorMessage(int sniError) - { - Debug.Assert(sniError > 0 && sniError <= (int)SNINativeMethodWrapper.SniSpecialErrors.MaxErrorValue, "SNI error is out of range"); - - string errorMessageId = string.Format("SNI_ERROR_{0}", sniError); - return StringsHelper.GetResourceString(errorMessageId); - } - - // Default values for SqlDependency and SqlNotificationRequest - internal const int SqlDependencyTimeoutDefault = 0; - internal const int SqlDependencyServerTimeout = 5 * 24 * 3600; // 5 days - used to compute default TTL of the dependency - internal const string SqlNotificationServiceDefault = "SqlQueryNotificationService"; - internal const string SqlNotificationStoredProcedureDefault = "SqlQueryNotificationStoredProcedure"; - - private static IEnumerable Map(IEnumerable source, Func selector) - { - if (source == null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (selector == null) - { - throw new ArgumentNullException(nameof(selector)); - } - - foreach (T element in source) - { - yield return selector(element); - } - } - } - - sealed internal class SQLMessage - { - private SQLMessage() { /* prevent utility class from being instantiated*/ } - - // The class SQLMessage defines the error messages that are specific to the SqlDataAdapter - // that are caused by a netlib error. The functions will be called and then return the - // appropriate error message from the resource Framework.txt. The SqlDataAdapter will then - // take the error message and then create a SqlError for the message and then place - // that into a SqlException that is either thrown to the user or cached for throwing at - // a later time. This class is used so that there will be compile time checking of error - // messages. The resource Framework.txt will ensure proper string text based on the appropriate - // locale. - - internal static string CultureIdError() - { - return StringsHelper.GetString(Strings.SQL_CultureIdError); - } - internal static string EncryptionNotSupportedByClient() - { - return StringsHelper.GetString(Strings.SQL_EncryptionNotSupportedByClient); - } - internal static string EncryptionNotSupportedByServer() - { - return StringsHelper.GetString(Strings.SQL_EncryptionNotSupportedByServer); - } - internal static string OperationCancelled() - { - return StringsHelper.GetString(Strings.SQL_OperationCancelled); - } - internal static string SevereError() - { - return StringsHelper.GetString(Strings.SQL_SevereError); - } - internal static string SSPIInitializeError() - { - return StringsHelper.GetString(Strings.SQL_SSPIInitializeError); - } - internal static string SSPIGenerateError() - { - return StringsHelper.GetString(Strings.SQL_SSPIGenerateError); - } - internal static string KerberosTicketMissingError() - { - return StringsHelper.GetString(Strings.SQL_KerberosTicketMissingError); - } - internal static string Timeout() - { - return StringsHelper.GetString(Strings.SQL_Timeout_Execution); - } - internal static string Timeout_PreLogin_Begin() - { - return StringsHelper.GetString(Strings.SQL_Timeout_PreLogin_Begin); - } - internal static string Timeout_PreLogin_InitializeConnection() - { - return StringsHelper.GetString(Strings.SQL_Timeout_PreLogin_InitializeConnection); - } - internal static string Timeout_PreLogin_SendHandshake() - { - return StringsHelper.GetString(Strings.SQL_Timeout_PreLogin_SendHandshake); - } - internal static string Timeout_PreLogin_ConsumeHandshake() - { - return StringsHelper.GetString(Strings.SQL_Timeout_PreLogin_ConsumeHandshake); - } - internal static string Timeout_Login_Begin() - { - return StringsHelper.GetString(Strings.SQL_Timeout_Login_Begin); - } - internal static string Timeout_Login_ProcessConnectionAuth() - { - return StringsHelper.GetString(Strings.SQL_Timeout_Login_ProcessConnectionAuth); - } - internal static string Timeout_PostLogin() - { - return StringsHelper.GetString(Strings.SQL_Timeout_PostLogin); - } - internal static string Timeout_FailoverInfo() - { - return StringsHelper.GetString(Strings.SQL_Timeout_FailoverInfo); - } - internal static string Timeout_RoutingDestination() - { - return StringsHelper.GetString(Strings.SQL_Timeout_RoutingDestinationInfo); - } - internal static string Duration_PreLogin_Begin(long PreLoginBeginDuration) - { - return StringsHelper.GetString(Strings.SQL_Duration_PreLogin_Begin, PreLoginBeginDuration); - } - internal static string Duration_PreLoginHandshake(long PreLoginBeginDuration, long PreLoginHandshakeDuration) - { - return StringsHelper.GetString(Strings.SQL_Duration_PreLoginHandshake, PreLoginBeginDuration, PreLoginHandshakeDuration); - } - internal static string Duration_Login_Begin(long PreLoginBeginDuration, long PreLoginHandshakeDuration, long LoginBeginDuration) - { - return StringsHelper.GetString(Strings.SQL_Duration_Login_Begin, PreLoginBeginDuration, PreLoginHandshakeDuration, LoginBeginDuration); - } - internal static string Duration_Login_ProcessConnectionAuth(long PreLoginBeginDuration, long PreLoginHandshakeDuration, long LoginBeginDuration, long LoginAuthDuration) - { - return StringsHelper.GetString(Strings.SQL_Duration_Login_ProcessConnectionAuth, PreLoginBeginDuration, PreLoginHandshakeDuration, LoginBeginDuration, LoginAuthDuration); - } - internal static string Duration_PostLogin(long PreLoginBeginDuration, long PreLoginHandshakeDuration, long LoginBeginDuration, long LoginAuthDuration, long PostLoginDuration) - { - return StringsHelper.GetString(Strings.SQL_Duration_PostLogin, PreLoginBeginDuration, PreLoginHandshakeDuration, LoginBeginDuration, LoginAuthDuration, PostLoginDuration); - } - internal static string UserInstanceFailure() - { - return StringsHelper.GetString(Strings.SQL_UserInstanceFailure); - } - internal static string PreloginError() - { - return StringsHelper.GetString(Strings.Snix_PreLogin); - } - internal static string ExClientConnectionId() - { - return StringsHelper.GetString(Strings.SQL_ExClientConnectionId); - } - internal static string ExErrorNumberStateClass() - { - return StringsHelper.GetString(Strings.SQL_ExErrorNumberStateClass); - } - internal static string ExOriginalClientConnectionId() - { - return StringsHelper.GetString(Strings.SQL_ExOriginalClientConnectionId); - } - internal static string ExRoutingDestination() - { - return StringsHelper.GetString(Strings.SQL_ExRoutingDestination); - } - } - - /// - /// This class holds helper methods to escape Microsoft SQL Server identifiers, such as table, schema, database or other names - /// - internal static class SqlServerEscapeHelper - { - /// - /// Escapes the identifier with square brackets. The input has to be in unescaped form, like the parts received from MultipartIdentifier.ParseMultipartIdentifier. - /// - /// name of the identifier, in unescaped form - /// escapes the name with [], also escapes the last close bracket with double-bracket - internal static string EscapeIdentifier(string name) - { - Debug.Assert(!string.IsNullOrEmpty(name), "null or empty identifiers are not allowed"); - return "[" + name.Replace("]", "]]") + "]"; - } - - /// - /// Same as above EscapeIdentifier, except that output is written into StringBuilder - /// - internal static void EscapeIdentifier(StringBuilder builder, string name) - { - Debug.Assert(builder != null, "builder cannot be null"); - Debug.Assert(!string.IsNullOrEmpty(name), "null or empty identifiers are not allowed"); - - builder.Append("["); - builder.Append(name.Replace("]", "]]")); - builder.Append("]"); - } - - /// - /// Escape a string to be used inside TSQL literal, such as N'somename' or 'somename' - /// - internal static string EscapeStringAsLiteral(string input) - { - Debug.Assert(input != null, "input string cannot be null"); - return input.Replace("'", "''"); - } - - /// - /// Escape a string as a TSQL literal, wrapping it around with single quotes. - /// Use this method to escape input strings to prevent SQL injection - /// and to get correct behavior for embedded quotes. - /// - /// unescaped string - /// escaped and quoted literal string - internal static string MakeStringLiteral(string input) - { - if (string.IsNullOrEmpty(input)) - { - return "''"; - } - else - { - return "'" + EscapeStringAsLiteral(input) + "'"; - } - } - } - - /// - /// This class holds methods invoked on System.Transactions through reflection for Global Transactions - /// - internal static class SysTxForGlobalTransactions - { - private static readonly Lazy _enlistPromotableSinglePhase = new Lazy(() => - typeof(Transaction).GetMethod("EnlistPromotableSinglePhase", new Type[] { typeof(IPromotableSinglePhaseNotification), typeof(Guid) })); - - private static readonly Lazy _setDistributedTransactionIdentifier = new Lazy(() => - typeof(Transaction).GetMethod("SetDistributedTransactionIdentifier", new Type[] { typeof(IPromotableSinglePhaseNotification), typeof(Guid) })); - - private static readonly Lazy _getPromotedToken = new Lazy(() => - typeof(Transaction).GetMethod("GetPromotedToken")); - - /// - /// Enlists the given IPromotableSinglePhaseNotification and Non-MSDTC Promoter type into a transaction - /// - /// The MethodInfo instance to be invoked. Null if the method doesn't exist - public static MethodInfo EnlistPromotableSinglePhase - { - get - { - return _enlistPromotableSinglePhase.Value; - } - } - - /// - /// Sets the given DistributedTransactionIdentifier for a Transaction instance. - /// Needs to be invoked when using a Non-MSDTC Promoter type - /// - /// The MethodInfo instance to be invoked. Null if the method doesn't exist - public static MethodInfo SetDistributedTransactionIdentifier - { - get - { - return _setDistributedTransactionIdentifier.Value; - } - } - - /// - /// Gets the Promoted Token for a Transaction - /// - /// The MethodInfo instance to be invoked. Null if the method doesn't exist - public static MethodInfo GetPromotedToken - { - get - { - return _getPromotedToken.Value; - } - } - } - -} diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj index 46a34e75d5..994e84bab5 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj @@ -691,7 +691,6 @@ - diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlUtil.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlUtil.cs deleted file mode 100644 index 7b387fe5c0..0000000000 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlUtil.cs +++ /dev/null @@ -1,2677 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Data; -using System.Diagnostics; -using System.Globalization; -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.ExceptionServices; -using System.Runtime.InteropServices; -using System.Runtime.Versioning; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using SysTx = System.Transactions; - -namespace Microsoft.Data.SqlClient -{ - using Microsoft.Data.Common; - static internal class AsyncHelper - { - internal static Task CreateContinuationTask(Task task, Action onSuccess, SqlInternalConnectionTds connectionToDoom = null, Action onFailure = null) - { - if (task == null) - { - onSuccess(); - return null; - } - else - { - TaskCompletionSource completion = new TaskCompletionSource(); - ContinueTask(task, completion, - onSuccess: () => - { - onSuccess(); - completion.SetResult(null); - }, - onFailure: onFailure, - connectionToDoom: connectionToDoom - ); - return completion.Task; - } - } - - internal static Task CreateContinuationTaskWithState(Task task, object state, Action onSuccess, Action onFailure = null) - { - if (task == null) - { - onSuccess(state); - return null; - } - else - { - TaskCompletionSource completion = new(); - ContinueTaskWithState(task, completion, state, - onSuccess: (object continueState) => - { - onSuccess(continueState); - completion.SetResult(null); - }, - onFailure: onFailure - ); - return completion.Task; - } - } - - internal static Task CreateContinuationTask(Task task, Action onSuccess, T1 arg1, T2 arg2, SqlInternalConnectionTds connectionToDoom = null, Action onFailure = null) - { - return CreateContinuationTask(task, () => onSuccess(arg1, arg2), connectionToDoom, onFailure); - } - - internal static void ContinueTask(Task task, - TaskCompletionSource completion, - Action onSuccess, - Action onFailure = null, - Action onCancellation = null, - Func exceptionConverter = null, - SqlInternalConnectionTds connectionToDoom = null, - SqlConnection connectionToAbort = null - ) - { - Debug.Assert((connectionToAbort == null) || (connectionToDoom == null), "Should not specify both connectionToDoom and connectionToAbort"); - task.ContinueWith( - tsk => - { - if (tsk.Exception != null) - { - Exception exc = tsk.Exception.InnerException; - if (exceptionConverter != null) - { - exc = exceptionConverter(exc); - } - try - { - if (onFailure != null) - { - onFailure(exc); - } - } - finally - { - completion.TrySetException(exc); - } - } - else if (tsk.IsCanceled) - { - try - { - if (onCancellation != null) - { - onCancellation(); - } - } - finally - { - completion.TrySetCanceled(); - } - } - else - { - if (connectionToDoom != null || connectionToAbort != null) - { - RuntimeHelpers.PrepareConstrainedRegions(); - try - { -#if DEBUG - TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection(); - RuntimeHelpers.PrepareConstrainedRegions(); - try - { - tdsReliabilitySection.Start(); -#endif //DEBUG - onSuccess(); -#if DEBUG - } - finally - { - tdsReliabilitySection.Stop(); - } -#endif //DEBUG - } - catch (System.OutOfMemoryException e) - { - if (connectionToDoom != null) - { - connectionToDoom.DoomThisConnection(); - } - else - { - connectionToAbort.Abort(e); - } - completion.SetException(e); - throw; - } - catch (System.StackOverflowException e) - { - if (connectionToDoom != null) - { - connectionToDoom.DoomThisConnection(); - } - else - { - connectionToAbort.Abort(e); - } - completion.SetException(e); - throw; - } - catch (System.Threading.ThreadAbortException e) - { - if (connectionToDoom != null) - { - connectionToDoom.DoomThisConnection(); - } - else - { - connectionToAbort.Abort(e); - } - completion.SetException(e); - throw; - } - catch (Exception e) - { - completion.SetException(e); - } - } - else - { // no connection to doom - reliability section not required - try - { - onSuccess(); - } - catch (Exception e) - { - completion.SetException(e); - } - } - } - }, TaskScheduler.Default - ); - } - - internal static void ContinueTaskWithState(Task task, - TaskCompletionSource completion, - object state, - Action onSuccess, - Action onFailure = null, - Action onCancellation = null, - Func exceptionConverter = null, - SqlInternalConnectionTds connectionToDoom = null, - SqlConnection connectionToAbort = null - ) - { - Debug.Assert((connectionToAbort == null) || (connectionToDoom == null), "Should not specify both connectionToDoom and connectionToAbort"); - task.ContinueWith( - (Task tsk, object state) => - { - if (tsk.Exception != null) - { - Exception exc = tsk.Exception.InnerException; - if (exceptionConverter != null) - { - exc = exceptionConverter(exc, state); - } - try - { - onFailure?.Invoke(exc, state); - } - finally - { - completion.TrySetException(exc); - } - } - else if (tsk.IsCanceled) - { - try - { - onCancellation?.Invoke(state); - } - finally - { - completion.TrySetCanceled(); - } - } - else - { - if (connectionToDoom != null || connectionToAbort != null) - { - RuntimeHelpers.PrepareConstrainedRegions(); - try - { -#if DEBUG - TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection(); - RuntimeHelpers.PrepareConstrainedRegions(); - try - { - tdsReliabilitySection.Start(); -#endif //DEBUG - onSuccess(state); -#if DEBUG - } - finally - { - tdsReliabilitySection.Stop(); - } -#endif //DEBUG - } - catch (System.OutOfMemoryException e) - { - if (connectionToDoom != null) - { - connectionToDoom.DoomThisConnection(); - } - else - { - connectionToAbort.Abort(e); - } - completion.SetException(e); - throw; - } - catch (System.StackOverflowException e) - { - if (connectionToDoom != null) - { - connectionToDoom.DoomThisConnection(); - } - else - { - connectionToAbort.Abort(e); - } - completion.SetException(e); - throw; - } - catch (System.Threading.ThreadAbortException e) - { - if (connectionToDoom != null) - { - connectionToDoom.DoomThisConnection(); - } - else - { - connectionToAbort.Abort(e); - } - completion.SetException(e); - throw; - } - catch (Exception e) - { - completion.SetException(e); - } - } - else - { // no connection to doom - reliability section not required - try - { - onSuccess(state); - } - catch (Exception e) - { - completion.SetException(e); - } - } - } - }, - state: state, - scheduler: TaskScheduler.Default - ); - } - - internal static void WaitForCompletion(Task task, int timeout, Action onTimeout = null, bool rethrowExceptions = true) - { - try - { - task.Wait(timeout > 0 ? (1000 * timeout) : Timeout.Infinite); - } - catch (AggregateException ae) - { - if (rethrowExceptions) - { - Debug.Assert(ae.InnerExceptions.Count == 1, "There is more than one exception in AggregateException"); - ExceptionDispatchInfo.Capture(ae.InnerException).Throw(); - } - } - if (!task.IsCompleted) - { - task.ContinueWith(t => { var ignored = t.Exception; }); //Ensure the task does not leave an unobserved exception - if (onTimeout != null) - { - onTimeout(); - } - } - } - - internal static void SetTimeoutException(TaskCompletionSource completion, int timeout, Func exc, CancellationToken ctoken) - { - if (timeout > 0) - { - Task.Delay(timeout * 1000, ctoken).ContinueWith((tsk) => - { - if (!tsk.IsCanceled && !completion.Task.IsCompleted) - { - completion.TrySetException(exc()); - } - }); - } - } - } - - sealed internal class InOutOfProcHelper - { - private static readonly InOutOfProcHelper SingletonInstance = new InOutOfProcHelper(); - - private bool _inProc = false; - - // InOutOfProcHelper detects whether it's running inside the server or not. It does this - // by checking for the existence of a well-known function export on the current process. - // Note that calling conventions, etc. do not matter -- we'll never call the function, so - // only the name match or lack thereof matter. - [ResourceExposure(ResourceScope.None)] - [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)] - private InOutOfProcHelper() - { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - // SafeNativeMethods.GetModuleHandle calls into kernel32.dll, so return early to avoid - // a System.EntryPointNotFoundException on non-Windows platforms, e.g. Mono. - return; - } - // Don't need to close this handle... - // SxS: we use this method to check if we are running inside the SQL Server process. This call should be safe in SxS environment. - IntPtr handle = SafeNativeMethods.GetModuleHandle(null); - if (IntPtr.Zero != handle) - { - // SQLBU 359301: Currently, the server exports different names for x86 vs. AMD64 and IA64. Supporting both names - // for now gives the server time to unify names across platforms without breaking currently-working ones. - // We can remove the obsolete name once the server is changed. - if (IntPtr.Zero != SafeNativeMethods.GetProcAddress(handle, "_______SQL______Process______Available@0")) - { - _inProc = true; - } - else if (IntPtr.Zero != SafeNativeMethods.GetProcAddress(handle, "______SQL______Process______Available")) - { - _inProc = true; - } - } - } - - internal static bool InProc - { - get - { - return SingletonInstance._inProc; - } - } - } - - static internal class SQL - { - // The class SQL defines the exceptions that are specific to the SQL Adapter. - // The class contains functions that take the proper informational variables and then construct - // the appropriate exception with an error string obtained from the resource Framework.txt. - // The exception is then returned to the caller, so that the caller may then throw from its - // location so that the catcher of the exception will have the appropriate call stack. - // This class is used so that there will be compile time checking of error - // messages. The resource Framework.txt will ensure proper string text based on the appropriate - // locale. - - // - // SQL specific exceptions - // - - // - // SQL.Connection - // - - static internal Exception CannotGetDTCAddress() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_CannotGetDTCAddress)); - } - - static internal Exception InvalidOptionLength(string key) - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_InvalidOptionLength, key)); - } - static internal Exception InvalidInternalPacketSize(string str) - { - return ADP.ArgumentOutOfRange(str); - } - static internal Exception InvalidPacketSize() - { - return ADP.ArgumentOutOfRange(StringsHelper.GetString(Strings.SQL_InvalidTDSPacketSize)); - } - static internal Exception InvalidPacketSizeValue() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_InvalidPacketSizeValue)); - } - static internal Exception InvalidSSPIPacketSize() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_InvalidSSPIPacketSize)); - } - static internal Exception NullEmptyTransactionName() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_NullEmptyTransactionName)); - } - static internal Exception SnapshotNotSupported(System.Data.IsolationLevel level) - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_SnapshotNotSupported, typeof(IsolationLevel), level.ToString())); - } - static internal Exception UserInstanceFailoverNotCompatible() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_UserInstanceFailoverNotCompatible)); - } - static internal Exception CredentialsNotProvided(SqlAuthenticationMethod auth) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_CredentialsNotProvided, DbConnectionStringBuilderUtil.AuthenticationTypeToString(auth))); - } - static internal Exception InvalidCertAuth() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_Certificate)); - } - static internal Exception AuthenticationAndIntegratedSecurity() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_AuthenticationAndIntegratedSecurity)); - } - static internal Exception IntegratedWithPassword() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_IntegratedWithPassword)); - } - static internal Exception InteractiveWithPassword() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_InteractiveWithPassword)); - } - static internal Exception DeviceFlowWithUsernamePassword() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_DeviceFlowWithUsernamePassword)); - } - static internal Exception NonInteractiveWithPassword(string authenticationMode) - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_NonInteractiveWithPassword, authenticationMode)); - } - static internal Exception SettingIntegratedWithCredential() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SettingIntegratedWithCredential)); - } - static internal Exception SettingInteractiveWithCredential() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SettingInteractiveWithCredential)); - } - static internal Exception SettingDeviceFlowWithCredential() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SettingDeviceFlowWithCredential)); - } - static internal Exception SettingNonInteractiveWithCredential(string authenticationMode) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SettingNonInteractiveWithCredential, authenticationMode)); - } - static internal Exception SettingCredentialWithIntegratedArgument() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_SettingCredentialWithIntegrated)); - } - static internal Exception SettingCredentialWithInteractiveArgument() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_SettingCredentialWithInteractive)); - } - static internal Exception SettingCredentialWithDeviceFlowArgument() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_SettingCredentialWithDeviceFlow)); - } - static internal Exception SettingCredentialWithNonInteractiveArgument(string authenticationMode) - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_SettingCredentialWithNonInteractive, authenticationMode)); - } - static internal Exception SettingCredentialWithIntegratedInvalid() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SettingCredentialWithIntegrated)); - } - static internal Exception SettingCredentialWithInteractiveInvalid() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SettingCredentialWithInteractive)); - } - static internal Exception SettingCredentialWithDeviceFlowInvalid() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SettingCredentialWithDeviceFlow)); - } - static internal Exception SettingCredentialWithNonInteractiveInvalid(string authenticationMode) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SettingCredentialWithNonInteractive, authenticationMode)); - } - static internal Exception InvalidSQLServerVersionUnknown() - { - return ADP.DataAdapter(StringsHelper.GetString(Strings.SQL_InvalidSQLServerVersionUnknown)); - } - static internal Exception SynchronousCallMayNotPend() - { - return new Exception(StringsHelper.GetString(Strings.Sql_InternalError)); - } - static internal Exception ConnectionLockedForBcpEvent() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ConnectionLockedForBcpEvent)); - } - static internal Exception FatalTimeout() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_FatalTimeout)); - } - static internal Exception InstanceFailure() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_InstanceFailure)); - } - static internal Exception ChangePasswordArgumentMissing(string argumentName) - { - return ADP.ArgumentNull(StringsHelper.GetString(Strings.SQL_ChangePasswordArgumentMissing, argumentName)); - } - static internal Exception ChangePasswordConflictsWithSSPI() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_ChangePasswordConflictsWithSSPI)); - } - static internal Exception ChangePasswordRequires2005() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ChangePasswordRequiresYukon)); - } - static internal Exception UnknownSysTxIsolationLevel(SysTx.IsolationLevel isolationLevel) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_UnknownSysTxIsolationLevel, isolationLevel.ToString())); - } - static internal Exception ChangePasswordUseOfUnallowedKey(string key) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ChangePasswordUseOfUnallowedKey, key)); - } - static internal Exception InvalidPartnerConfiguration(string server, string database) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_InvalidPartnerConfiguration, server, database)); - } - static internal Exception BatchedUpdateColumnEncryptionSettingMismatch() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_BatchedUpdateColumnEncryptionSettingMismatch, "SqlCommandColumnEncryptionSetting", "SelectCommand", "InsertCommand", "UpdateCommand", "DeleteCommand")); - } - static internal Exception MARSUnsupportedOnConnection() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_MarsUnsupportedOnConnection)); - } - - static internal Exception CannotModifyPropertyAsyncOperationInProgress(string property) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_CannotModifyPropertyAsyncOperationInProgress, property)); - } - static internal Exception NonLocalSSEInstance() - { - return ADP.NotSupported(StringsHelper.GetString(Strings.SQL_NonLocalSSEInstance)); - } - - // SQL.ActiveDirectoryAuth - // - static internal Exception UnsupportedAuthentication(string authentication) - { - return ADP.NotSupported(StringsHelper.GetString(Strings.SQL_UnsupportedAuthentication, authentication)); - } - - static internal Exception UnsupportedSqlAuthenticationMethod(SqlAuthenticationMethod authentication) - { - return ADP.NotSupported(StringsHelper.GetString(Strings.SQL_UnsupportedSqlAuthenticationMethod, authentication)); - } - - static internal Exception UnsupportedAuthenticationSpecified(SqlAuthenticationMethod authentication) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_UnsupportedAuthenticationSpecified, authentication)); - } - - static internal Exception CannotCreateAuthProvider(string authentication, string type, Exception e) - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_CannotCreateAuthProvider, authentication, type), e); - } - - static internal Exception CannotCreateSqlAuthInitializer(string type, Exception e) - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_CannotCreateAuthInitializer, type), e); - } - - static internal Exception CannotInitializeAuthProvider(string type, Exception e) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_CannotInitializeAuthProvider, type), e); - } - - static internal Exception UnsupportedAuthenticationByProvider(string authentication, string type) - { - return ADP.NotSupported(StringsHelper.GetString(Strings.SQL_UnsupportedAuthenticationByProvider, type, authentication)); - } - - static internal Exception CannotFindAuthProvider(string authentication) - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_CannotFindAuthProvider, authentication)); - } - - static internal Exception CannotGetAuthProviderConfig(Exception e) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_CannotGetAuthProviderConfig), e); - } - - static internal Exception ParameterCannotBeEmpty(string paramName) - { - return ADP.ArgumentNull(StringsHelper.GetString(Strings.SQL_ParameterCannotBeEmpty, paramName)); - } - - internal static Exception ParameterDirectionInvalidForOptimizedBinding(string paramName) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParameterDirectionInvalidForOptimizedBinding, paramName)); - } - - static internal Exception ActiveDirectoryInteractiveTimeout() - { - return ADP.TimeoutException(Strings.SQL_Timeout_Active_Directory_Interactive_Authentication); - } - - static internal Exception ActiveDirectoryDeviceFlowTimeout() - { - return ADP.TimeoutException(Strings.SQL_Timeout_Active_Directory_DeviceFlow_Authentication); - } - - internal static Exception ActiveDirectoryTokenRetrievingTimeout(string authenticaton, string errorCode, Exception exception) - { - return ADP.TimeoutException(StringsHelper.GetString(Strings.AAD_Token_Retrieving_Timeout, authenticaton, errorCode, exception?.Message), exception); - } - - // - // SQL.DataCommand - // - static internal Exception NotificationsRequire2005() - { - return ADP.NotSupported(StringsHelper.GetString(Strings.SQL_NotificationsRequireYukon)); - } - - static internal ArgumentOutOfRangeException NotSupportedEnumerationValue(Type type, int value) - { - return ADP.ArgumentOutOfRange(StringsHelper.GetString(Strings.SQL_NotSupportedEnumerationValue, type.Name, value.ToString(System.Globalization.CultureInfo.InvariantCulture)), type.Name); - } - - static internal ArgumentOutOfRangeException NotSupportedCommandType(CommandType value) - { -#if DEBUG - switch (value) - { - case CommandType.Text: - case CommandType.StoredProcedure: - Debug.Fail("valid CommandType " + value.ToString()); - break; - case CommandType.TableDirect: - break; - default: - Debug.Fail("invalid CommandType " + value.ToString()); - break; - } -#endif - return NotSupportedEnumerationValue(typeof(CommandType), (int)value); - } - static internal ArgumentOutOfRangeException NotSupportedIsolationLevel(IsolationLevel value) - { -#if DEBUG - switch (value) - { - case IsolationLevel.Unspecified: - case IsolationLevel.ReadCommitted: - case IsolationLevel.ReadUncommitted: - case IsolationLevel.RepeatableRead: - case IsolationLevel.Serializable: - case IsolationLevel.Snapshot: - Debug.Fail("valid IsolationLevel " + value.ToString()); - break; - case IsolationLevel.Chaos: - break; - default: - Debug.Fail("invalid IsolationLevel " + value.ToString()); - break; - } -#endif - return NotSupportedEnumerationValue(typeof(IsolationLevel), (int)value); - } - - static internal Exception OperationCancelled() - { - Exception exception = ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_OperationCancelled)); - return exception; - } - - static internal Exception PendingBeginXXXExists() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_PendingBeginXXXExists)); - } - - static internal ArgumentOutOfRangeException InvalidSqlDependencyTimeout(string param) - { - return ADP.ArgumentOutOfRange(StringsHelper.GetString(Strings.SqlDependency_InvalidTimeout), param); - } - - static internal Exception NonXmlResult() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_NonXmlResult)); - } - - // - // SQL.DataParameter - // - static internal Exception InvalidUdt3PartNameFormat() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_InvalidUdt3PartNameFormat)); - } - static internal Exception InvalidParameterTypeNameFormat() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_InvalidParameterTypeNameFormat)); - } - static internal Exception InvalidParameterNameLength(string value) - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_InvalidParameterNameLength, value)); - } - static internal Exception PrecisionValueOutOfRange(byte precision) - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_PrecisionValueOutOfRange, precision.ToString(CultureInfo.InvariantCulture))); - } - static internal Exception ScaleValueOutOfRange(byte scale) - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_ScaleValueOutOfRange, scale.ToString(CultureInfo.InvariantCulture))); - } - static internal Exception TimeScaleValueOutOfRange(byte scale) - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_TimeScaleValueOutOfRange, scale.ToString(CultureInfo.InvariantCulture))); - } - static internal Exception InvalidSqlDbType(SqlDbType value) - { - return ADP.InvalidEnumerationValue(typeof(SqlDbType), (int)value); - } - static internal Exception UnsupportedTVPOutputParameter(ParameterDirection direction, string paramName) - { - return ADP.NotSupported(StringsHelper.GetString(Strings.SqlParameter_UnsupportedTVPOutputParameter, - direction.ToString(), paramName)); - } - static internal Exception DBNullNotSupportedForTVPValues(string paramName) - { - return ADP.NotSupported(StringsHelper.GetString(Strings.SqlParameter_DBNullNotSupportedForTVP, paramName)); - } - static internal Exception InvalidTableDerivedPrecisionForTvp(string columnName, byte precision) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlParameter_InvalidTableDerivedPrecisionForTvp, precision, columnName, System.Data.SqlTypes.SqlDecimal.MaxPrecision)); - } - static internal Exception UnexpectedTypeNameForNonStructParams(string paramName) - { - return ADP.NotSupported(StringsHelper.GetString(Strings.SqlParameter_UnexpectedTypeNameForNonStruct, paramName)); - } - static internal Exception SingleValuedStructNotSupported() - { - return ADP.NotSupported(StringsHelper.GetString(Strings.MetaType_SingleValuedStructNotSupported)); - } - static internal Exception ParameterInvalidVariant(string paramName) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParameterInvalidVariant, paramName)); - } - - static internal Exception MustSetTypeNameForParam(string paramType, string paramName) - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_ParameterTypeNameRequired, paramType, paramName)); - } - static internal Exception NullSchemaTableDataTypeNotSupported(string columnName) - { - return ADP.Argument(StringsHelper.GetString(Strings.NullSchemaTableDataTypeNotSupported, columnName)); - } - static internal Exception InvalidSchemaTableOrdinals() - { - return ADP.Argument(StringsHelper.GetString(Strings.InvalidSchemaTableOrdinals)); - } - static internal Exception EnumeratedRecordMetaDataChanged(string fieldName, int recordNumber) - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_EnumeratedRecordMetaDataChanged, fieldName, recordNumber)); - } - static internal Exception EnumeratedRecordFieldCountChanged(int recordNumber) - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_EnumeratedRecordFieldCountChanged, recordNumber)); - } - - // - // SQL.SqlDataAdapter - // - - // - // SQL.TDSParser - // - static internal Exception InvalidTDSVersion() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_InvalidTDSVersion)); - } - static internal Exception ParsingError(ParsingErrorState state) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParsingErrorWithState, ((int)state).ToString(CultureInfo.InvariantCulture))); - } - static internal Exception ParsingError(ParsingErrorState state, Exception innerException) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParsingErrorWithState, ((int)state).ToString(CultureInfo.InvariantCulture)), innerException); - } - static internal Exception ParsingErrorValue(ParsingErrorState state, int value) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParsingErrorValue, ((int)state).ToString(CultureInfo.InvariantCulture), value)); - } - static internal Exception ParsingErrorOffset(ParsingErrorState state, int offset) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParsingErrorOffset, ((int)state).ToString(CultureInfo.InvariantCulture), offset)); - } - static internal Exception ParsingErrorFeatureId(ParsingErrorState state, int featureId) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParsingErrorFeatureId, ((int)state).ToString(CultureInfo.InvariantCulture), featureId)); - } - static internal Exception ParsingErrorToken(ParsingErrorState state, int token) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParsingErrorToken, ((int)state).ToString(CultureInfo.InvariantCulture), token)); - } - static internal Exception ParsingErrorLength(ParsingErrorState state, int length) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParsingErrorLength, ((int)state).ToString(CultureInfo.InvariantCulture), length)); - } - static internal Exception ParsingErrorStatus(ParsingErrorState state, int status) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParsingErrorStatus, ((int)state).ToString(CultureInfo.InvariantCulture), status)); - } - static internal Exception ParsingErrorLibraryType(ParsingErrorState state, int libraryType) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParsingErrorAuthLibraryType, ((int)state).ToString(CultureInfo.InvariantCulture), libraryType)); - } - - static internal Exception MoneyOverflow(string moneyValue) - { - return ADP.Overflow(StringsHelper.GetString(Strings.SQL_MoneyOverflow, moneyValue)); - } - static internal Exception SmallDateTimeOverflow(string datetime) - { - return ADP.Overflow(StringsHelper.GetString(Strings.SQL_SmallDateTimeOverflow, datetime)); - } - static internal Exception SNIPacketAllocationFailure() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SNIPacketAllocationFailure)); - } - static internal Exception TimeOverflow(string time) - { - return ADP.Overflow(StringsHelper.GetString(Strings.SQL_TimeOverflow, time)); - } - static internal Exception InvalidServerCertificate() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_InvalidServerCertificate)); - } - - // - // SQL.SqlDataReader - // - static internal Exception InvalidRead() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_InvalidRead)); - } - - static internal Exception NonBlobColumn(string columnName) - { - return ADP.InvalidCast(StringsHelper.GetString(Strings.SQL_NonBlobColumn, columnName)); - } - - static internal Exception NonCharColumn(string columnName) - { - return ADP.InvalidCast(StringsHelper.GetString(Strings.SQL_NonCharColumn, columnName)); - } - - static internal Exception StreamNotSupportOnColumnType(string columnName) - { - return ADP.InvalidCast(StringsHelper.GetString(Strings.SQL_StreamNotSupportOnColumnType, columnName)); - } - - static internal Exception StreamNotSupportOnEncryptedColumn(string columnName) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_StreamNotSupportOnEncryptedColumn, columnName, "Stream")); - } - - static internal Exception SequentialAccessNotSupportedOnEncryptedColumn(string columnName) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_SequentialAccessNotSupportedOnEncryptedColumn, columnName, "CommandBehavior=SequentialAccess")); - } - - static internal Exception TextReaderNotSupportOnColumnType(string columnName) - { - return ADP.InvalidCast(StringsHelper.GetString(Strings.SQL_TextReaderNotSupportOnColumnType, columnName)); - } - - static internal Exception XmlReaderNotSupportOnColumnType(string columnName) - { - return ADP.InvalidCast(StringsHelper.GetString(Strings.SQL_XmlReaderNotSupportOnColumnType, columnName)); - } - - static internal Exception UDTUnexpectedResult(string exceptionText) - { - return ADP.TypeLoad(StringsHelper.GetString(Strings.SQLUDT_Unexpected, exceptionText)); - } - - - // - // SQL.SqlDelegatedTransaction - // - static internal Exception CannotCompleteDelegatedTransactionWithOpenResults(SqlInternalConnectionTds internalConnection, bool marsOn) - { - SqlErrorCollection errors = new SqlErrorCollection(); - errors.Add(new SqlError(TdsEnums.TIMEOUT_EXPIRED, (byte)0x00, TdsEnums.MIN_ERROR_CLASS, null, (StringsHelper.GetString(Strings.ADP_OpenReaderExists, marsOn ? ADP.Command : ADP.Connection)), "", 0, TdsEnums.SNI_WAIT_TIMEOUT)); - return SqlException.CreateException(errors, null, internalConnection, innerException: null, batchCommand: null); - } - static internal SysTx.TransactionPromotionException PromotionFailed(Exception inner) - { - SysTx.TransactionPromotionException e = new SysTx.TransactionPromotionException(StringsHelper.GetString(Strings.SqlDelegatedTransaction_PromotionFailed), inner); - ADP.TraceExceptionAsReturnValue(e); - return e; - } - - internal static Exception DateTimeOverflow() - { - return new OverflowException(SqlTypes.SQLResource.DateTimeOverflowMessage); - } - - // - // SQL.SqlDependency - // - static internal Exception SqlCommandHasExistingSqlNotificationRequest() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQLNotify_AlreadyHasCommand)); - } - - static internal Exception SqlDepCannotBeCreatedInProc() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlNotify_SqlDepCannotBeCreatedInProc)); - } - - static internal Exception SqlDepDefaultOptionsButNoStart() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlDependency_DefaultOptionsButNoStart)); - } - - static internal Exception SqlDependencyDatabaseBrokerDisabled() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlDependency_DatabaseBrokerDisabled)); - } - - static internal Exception SqlDependencyEventNoDuplicate() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlDependency_EventNoDuplicate)); - } - - static internal Exception SqlDependencyDuplicateStart() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlDependency_DuplicateStart)); - } - - static internal Exception SqlDependencyIdMismatch() - { - // do not include the id because it may require SecurityPermission(Infrastructure) permission - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlDependency_IdMismatch)); - } - - static internal Exception SqlDependencyNoMatchingServerStart() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlDependency_NoMatchingServerStart)); - } - - static internal Exception SqlDependencyNoMatchingServerDatabaseStart() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlDependency_NoMatchingServerDatabaseStart)); - } - - static internal Exception SqlNotificationException(SqlNotificationEventArgs notify) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQLNotify_ErrorFormat, notify.Type, notify.Info, notify.Source)); - } - - // - // SQL.SqlMetaData - // - static internal Exception SqlMetaDataNoMetaData() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlMetaData_NoMetadata)); - } - - static internal Exception MustSetUdtTypeNameForUdtParams() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQLUDT_InvalidUdtTypeName)); - } - - static internal Exception UnexpectedUdtTypeNameForNonUdtParams() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQLUDT_UnexpectedUdtTypeName)); - } - - static internal Exception UDTInvalidSqlType(string typeName) - { - return ADP.Argument(StringsHelper.GetString(Strings.SQLUDT_InvalidSqlType, typeName)); - } - - static internal Exception UDTInvalidSize(int maxSize, int maxSupportedSize) - { - throw ADP.ArgumentOutOfRange(StringsHelper.GetString(Strings.SQLUDT_InvalidSize, maxSize, maxSupportedSize)); - } - - - static internal Exception InvalidSqlDbTypeForConstructor(SqlDbType type) - { - return ADP.Argument(StringsHelper.GetString(Strings.SqlMetaData_InvalidSqlDbTypeForConstructorFormat, type.ToString())); - } - - static internal Exception NameTooLong(string parameterName) - { - return ADP.Argument(StringsHelper.GetString(Strings.SqlMetaData_NameTooLong), parameterName); - } - - static internal Exception InvalidSortOrder(SortOrder order) - { - return ADP.InvalidEnumerationValue(typeof(SortOrder), (int)order); - } - - static internal Exception MustSpecifyBothSortOrderAndOrdinal(SortOrder order, int ordinal) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlMetaData_SpecifyBothSortOrderAndOrdinal, order.ToString(), ordinal)); - } - - static internal Exception TableTypeCanOnlyBeParameter() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQLTVP_TableTypeCanOnlyBeParameter)); - } - static internal Exception UnsupportedColumnTypeForSqlProvider(string columnName, string typeName) - { - return ADP.Argument(StringsHelper.GetString(Strings.SqlProvider_InvalidDataColumnType, columnName, typeName)); - } - static internal Exception InvalidColumnMaxLength(string columnName, long maxLength) - { - return ADP.Argument(StringsHelper.GetString(Strings.SqlProvider_InvalidDataColumnMaxLength, columnName, maxLength)); - } - static internal Exception InvalidColumnPrecScale() - { - return ADP.Argument(StringsHelper.GetString(Strings.SqlMisc_InvalidPrecScaleMessage)); - } - static internal Exception NotEnoughColumnsInStructuredType() - { - return ADP.Argument(StringsHelper.GetString(Strings.SqlProvider_NotEnoughColumnsInStructuredType)); - } - static internal Exception DuplicateSortOrdinal(int sortOrdinal) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlProvider_DuplicateSortOrdinal, sortOrdinal)); - } - static internal Exception MissingSortOrdinal(int sortOrdinal) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlProvider_MissingSortOrdinal, sortOrdinal)); - } - static internal Exception SortOrdinalGreaterThanFieldCount(int columnOrdinal, int sortOrdinal) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlProvider_SortOrdinalGreaterThanFieldCount, sortOrdinal, columnOrdinal)); - } - static internal Exception IEnumerableOfSqlDataRecordHasNoRows() - { - return ADP.Argument(StringsHelper.GetString(Strings.IEnumerableOfSqlDataRecordHasNoRows)); - } - - - - // - // SqlPipe - // - static internal Exception SqlPipeCommandHookedUpToNonContextConnection() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlPipe_CommandHookedUpToNonContextConnection)); - } - - static internal Exception SqlPipeMessageTooLong(int messageLength) - { - return ADP.Argument(StringsHelper.GetString(Strings.SqlPipe_MessageTooLong, messageLength)); - } - - static internal Exception SqlPipeIsBusy() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlPipe_IsBusy)); - } - - static internal Exception SqlPipeAlreadyHasAnOpenResultSet(string methodName) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlPipe_AlreadyHasAnOpenResultSet, methodName)); - } - - static internal Exception SqlPipeDoesNotHaveAnOpenResultSet(string methodName) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlPipe_DoesNotHaveAnOpenResultSet, methodName)); - } - - // - // : ISqlResultSet - // - static internal Exception SqlResultSetClosed(string methodname) - { - if (methodname == null) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SqlResultSetClosed2)); - } - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SqlResultSetClosed, methodname)); - } - static internal Exception SqlResultSetNoData(string methodname) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.ADP_DataReaderNoData, methodname)); - } - static internal Exception SqlRecordReadOnly(string methodname) - { - if (methodname == null) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SqlRecordReadOnly2)); - } - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SqlRecordReadOnly, methodname)); - } - - static internal Exception SqlResultSetRowDeleted(string methodname) - { - if (methodname == null) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SqlResultSetRowDeleted2)); - } - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SqlResultSetRowDeleted, methodname)); - } - - static internal Exception SqlResultSetCommandNotInSameConnection() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SqlResultSetCommandNotInSameConnection)); - } - - static internal Exception SqlResultSetNoAcceptableCursor() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SqlResultSetNoAcceptableCursor)); - } - - // - // SQL.BulkLoad - // - static internal Exception BulkLoadMappingInaccessible() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadMappingInaccessible)); - } - static internal Exception BulkLoadMappingsNamesOrOrdinalsOnly() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadMappingsNamesOrOrdinalsOnly)); - } - static internal Exception BulkLoadCannotConvertValue(Type sourcetype, MetaType metatype, int ordinal, int rowNumber, bool isEncrypted, string columnName, string value, Exception e) - { - string quotedValue = string.Empty; - if (!isEncrypted) - { - quotedValue = string.Format(" '{0}'", (value.Length > 100 ? value.Substring(0, 100) : value)); - } - if (rowNumber == -1) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadCannotConvertValueWithoutRowNo, quotedValue, sourcetype.Name, metatype.TypeName, ordinal, columnName), e); - } - else - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadCannotConvertValue, quotedValue, sourcetype.Name, metatype.TypeName, ordinal, columnName, rowNumber), e); - } - } - static internal Exception BulkLoadNonMatchingColumnMapping() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadNonMatchingColumnMapping)); - } - static internal Exception BulkLoadNonMatchingColumnName(string columnName) - { - return BulkLoadNonMatchingColumnName(columnName, null); - } - static internal Exception BulkLoadNonMatchingColumnName(string columnName, Exception e) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadNonMatchingColumnName, columnName), e); - } - internal static Exception BulkLoadNullEmptyColumnName(string paramName) - { - return ADP.Argument(string.Format(StringsHelper.GetString(Strings.SQL_ParameterCannotBeEmpty), paramName)); - } - internal static Exception BulkLoadUnspecifiedSortOrder() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_BulkLoadUnspecifiedSortOrder)); - } - internal static Exception BulkLoadInvalidOrderHint() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_BulkLoadInvalidOrderHint)); - } - internal static Exception BulkLoadOrderHintInvalidColumn(string columnName) - { - return ADP.InvalidOperation(string.Format(StringsHelper.GetString(Strings.SQL_BulkLoadOrderHintInvalidColumn), columnName)); - } - internal static Exception BulkLoadOrderHintDuplicateColumn(string columnName) - { - return ADP.InvalidOperation(string.Format(StringsHelper.GetString(Strings.SQL_BulkLoadOrderHintDuplicateColumn), columnName)); - } - static internal Exception BulkLoadStringTooLong(string tableName, string columnName, string truncatedValue) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadStringTooLong, tableName, columnName, truncatedValue)); - } - static internal Exception BulkLoadInvalidVariantValue() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadInvalidVariantValue)); - } - static internal Exception BulkLoadInvalidTimeout(int timeout) - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_BulkLoadInvalidTimeout, timeout.ToString(CultureInfo.InvariantCulture))); - } - static internal Exception BulkLoadExistingTransaction() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadExistingTransaction)); - } - static internal Exception BulkLoadNoCollation() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadNoCollation)); - } - static internal Exception BulkLoadConflictingTransactionOption() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_BulkLoadConflictingTransactionOption)); - } - static internal Exception BulkLoadLcidMismatch(int sourceLcid, string sourceColumnName, int destinationLcid, string destinationColumnName) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.Sql_BulkLoadLcidMismatch, sourceLcid, sourceColumnName, destinationLcid, destinationColumnName)); - } - static internal Exception InvalidOperationInsideEvent() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadInvalidOperationInsideEvent)); - } - static internal Exception BulkLoadMissingDestinationTable() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadMissingDestinationTable)); - } - static internal Exception BulkLoadInvalidDestinationTable(string tableName, Exception inner) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadInvalidDestinationTable, tableName), inner); - } - static internal Exception BulkLoadBulkLoadNotAllowDBNull(string columnName) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadNotAllowDBNull, columnName)); - } - static internal Exception BulkLoadPendingOperation() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadPendingOperation)); - } - - // - // TCE - Certificate Store Provider Errors. - // - static internal Exception InvalidKeyEncryptionAlgorithm(string encryptionAlgorithm, string validEncryptionAlgorithm, bool isSystemOp) - { - if (isSystemOp) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidKeyEncryptionAlgorithmSysErr, encryptionAlgorithm, validEncryptionAlgorithm), TdsEnums.TCE_PARAM_ENCRYPTION_ALGORITHM); - } - else - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidKeyEncryptionAlgorithm, encryptionAlgorithm, validEncryptionAlgorithm), TdsEnums.TCE_PARAM_ENCRYPTION_ALGORITHM); - } - } - - static internal Exception NullKeyEncryptionAlgorithm(bool isSystemOp) - { - if (isSystemOp) - { - return ADP.ArgumentNull(TdsEnums.TCE_PARAM_ENCRYPTION_ALGORITHM, StringsHelper.GetString(Strings.TCE_NullKeyEncryptionAlgorithmSysErr)); - } - else - { - return ADP.ArgumentNull(TdsEnums.TCE_PARAM_ENCRYPTION_ALGORITHM, StringsHelper.GetString(Strings.TCE_NullKeyEncryptionAlgorithm)); - } - } - - static internal Exception EmptyColumnEncryptionKey() - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_EmptyColumnEncryptionKey), TdsEnums.TCE_PARAM_COLUMNENCRYPTION_KEY); - } - - static internal Exception NullColumnEncryptionKey() - { - return ADP.ArgumentNull(TdsEnums.TCE_PARAM_COLUMNENCRYPTION_KEY, StringsHelper.GetString(Strings.TCE_NullColumnEncryptionKey)); - } - - static internal Exception EmptyEncryptedColumnEncryptionKey() - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_EmptyEncryptedColumnEncryptionKey), TdsEnums.TCE_PARAM_ENCRYPTED_CEK); - } - - static internal Exception NullEncryptedColumnEncryptionKey() - { - return ADP.ArgumentNull(TdsEnums.TCE_PARAM_ENCRYPTED_CEK, StringsHelper.GetString(Strings.TCE_NullEncryptedColumnEncryptionKey)); - } - - static internal Exception LargeCertificatePathLength(int actualLength, int maxLength, bool isSystemOp) - { - if (isSystemOp) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_LargeCertificatePathLengthSysErr, actualLength, maxLength), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - else - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_LargeCertificatePathLength, actualLength, maxLength), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - } - - static internal Exception NullCertificatePath(string[] validLocations, bool isSystemOp) - { - Debug.Assert(2 == validLocations.Length); - if (isSystemOp) - { - return ADP.ArgumentNull(TdsEnums.TCE_PARAM_MASTERKEY_PATH, StringsHelper.GetString(Strings.TCE_NullCertificatePathSysErr, validLocations[0], validLocations[1], @"/")); - } - else - { - return ADP.ArgumentNull(TdsEnums.TCE_PARAM_MASTERKEY_PATH, StringsHelper.GetString(Strings.TCE_NullCertificatePath, validLocations[0], validLocations[1], @"/")); - } - } - - static internal Exception NullCspKeyPath(bool isSystemOp) - { - if (isSystemOp) - { - return ADP.ArgumentNull(TdsEnums.TCE_PARAM_MASTERKEY_PATH, StringsHelper.GetString(Strings.TCE_NullCspPathSysErr, @"/")); - } - else - { - return ADP.ArgumentNull(TdsEnums.TCE_PARAM_MASTERKEY_PATH, StringsHelper.GetString(Strings.TCE_NullCspPath, @"/")); - } - } - - static internal Exception NullCngKeyPath(bool isSystemOp) - { - if (isSystemOp) - { - return ADP.ArgumentNull(TdsEnums.TCE_PARAM_MASTERKEY_PATH, StringsHelper.GetString(Strings.TCE_NullCngPathSysErr, @"/")); - } - else - { - return ADP.ArgumentNull(TdsEnums.TCE_PARAM_MASTERKEY_PATH, StringsHelper.GetString(Strings.TCE_NullCngPath, @"/")); - } - } - - static internal Exception InvalidCertificatePath(string actualCertificatePath, string[] validLocations, bool isSystemOp) - { - Debug.Assert(2 == validLocations.Length); - if (isSystemOp) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCertificatePathSysErr, actualCertificatePath, validLocations[0], validLocations[1], @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - else - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCertificatePath, actualCertificatePath, validLocations[0], validLocations[1], @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - } - - static internal Exception InvalidCspPath(string masterKeyPath, bool isSystemOp) - { - if (isSystemOp) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCspPathSysErr, masterKeyPath, @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - else - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCspPath, masterKeyPath, @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - } - - static internal Exception InvalidCngPath(string masterKeyPath, bool isSystemOp) - { - if (isSystemOp) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCngPathSysErr, masterKeyPath, @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - else - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCngPath, masterKeyPath, @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - } - - static internal Exception EmptyCspName(string masterKeyPath, bool isSystemOp) - { - if (isSystemOp) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_EmptyCspNameSysErr, masterKeyPath, @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - else - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_EmptyCspName, masterKeyPath, @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - } - - static internal Exception EmptyCngName(string masterKeyPath, bool isSystemOp) - { - if (isSystemOp) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_EmptyCngNameSysErr, masterKeyPath, @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - else - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_EmptyCngName, masterKeyPath, @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - } - - static internal Exception EmptyCspKeyId(string masterKeyPath, bool isSystemOp) - { - if (isSystemOp) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_EmptyCspKeyIdSysErr, masterKeyPath, @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - else - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_EmptyCspKeyId, masterKeyPath, @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - } - - static internal Exception EmptyCngKeyId(string masterKeyPath, bool isSystemOp) - { - if (isSystemOp) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_EmptyCngKeyIdSysErr, masterKeyPath, @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - else - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_EmptyCngKeyId, masterKeyPath, @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - } - - static internal Exception InvalidCspName(string cspName, string masterKeyPath, bool isSystemOp) - { - if (isSystemOp) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCspNameSysErr, cspName, masterKeyPath), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - else - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCspName, cspName, masterKeyPath), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - } - - static internal Exception InvalidCspKeyIdentifier(string keyIdentifier, string masterKeyPath, bool isSystemOp) - { - if (isSystemOp) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCspKeyIdSysErr, keyIdentifier, masterKeyPath), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - else - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCspKeyId, keyIdentifier, masterKeyPath), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - } - - static internal Exception InvalidCngKey(string masterKeyPath, string cngProviderName, string keyIdentifier, bool isSystemOp) - { - if (isSystemOp) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCngKeySysErr, masterKeyPath, cngProviderName, keyIdentifier), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - else - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCngKey, masterKeyPath, cngProviderName, keyIdentifier), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - } - - static internal Exception InvalidCertificateLocation(string certificateLocation, string certificatePath, string[] validLocations, bool isSystemOp) - { - Debug.Assert(2 == validLocations.Length); - if (isSystemOp) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCertificateLocationSysErr, certificateLocation, certificatePath, validLocations[0], validLocations[1], @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - else - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCertificateLocation, certificateLocation, certificatePath, validLocations[0], validLocations[1], @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - } - - static internal Exception InvalidCertificateStore(string certificateStore, string certificatePath, string validCertificateStore, bool isSystemOp) - { - if (isSystemOp) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCertificateStoreSysErr, certificateStore, certificatePath, validCertificateStore), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - else - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCertificateStore, certificateStore, certificatePath, validCertificateStore), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - } - - static internal Exception EmptyCertificateThumbprint(string certificatePath, bool isSystemOp) - { - if (isSystemOp) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_EmptyCertificateThumbprintSysErr, certificatePath), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - else - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_EmptyCertificateThumbprint, certificatePath), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - } - - static internal Exception CertificateNotFound(string thumbprint, string certificateLocation, string certificateStore, bool isSystemOp) - { - if (isSystemOp) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_CertificateNotFoundSysErr, thumbprint, certificateLocation, certificateStore), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - else - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_CertificateNotFound, thumbprint, certificateLocation, certificateStore), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - } - - static internal Exception InvalidAlgorithmVersionInEncryptedCEK(byte actual, byte expected) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidAlgorithmVersionInEncryptedCEK, actual.ToString(@"X2"), expected.ToString(@"X2")), TdsEnums.TCE_PARAM_ENCRYPTED_CEK); - } - - static internal Exception InvalidCiphertextLengthInEncryptedCEK(int actual, int expected, string certificateName) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCiphertextLengthInEncryptedCEK, actual, expected, certificateName), TdsEnums.TCE_PARAM_ENCRYPTED_CEK); - } - - static internal Exception InvalidCiphertextLengthInEncryptedCEKCsp(int actual, int expected, string masterKeyPath) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCiphertextLengthInEncryptedCEKCsp, actual, expected, masterKeyPath), TdsEnums.TCE_PARAM_ENCRYPTED_CEK); - } - - static internal Exception InvalidCiphertextLengthInEncryptedCEKCng(int actual, int expected, string masterKeyPath) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCiphertextLengthInEncryptedCEKCng, actual, expected, masterKeyPath), TdsEnums.TCE_PARAM_ENCRYPTED_CEK); - } - - static internal Exception InvalidSignatureInEncryptedCEK(int actual, int expected, string masterKeyPath) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidSignatureInEncryptedCEK, actual, expected, masterKeyPath), TdsEnums.TCE_PARAM_ENCRYPTED_CEK); - } - - static internal Exception InvalidSignatureInEncryptedCEKCsp(int actual, int expected, string masterKeyPath) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidSignatureInEncryptedCEKCsp, actual, expected, masterKeyPath), TdsEnums.TCE_PARAM_ENCRYPTED_CEK); - } - - static internal Exception InvalidSignatureInEncryptedCEKCng(int actual, int expected, string masterKeyPath) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidSignatureInEncryptedCEKCng, actual, expected, masterKeyPath), TdsEnums.TCE_PARAM_ENCRYPTED_CEK); - } - - static internal Exception InvalidCertificateSignature(string certificatePath) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCertificateSignature, certificatePath), TdsEnums.TCE_PARAM_ENCRYPTED_CEK); - } - - static internal Exception InvalidSignature(string masterKeyPath) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidSignature, masterKeyPath), TdsEnums.TCE_PARAM_ENCRYPTED_CEK); - } - - static internal Exception CertificateWithNoPrivateKey(string keyPath, bool isSystemOp) - { - if (isSystemOp) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_CertificateWithNoPrivateKeySysErr, keyPath), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - else - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_CertificateWithNoPrivateKey, keyPath), TdsEnums.TCE_PARAM_MASTERKEY_PATH); - } - } - - // - // TCE - Cryptographic Algorithms Error messages - // - static internal Exception NullColumnEncryptionKeySysErr() - { - return ADP.ArgumentNull(TdsEnums.TCE_PARAM_ENCRYPTIONKEY, StringsHelper.GetString(Strings.TCE_NullColumnEncryptionKeySysErr)); - } - - static internal Exception InvalidKeySize(string algorithmName, int actualKeylength, int expectedLength) - { - return ADP.Argument(StringsHelper.GetString( - Strings.TCE_InvalidKeySize, - algorithmName, - actualKeylength, - expectedLength), TdsEnums.TCE_PARAM_ENCRYPTIONKEY); - } - - static internal Exception InvalidEncryptionType(string algorithmName, SqlClientEncryptionType encryptionType, params SqlClientEncryptionType[] validEncryptionTypes) - { - const string valueSeparator = @", "; - return ADP.Argument( - StringsHelper.GetString( - Strings.TCE_InvalidEncryptionType, - algorithmName, - encryptionType.ToString(), - string.Join(valueSeparator, Map(validEncryptionTypes, static validEncryptionType => $"'{validEncryptionType:G}'")) - ), - TdsEnums.TCE_PARAM_ENCRYPTIONTYPE - ); - } - - static internal Exception NullPlainText() - { - return ADP.ArgumentNull(StringsHelper.GetString(Strings.TCE_NullPlainText)); - } - - static internal Exception VeryLargeCiphertext(long cipherTextLength, long maxCipherTextSize, long plainTextLength) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_VeryLargeCiphertext, cipherTextLength, maxCipherTextSize, plainTextLength)); - } - - static internal Exception NullCipherText() - { - return ADP.ArgumentNull(StringsHelper.GetString(Strings.TCE_NullCipherText)); - } - - static internal Exception InvalidCipherTextSize(int actualSize, int minimumSize) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCipherTextSize, actualSize, minimumSize), TdsEnums.TCE_PARAM_CIPHERTEXT); - } - - static internal Exception InvalidAlgorithmVersion(byte actual, byte expected) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidAlgorithmVersion, actual.ToString(@"X2"), expected.ToString(@"X2")), TdsEnums.TCE_PARAM_CIPHERTEXT); - } - - static internal Exception InvalidAuthenticationTag() - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidAuthenticationTag), TdsEnums.TCE_PARAM_CIPHERTEXT); - } - - static internal Exception NullColumnEncryptionAlgorithm(string supportedAlgorithms) - { - return ADP.ArgumentNull(TdsEnums.TCE_PARAM_ENCRYPTION_ALGORITHM, StringsHelper.GetString(Strings.TCE_NullColumnEncryptionAlgorithm, supportedAlgorithms)); - } - - // - // TCE - Errors from sp_describe_parameter_encryption - // - static internal Exception UnexpectedDescribeParamFormatParameterMetadata() - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_UnexpectedDescribeParamFormatParameterMetadata, "sp_describe_parameter_encryption")); - } - - static internal Exception UnexpectedDescribeParamFormatAttestationInfo(string enclaveType) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_UnexpectedDescribeParamFormatAttestationInfo, "sp_describe_parameter_encryption", enclaveType)); - } - - static internal Exception InvalidEncryptionKeyOrdinalEnclaveMetadata(int ordinal, int maxOrdinal) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_InvalidEncryptionKeyOrdinalEnclaveMetadata, ordinal, maxOrdinal)); - } - static internal Exception InvalidEncryptionKeyOrdinalParameterMetadata(int ordinal, int maxOrdinal) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_InvalidEncryptionKeyOrdinalParameterMetadata, ordinal, maxOrdinal)); - } - - public static Exception MultipleRowsReturnedForAttestationInfo() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_MultipleRowsReturnedForAttestationInfo, "sp_describe_parameter_encryption")); - } - - static internal Exception ParamEncryptionMetadataMissing(string paramName, string procedureName) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_ParamEncryptionMetaDataMissing, "sp_describe_parameter_encryption", paramName, procedureName)); - } - - static internal Exception ParamInvalidForceColumnEncryptionSetting(string paramName, string procedureName) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_ParamInvalidForceColumnEncryptionSetting, TdsEnums.TCE_PARAM_FORCE_COLUMN_ENCRYPTION, paramName, procedureName, "SqlParameter")); - } - - static internal Exception ParamUnExpectedEncryptionMetadata(string paramName, string procedureName) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_ParamUnExpectedEncryptionMetadata, paramName, procedureName, TdsEnums.TCE_PARAM_FORCE_COLUMN_ENCRYPTION, "SqlParameter")); - } - - static internal Exception ProcEncryptionMetadataMissing(string procedureName) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_ProcEncryptionMetaDataMissing, "sp_describe_parameter_encryption", procedureName)); - } - - static internal Exception InvalidKeyStoreProviderName(string providerName, List systemProviders, List customProviders) - { - const string valueSeparator = @", "; - string systemProviderStr = string.Join(valueSeparator, Map(systemProviders, static provider => $"'{provider}'")); - string customProviderStr = string.Join(valueSeparator, Map(customProviders, static provider => $"'{provider}'")); - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidKeyStoreProviderName, providerName, systemProviderStr, customProviderStr)); - } - - static internal Exception UnableToVerifyColumnMasterKeySignature(Exception innerException) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_UnableToVerifyColumnMasterKeySignature, innerException.Message), innerException); - } - - static internal Exception ColumnMasterKeySignatureVerificationFailed(string cmkPath) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_ColumnMasterKeySignatureVerificationFailed, cmkPath)); - } - - static internal Exception ColumnMasterKeySignatureNotFound(string cmkPath) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_ColumnMasterKeySignatureNotFound, cmkPath)); - } - - // - // TCE - Errors from secure channel Communication - // - internal static Exception ExceptionWhenGeneratingEnclavePackage(Exception innerException) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_ExceptionWhenGeneratingEnclavePackage, innerException.Message), innerException); - } - - static internal Exception FailedToEncryptRegisterRulesBytePackage(Exception innerException) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_FailedToEncryptRegisterRulesBytePackage, innerException.Message), innerException); - } - - static internal Exception InvalidKeyIdUnableToCastToUnsignedShort(int keyId, Exception innerException) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidKeyIdUnableToCastToUnsignedShort, keyId, innerException.Message), innerException); - } - - static internal Exception InvalidDatabaseIdUnableToCastToUnsignedInt(int databaseId, Exception innerException) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidDatabaseIdUnableToCastToUnsignedInt, databaseId, innerException.Message), innerException); - } - - static internal Exception InvalidAttestationParameterUnableToConvertToUnsignedInt(string variableName, int intValue, string enclaveType, Exception innerException) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidAttestationParameterUnableToConvertToUnsignedInt, enclaveType, intValue, variableName, innerException.Message), innerException); - } - - static internal Exception OffsetOutOfBounds(string argument, string type, string method) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_OffsetOutOfBounds, type, method)); - } - - static internal Exception InsufficientBuffer(string argument, string type, string method) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InsufficientBuffer, argument, type, method)); - } - - static internal Exception ColumnEncryptionKeysNotFound() - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_ColumnEncryptionKeysNotFound)); - } - - internal static SqlException AttestationFailed(string errorMessage, Exception innerException = null) - { - SqlErrorCollection errors = new(); - errors.Add(new SqlError( - infoNumber: 0, - errorState: 0, - errorClass: 0, - server: null, - errorMessage, - procedure: string.Empty, - lineNumber: 0)); - return SqlException.CreateException(errors, serverVersion: string.Empty, Guid.Empty, innerException); - } - - // - // TCE - Errors when performing attestation - // - - static internal Exception AttestationInfoNotReturnedFromSqlServer(string enclaveType, string enclaveAttestationUrl) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_AttestationInfoNotReturnedFromSQLServer, enclaveType, enclaveAttestationUrl)); - } - - // - // TCE - Errors when establishing secure channel - // - static internal Exception NullArgumentInConstructorInternal(string argumentName, string objectUnderConstruction) - { - return ADP.ArgumentNull(argumentName, StringsHelper.GetString(Strings.TCE_NullArgumentInConstructorInternal, argumentName, objectUnderConstruction)); - } - - static internal Exception EmptyArgumentInConstructorInternal(string argumentName, string objectUnderConstruction) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_EmptyArgumentInConstructorInternal, argumentName, objectUnderConstruction)); - } - - static internal Exception NullArgumentInternal(string argumentName, string type, string method) - { - return ADP.ArgumentNull(argumentName, StringsHelper.GetString(Strings.TCE_NullArgumentInternal, argumentName, type, method)); - } - - static internal Exception EmptyArgumentInternal(string argumentName, string type, string method) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_EmptyArgumentInternal, argumentName, type, method)); - } - - // - // TCE - enclave provider/configuration errors - // - static internal Exception CannotGetSqlColumnEncryptionEnclaveProviderConfig(Exception innerException) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_CannotGetSqlColumnEncryptionEnclaveProviderConfig, innerException.Message), innerException); - } - - static internal Exception CannotCreateSqlColumnEncryptionEnclaveProvider(string providerName, string type, Exception innerException) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_CannotCreateSqlColumnEncryptionEnclaveProvider, providerName, type, innerException.Message), innerException); - } - - static internal Exception SqlColumnEncryptionEnclaveProviderNameCannotBeEmpty() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_SqlColumnEncryptionEnclaveProviderNameCannotBeEmpty)); - } - - static internal Exception NoAttestationUrlSpecifiedForEnclaveBasedQuerySpDescribe(string enclaveType) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_NoAttestationUrlSpecifiedForEnclaveBasedQuerySpDescribe, "sp_describe_parameter_encryption", enclaveType)); - } - - static internal Exception NoAttestationUrlSpecifiedForEnclaveBasedQueryGeneratingEnclavePackage(string enclaveType) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_NoAttestationUrlSpecifiedForEnclaveBasedQueryGeneratingEnclavePackage, enclaveType)); - } - - static internal Exception EnclaveTypeNullForEnclaveBasedQuery() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_EnclaveTypeNullForEnclaveBasedQuery)); - } - - static internal Exception EnclaveProvidersNotConfiguredForEnclaveBasedQuery() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_EnclaveProvidersNotConfiguredForEnclaveBasedQuery)); - } - - static internal Exception EnclaveProviderNotFound(string enclaveType, string attestationProtocol) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_EnclaveProviderNotFound, enclaveType, attestationProtocol)); - } - - static internal Exception AttestationProtocolNotSpecifiedForGeneratingEnclavePackage() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_AttestationProtocolNotSpecifiedForGeneratingEnclavePackage)); - } - - static internal Exception NullEnclaveSessionReturnedFromProvider(string enclaveType, string attestationUrl) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_NullEnclaveSessionReturnedFromProvider, enclaveType, attestationUrl)); - } - - // - // TCE- Generic toplevel failuStrings. - // - static internal Exception GetExceptionArray(string serverName, string errorMessage, Exception e) - { - // Create and throw an exception array - SqlErrorCollection sqlErs = new SqlErrorCollection(); - Exception exceptionToInclude = (null != e.InnerException) ? e.InnerException : e; - sqlErs.Add(new SqlError(infoNumber: 0, errorState: (byte)0x00, errorClass: (byte)TdsEnums.MIN_ERROR_CLASS, server: serverName, errorMessage: errorMessage, procedure: null, lineNumber: 0)); - - if (e is SqlException) - { - SqlException exThrown = (SqlException)e; - SqlErrorCollection errorList = exThrown.Errors; - for (int i = 0; i < exThrown.Errors.Count; i++) - { - sqlErs.Add(errorList[i]); - } - } - else - { - sqlErs.Add(new SqlError(infoNumber: 0, errorState: (byte)0x00, errorClass: (byte)TdsEnums.MIN_ERROR_CLASS, server: serverName, errorMessage: e.Message, procedure: null, lineNumber: 0)); - } - - return SqlException.CreateException(sqlErs, "", null, exceptionToInclude); - } - - static internal Exception ParamEncryptionFailed(string paramName, string serverName, Exception e) - { - return GetExceptionArray(serverName, StringsHelper.GetString(Strings.TCE_ParamEncryptionFailed, paramName), e); - } - - static internal Exception ParamDecryptionFailed(string paramName, string serverName, Exception e) - { - return GetExceptionArray(serverName, StringsHelper.GetString(Strings.TCE_ParamDecryptionFailed, paramName), e); - } - - static internal Exception ColumnDecryptionFailed(string columnName, string serverName, Exception e) - { - return GetExceptionArray(serverName, StringsHelper.GetString(Strings.TCE_ColumnDecryptionFailed, columnName), e); - } - - // - // TCE- Client side query processing errors. - // - static internal Exception UnknownColumnEncryptionAlgorithm(string algorithmName, string supportedAlgorithms) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_UnknownColumnEncryptionAlgorithm, algorithmName, supportedAlgorithms)); - } - - static internal Exception UnknownColumnEncryptionAlgorithmId(int algoId, string supportAlgorithmIds) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_UnknownColumnEncryptionAlgorithmId, algoId, supportAlgorithmIds), TdsEnums.TCE_PARAM_CIPHER_ALGORITHM_ID); - } - - static internal Exception UnsupportedNormalizationVersion(byte version) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_UnsupportedNormalizationVersion, version, "'1'", "SQL Server")); - } - - static internal Exception UnrecognizedKeyStoreProviderName(string providerName, List systemProviders, List customProviders) - { - const string valueSeparator = @", "; - string systemProviderStr = string.Join(valueSeparator, Map(systemProviders, static provider => @"'" + provider + @"'")); - string customProviderStr = string.Join(valueSeparator, Map(customProviders, static provider => @"'" + provider + @"'")); - return ADP.Argument(StringsHelper.GetString(Strings.TCE_UnrecognizedKeyStoreProviderName, providerName, systemProviderStr, customProviderStr)); - } - - static internal Exception InvalidDataTypeForEncryptedParameter(string parameterName, int actualDataType, int expectedDataType) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_NullProviderValue, parameterName, actualDataType, expectedDataType)); - } - - static internal Exception KeyDecryptionFailed(string providerName, string keyHex, Exception e) - { - if (providerName.Equals(SqlColumnEncryptionCertificateStoreProvider.ProviderName)) - { - return GetExceptionArray(null, StringsHelper.GetString(Strings.TCE_KeyDecryptionFailedCertStore, providerName, keyHex), e); - } - else - { - return GetExceptionArray(null, StringsHelper.GetString(Strings.TCE_KeyDecryptionFailed, providerName, keyHex), e); - } - } - - static internal Exception UntrustedKeyPath(string keyPath, string serverName) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_UntrustedKeyPath, keyPath, serverName)); - } - - static internal Exception UnsupportedDatatypeEncryption(string dataType) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_UnsupportedDatatype, dataType)); - } - - static internal Exception ThrowDecryptionFailed(string keyStr, string valStr, Exception e) - { - return GetExceptionArray(null, StringsHelper.GetString(Strings.TCE_DecryptionFailed, keyStr, valStr), e); - } - - static internal Exception NullEnclaveSessionDuringQueryExecution(string enclaveType, string enclaveAttestationUrl) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_NullEnclaveSessionDuringQueryExecution, enclaveType, enclaveAttestationUrl)); - } - - static internal Exception NullEnclavePackageForEnclaveBasedQuery(string enclaveType, string enclaveAttestationUrl) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_NullEnclavePackageForEnclaveBasedQuery, enclaveType, enclaveAttestationUrl)); - } - - // - // TCE- SQL connection related error messages - // - static internal Exception TceNotSupported() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_NotSupportedByServer, "SQL Server")); - } - - static internal Exception EnclaveComputationsNotSupported() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_EnclaveComputationsNotSupported)); - } - - internal static Exception AttestationURLNotSupported() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_AttestationURLNotSupported)); - } - - internal static Exception AttestationProtocolNotSupported() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_AttestationProtocolNotSupported)); - } - - static internal Exception EnclaveTypeNotReturned() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_EnclaveTypeNotReturned)); - } - - static internal Exception EnclaveTypeNotSupported(string enclaveType) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_EnclaveTypeNotSupported, enclaveType)); - } - - static internal Exception AttestationProtocolNotSupportEnclaveType(string attestationProtocolStr, string enclaveType) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_AttestationProtocolNotSupportEnclaveType, attestationProtocolStr, enclaveType)); - } - - // - // TCE- Extensibility related error messages - // - static internal Exception CanOnlyCallOnce() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_CanOnlyCallOnce)); - } - - static internal Exception NullCustomKeyStoreProviderDictionary() - { - return ADP.ArgumentNull(TdsEnums.TCE_PARAM_CLIENT_KEYSTORE_PROVIDERS, StringsHelper.GetString(Strings.TCE_NullCustomKeyStoreProviderDictionary)); - } - - static internal Exception InvalidCustomKeyStoreProviderName(string providerName, string prefix) - { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCustomKeyStoreProviderName, providerName, prefix), TdsEnums.TCE_PARAM_CLIENT_KEYSTORE_PROVIDERS); - } - - static internal Exception NullProviderValue(string providerName) - { - return ADP.ArgumentNull(TdsEnums.TCE_PARAM_CLIENT_KEYSTORE_PROVIDERS, StringsHelper.GetString(Strings.TCE_NullProviderValue, providerName)); - } - - static internal Exception EmptyProviderName() - { - return ADP.ArgumentNull(TdsEnums.TCE_PARAM_CLIENT_KEYSTORE_PROVIDERS, StringsHelper.GetString(Strings.TCE_EmptyProviderName)); - } - - // - // transactions. - // - static internal Exception ConnectionDoomed() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ConnectionDoomed)); - } - - static internal Exception OpenResultCountExceeded() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_OpenResultCountExceeded)); - } - - // - // Global Transactions. - // - static internal Exception GlobalTransactionsNotEnabled() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.GT_Disabled)); - } - - static internal Exception UnsupportedSysTxForGlobalTransactions() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.GT_UnsupportedSysTxVersion)); - } - - static internal readonly byte[] AttentionHeader = new byte[] { - TdsEnums.MT_ATTN, // Message Type - TdsEnums.ST_EOM, // Status - TdsEnums.HEADER_LEN >> 8, // length - upper byte - TdsEnums.HEADER_LEN & 0xff, // length - lower byte - 0, // spid - 0, // spid - 0, // packet (out of band) - 0 // window - }; - - // - // MultiSubnetFailover - // - - /// - /// used to block two scenarios if MultiSubnetFailover is true: - /// * server-provided failover partner - raising SqlException in this case - /// * connection string with failover partner and MultiSubnetFailover=true - rasing argument one in this case with the same message - /// - static internal Exception MultiSubnetFailoverWithFailoverPartner(bool serverProvidedFailoverPartner, SqlInternalConnectionTds internalConnection) - { - string msg = StringsHelper.GetString(Strings.SQLMSF_FailoverPartnerNotSupported); - if (serverProvidedFailoverPartner) - { - // VSTFDEVDIV\DevDiv2\179041 - replacing InvalidOperation with SQL exception - SqlErrorCollection errors = new SqlErrorCollection(); - errors.Add(new SqlError(0, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, null, msg, "", 0)); - SqlException exc = SqlException.CreateException(errors, null, internalConnection, innerException: null, batchCommand: null); - exc._doNotReconnect = true; // disable open retry logic on this error - return exc; - } - else - { - return ADP.Argument(msg); - } - } - - static internal Exception MultiSubnetFailoverWithMoreThan64IPs() - { - string msg = GetSNIErrorMessage((int)SNINativeMethodWrapper.SniSpecialErrors.MultiSubnetFailoverWithMoreThan64IPs); - return ADP.InvalidOperation(msg); - } - - static internal Exception MultiSubnetFailoverWithInstanceSpecified() - { - string msg = GetSNIErrorMessage((int)SNINativeMethodWrapper.SniSpecialErrors.MultiSubnetFailoverWithInstanceSpecified); - return ADP.Argument(msg); - } - - static internal Exception MultiSubnetFailoverWithNonTcpProtocol() - { - string msg = GetSNIErrorMessage((int)SNINativeMethodWrapper.SniSpecialErrors.MultiSubnetFailoverWithNonTcpProtocol); - return ADP.Argument(msg); - } - - // - // Read-only routing - // - - static internal Exception ROR_FailoverNotSupportedConnString() - { - return ADP.Argument(StringsHelper.GetString(Strings.SQLROR_FailoverNotSupported)); - } - - static internal Exception ROR_FailoverNotSupportedServer(SqlInternalConnectionTds internalConnection) - { - SqlErrorCollection errors = new SqlErrorCollection(); - errors.Add(new SqlError(0, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, null, (StringsHelper.GetString(Strings.SQLROR_FailoverNotSupported)), "", 0)); - SqlException exc = SqlException.CreateException(errors, null, internalConnection, innerException: null, batchCommand: null); - exc._doNotReconnect = true; - return exc; - } - - static internal Exception ROR_RecursiveRoutingNotSupported(SqlInternalConnectionTds internalConnection) - { - SqlErrorCollection errors = new SqlErrorCollection(); - errors.Add(new SqlError(0, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, null, (StringsHelper.GetString(Strings.SQLROR_RecursiveRoutingNotSupported)), "", 0)); - SqlException exc = SqlException.CreateException(errors, null, internalConnection, innerException: null, batchCommand: null); - exc._doNotReconnect = true; - return exc; - } - - static internal Exception ROR_UnexpectedRoutingInfo(SqlInternalConnectionTds internalConnection) - { - SqlErrorCollection errors = new SqlErrorCollection(); - errors.Add(new SqlError(0, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, null, (StringsHelper.GetString(Strings.SQLROR_UnexpectedRoutingInfo)), "", 0)); - SqlException exc = SqlException.CreateException(errors, null, internalConnection, innerException: null, batchCommand: null); - exc._doNotReconnect = true; - return exc; - } - - static internal Exception ROR_InvalidRoutingInfo(SqlInternalConnectionTds internalConnection) - { - SqlErrorCollection errors = new SqlErrorCollection(); - errors.Add(new SqlError(0, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, null, (StringsHelper.GetString(Strings.SQLROR_InvalidRoutingInfo)), "", 0)); - SqlException exc = SqlException.CreateException(errors, null, internalConnection, innerException: null, batchCommand: null); - exc._doNotReconnect = true; - return exc; - } - - static internal Exception ROR_TimeoutAfterRoutingInfo(SqlInternalConnectionTds internalConnection) - { - SqlErrorCollection errors = new SqlErrorCollection(); - errors.Add(new SqlError(0, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, null, (StringsHelper.GetString(Strings.SQLROR_TimeoutAfterRoutingInfo)), "", 0)); - SqlException exc = SqlException.CreateException(errors, null, internalConnection, innerException: null, batchCommand: null); - exc._doNotReconnect = true; - return exc; - } - - // - // Connection resiliency - // - static internal SqlException CR_ReconnectTimeout() - { - SqlErrorCollection errors = new SqlErrorCollection(); - errors.Add(new SqlError(TdsEnums.TIMEOUT_EXPIRED, (byte)0x00, TdsEnums.MIN_ERROR_CLASS, null, SQLMessage.Timeout(), "", 0, TdsEnums.SNI_WAIT_TIMEOUT)); - SqlException exc = SqlException.CreateException(errors, ""); - return exc; - } - - static internal SqlException CR_ReconnectionCancelled() - { - SqlErrorCollection errors = new SqlErrorCollection(); - errors.Add(new SqlError(0, 0, TdsEnums.MIN_ERROR_CLASS, null, SQLMessage.OperationCancelled(), "", 0)); - SqlException exc = SqlException.CreateException(errors, ""); - return exc; - } - - static internal Exception CR_NextAttemptWillExceedQueryTimeout(SqlException innerException, Guid connectionId) - { - SqlErrorCollection errors = new SqlErrorCollection(); - errors.Add(new SqlError(0, 0, TdsEnums.MIN_ERROR_CLASS, null, StringsHelper.GetString(Strings.SQLCR_NextAttemptWillExceedQueryTimeout), "", 0)); - SqlException exc = SqlException.CreateException(errors, "", connectionId, innerException, batchCommand: null); - return exc; - } - - static internal Exception CR_EncryptionChanged(SqlInternalConnectionTds internalConnection) - { - SqlErrorCollection errors = new SqlErrorCollection(); - errors.Add(new SqlError(0, 0, TdsEnums.FATAL_ERROR_CLASS, null, StringsHelper.GetString(Strings.SQLCR_EncryptionChanged), "", 0)); - SqlException exc = SqlException.CreateException(errors, "", internalConnection, innerException: null, batchCommand: null); - return exc; - } - - static internal SqlException CR_AllAttemptsFailed(SqlException innerException, Guid connectionId) - { - SqlErrorCollection errors = new SqlErrorCollection(); - errors.Add(new SqlError(0, 0, TdsEnums.MIN_ERROR_CLASS, null, StringsHelper.GetString(Strings.SQLCR_AllAttemptsFailed), "", 0)); - SqlException exc = SqlException.CreateException(errors, "", connectionId, innerException, batchCommand: null); - return exc; - } - - static internal SqlException CR_NoCRAckAtReconnection(SqlInternalConnectionTds internalConnection) - { - SqlErrorCollection errors = new SqlErrorCollection(); - errors.Add(new SqlError(0, 0, TdsEnums.FATAL_ERROR_CLASS, null, StringsHelper.GetString(Strings.SQLCR_NoCRAckAtReconnection), "", 0)); - SqlException exc = SqlException.CreateException(errors, "", internalConnection, innerException: null, batchCommand: null); - return exc; - } - - static internal SqlException CR_TDSVersionNotPreserved(SqlInternalConnectionTds internalConnection) - { - SqlErrorCollection errors = new SqlErrorCollection(); - errors.Add(new SqlError(0, 0, TdsEnums.FATAL_ERROR_CLASS, null, StringsHelper.GetString(Strings.SQLCR_TDSVestionNotPreserved), "", 0)); - SqlException exc = SqlException.CreateException(errors, "", internalConnection, innerException: null, batchCommand: null); - return exc; - } - - static internal SqlException CR_UnrecoverableServer(Guid connectionId) - { - SqlErrorCollection errors = new SqlErrorCollection(); - errors.Add(new SqlError(0, 0, TdsEnums.FATAL_ERROR_CLASS, null, StringsHelper.GetString(Strings.SQLCR_UnrecoverableServer), "", 0)); - SqlException exc = SqlException.CreateException(errors, "", connectionId, innerException: null, batchCommand: null); - return exc; - } - - static internal SqlException CR_UnrecoverableClient(Guid connectionId) - { - SqlErrorCollection errors = new SqlErrorCollection(); - errors.Add(new SqlError(0, 0, TdsEnums.FATAL_ERROR_CLASS, null, StringsHelper.GetString(Strings.SQLCR_UnrecoverableClient), "", 0)); - SqlException exc = SqlException.CreateException(errors, "", connectionId, innerException: null, batchCommand: null); - return exc; - } - internal static Exception Azure_ManagedIdentityException(string msg) - { - SqlErrorCollection errors = new SqlErrorCollection - { - new SqlError(0, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, null, msg, "", 0) - }; - SqlException exc = SqlException.CreateException(errors, null); - exc._doNotReconnect = true; // disable open retry logic on this error - return exc; - } - - // - // Merged Provider - // - static internal Exception BatchedUpdatesNotAvailableOnContextConnection() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BatchedUpdatesNotAvailableOnContextConnection)); - } - static internal Exception ContextAllowsLimitedKeywords() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ContextAllowsLimitedKeywords)); - } - static internal Exception ContextAllowsOnlyTypeSystem2005() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ContextAllowsOnlyTypeSystem2005)); - } - static internal Exception ContextConnectionIsInUse() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ContextConnectionIsInUse)); - } - static internal Exception ContextUnavailableOutOfProc() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ContextUnavailableOutOfProc)); - } - static internal Exception ContextUnavailableWhileInProc() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ContextUnavailableWhileInProc)); - } - static internal Exception NestedTransactionScopesNotSupported() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_NestedTransactionScopesNotSupported)); - } - static internal Exception NotAvailableOnContextConnection() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_NotAvailableOnContextConnection)); - } - static internal Exception NotificationsNotAvailableOnContextConnection() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_NotificationsNotAvailableOnContextConnection)); - } - static internal Exception UnexpectedSmiEvent(Microsoft.Data.SqlClient.Server.SmiEventSink_Default.UnexpectedEventType eventType) - { - Debug.Assert(false, "UnexpectedSmiEvent: " + eventType.ToString()); // Assert here, because these exceptions will most likely be eaten by the server. - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_UnexpectedSmiEvent, (int)eventType)); - } - static internal Exception UserInstanceNotAvailableInProc() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_UserInstanceNotAvailableInProc)); - } - static internal Exception ArgumentLengthMismatch(string arg1, string arg2) - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_ArgumentLengthMismatch, arg1, arg2)); - } - static internal Exception InvalidSqlDbTypeOneAllowedType(SqlDbType invalidType, string method, SqlDbType allowedType) - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_InvalidSqlDbTypeWithOneAllowedType, invalidType, method, allowedType)); - } - static internal Exception SqlPipeErrorRequiresSendEnd() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_PipeErrorRequiresSendEnd)); - } - static internal Exception TooManyValues(string arg) - { - return ADP.Argument(StringsHelper.GetString(Strings.SQL_TooManyValues), arg); - } - static internal Exception StreamWriteNotSupported() - { - return ADP.NotSupported(StringsHelper.GetString(Strings.SQL_StreamWriteNotSupported)); - } - static internal Exception StreamReadNotSupported() - { - return ADP.NotSupported(StringsHelper.GetString(Strings.SQL_StreamReadNotSupported)); - } - static internal Exception StreamSeekNotSupported() - { - return ADP.NotSupported(StringsHelper.GetString(Strings.SQL_StreamSeekNotSupported)); - } - static internal System.Data.SqlTypes.SqlNullValueException SqlNullValue() - { - System.Data.SqlTypes.SqlNullValueException e = new System.Data.SqlTypes.SqlNullValueException(); - ADP.TraceExceptionAsReturnValue(e); - return e; - } - // SQLBU 402363: Exception to prevent Parameter.Size data corruption case from working. - // This should be temporary until changing to correct behavior can be safely implemented. - static internal Exception ParameterSizeRestrictionFailure(int index) - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.OleDb_CommandParameterError, index.ToString(CultureInfo.InvariantCulture), "SqlParameter.Size")); - } - static internal Exception SubclassMustOverride() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlMisc_SubclassMustOverride)); - } - - /// - /// gets a message for SNI error (sniError must be valid, non-zero error code) - /// - static internal string GetSNIErrorMessage(int sniError) - { - Debug.Assert(sniError > 0 && sniError <= (int)SNINativeMethodWrapper.SniSpecialErrors.MaxErrorValue, "SNI error is out of range"); - - string errorMessageId = string.Format("SNI_ERROR_{0}", sniError); - return StringsHelper.GetString(errorMessageId); - } - - // BulkLoad - internal const string WriteToServer = "WriteToServer"; - - // Default values for SqlDependency and SqlNotificationRequest - internal const int SqlDependencyTimeoutDefault = 0; - internal const int SqlDependencyServerTimeout = 5 * 24 * 3600; // 5 days - used to compute default TTL of the dependency - internal const string SqlNotificationServiceDefault = "SqlQueryNotificationService"; - internal const string SqlNotificationStoredProcedureDefault = "SqlQueryNotificationStoredProcedure"; - - // constant strings - internal const string Transaction = "Transaction"; - internal const string Connection = "Connection"; - - private static IEnumerable Map(IEnumerable source, Func selector) - { - if (source == null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (selector == null) - { - throw new ArgumentNullException(nameof(selector)); - } - - foreach (T element in source) - { - yield return selector(element); - } - } - } - - sealed internal class SQLMessage - { - - // UNDONE - TODO - BUG - need to possibly re-work this since Dbnetlib removed. - - private SQLMessage() { /* prevent utility class from being insantiated*/ } - - // The class SQLMessage defines the error messages that are specific to the SqlDataAdapter - // that are caused by a netlib error. The functions will be called and then return the - // appropriate error message from the resource Framework.txt. The SqlDataAdapter will then - // take the error message and then create a SqlError for the message and then place - // that into a SqlException that is either thrown to the user or cached for throwing at - // a later time. This class is used so that there will be compile time checking of error - // messages. The resource Framework.txt will ensure proper string text based on the appropriate - // locale. - - static internal string CultureIdError() - { - return StringsHelper.GetString(Strings.SQL_CultureIdError); - } - static internal string EncryptionNotSupportedByClient() - { - return StringsHelper.GetString(Strings.SQL_EncryptionNotSupportedByClient); - } - static internal string EncryptionNotSupportedByServer() - { - return StringsHelper.GetString(Strings.SQL_EncryptionNotSupportedByServer); - } - static internal string CTAIPNotSupportedByServer() - { - return StringsHelper.GetString(Strings.SQL_CTAIPNotSupportedByServer); - } - static internal string OperationCancelled() - { - return StringsHelper.GetString(Strings.SQL_OperationCancelled); - } - static internal string SevereError() - { - return StringsHelper.GetString(Strings.SQL_SevereError); - } - static internal string SSPIInitializeError() - { - return StringsHelper.GetString(Strings.SQL_SSPIInitializeError); - } - static internal string SSPIGenerateError() - { - return StringsHelper.GetString(Strings.SQL_SSPIGenerateError); - } - static internal string Timeout() - { - return StringsHelper.GetString(Strings.SQL_Timeout_Execution); - } - static internal string Timeout_PreLogin_Begin() - { - return StringsHelper.GetString(Strings.SQL_Timeout_PreLogin_Begin); - } - static internal string Timeout_PreLogin_InitializeConnection() - { - return StringsHelper.GetString(Strings.SQL_Timeout_PreLogin_InitializeConnection); - } - static internal string Timeout_PreLogin_SendHandshake() - { - return StringsHelper.GetString(Strings.SQL_Timeout_PreLogin_SendHandshake); - } - static internal string Timeout_PreLogin_ConsumeHandshake() - { - return StringsHelper.GetString(Strings.SQL_Timeout_PreLogin_ConsumeHandshake); - } - static internal string Timeout_Login_Begin() - { - return StringsHelper.GetString(Strings.SQL_Timeout_Login_Begin); - } - static internal string Timeout_Login_ProcessConnectionAuth() - { - return StringsHelper.GetString(Strings.SQL_Timeout_Login_ProcessConnectionAuth); - } - static internal string Timeout_PostLogin() - { - return StringsHelper.GetString(Strings.SQL_Timeout_PostLogin); - } - static internal string Timeout_FailoverInfo() - { - return StringsHelper.GetString(Strings.SQL_Timeout_FailoverInfo); - } - static internal string Timeout_RoutingDestination() - { - return StringsHelper.GetString(Strings.SQL_Timeout_RoutingDestinationInfo); - } - static internal string Duration_PreLogin_Begin(long PreLoginBeginDuration) - { - return StringsHelper.GetString(Strings.SQL_Duration_PreLogin_Begin, PreLoginBeginDuration); - } - static internal string Duration_PreLoginHandshake(long PreLoginBeginDuration, long PreLoginHandshakeDuration) - { - return StringsHelper.GetString(Strings.SQL_Duration_PreLoginHandshake, PreLoginBeginDuration, PreLoginHandshakeDuration); - } - static internal string Duration_Login_Begin(long PreLoginBeginDuration, long PreLoginHandshakeDuration, long LoginBeginDuration) - { - return StringsHelper.GetString(Strings.SQL_Duration_Login_Begin, PreLoginBeginDuration, PreLoginHandshakeDuration, LoginBeginDuration); - } - static internal string Duration_Login_ProcessConnectionAuth(long PreLoginBeginDuration, long PreLoginHandshakeDuration, long LoginBeginDuration, long LoginAuthDuration) - { - return StringsHelper.GetString(Strings.SQL_Duration_Login_ProcessConnectionAuth, PreLoginBeginDuration, PreLoginHandshakeDuration, LoginBeginDuration, LoginAuthDuration); - } - static internal string Duration_PostLogin(long PreLoginBeginDuration, long PreLoginHandshakeDuration, long LoginBeginDuration, long LoginAuthDuration, long PostLoginDuration) - { - return StringsHelper.GetString(Strings.SQL_Duration_PostLogin, PreLoginBeginDuration, PreLoginHandshakeDuration, LoginBeginDuration, LoginAuthDuration, PostLoginDuration); - } - static internal string UserInstanceFailure() - { - return StringsHelper.GetString(Strings.SQL_UserInstanceFailure); - } - static internal string PreloginError() - { - return StringsHelper.GetString(Strings.Snix_PreLogin); - } - static internal string ExClientConnectionId() - { - return StringsHelper.GetString(Strings.SQL_ExClientConnectionId); - } - static internal string ExErrorNumberStateClass() - { - return StringsHelper.GetString(Strings.SQL_ExErrorNumberStateClass); - } - static internal string ExOriginalClientConnectionId() - { - return StringsHelper.GetString(Strings.SQL_ExOriginalClientConnectionId); - } - static internal string ExRoutingDestination() - { - return StringsHelper.GetString(Strings.SQL_ExRoutingDestination); - } - } - - /// - /// This class holds helper methods to escape Microsoft SQL Server identifiers, such as table, schema, database or other names - /// - static internal class SqlServerEscapeHelper - { - - /// - /// Escapes the identifier with square brackets. The input has to be in unescaped form, like the parts received from MultipartIdentifier.ParseMultipartIdentifier. - /// - /// name of the identifier, in unescaped form - /// escapes the name with [], also escapes the last close bracket with double-bracket - static internal string EscapeIdentifier(string name) - { - Debug.Assert(!ADP.IsEmpty(name), "null or empty identifiers are not allowed"); - return "[" + name.Replace("]", "]]") + "]"; - } - - /// - /// Same as above EscapeIdentifier, except that output is written into StringBuilder - /// - static internal void EscapeIdentifier(StringBuilder builder, string name) - { - Debug.Assert(builder != null, "builder cannot be null"); - Debug.Assert(!ADP.IsEmpty(name), "null or empty identifiers are not allowed"); - - builder.Append("["); - builder.Append(name.Replace("]", "]]")); - builder.Append("]"); - } - - /// - /// Escape a string to be used inside TSQL literal, such as N'somename' or 'somename' - /// - static internal string EscapeStringAsLiteral(string input) - { - Debug.Assert(input != null, "input string cannot be null"); - return input.Replace("'", "''"); - } - - /// - /// Escape a string as a TSQL literal, wrapping it around with single quotes. - /// Use this method to escape input strings to prevent SQL injection - /// and to get correct behavior for embedded quotes. - /// - /// unescaped string - /// escaped and quoted literal string - static internal string MakeStringLiteral(string input) - { - if (ADP.IsEmpty(input)) - { - return "''"; - } - else - { - return "'" + EscapeStringAsLiteral(input) + "'"; - } - } - } - - /// - /// This class holds methods invoked on System.Transactions through reflection for Global Transactions - /// - static internal class SysTxForGlobalTransactions - { - - private static readonly Lazy _enlistPromotableSinglePhase = new Lazy(() => - typeof(SysTx.Transaction).GetMethod("EnlistPromotableSinglePhase", new Type[] { typeof(SysTx.IPromotableSinglePhaseNotification), typeof(Guid) })); - - private static readonly Lazy _setDistributedTransactionIdentifier = new Lazy(() => - typeof(SysTx.Transaction).GetMethod("SetDistributedTransactionIdentifier", new Type[] { typeof(SysTx.IPromotableSinglePhaseNotification), typeof(Guid) })); - - private static readonly Lazy _getPromotedToken = new Lazy(() => - typeof(SysTx.Transaction).GetMethod("GetPromotedToken")); - - /// - /// Enlists the given IPromotableSinglePhaseNotification and Non-MSDTC Promoter type into a transaction - /// - /// The MethodInfo instance to be invoked. Null if the method doesn't exist - public static MethodInfo EnlistPromotableSinglePhase - { - get - { - return _enlistPromotableSinglePhase.Value; - } - } - - /// - /// Sets the given DistributedTransactionIdentifier for a Transaction instance. - /// Needs to be invoked when using a Non-MSDTC Promoter type - /// - /// The MethodInfo instance to be invoked. Null if the method doesn't exist - public static MethodInfo SetDistributedTransactionIdentifier - { - get - { - return _setDistributedTransactionIdentifier.Value; - } - } - - /// - /// Gets the Promoted Token for a Transaction - /// - /// The MethodInfo instance to be invoked. Null if the method doesn't exist - public static MethodInfo GetPromotedToken - { - get - { - return _getPromotedToken.Value; - } - } - } -}//namespace diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlUtil.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlUtil.cs index f375644818..154872a8e4 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlUtil.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlUtil.cs @@ -4,8 +4,22 @@ using System; using System.Collections.Generic; +using System.Data; +using System.Diagnostics; +using System.Globalization; +using System.Net; +using System.Net.Sockets; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.ExceptionServices; +using System.Runtime.InteropServices; +using System.Runtime.Versioning; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Transactions; +using Microsoft.Data.Common; -// This file will be used to merge code from the NetFx and NetCore SqlUtil.cs in the future. namespace Microsoft.Data.SqlClient { /// @@ -27,6 +41,2784 @@ internal static ArgumentNullException ArgumentNull(string paramName) => new ArgumentNullException(paramName); internal static ArgumentOutOfRangeException InvalidMinAndMaxPair(string minParamName, TimeSpan minValue, string maxParamName, TimeSpan maxValue) - => new ArgumentOutOfRangeException(minParamName, StringsHelper.GetString(Strings.SqlRetryLogic_InvalidMinMaxPair, minValue, maxValue , minParamName, maxParamName)); + => new ArgumentOutOfRangeException(minParamName, StringsHelper.GetString(Strings.SqlRetryLogic_InvalidMinMaxPair, minValue, maxValue, minParamName, maxParamName)); } + + internal static class AsyncHelper + { + internal static Task CreateContinuationTask(Task task, Action onSuccess, +#if NETFRAMEWORK + SqlInternalConnectionTds connectionToDoom = null, +#endif + Action onFailure = null) + { + if (task == null) + { + onSuccess(); + return null; + } + else + { + TaskCompletionSource completion = new TaskCompletionSource(); +#if NET6_0_OR_GREATER + ContinueTaskWithState(task, completion, + state: Tuple.Create(onSuccess, onFailure, completion), + onSuccess: static (object state) => + { + var parameters = (Tuple, TaskCompletionSource>)state; + Action success = parameters.Item1; + TaskCompletionSource taskCompletionSource = parameters.Item3; + success(); + taskCompletionSource.SetResult(null); + }, + onFailure: static (Exception exception, object state) => + { + var parameters = (Tuple, TaskCompletionSource>)state; + Action failure = parameters.Item2; + failure?.Invoke(exception); + } +#else + ContinueTask(task, completion, + onSuccess: () => + { + onSuccess(); + completion.SetResult(null); + }, + onFailure: onFailure, + connectionToDoom: connectionToDoom +#endif + ); + return completion.Task; + } + } + + internal static Task CreateContinuationTaskWithState(Task task, object state, Action onSuccess, Action onFailure = null) + { + if (task == null) + { + onSuccess(state); + return null; + } + else + { + var completion = new TaskCompletionSource(); + ContinueTaskWithState(task, completion, state, + onSuccess: (object continueState) => + { + onSuccess(continueState); + completion.SetResult(null); + }, + onFailure: onFailure + ); + return completion.Task; + } + } + + internal static Task CreateContinuationTask(Task task, Action onSuccess, T1 arg1, T2 arg2, SqlInternalConnectionTds connectionToDoom = null, Action onFailure = null) + { + return CreateContinuationTask(task, () => onSuccess(arg1, arg2), +#if NETFRAMEWORK + connectionToDoom, +#endif + onFailure); + } + + internal static void ContinueTask(Task task, + TaskCompletionSource completion, + Action onSuccess, + Action onFailure = null, + Action onCancellation = null, +#if NET6_0_OR_GREATER + Func exceptionConverter = null +#else + Func exceptionConverter = null, + SqlInternalConnectionTds connectionToDoom = null, + SqlConnection connectionToAbort = null +#endif + ) + { +#if NETFRAMEWORK + Debug.Assert((connectionToAbort == null) || (connectionToDoom == null), "Should not specify both connectionToDoom and connectionToAbort"); +#endif + task.ContinueWith( + tsk => + { + if (tsk.Exception != null) + { + Exception exc = tsk.Exception.InnerException; + if (exceptionConverter != null) + { + exc = exceptionConverter(exc); + } + try + { + onFailure?.Invoke(exc); + } + finally + { + completion.TrySetException(exc); + } + } + else if (tsk.IsCanceled) + { + try + { + onCancellation?.Invoke(); + } + finally + { + completion.TrySetCanceled(); + } + } + else + { +#if NETFRAMEWORK + if (connectionToDoom != null || connectionToAbort != null) + { + RuntimeHelpers.PrepareConstrainedRegions(); + try + { +#if DEBUG + TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection(); + RuntimeHelpers.PrepareConstrainedRegions(); + try + { + tdsReliabilitySection.Start(); +#endif //DEBUG + onSuccess(); +#if DEBUG + } + finally + { + tdsReliabilitySection.Stop(); + } +#endif //DEBUG + } + catch (System.OutOfMemoryException e) + { + if (connectionToDoom != null) + { + connectionToDoom.DoomThisConnection(); + } + else + { + connectionToAbort.Abort(e); + } + completion.SetException(e); + throw; + } + catch (System.StackOverflowException e) + { + if (connectionToDoom != null) + { + connectionToDoom.DoomThisConnection(); + } + else + { + connectionToAbort.Abort(e); + } + completion.SetException(e); + throw; + } + catch (System.Threading.ThreadAbortException e) + { + if (connectionToDoom != null) + { + connectionToDoom.DoomThisConnection(); + } + else + { + connectionToAbort.Abort(e); + } + completion.SetException(e); + throw; + } + catch (Exception e) + { + completion.SetException(e); + } + } + else + { // no connection to doom - reliability section not required + try + { + onSuccess(); + } + catch (Exception e) + { + completion.SetException(e); + } + } + } +#else + try + { + onSuccess(); + } + catch (Exception e) + { + completion.SetException(e); + } + } +#endif + }, TaskScheduler.Default + ); + } + + // the same logic as ContinueTask but with an added state parameter to allow the caller to avoid the use of a closure + // the parameter allocation cannot be avoided here and using closure names is clearer than Tuple numbered properties + internal static void ContinueTaskWithState(Task task, + TaskCompletionSource completion, + object state, + Action onSuccess, + Action onFailure = null, + Action onCancellation = null, +#if NET6_0_OR_GREATER + Func exceptionConverter = null +#else + Func exceptionConverter = null, + SqlInternalConnectionTds connectionToDoom = null, + SqlConnection connectionToAbort = null +#endif + ) + { +#if NETFRAMEWORK + Debug.Assert((connectionToAbort == null) || (connectionToDoom == null), "Should not specify both connectionToDoom and connectionToAbort"); +#endif + task.ContinueWith( + (Task tsk, object state2) => + { + if (tsk.Exception != null) + { + Exception exc = tsk.Exception.InnerException; + if (exceptionConverter != null) + { + exc = exceptionConverter(exc +#if NETFRAMEWORK + , state2 +#endif + ); + } + try + { + onFailure?.Invoke(exc, state2); + } + finally + { + completion.TrySetException(exc); + } + } + else if (tsk.IsCanceled) + { + try + { + onCancellation?.Invoke(state2); + } + finally + { + completion.TrySetCanceled(); + } + } +#if NETFRAMEWORK + else if (connectionToDoom != null || connectionToAbort != null) + { + RuntimeHelpers.PrepareConstrainedRegions(); + try + { +#if DEBUG + TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection(); + RuntimeHelpers.PrepareConstrainedRegions(); + try + { + tdsReliabilitySection.Start(); +#endif //DEBUG + onSuccess(state2); +#if DEBUG + } + finally + { + tdsReliabilitySection.Stop(); + } +#endif //DEBUG + } + catch (System.OutOfMemoryException e) + { + if (connectionToDoom != null) + { + connectionToDoom.DoomThisConnection(); + } + else + { + connectionToAbort.Abort(e); + } + completion.SetException(e); + throw; + } + catch (System.StackOverflowException e) + { + if (connectionToDoom != null) + { + connectionToDoom.DoomThisConnection(); + } + else + { + connectionToAbort.Abort(e); + } + completion.SetException(e); + throw; + } + catch (System.Threading.ThreadAbortException e) + { + if (connectionToDoom != null) + { + connectionToDoom.DoomThisConnection(); + } + else + { + connectionToAbort.Abort(e); + } + completion.SetException(e); + throw; + } + catch (Exception e) + { + completion.SetException(e); + } + } +#endif + else + { + try + { + onSuccess(state2); + } + catch (Exception e) + { + completion.SetException(e); + } + } + }, + state: state, + scheduler: TaskScheduler.Default + ); + } + + internal static void WaitForCompletion(Task task, int timeout, Action onTimeout = null, bool rethrowExceptions = true) + { + try + { + task.Wait(timeout > 0 ? (1000 * timeout) : Timeout.Infinite); + } + catch (AggregateException ae) + { + if (rethrowExceptions) + { + Debug.Assert(ae.InnerExceptions.Count == 1, "There is more than one exception in AggregateException"); + ExceptionDispatchInfo.Capture(ae.InnerException).Throw(); + } + } + if (!task.IsCompleted) + { + task.ContinueWith(static t => { var ignored = t.Exception; }); //Ensure the task does not leave an unobserved exception + onTimeout?.Invoke(); + } + } + + internal static void SetTimeoutException(TaskCompletionSource completion, int timeout, Func onFailure, CancellationToken ctoken) + { + if (timeout > 0) + { + Task.Delay(timeout * 1000, ctoken).ContinueWith( + (Task task) => + { + if (!task.IsCanceled && !completion.Task.IsCompleted) + { + completion.TrySetException(onFailure()); + } + } + ); + } + } + +#if NET6_0_OR_GREATER + internal static void SetTimeoutExceptionWithState(TaskCompletionSource completion, int timeout, object state, Func onFailure, CancellationToken cancellationToken) + { + if (timeout > 0) + { + Task.Delay(timeout * 1000, cancellationToken).ContinueWith( + (Task task, object state) => + { + if (!task.IsCanceled && !completion.Task.IsCompleted) + { + completion.TrySetException(onFailure(state)); + } + }, + state: state, + cancellationToken: CancellationToken.None + ); + } + } +#endif + } + + internal static class SQL + { + // The class SQL defines the exceptions that are specific to the SQL Adapter. + // The class contains functions that take the proper informational variables and then construct + // the appropriate exception with an error string obtained from the resource Framework.txt. + // The exception is then returned to the caller, so that the caller may then throw from its + // location so that the catcher of the exception will have the appropriate call stack. + // This class is used so that there will be compile time checking of error + // messages. The resource Framework.txt will ensure proper string text based on the appropriate + // locale. + + // + // SQL specific exceptions + // + + // + // SQL.Connection + // + internal static Exception CannotGetDTCAddress() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_CannotGetDTCAddress)); + } + + static internal Exception InvalidOptionLength(string key) + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_InvalidOptionLength, key)); + } + internal static Exception InvalidInternalPacketSize(string str) + { + return ADP.ArgumentOutOfRange(str); + } + internal static Exception InvalidPacketSize() + { + return ADP.ArgumentOutOfRange(StringsHelper.GetString(Strings.SQL_InvalidTDSPacketSize)); + } + internal static Exception InvalidPacketSizeValue() + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_InvalidPacketSizeValue)); + } + internal static Exception InvalidSSPIPacketSize() + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_InvalidSSPIPacketSize)); + } + static internal Exception NullEmptyTransactionName() + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_NullEmptyTransactionName)); + } + + static internal Exception UserInstanceFailoverNotCompatible() + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_UserInstanceFailoverNotCompatible)); + } + static internal Exception CredentialsNotProvided(SqlAuthenticationMethod auth) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_CredentialsNotProvided, DbConnectionStringBuilderUtil.AuthenticationTypeToString(auth))); + } + static internal Exception InvalidCertAuth() + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_Certificate)); + } + internal static Exception AuthenticationAndIntegratedSecurity() + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_AuthenticationAndIntegratedSecurity)); + } + internal static Exception IntegratedWithPassword() + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_IntegratedWithPassword)); + } + internal static Exception InteractiveWithPassword() + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_InteractiveWithPassword)); + } + internal static Exception DeviceFlowWithUsernamePassword() + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_DeviceFlowWithUsernamePassword)); + } + internal static Exception NonInteractiveWithPassword(string authenticationMode) + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_NonInteractiveWithPassword, authenticationMode)); + } + internal static Exception SettingIntegratedWithCredential() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SettingIntegratedWithCredential)); + } + internal static Exception SettingInteractiveWithCredential() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SettingInteractiveWithCredential)); + } + internal static Exception SettingDeviceFlowWithCredential() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SettingDeviceFlowWithCredential)); + } + internal static Exception SettingNonInteractiveWithCredential(string authenticationMode) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SettingNonInteractiveWithCredential, authenticationMode)); + } + internal static Exception SettingCredentialWithIntegratedArgument() + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_SettingCredentialWithIntegrated)); + } + internal static Exception SettingCredentialWithInteractiveArgument() + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_SettingCredentialWithInteractive)); + } + internal static Exception SettingCredentialWithDeviceFlowArgument() + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_SettingCredentialWithDeviceFlow)); + } + internal static Exception SettingCredentialWithNonInteractiveArgument(string authenticationMode) + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_SettingCredentialWithNonInteractive, authenticationMode)); + } + internal static Exception SettingCredentialWithIntegratedInvalid() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SettingCredentialWithIntegrated)); + } + internal static Exception SettingCredentialWithInteractiveInvalid() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SettingCredentialWithInteractive)); + } + internal static Exception SettingCredentialWithDeviceFlowInvalid() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SettingCredentialWithDeviceFlow)); + } + internal static Exception SettingCredentialWithNonInteractiveInvalid(string authenticationMode) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SettingCredentialWithNonInteractive, authenticationMode)); + } + + internal static Exception ParsingErrorLibraryType(ParsingErrorState state, int libraryType) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParsingErrorAuthLibraryType, ((int)state).ToString(CultureInfo.InvariantCulture), libraryType)); + } + internal static Exception InvalidSQLServerVersionUnknown() + { + return ADP.DataAdapter(StringsHelper.GetString(Strings.SQL_InvalidSQLServerVersionUnknown)); + } + internal static Exception SynchronousCallMayNotPend() + { + return new Exception(StringsHelper.GetString(Strings.Sql_InternalError)); + } + + internal static Exception ConnectionLockedForBcpEvent() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ConnectionLockedForBcpEvent)); + } + internal static Exception FatalTimeout() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_FatalTimeout)); + } + internal static Exception InstanceFailure() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_InstanceFailure)); + } + internal static Exception ChangePasswordArgumentMissing(string argumentName) + { + return ADP.ArgumentNull(StringsHelper.GetString(Strings.SQL_ChangePasswordArgumentMissing, argumentName)); + } + internal static Exception ChangePasswordConflictsWithSSPI() + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_ChangePasswordConflictsWithSSPI)); + } + internal static Exception ChangePasswordRequires2005() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ChangePasswordRequiresYukon)); + } + internal static Exception UnknownSysTxIsolationLevel(System.Transactions.IsolationLevel isolationLevel) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_UnknownSysTxIsolationLevel, isolationLevel.ToString())); + } + internal static Exception ChangePasswordUseOfUnallowedKey(string key) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ChangePasswordUseOfUnallowedKey, key)); + } + internal static Exception GlobalizationInvariantModeNotSupported() + { + return ADP.NotSupported(StringsHelper.GetString(Strings.SQL_GlobalizationInvariantModeNotSupported)); + } + + // + // Global Transactions. + // + internal static Exception GlobalTransactionsNotEnabled() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.GT_Disabled)); + } + + internal static Exception InvalidPartnerConfiguration(string server, string database) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_InvalidPartnerConfiguration, server, database)); + } + + internal static Exception BatchedUpdateColumnEncryptionSettingMismatch() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_BatchedUpdateColumnEncryptionSettingMismatch, "SqlCommandColumnEncryptionSetting", "SelectCommand", "InsertCommand", "UpdateCommand", "DeleteCommand")); + } + internal static Exception MARSUnsupportedOnConnection() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_MarsUnsupportedOnConnection)); + } + + internal static Exception CannotModifyPropertyAsyncOperationInProgress([CallerMemberName] string property = "") + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_CannotModifyPropertyAsyncOperationInProgress, property)); + } + internal static Exception NonLocalSSEInstance() + { + return ADP.NotSupported(StringsHelper.GetString(Strings.SQL_NonLocalSSEInstance)); + } + + // SQL.ActiveDirectoryAuth + // + internal static Exception UnsupportedAuthentication(string authentication) + { + return ADP.NotSupported(StringsHelper.GetString(Strings.SQL_UnsupportedAuthentication, authentication)); + } + + internal static Exception UnsupportedSqlAuthenticationMethod(SqlAuthenticationMethod authentication) + { + return ADP.NotSupported(StringsHelper.GetString(Strings.SQL_UnsupportedSqlAuthenticationMethod, authentication)); + } + + internal static Exception UnsupportedAuthenticationSpecified(SqlAuthenticationMethod authentication) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_UnsupportedAuthenticationSpecified, authentication)); + } + + internal static Exception CannotCreateAuthProvider(string authentication, string type, Exception e) + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_CannotCreateAuthProvider, authentication, type), e); + } + + internal static Exception CannotCreateSqlAuthInitializer(string type, Exception e) + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_CannotCreateAuthInitializer, type), e); + } + + internal static Exception CannotInitializeAuthProvider(string type, Exception e) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_CannotInitializeAuthProvider, type), e); + } + + internal static Exception UnsupportedAuthenticationByProvider(string authentication, string type) + { + return ADP.NotSupported(StringsHelper.GetString(Strings.SQL_UnsupportedAuthenticationByProvider, type, authentication)); + } + + internal static Exception CannotFindAuthProvider(string authentication) + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_CannotFindAuthProvider, authentication)); + } + + internal static Exception CannotGetAuthProviderConfig(Exception e) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_CannotGetAuthProviderConfig), e); + } + + internal static Exception ParameterCannotBeEmpty(string paramName) + { + return ADP.ArgumentNull(StringsHelper.GetString(Strings.SQL_ParameterCannotBeEmpty, paramName)); + } + + internal static Exception ParameterDirectionInvalidForOptimizedBinding(string paramName) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParameterDirectionInvalidForOptimizedBinding, paramName)); + } + + internal static Exception ActiveDirectoryInteractiveTimeout() + { + return ADP.TimeoutException(Strings.SQL_Timeout_Active_Directory_Interactive_Authentication); + } + + internal static Exception ActiveDirectoryDeviceFlowTimeout() + { + return ADP.TimeoutException(Strings.SQL_Timeout_Active_Directory_DeviceFlow_Authentication); + } + + internal static Exception ActiveDirectoryTokenRetrievingTimeout(string authenticaton, string errorCode, Exception exception) + { + return ADP.TimeoutException(StringsHelper.GetString(Strings.AAD_Token_Retrieving_Timeout, authenticaton, errorCode, exception?.Message), exception); + } + + // + // SQL.DataCommand + // + internal static Exception NotificationsRequire2005() + { + return ADP.NotSupported(StringsHelper.GetString(Strings.SQL_NotificationsRequireYukon)); + } + + internal static ArgumentOutOfRangeException NotSupportedEnumerationValue(Type type, int value) + { + return ADP.ArgumentOutOfRange(StringsHelper.GetString(Strings.SQL_NotSupportedEnumerationValue, type.Name, value.ToString(System.Globalization.CultureInfo.InvariantCulture)), type.Name); + } + + internal static ArgumentOutOfRangeException NotSupportedCommandType(CommandType value) + { +#if DEBUG + switch (value) + { + case CommandType.Text: + case CommandType.StoredProcedure: + Debug.Fail("valid CommandType " + value.ToString()); + break; + case CommandType.TableDirect: + break; + default: + Debug.Fail("invalid CommandType " + value.ToString()); + break; + } +#endif + return NotSupportedEnumerationValue(typeof(CommandType), (int)value); + } + internal static ArgumentOutOfRangeException NotSupportedIsolationLevel(System.Data.IsolationLevel value) + { +#if DEBUG + switch (value) + { + case System.Data.IsolationLevel.Unspecified: + case System.Data.IsolationLevel.ReadCommitted: + case System.Data.IsolationLevel.ReadUncommitted: + case System.Data.IsolationLevel.RepeatableRead: + case System.Data.IsolationLevel.Serializable: + case System.Data.IsolationLevel.Snapshot: + Debug.Fail("valid IsolationLevel " + value.ToString()); + break; + case System.Data.IsolationLevel.Chaos: + break; + default: + Debug.Fail("invalid IsolationLevel " + value.ToString()); + break; + } +#endif + return NotSupportedEnumerationValue(typeof(System.Data.IsolationLevel), (int)value); + } + + internal static Exception OperationCancelled() + { + Exception exception = ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_OperationCancelled)); + return exception; + } + + internal static Exception PendingBeginXXXExists() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_PendingBeginXXXExists)); + } + + internal static ArgumentOutOfRangeException InvalidSqlDependencyTimeout(string param) + { + return ADP.ArgumentOutOfRange(StringsHelper.GetString(Strings.SqlDependency_InvalidTimeout), param); + } + + internal static Exception NonXmlResult() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_NonXmlResult)); + } + + // + // SQL.DataParameter + // + internal static Exception InvalidUdt3PartNameFormat() + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_InvalidUdt3PartNameFormat)); + } + internal static Exception InvalidParameterTypeNameFormat() + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_InvalidParameterTypeNameFormat)); + } + internal static Exception InvalidParameterNameLength(string value) + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_InvalidParameterNameLength, value)); + } + internal static Exception PrecisionValueOutOfRange(byte precision) + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_PrecisionValueOutOfRange, precision.ToString(CultureInfo.InvariantCulture))); + } + internal static Exception ScaleValueOutOfRange(byte scale) + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_ScaleValueOutOfRange, scale.ToString(CultureInfo.InvariantCulture))); + } + internal static Exception TimeScaleValueOutOfRange(byte scale) + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_TimeScaleValueOutOfRange, scale.ToString(CultureInfo.InvariantCulture))); + } + internal static Exception InvalidSqlDbType(SqlDbType value) + { + return ADP.InvalidEnumerationValue(typeof(SqlDbType), (int)value); + } + internal static Exception UnsupportedTVPOutputParameter(ParameterDirection direction, string paramName) + { + return ADP.NotSupported(StringsHelper.GetString(Strings.SqlParameter_UnsupportedTVPOutputParameter, + direction.ToString(), paramName)); + } + internal static Exception DBNullNotSupportedForTVPValues(string paramName) + { + return ADP.NotSupported(StringsHelper.GetString(Strings.SqlParameter_DBNullNotSupportedForTVP, paramName)); + } + internal static Exception InvalidTableDerivedPrecisionForTvp(string columnName, byte precision) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlParameter_InvalidTableDerivedPrecisionForTvp, precision, columnName, System.Data.SqlTypes.SqlDecimal.MaxPrecision)); + } + internal static Exception UnexpectedTypeNameForNonStructParams(string paramName) + { + return ADP.NotSupported(StringsHelper.GetString(Strings.SqlParameter_UnexpectedTypeNameForNonStruct, paramName)); + } + internal static Exception SingleValuedStructNotSupported() + { + return ADP.NotSupported(StringsHelper.GetString(Strings.MetaType_SingleValuedStructNotSupported)); + } + internal static Exception ParameterInvalidVariant(string paramName) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParameterInvalidVariant, paramName)); + } + + internal static Exception MustSetTypeNameForParam(string paramType, string paramName) + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_ParameterTypeNameRequired, paramType, paramName)); + } + internal static Exception NullSchemaTableDataTypeNotSupported(string columnName) + { + return ADP.Argument(StringsHelper.GetString(Strings.NullSchemaTableDataTypeNotSupported, columnName)); + } + internal static Exception InvalidSchemaTableOrdinals() + { + return ADP.Argument(StringsHelper.GetString(Strings.InvalidSchemaTableOrdinals)); + } + internal static Exception EnumeratedRecordMetaDataChanged(string fieldName, int recordNumber) + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_EnumeratedRecordMetaDataChanged, fieldName, recordNumber)); + } + internal static Exception EnumeratedRecordFieldCountChanged(int recordNumber) + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_EnumeratedRecordFieldCountChanged, recordNumber)); + } + + // + // SQL.SqlDataAdapter + // + + // + // SQL.TDSParser + // + internal static Exception InvalidTDSVersion() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_InvalidTDSVersion)); + } + internal static Exception ParsingError() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParsingError)); + } + internal static Exception ParsingError(ParsingErrorState state) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParsingErrorWithState, ((int)state).ToString(CultureInfo.InvariantCulture))); + } + internal static Exception ParsingError(ParsingErrorState state, Exception innerException) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParsingErrorWithState, ((int)state).ToString(CultureInfo.InvariantCulture)), innerException); + } + internal static Exception ParsingErrorValue(ParsingErrorState state, int value) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParsingErrorValue, ((int)state).ToString(CultureInfo.InvariantCulture), value)); + } + internal static Exception ParsingErrorOffset(ParsingErrorState state, int offset) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParsingErrorOffset, ((int)state).ToString(CultureInfo.InvariantCulture), offset)); + } + internal static Exception ParsingErrorFeatureId(ParsingErrorState state, int featureId) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParsingErrorFeatureId, ((int)state).ToString(CultureInfo.InvariantCulture), featureId)); + } + internal static Exception ParsingErrorToken(ParsingErrorState state, int token) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParsingErrorToken, ((int)state).ToString(CultureInfo.InvariantCulture), token)); + } + internal static Exception ParsingErrorLength(ParsingErrorState state, int length) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParsingErrorLength, ((int)state).ToString(CultureInfo.InvariantCulture), length)); + } + internal static Exception ParsingErrorStatus(ParsingErrorState state, int status) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ParsingErrorStatus, ((int)state).ToString(CultureInfo.InvariantCulture), status)); + } + internal static Exception MoneyOverflow(string moneyValue) + { + return ADP.Overflow(StringsHelper.GetString(Strings.SQL_MoneyOverflow, moneyValue)); + } + internal static Exception SmallDateTimeOverflow(string datetime) + { + return ADP.Overflow(StringsHelper.GetString(Strings.SQL_SmallDateTimeOverflow, datetime)); + } + internal static Exception SNIPacketAllocationFailure() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SNIPacketAllocationFailure)); + } + internal static Exception TimeOverflow(string time) + { + return ADP.Overflow(StringsHelper.GetString(Strings.SQL_TimeOverflow, time)); + } + internal static Exception InvalidServerCertificate() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_InvalidServerCertificate)); + } + + // + // SQL.SqlDataReader + // + internal static Exception InvalidRead() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_InvalidRead)); + } + + internal static Exception NonBlobColumn(string columnName) + { + return ADP.InvalidCast(StringsHelper.GetString(Strings.SQL_NonBlobColumn, columnName)); + } + + internal static Exception NonCharColumn(string columnName) + { + return ADP.InvalidCast(StringsHelper.GetString(Strings.SQL_NonCharColumn, columnName)); + } + + internal static Exception StreamNotSupportOnColumnType(string columnName) + { + return ADP.InvalidCast(StringsHelper.GetString(Strings.SQL_StreamNotSupportOnColumnType, columnName)); + } + + internal static Exception StreamNotSupportOnEncryptedColumn(string columnName) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_StreamNotSupportOnEncryptedColumn, columnName, "Stream")); + } + + internal static Exception SequentialAccessNotSupportedOnEncryptedColumn(string columnName) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_SequentialAccessNotSupportedOnEncryptedColumn, columnName, "CommandBehavior=SequentialAccess")); + } + + internal static Exception TextReaderNotSupportOnColumnType(string columnName) + { + return ADP.InvalidCast(StringsHelper.GetString(Strings.SQL_TextReaderNotSupportOnColumnType, columnName)); + } + + internal static Exception XmlReaderNotSupportOnColumnType(string columnName) + { + return ADP.InvalidCast(StringsHelper.GetString(Strings.SQL_XmlReaderNotSupportOnColumnType, columnName)); + } + + internal static Exception UDTUnexpectedResult(string exceptionText) + { + return ADP.TypeLoad(StringsHelper.GetString(Strings.SQLUDT_Unexpected, exceptionText)); + } + + internal static Exception DateTimeOverflow() + { + return new OverflowException(SqlTypes.SQLResource.DateTimeOverflowMessage); + } + + // + // SQL.SqlDependency + // + internal static Exception SqlCommandHasExistingSqlNotificationRequest() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQLNotify_AlreadyHasCommand)); + } + + internal static Exception SqlDepDefaultOptionsButNoStart() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlDependency_DefaultOptionsButNoStart)); + } + + internal static Exception SqlDependencyDatabaseBrokerDisabled() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlDependency_DatabaseBrokerDisabled)); + } + + internal static Exception SqlDependencyEventNoDuplicate() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlDependency_EventNoDuplicate)); + } + + internal static Exception SqlDependencyDuplicateStart() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlDependency_DuplicateStart)); + } + + internal static Exception SqlDependencyIdMismatch() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlDependency_IdMismatch)); + } + + internal static Exception SqlDependencyNoMatchingServerStart() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlDependency_NoMatchingServerStart)); + } + + internal static Exception SqlDependencyNoMatchingServerDatabaseStart() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlDependency_NoMatchingServerDatabaseStart)); + } + + // + // SQL.SqlDelegatedTransaction + // + static internal Exception CannotCompleteDelegatedTransactionWithOpenResults(SqlInternalConnectionTds internalConnection, bool marsOn) + { + SqlErrorCollection errors = new SqlErrorCollection(); + errors.Add(new SqlError(TdsEnums.TIMEOUT_EXPIRED, (byte)0x00, TdsEnums.MIN_ERROR_CLASS, null, (StringsHelper.GetString(Strings.ADP_OpenReaderExists, marsOn ? ADP.Command : ADP.Connection)), "", 0, TdsEnums.SNI_WAIT_TIMEOUT)); + return SqlException.CreateException(errors, null, internalConnection, innerException: null, batchCommand: null); + } + + internal static TransactionPromotionException PromotionFailed(Exception inner) + { + TransactionPromotionException e = new TransactionPromotionException(StringsHelper.GetString(Strings.SqlDelegatedTransaction_PromotionFailed), inner); + ADP.TraceExceptionAsReturnValue(e); + return e; + } + + internal static Exception SqlDepCannotBeCreatedInProc() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlNotify_SqlDepCannotBeCreatedInProc)); + } + + static internal Exception SqlNotificationException(SqlNotificationEventArgs notify) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQLNotify_ErrorFormat, notify.Type, notify.Info, notify.Source)); + } + + // + // SQL.SqlMetaData + // + internal static Exception SqlMetaDataNoMetaData() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlMetaData_NoMetadata)); + } + internal static Exception UnexpectedUdtTypeNameForNonUdtParams() + { + return ADP.Argument(StringsHelper.GetString(Strings.SQLUDT_UnexpectedUdtTypeName)); + } + internal static Exception MustSetUdtTypeNameForUdtParams() + { + return ADP.Argument(StringsHelper.GetString(Strings.SQLUDT_InvalidUdtTypeName)); + } + internal static Exception UDTInvalidSqlType(string typeName) + { + return ADP.Argument(StringsHelper.GetString(Strings.SQLUDT_InvalidSqlType, typeName)); + } + + internal static Exception UDTInvalidSize(int maxSize, int maxSupportedSize) + { + throw ADP.ArgumentOutOfRange(StringsHelper.GetString(Strings.SQLUDT_InvalidSize, maxSize, maxSupportedSize)); + } + + internal static Exception InvalidSqlDbTypeForConstructor(SqlDbType type) + { + return ADP.Argument(StringsHelper.GetString(Strings.SqlMetaData_InvalidSqlDbTypeForConstructorFormat, type.ToString())); + } + + internal static Exception NameTooLong(string parameterName) + { + return ADP.Argument(StringsHelper.GetString(Strings.SqlMetaData_NameTooLong), parameterName); + } + + internal static Exception InvalidSortOrder(SortOrder order) + { + return ADP.InvalidEnumerationValue(typeof(SortOrder), (int)order); + } + + internal static Exception MustSpecifyBothSortOrderAndOrdinal(SortOrder order, int ordinal) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlMetaData_SpecifyBothSortOrderAndOrdinal, order.ToString(), ordinal)); + } + + internal static Exception TableTypeCanOnlyBeParameter() + { + return ADP.Argument(StringsHelper.GetString(Strings.SQLTVP_TableTypeCanOnlyBeParameter)); + } + internal static Exception UnsupportedColumnTypeForSqlProvider(string columnName, string typeName) + { + return ADP.Argument(StringsHelper.GetString(Strings.SqlProvider_InvalidDataColumnType, columnName, typeName)); + } + internal static Exception InvalidColumnMaxLength(string columnName, long maxLength) + { + return ADP.Argument(StringsHelper.GetString(Strings.SqlProvider_InvalidDataColumnMaxLength, columnName, maxLength)); + } + internal static Exception InvalidColumnPrecScale() + { + return ADP.Argument(StringsHelper.GetString(Strings.SqlMisc_InvalidPrecScaleMessage)); + } + internal static Exception NotEnoughColumnsInStructuredType() + { + return ADP.Argument(StringsHelper.GetString(Strings.SqlProvider_NotEnoughColumnsInStructuredType)); + } + internal static Exception DuplicateSortOrdinal(int sortOrdinal) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlProvider_DuplicateSortOrdinal, sortOrdinal)); + } + internal static Exception MissingSortOrdinal(int sortOrdinal) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlProvider_MissingSortOrdinal, sortOrdinal)); + } + internal static Exception SortOrdinalGreaterThanFieldCount(int columnOrdinal, int sortOrdinal) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlProvider_SortOrdinalGreaterThanFieldCount, sortOrdinal, columnOrdinal)); + } + internal static Exception IEnumerableOfSqlDataRecordHasNoRows() + { + return ADP.Argument(StringsHelper.GetString(Strings.IEnumerableOfSqlDataRecordHasNoRows)); + } + + // + // SqlPipe + // + internal static Exception SqlPipeCommandHookedUpToNonContextConnection() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlPipe_CommandHookedUpToNonContextConnection)); + } + + internal static Exception SqlPipeMessageTooLong(int messageLength) + { + return ADP.Argument(StringsHelper.GetString(Strings.SqlPipe_MessageTooLong, messageLength)); + } + + internal static Exception SqlPipeIsBusy() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlPipe_IsBusy)); + } + + internal static Exception SqlPipeAlreadyHasAnOpenResultSet(string methodName) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlPipe_AlreadyHasAnOpenResultSet, methodName)); + } + + internal static Exception SqlPipeDoesNotHaveAnOpenResultSet(string methodName) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlPipe_DoesNotHaveAnOpenResultSet, methodName)); + } + + // + // : ISqlResultSet + // + internal static Exception SqlResultSetClosed(string methodname) + { + if (methodname == null) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SqlResultSetClosed2)); + } + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SqlResultSetClosed, methodname)); + } + internal static Exception SqlResultSetNoData(string methodname) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.ADP_DataReaderNoData, methodname)); + } + internal static Exception SqlRecordReadOnly(string methodname) + { + if (methodname == null) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SqlRecordReadOnly2)); + } + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SqlRecordReadOnly, methodname)); + } + + internal static Exception SqlResultSetRowDeleted(string methodname) + { + if (methodname == null) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SqlResultSetRowDeleted2)); + } + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SqlResultSetRowDeleted, methodname)); + } + + internal static Exception SqlResultSetCommandNotInSameConnection() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SqlResultSetCommandNotInSameConnection)); + } + + internal static Exception SqlResultSetNoAcceptableCursor() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_SqlResultSetNoAcceptableCursor)); + } + + // + // SQL.BulkLoad + // + internal static Exception BulkLoadMappingInaccessible() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadMappingInaccessible)); + } + internal static Exception BulkLoadMappingsNamesOrOrdinalsOnly() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadMappingsNamesOrOrdinalsOnly)); + } + internal static Exception BulkLoadCannotConvertValue(Type sourcetype, MetaType metatype, int ordinal, int rowNumber, bool isEncrypted, string columnName, string value, Exception e) + { + string quotedValue = string.Empty; + if (!isEncrypted) + { + quotedValue = string.Format(" '{0}'", (value.Length > 100 ? value.Substring(0, 100) : value)); + } + if (rowNumber == -1) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadCannotConvertValueWithoutRowNo, quotedValue, sourcetype.Name, metatype.TypeName, ordinal, columnName), e); + } + else + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadCannotConvertValue, quotedValue, sourcetype.Name, metatype.TypeName, ordinal, columnName, rowNumber), e); + } + } + internal static Exception BulkLoadNonMatchingColumnMapping() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadNonMatchingColumnMapping)); + } + internal static Exception BulkLoadNonMatchingColumnName(string columnName) + { + return BulkLoadNonMatchingColumnName(columnName, null); + } + internal static Exception BulkLoadNonMatchingColumnName(string columnName, Exception e) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadNonMatchingColumnName, columnName), e); + } + internal static Exception BulkLoadNullEmptyColumnName(string paramName) + { + return ADP.Argument(string.Format(StringsHelper.GetString(Strings.SQL_ParameterCannotBeEmpty), paramName)); + } + internal static Exception BulkLoadUnspecifiedSortOrder() + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_BulkLoadUnspecifiedSortOrder)); + } + internal static Exception BulkLoadInvalidOrderHint() + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_BulkLoadInvalidOrderHint)); + } + internal static Exception BulkLoadOrderHintInvalidColumn(string columnName) + { + return ADP.InvalidOperation(string.Format(StringsHelper.GetString(Strings.SQL_BulkLoadOrderHintInvalidColumn), columnName)); + } + internal static Exception BulkLoadOrderHintDuplicateColumn(string columnName) + { + return ADP.InvalidOperation(string.Format(StringsHelper.GetString(Strings.SQL_BulkLoadOrderHintDuplicateColumn), columnName)); + } + internal static Exception BulkLoadStringTooLong(string tableName, string columnName, string truncatedValue) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadStringTooLong, tableName, columnName, truncatedValue)); + } + internal static Exception BulkLoadInvalidVariantValue() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadInvalidVariantValue)); + } + internal static Exception BulkLoadInvalidTimeout(int timeout) + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_BulkLoadInvalidTimeout, timeout.ToString(CultureInfo.InvariantCulture))); + } + internal static Exception BulkLoadExistingTransaction() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadExistingTransaction)); + } + internal static Exception BulkLoadNoCollation() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadNoCollation)); + } + internal static Exception BulkLoadConflictingTransactionOption() + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_BulkLoadConflictingTransactionOption)); + } + internal static Exception BulkLoadLcidMismatch(int sourceLcid, string sourceColumnName, int destinationLcid, string destinationColumnName) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.Sql_BulkLoadLcidMismatch, sourceLcid, sourceColumnName, destinationLcid, destinationColumnName)); + } + internal static Exception InvalidOperationInsideEvent() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadInvalidOperationInsideEvent)); + } + internal static Exception BulkLoadMissingDestinationTable() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadMissingDestinationTable)); + } + internal static Exception BulkLoadInvalidDestinationTable(string tableName, Exception inner) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadInvalidDestinationTable, tableName), inner); + } + internal static Exception BulkLoadBulkLoadNotAllowDBNull(string columnName) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadNotAllowDBNull, columnName)); + } + internal static Exception BulkLoadPendingOperation() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BulkLoadPendingOperation)); + } + + // + // transactions. + // + internal static Exception ConnectionDoomed() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ConnectionDoomed)); + } + + internal static Exception OpenResultCountExceeded() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_OpenResultCountExceeded)); + } + + internal static Exception UnsupportedSysTxForGlobalTransactions() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings. +#if NET6_0_OR_GREATER + SQL_UnsupportedSysTxVersion)); +#else + GT_UnsupportedSysTxVersion)); +#endif + } + + internal static readonly byte[] AttentionHeader = new byte[] { + TdsEnums.MT_ATTN, // Message Type + TdsEnums.ST_EOM, // Status + TdsEnums.HEADER_LEN >> 8, // length - upper byte + TdsEnums.HEADER_LEN & 0xff, // length - lower byte + 0, // spid + 0, // spid + 0, // packet (out of band) + 0 // window + }; + + // + // MultiSubnetFailover + // + + /// + /// used to block two scenarios if MultiSubnetFailover is true: + /// * server-provided failover partner - raising SqlException in this case + /// * connection string with failover partner and MultiSubnetFailover=true - raising argument one in this case with the same message + /// + internal static Exception MultiSubnetFailoverWithFailoverPartner(bool serverProvidedFailoverPartner, SqlInternalConnectionTds internalConnection) + { + string msg = StringsHelper.GetString(Strings.SQLMSF_FailoverPartnerNotSupported); + if (serverProvidedFailoverPartner) + { + // Replacing InvalidOperation with SQL exception + SqlErrorCollection errors = new SqlErrorCollection(); + errors.Add(new SqlError(0, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, null, msg, "", 0)); + SqlException exc = SqlException.CreateException(errors, null, internalConnection, innerException: null, batchCommand: null); + exc._doNotReconnect = true; // disable open retry logic on this error + return exc; + } + else + { + return ADP.Argument(msg); + } + } + + internal static Exception MultiSubnetFailoverWithMoreThan64IPs() + { + string msg = GetSNIErrorMessage((int)SNINativeMethodWrapper.SniSpecialErrors.MultiSubnetFailoverWithMoreThan64IPs); + return ADP.InvalidOperation(msg); + } + + internal static Exception MultiSubnetFailoverWithInstanceSpecified() + { + string msg = GetSNIErrorMessage((int)SNINativeMethodWrapper.SniSpecialErrors.MultiSubnetFailoverWithInstanceSpecified); + return ADP.Argument(msg); + } + + internal static Exception MultiSubnetFailoverWithNonTcpProtocol() + { + string msg = GetSNIErrorMessage((int)SNINativeMethodWrapper.SniSpecialErrors.MultiSubnetFailoverWithNonTcpProtocol); + return ADP.Argument(msg); + } + + // + // Read-only routing + // + internal static Exception ROR_FailoverNotSupportedConnString() + { + return ADP.Argument(StringsHelper.GetString(Strings.SQLROR_FailoverNotSupported)); + } + + internal static Exception ROR_FailoverNotSupportedServer(SqlInternalConnectionTds internalConnection) + { + SqlErrorCollection errors = new SqlErrorCollection(); + errors.Add(new SqlError(0, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, null, (StringsHelper.GetString(Strings.SQLROR_FailoverNotSupported)), "", 0)); + SqlException exc = SqlException.CreateException(errors, null, internalConnection, innerException: null, batchCommand: null); + exc._doNotReconnect = true; + return exc; + } + + internal static Exception ROR_RecursiveRoutingNotSupported(SqlInternalConnectionTds internalConnection) + { + SqlErrorCollection errors = new SqlErrorCollection(); + errors.Add(new SqlError(0, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, null, (StringsHelper.GetString(Strings.SQLROR_RecursiveRoutingNotSupported)), "", 0)); + SqlException exc = SqlException.CreateException(errors, null, internalConnection, innerException: null, batchCommand: null); + exc._doNotReconnect = true; + return exc; + } + + internal static Exception ROR_UnexpectedRoutingInfo(SqlInternalConnectionTds internalConnection) + { + SqlErrorCollection errors = new SqlErrorCollection(); + errors.Add(new SqlError(0, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, null, (StringsHelper.GetString(Strings.SQLROR_UnexpectedRoutingInfo)), "", 0)); + SqlException exc = SqlException.CreateException(errors, null, internalConnection, innerException: null, batchCommand: null); + exc._doNotReconnect = true; + return exc; + } + + internal static Exception ROR_InvalidRoutingInfo(SqlInternalConnectionTds internalConnection) + { + SqlErrorCollection errors = new SqlErrorCollection(); + errors.Add(new SqlError(0, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, null, (StringsHelper.GetString(Strings.SQLROR_InvalidRoutingInfo)), "", 0)); + SqlException exc = SqlException.CreateException(errors, null, internalConnection, innerException: null, batchCommand: null); + exc._doNotReconnect = true; + return exc; + } + + internal static Exception ROR_TimeoutAfterRoutingInfo(SqlInternalConnectionTds internalConnection) + { + SqlErrorCollection errors = new SqlErrorCollection(); + errors.Add(new SqlError(0, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, null, (StringsHelper.GetString(Strings.SQLROR_TimeoutAfterRoutingInfo)), "", 0)); + SqlException exc = SqlException.CreateException(errors, null, internalConnection, innerException: null, batchCommand: null); + exc._doNotReconnect = true; + return exc; + } + + // + // Connection resiliency + // + internal static SqlException CR_ReconnectTimeout() + { + SqlErrorCollection errors = new SqlErrorCollection(); + errors.Add(new SqlError(TdsEnums.TIMEOUT_EXPIRED, (byte)0x00, TdsEnums.MIN_ERROR_CLASS, null, SQLMessage.Timeout(), "", 0, TdsEnums.SNI_WAIT_TIMEOUT)); + SqlException exc = SqlException.CreateException(errors, ""); + return exc; + } + + internal static SqlException CR_ReconnectionCancelled() + { + SqlErrorCollection errors = new SqlErrorCollection(); + errors.Add(new SqlError(0, 0, TdsEnums.MIN_ERROR_CLASS, null, SQLMessage.OperationCancelled(), "", 0)); + SqlException exc = SqlException.CreateException(errors, ""); + return exc; + } + + internal static Exception CR_NextAttemptWillExceedQueryTimeout(SqlException innerException, Guid connectionId) + { + SqlErrorCollection errors = new SqlErrorCollection(); + errors.Add(new SqlError(0, 0, TdsEnums.MIN_ERROR_CLASS, null, StringsHelper.GetString(Strings.SQLCR_NextAttemptWillExceedQueryTimeout), "", 0)); + SqlException exc = SqlException.CreateException(errors, "", connectionId, innerException +#if NETFRAMEWORK + , batchCommand: null +#endif + ); + return exc; + } + + internal static Exception CR_EncryptionChanged(SqlInternalConnectionTds internalConnection) + { + SqlErrorCollection errors = new SqlErrorCollection(); + errors.Add(new SqlError(0, 0, TdsEnums.FATAL_ERROR_CLASS, null, StringsHelper.GetString(Strings.SQLCR_EncryptionChanged), "", 0)); + SqlException exc = SqlException.CreateException(errors, "", internalConnection, innerException: null, batchCommand: null); + return exc; + } + + internal static SqlException CR_AllAttemptsFailed(SqlException innerException, Guid connectionId) + { + SqlErrorCollection errors = new SqlErrorCollection(); + errors.Add(new SqlError(0, 0, TdsEnums.MIN_ERROR_CLASS, null, StringsHelper.GetString(Strings.SQLCR_AllAttemptsFailed), "", 0)); + SqlException exc = SqlException.CreateException(errors, "", connectionId, innerException, batchCommand: null); + return exc; + } + + internal static SqlException CR_NoCRAckAtReconnection(SqlInternalConnectionTds internalConnection) + { + SqlErrorCollection errors = new SqlErrorCollection(); + errors.Add(new SqlError(0, 0, TdsEnums.FATAL_ERROR_CLASS, null, StringsHelper.GetString(Strings.SQLCR_NoCRAckAtReconnection), "", 0)); + SqlException exc = SqlException.CreateException(errors, "", internalConnection, innerException: null, batchCommand: null); + return exc; + } + + internal static SqlException CR_TDSVersionNotPreserved(SqlInternalConnectionTds internalConnection) + { + SqlErrorCollection errors = new SqlErrorCollection(); + errors.Add(new SqlError(0, 0, TdsEnums.FATAL_ERROR_CLASS, null, StringsHelper.GetString(Strings.SQLCR_TDSVestionNotPreserved), "", 0)); + SqlException exc = SqlException.CreateException(errors, "", internalConnection, innerException: null, batchCommand: null); + return exc; + } + + internal static SqlException CR_UnrecoverableServer(Guid connectionId) + { + SqlErrorCollection errors = new SqlErrorCollection(); + errors.Add(new SqlError(0, 0, TdsEnums.FATAL_ERROR_CLASS, null, StringsHelper.GetString(Strings.SQLCR_UnrecoverableServer), "", 0)); + SqlException exc = SqlException.CreateException(errors, "", connectionId, innerException: null, batchCommand: null); + return exc; + } + + internal static SqlException CR_UnrecoverableClient(Guid connectionId) + { + SqlErrorCollection errors = new SqlErrorCollection(); + errors.Add(new SqlError(0, 0, TdsEnums.FATAL_ERROR_CLASS, null, StringsHelper.GetString(Strings.SQLCR_UnrecoverableClient), "", 0)); + SqlException exc = SqlException.CreateException(errors, "", connectionId, innerException: null, batchCommand: null); + return exc; + } + + internal static Exception StreamWriteNotSupported() + { + return ADP.NotSupported(StringsHelper.GetString(Strings.SQL_StreamWriteNotSupported)); + } + internal static Exception StreamReadNotSupported() + { + return ADP.NotSupported(StringsHelper.GetString(Strings.SQL_StreamReadNotSupported)); + } + internal static Exception StreamSeekNotSupported() + { + return ADP.NotSupported(StringsHelper.GetString(Strings.SQL_StreamSeekNotSupported)); + } + internal static System.Data.SqlTypes.SqlNullValueException SqlNullValue() + { + System.Data.SqlTypes.SqlNullValueException e = new System.Data.SqlTypes.SqlNullValueException(); + ADP.TraceExceptionAsReturnValue(e); + return e; + } + // SQLBU 402363: Exception to prevent Parameter.Size data corruption case from working. + // This should be temporary until changing to correct behavior can be safely implemented. + static internal Exception ParameterSizeRestrictionFailure(int index) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.OleDb_CommandParameterError, index.ToString(CultureInfo.InvariantCulture), "SqlParameter.Size")); + } + internal static Exception SubclassMustOverride() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SqlMisc_SubclassMustOverride)); + } + + // ProjectK\CoreCLR specific errors + internal static Exception UnsupportedKeyword(string keyword) + { + return ADP.NotSupported(StringsHelper.GetString(Strings.SQL_UnsupportedKeyword, keyword)); + } + internal static Exception NetworkLibraryKeywordNotSupported() + { + return ADP.NotSupported(StringsHelper.GetString(Strings.SQL_NetworkLibraryNotSupported)); + } + internal static Exception UnsupportedFeatureAndToken(SqlInternalConnectionTds internalConnection, string token) + { + var innerException = ADP.NotSupported(StringsHelper.GetString(Strings.SQL_UnsupportedToken, token)); + + SqlErrorCollection errors = new SqlErrorCollection(); + errors.Add(new SqlError(0, 0, TdsEnums.FATAL_ERROR_CLASS, null, StringsHelper.GetString(Strings.SQL_UnsupportedFeature), "", 0)); + SqlException exc = SqlException.CreateException(errors, "", internalConnection, innerException); + return exc; + } + + internal static Exception BatchedUpdatesNotAvailableOnContextConnection() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_BatchedUpdatesNotAvailableOnContextConnection)); + } + internal static Exception Azure_ManagedIdentityException(string msg) + { + SqlErrorCollection errors = new SqlErrorCollection + { + new SqlError(0, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, null, msg, "", 0) + }; + SqlException exc = SqlException.CreateException(errors, null); + exc._doNotReconnect = true; // disable open retry logic on this error + return exc; + } + + #region Always Encrypted Errors + + #region Always Encrypted - Certificate Store Provider Errors + internal static Exception InvalidKeyEncryptionAlgorithm(string encryptionAlgorithm, string validEncryptionAlgorithm, bool isSystemOp) + { + if (isSystemOp) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidKeyEncryptionAlgorithmSysErr, encryptionAlgorithm, validEncryptionAlgorithm), TdsEnums.TCE_PARAM_ENCRYPTION_ALGORITHM); + } + else + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidKeyEncryptionAlgorithm, encryptionAlgorithm, validEncryptionAlgorithm), TdsEnums.TCE_PARAM_ENCRYPTION_ALGORITHM); + } + } + + internal static Exception NullKeyEncryptionAlgorithm(bool isSystemOp) + { + if (isSystemOp) + { + return ADP.ArgumentNull(TdsEnums.TCE_PARAM_ENCRYPTION_ALGORITHM, StringsHelper.GetString(Strings.TCE_NullKeyEncryptionAlgorithmSysErr)); + } + else + { + return ADP.ArgumentNull(TdsEnums.TCE_PARAM_ENCRYPTION_ALGORITHM, StringsHelper.GetString(Strings.TCE_NullKeyEncryptionAlgorithm)); + } + } + + internal static Exception EmptyColumnEncryptionKey() + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_EmptyColumnEncryptionKey), TdsEnums.TCE_PARAM_COLUMNENCRYPTION_KEY); + } + + internal static Exception NullColumnEncryptionKey() + { + return ADP.ArgumentNull(TdsEnums.TCE_PARAM_COLUMNENCRYPTION_KEY, StringsHelper.GetString(Strings.TCE_NullColumnEncryptionKey)); + } + + internal static Exception EmptyEncryptedColumnEncryptionKey() + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_EmptyEncryptedColumnEncryptionKey), TdsEnums.TCE_PARAM_ENCRYPTED_CEK); + } + + internal static Exception NullEncryptedColumnEncryptionKey() + { + return ADP.ArgumentNull(TdsEnums.TCE_PARAM_ENCRYPTED_CEK, StringsHelper.GetString(Strings.TCE_NullEncryptedColumnEncryptionKey)); + } + + internal static Exception LargeCertificatePathLength(int actualLength, int maxLength, bool isSystemOp) + { + if (isSystemOp) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_LargeCertificatePathLengthSysErr, actualLength, maxLength), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + else + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_LargeCertificatePathLength, actualLength, maxLength), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + } + + internal static Exception NullCertificatePath(string[] validLocations, bool isSystemOp) + { + Debug.Assert(2 == validLocations.Length); + if (isSystemOp) + { + return ADP.ArgumentNull(TdsEnums.TCE_PARAM_MASTERKEY_PATH, StringsHelper.GetString(Strings.TCE_NullCertificatePathSysErr, validLocations[0], validLocations[1], @"/")); + } + else + { + return ADP.ArgumentNull(TdsEnums.TCE_PARAM_MASTERKEY_PATH, StringsHelper.GetString(Strings.TCE_NullCertificatePath, validLocations[0], validLocations[1], @"/")); + } + } + + internal static Exception NullCspKeyPath(bool isSystemOp) + { + if (isSystemOp) + { + return ADP.ArgumentNull(TdsEnums.TCE_PARAM_MASTERKEY_PATH, StringsHelper.GetString(Strings.TCE_NullCspPathSysErr, @"/")); + } + else + { + return ADP.ArgumentNull(TdsEnums.TCE_PARAM_MASTERKEY_PATH, StringsHelper.GetString(Strings.TCE_NullCspPath, @"/")); + } + } + + internal static Exception NullCngKeyPath(bool isSystemOp) + { + if (isSystemOp) + { + return ADP.ArgumentNull(TdsEnums.TCE_PARAM_MASTERKEY_PATH, StringsHelper.GetString(Strings.TCE_NullCngPathSysErr, @"/")); + } + else + { + return ADP.ArgumentNull(TdsEnums.TCE_PARAM_MASTERKEY_PATH, StringsHelper.GetString(Strings.TCE_NullCngPath, @"/")); + } + } + + internal static Exception InvalidCertificatePath(string actualCertificatePath, string[] validLocations, bool isSystemOp) + { + Debug.Assert(2 == validLocations.Length); + if (isSystemOp) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCertificatePathSysErr, actualCertificatePath, validLocations[0], validLocations[1], @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + else + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCertificatePath, actualCertificatePath, validLocations[0], validLocations[1], @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + } + + internal static Exception InvalidCspPath(string masterKeyPath, bool isSystemOp) + { + if (isSystemOp) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCspPathSysErr, masterKeyPath, @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + else + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCspPath, masterKeyPath, @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + } + + internal static Exception InvalidCngPath(string masterKeyPath, bool isSystemOp) + { + if (isSystemOp) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCngPathSysErr, masterKeyPath, @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + else + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCngPath, masterKeyPath, @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + } + + internal static Exception EmptyCspName(string masterKeyPath, bool isSystemOp) + { + if (isSystemOp) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_EmptyCspNameSysErr, masterKeyPath, @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + else + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_EmptyCspName, masterKeyPath, @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + } + + internal static Exception EmptyCngName(string masterKeyPath, bool isSystemOp) + { + if (isSystemOp) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_EmptyCngNameSysErr, masterKeyPath, @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + else + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_EmptyCngName, masterKeyPath, @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + } + + internal static Exception EmptyCspKeyId(string masterKeyPath, bool isSystemOp) + { + if (isSystemOp) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_EmptyCspKeyIdSysErr, masterKeyPath, @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + else + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_EmptyCspKeyId, masterKeyPath, @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + } + + internal static Exception EmptyCngKeyId(string masterKeyPath, bool isSystemOp) + { + if (isSystemOp) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_EmptyCngKeyIdSysErr, masterKeyPath, @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + else + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_EmptyCngKeyId, masterKeyPath, @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + } + + internal static Exception InvalidCspName(string cspName, string masterKeyPath, bool isSystemOp) + { + if (isSystemOp) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCspNameSysErr, cspName, masterKeyPath), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + else + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCspName, cspName, masterKeyPath), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + } + + internal static Exception InvalidCspKeyIdentifier(string keyIdentifier, string masterKeyPath, bool isSystemOp) + { + if (isSystemOp) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCspKeyIdSysErr, keyIdentifier, masterKeyPath), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + else + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCspKeyId, keyIdentifier, masterKeyPath), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + } + + internal static Exception InvalidCngKey(string masterKeyPath, string cngProviderName, string keyIdentifier, bool isSystemOp) + { + if (isSystemOp) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCngKeySysErr, masterKeyPath, cngProviderName, keyIdentifier), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + else + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCngKey, masterKeyPath, cngProviderName, keyIdentifier), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + } + + internal static Exception InvalidCertificateLocation(string certificateLocation, string certificatePath, string[] validLocations, bool isSystemOp) + { + +#if NETFRAMEWORK + Debug.Assert(2 == validLocations.Length); +#endif + if (isSystemOp) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCertificateLocationSysErr, certificateLocation, certificatePath, validLocations[0], validLocations[1], @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + else + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCertificateLocation, certificateLocation, certificatePath, validLocations[0], validLocations[1], @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + } + + internal static Exception InvalidCertificateStore(string certificateStore, string certificatePath, string validCertificateStore, bool isSystemOp) + { + if (isSystemOp) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCertificateStoreSysErr, certificateStore, certificatePath, validCertificateStore), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + else + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCertificateStore, certificateStore, certificatePath, validCertificateStore), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + } + + internal static Exception EmptyCertificateThumbprint(string certificatePath, bool isSystemOp) + { + if (isSystemOp) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_EmptyCertificateThumbprintSysErr, certificatePath), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + else + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_EmptyCertificateThumbprint, certificatePath), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + } + + internal static Exception CertificateNotFound(string thumbprint, string certificateLocation, string certificateStore, bool isSystemOp) + { + if (isSystemOp) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_CertificateNotFoundSysErr, thumbprint, certificateLocation, certificateStore), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + else + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_CertificateNotFound, thumbprint, certificateLocation, certificateStore), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + } + + internal static Exception InvalidAlgorithmVersionInEncryptedCEK(byte actual, byte expected) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidAlgorithmVersionInEncryptedCEK, actual.ToString(@"X2"), expected.ToString(@"X2")), TdsEnums.TCE_PARAM_ENCRYPTED_CEK); + } + + internal static Exception InvalidCiphertextLengthInEncryptedCEK(int actual, int expected, string certificateName) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCiphertextLengthInEncryptedCEK, actual, expected, certificateName), TdsEnums.TCE_PARAM_ENCRYPTED_CEK); + } + + internal static Exception InvalidCiphertextLengthInEncryptedCEKCsp(int actual, int expected, string masterKeyPath) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCiphertextLengthInEncryptedCEKCsp, actual, expected, masterKeyPath), TdsEnums.TCE_PARAM_ENCRYPTED_CEK); + } + + internal static Exception InvalidCiphertextLengthInEncryptedCEKCng(int actual, int expected, string masterKeyPath) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCiphertextLengthInEncryptedCEKCng, actual, expected, masterKeyPath), TdsEnums.TCE_PARAM_ENCRYPTED_CEK); + } + + internal static Exception InvalidSignatureInEncryptedCEK(int actual, int expected, string masterKeyPath) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidSignatureInEncryptedCEK, actual, expected, masterKeyPath), TdsEnums.TCE_PARAM_ENCRYPTED_CEK); + } + + internal static Exception InvalidSignatureInEncryptedCEKCsp(int actual, int expected, string masterKeyPath) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidSignatureInEncryptedCEKCsp, actual, expected, masterKeyPath), TdsEnums.TCE_PARAM_ENCRYPTED_CEK); + } + + internal static Exception InvalidSignatureInEncryptedCEKCng(int actual, int expected, string masterKeyPath) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidSignatureInEncryptedCEKCng, actual, expected, masterKeyPath), TdsEnums.TCE_PARAM_ENCRYPTED_CEK); + } + + internal static Exception InvalidCertificateSignature(string certificatePath) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCertificateSignature, certificatePath), TdsEnums.TCE_PARAM_ENCRYPTED_CEK); + } + + internal static Exception InvalidSignature(string masterKeyPath) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidSignature, masterKeyPath), TdsEnums.TCE_PARAM_ENCRYPTED_CEK); + } + + internal static Exception CertificateWithNoPrivateKey(string keyPath, bool isSystemOp) + { + if (isSystemOp) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_CertificateWithNoPrivateKeySysErr, keyPath), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + else + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_CertificateWithNoPrivateKey, keyPath), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + } + #endregion Always Encrypted - Certificate Store Provider Errors + + #region Always Encrypted - Cryptographic Algorithms Error messages + internal static Exception NullPlainText() + { + return ADP.ArgumentNull(StringsHelper.GetString(Strings.TCE_NullPlainText)); + } + + static internal Exception VeryLargeCiphertext(long cipherTextLength, long maxCipherTextSize, long plainTextLength) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_VeryLargeCiphertext, cipherTextLength, maxCipherTextSize, plainTextLength)); + } + + internal static Exception NullCipherText() + { + return ADP.ArgumentNull(StringsHelper.GetString(Strings.TCE_NullCipherText)); + } + + internal static Exception NullColumnEncryptionAlgorithm(string supportedAlgorithms) + { + return ADP.ArgumentNull(TdsEnums.TCE_PARAM_ENCRYPTION_ALGORITHM, StringsHelper.GetString(Strings.TCE_NullColumnEncryptionAlgorithm, supportedAlgorithms)); + } + + internal static Exception NullColumnEncryptionKeySysErr() + { + return ADP.ArgumentNull(TdsEnums.TCE_PARAM_ENCRYPTIONKEY, StringsHelper.GetString(Strings.TCE_NullColumnEncryptionKeySysErr)); + } + + internal static Exception InvalidKeySize(string algorithmName, int actualKeylength, int expectedLength) + { + return ADP.Argument(StringsHelper.GetString( + Strings.TCE_InvalidKeySize, + algorithmName, + actualKeylength, + expectedLength), TdsEnums.TCE_PARAM_ENCRYPTIONKEY); + } + + internal static Exception InvalidEncryptionType(string algorithmName, SqlClientEncryptionType encryptionType, params SqlClientEncryptionType[] validEncryptionTypes) + { + const string valueSeparator = @", "; + return ADP.Argument( + StringsHelper.GetString( + Strings.TCE_InvalidEncryptionType, + algorithmName, + encryptionType.ToString(), + string.Join(valueSeparator, Map(validEncryptionTypes, static validEncryptionType => $"'{validEncryptionType:G}'")) + ), + TdsEnums.TCE_PARAM_ENCRYPTIONTYPE + ); + } + + internal static Exception InvalidCipherTextSize(int actualSize, int minimumSize) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCipherTextSize, actualSize, minimumSize), TdsEnums.TCE_PARAM_CIPHERTEXT); + } + + internal static Exception InvalidAlgorithmVersion(byte actual, byte expected) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidAlgorithmVersion, actual.ToString(@"X2"), expected.ToString(@"X2")), TdsEnums.TCE_PARAM_CIPHERTEXT); + } + + internal static Exception InvalidAuthenticationTag() + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidAuthenticationTag), TdsEnums.TCE_PARAM_CIPHERTEXT); + } + #endregion Always Encrypted - Cryptographic Algorithms Error messages + + #region Always Encrypted - Errors from sp_describe_parameter_encryption + internal static Exception UnexpectedDescribeParamFormatParameterMetadata() + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_UnexpectedDescribeParamFormatParameterMetadata, "sp_describe_parameter_encryption")); + } + + internal static Exception UnexpectedDescribeParamFormatAttestationInfo(string enclaveType) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_UnexpectedDescribeParamFormatAttestationInfo, "sp_describe_parameter_encryption", enclaveType)); + } + + internal static Exception InvalidEncryptionKeyOrdinalEnclaveMetadata(int ordinal, int maxOrdinal) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_InvalidEncryptionKeyOrdinalEnclaveMetadata, ordinal, maxOrdinal)); + } + + internal static Exception InvalidEncryptionKeyOrdinalParameterMetadata(int ordinal, int maxOrdinal) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_InvalidEncryptionKeyOrdinalParameterMetadata, ordinal, maxOrdinal)); + } + + public static Exception MultipleRowsReturnedForAttestationInfo() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_MultipleRowsReturnedForAttestationInfo, "sp_describe_parameter_encryption")); + } + + internal static Exception ParamEncryptionMetadataMissing(string paramName, string procedureName) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_ParamEncryptionMetaDataMissing, "sp_describe_parameter_encryption", paramName, procedureName)); + } + + internal static Exception ProcEncryptionMetadataMissing(string procedureName) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_ProcEncryptionMetaDataMissing, "sp_describe_parameter_encryption", procedureName)); + } + + internal static Exception UnableToVerifyColumnMasterKeySignature(Exception innerException) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_UnableToVerifyColumnMasterKeySignature, innerException.Message), innerException); + } + + internal static Exception ColumnMasterKeySignatureVerificationFailed(string cmkPath) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_ColumnMasterKeySignatureVerificationFailed, cmkPath)); + } + + internal static Exception InvalidKeyStoreProviderName(string providerName, List systemProviders, List customProviders) + { + const string valueSeparator = @", "; + string systemProviderStr = string.Join(valueSeparator, Map(systemProviders, static provider => $"'{provider}'")); + string customProviderStr = string.Join(valueSeparator, Map(customProviders, static provider => $"'{provider}'")); + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidKeyStoreProviderName, providerName, systemProviderStr, customProviderStr)); + } + + internal static Exception ParamInvalidForceColumnEncryptionSetting(string paramName, string procedureName) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_ParamInvalidForceColumnEncryptionSetting, TdsEnums.TCE_PARAM_FORCE_COLUMN_ENCRYPTION, paramName, procedureName, "SqlParameter")); + } + + internal static Exception ParamUnExpectedEncryptionMetadata(string paramName, string procedureName) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_ParamUnExpectedEncryptionMetadata, paramName, procedureName, TdsEnums.TCE_PARAM_FORCE_COLUMN_ENCRYPTION, "SqlParameter")); + } + + internal static Exception ColumnMasterKeySignatureNotFound(string cmkPath) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_ColumnMasterKeySignatureNotFound, cmkPath)); + } + #endregion Always Encrypted - Errors from sp_describe_parameter_encryption + + #region Always Encrypted - Errors from secure channel Communication + + internal static Exception ExceptionWhenGeneratingEnclavePackage(Exception innerException) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_ExceptionWhenGeneratingEnclavePackage, innerException.Message), innerException); + } + + internal static Exception FailedToEncryptRegisterRulesBytePackage(Exception innerException) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_FailedToEncryptRegisterRulesBytePackage, innerException.Message), innerException); + } + + internal static Exception InvalidKeyIdUnableToCastToUnsignedShort(int keyId, Exception innerException) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidKeyIdUnableToCastToUnsignedShort, keyId, innerException.Message), innerException); + } + + internal static Exception InvalidDatabaseIdUnableToCastToUnsignedInt(int databaseId, Exception innerException) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidDatabaseIdUnableToCastToUnsignedInt, databaseId, innerException.Message), innerException); + } + + internal static Exception InvalidAttestationParameterUnableToConvertToUnsignedInt(string variableName, int intValue, string enclaveType, Exception innerException) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidAttestationParameterUnableToConvertToUnsignedInt, enclaveType, intValue, variableName, innerException.Message), innerException); + } + + internal static Exception OffsetOutOfBounds(string argument, string type, string method) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_OffsetOutOfBounds, type, method)); + } + + internal static Exception InsufficientBuffer(string argument, string type, string method) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InsufficientBuffer, argument, type, method)); + } + + internal static Exception ColumnEncryptionKeysNotFound() + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_ColumnEncryptionKeysNotFound)); + } + + #endregion Always Encrypted - Errors from secure channel Communication + + #region Always Encrypted - Errors when performing attestation + internal static Exception AttestationInfoNotReturnedFromSqlServer(string enclaveType, string enclaveAttestationUrl) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_AttestationInfoNotReturnedFromSQLServer, enclaveType, enclaveAttestationUrl)); + } + + internal static SqlException AttestationFailed(string errorMessage, Exception innerException = null) + { + SqlErrorCollection errors = new(); + errors.Add(new SqlError( + infoNumber: 0, + errorState: 0, + errorClass: 0, + server: null, + errorMessage, + procedure: string.Empty, + lineNumber: 0)); + return SqlException.CreateException(errors, serverVersion: string.Empty, Guid.Empty, innerException); + } + + #endregion Always Encrypted - Errors when performing attestation + + #region Always Encrypted - Errors when establishing secure channel + internal static Exception NullArgumentInConstructorInternal(string argumentName, string objectUnderConstruction) + { + return ADP.ArgumentNull(argumentName, StringsHelper.GetString(Strings.TCE_NullArgumentInConstructorInternal, argumentName, objectUnderConstruction)); + } + + internal static Exception EmptyArgumentInConstructorInternal(string argumentName, string objectUnderConstruction) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_EmptyArgumentInConstructorInternal, argumentName, objectUnderConstruction)); + } + + internal static Exception NullArgumentInternal(string argumentName, string type, string method) + { + return ADP.ArgumentNull(argumentName, StringsHelper.GetString(Strings.TCE_NullArgumentInternal, argumentName, type, method)); + } + + internal static Exception EmptyArgumentInternal(string argumentName, string type, string method) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_EmptyArgumentInternal, argumentName, type, method)); + } + #endregion Always Encrypted - Errors when establishing secure channel + + #region Always Encrypted - Enclave provider/configuration errors + + internal static Exception CannotGetSqlColumnEncryptionEnclaveProviderConfig(Exception innerException) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_CannotGetSqlColumnEncryptionEnclaveProviderConfig, innerException.Message), innerException); + } + + internal static Exception CannotCreateSqlColumnEncryptionEnclaveProvider(string providerName, string type, Exception innerException) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_CannotCreateSqlColumnEncryptionEnclaveProvider, providerName, type, innerException.Message), innerException); + } + + internal static Exception SqlColumnEncryptionEnclaveProviderNameCannotBeEmpty() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_SqlColumnEncryptionEnclaveProviderNameCannotBeEmpty)); + } + + internal static Exception NoAttestationUrlSpecifiedForEnclaveBasedQuerySpDescribe(string enclaveType) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_NoAttestationUrlSpecifiedForEnclaveBasedQuerySpDescribe, "sp_describe_parameter_encryption", enclaveType)); + } + + internal static Exception NoAttestationUrlSpecifiedForEnclaveBasedQueryGeneratingEnclavePackage(string enclaveType) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_NoAttestationUrlSpecifiedForEnclaveBasedQueryGeneratingEnclavePackage, enclaveType)); + } + + internal static Exception EnclaveTypeNullForEnclaveBasedQuery() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_EnclaveTypeNullForEnclaveBasedQuery)); + } + + internal static Exception EnclaveProvidersNotConfiguredForEnclaveBasedQuery() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_EnclaveProvidersNotConfiguredForEnclaveBasedQuery)); + } + + internal static Exception EnclaveProviderNotFound(string enclaveType, string attestationProtocol = null) + { + return attestationProtocol != null ? ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_EnclaveProviderNotFound, enclaveType, attestationProtocol)) + : ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_EnclaveProviderNotFound, enclaveType)); + } + + internal static Exception NullEnclaveSessionReturnedFromProvider(string enclaveType, string attestationUrl) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_NullEnclaveSessionReturnedFromProvider, enclaveType, attestationUrl)); + } + + #endregion Always Encrypted - Enclave provider/configuration errors + + #region Always Encrypted - Generic toplevel failures + + internal static Exception GetExceptionArray(string serverName, string errorMessage, Exception e) + { + // Create and throw an exception array + SqlErrorCollection sqlErs = new SqlErrorCollection(); + Exception exceptionToInclude = (null != e.InnerException) ? e.InnerException : e; + sqlErs.Add(new SqlError(infoNumber: 0, errorState: (byte)0x00, errorClass: (byte)TdsEnums.MIN_ERROR_CLASS, server: serverName, errorMessage: errorMessage, procedure: null, lineNumber: 0)); + + if (e is SqlException) + { + SqlException exThrown = (SqlException)e; + SqlErrorCollection errorList = exThrown.Errors; + for (int i = 0; i < exThrown.Errors.Count; i++) + { + sqlErs.Add(errorList[i]); + } + } + else + { + sqlErs.Add(new SqlError(infoNumber: 0, errorState: (byte)0x00, errorClass: (byte)TdsEnums.MIN_ERROR_CLASS, server: serverName, errorMessage: e.Message, procedure: null, lineNumber: 0)); + } + + return SqlException.CreateException(sqlErs, "", null, exceptionToInclude); + } + + internal static Exception ColumnDecryptionFailed(string columnName, string serverName, Exception e) + { + return GetExceptionArray(serverName, StringsHelper.GetString(Strings.TCE_ColumnDecryptionFailed, columnName), e); + } + + internal static Exception ParamEncryptionFailed(string paramName, string serverName, Exception e) + { + return GetExceptionArray(serverName, StringsHelper.GetString(Strings.TCE_ParamEncryptionFailed, paramName), e); + } + + internal static Exception ParamDecryptionFailed(string paramName, string serverName, Exception e) + { + return GetExceptionArray(serverName, StringsHelper.GetString(Strings.TCE_ParamDecryptionFailed, paramName), e); + } + #endregion Always Encrypted - Generic toplevel failures + + #region Always Encrypted - Client side query processing errors + + internal static Exception UnknownColumnEncryptionAlgorithm(string algorithmName, string supportedAlgorithms) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_UnknownColumnEncryptionAlgorithm, algorithmName, supportedAlgorithms)); + } + + internal static Exception UnknownColumnEncryptionAlgorithmId(int algoId, string supportAlgorithmIds) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_UnknownColumnEncryptionAlgorithmId, algoId, supportAlgorithmIds), TdsEnums.TCE_PARAM_CIPHER_ALGORITHM_ID); + } + + internal static Exception UnsupportedNormalizationVersion(byte version) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_UnsupportedNormalizationVersion, version, "'1'", "SQL Server")); + } + + internal static Exception UnrecognizedKeyStoreProviderName(string providerName, List systemProviders, List customProviders) + { + const string valueSeparator = @", "; + string systemProviderStr = string.Join(valueSeparator, Map(systemProviders, static provider => @"'" + provider + @"'")); + string customProviderStr = string.Join(valueSeparator, Map(customProviders, static provider => @"'" + provider + @"'")); + return ADP.Argument(StringsHelper.GetString(Strings.TCE_UnrecognizedKeyStoreProviderName, providerName, systemProviderStr, customProviderStr)); + } + + internal static Exception InvalidDataTypeForEncryptedParameter(string parameterName, int actualDataType, int expectedDataType) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_NullProviderValue, parameterName, actualDataType, expectedDataType)); + } + + internal static Exception KeyDecryptionFailed(string providerName, string keyHex, Exception e) + { + + if (providerName.Equals(SqlColumnEncryptionCertificateStoreProvider.ProviderName)) + { + return GetExceptionArray(null, StringsHelper.GetString(Strings.TCE_KeyDecryptionFailedCertStore, providerName, keyHex), e); + } + else + { + return GetExceptionArray(null, StringsHelper.GetString(Strings.TCE_KeyDecryptionFailed, providerName, keyHex), e); + } + } + + internal static Exception UntrustedKeyPath(string keyPath, string serverName) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_UntrustedKeyPath, keyPath, serverName)); + } + + internal static Exception UnsupportedDatatypeEncryption(string dataType) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_UnsupportedDatatype, dataType)); + } + + internal static Exception ThrowDecryptionFailed(string keyStr, string valStr, Exception e) + { + return GetExceptionArray(null, StringsHelper.GetString(Strings.TCE_DecryptionFailed, keyStr, valStr), e); + } + + internal static Exception NullEnclaveSessionDuringQueryExecution(string enclaveType, string enclaveAttestationUrl) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_NullEnclaveSessionDuringQueryExecution, enclaveType, enclaveAttestationUrl)); + } + + internal static Exception NullEnclavePackageForEnclaveBasedQuery(string enclaveType, string enclaveAttestationUrl) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_NullEnclavePackageForEnclaveBasedQuery, enclaveType, enclaveAttestationUrl)); + } + + internal static Exception EnclaveTypeNotSupported(string enclaveType) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_EnclaveTypeNotSupported, enclaveType)); + } + + internal static Exception AttestationProtocolNotSupportEnclaveType(string attestationProtocolStr, string enclaveType) + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_AttestationProtocolNotSupportEnclaveType, attestationProtocolStr, enclaveType)); + } + + internal static Exception AttestationProtocolNotSpecifiedForGeneratingEnclavePackage() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_AttestationProtocolNotSpecifiedForGeneratingEnclavePackage)); + } + + #endregion Always Encrypted - Client side query processing errors + + #region Always Encrypted - SQL connection related error messages + + internal static Exception TceNotSupported() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_NotSupportedByServer, "SQL Server")); + } + + internal static Exception EnclaveComputationsNotSupported() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_EnclaveComputationsNotSupported)); + } + + internal static Exception AttestationURLNotSupported() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_AttestationURLNotSupported)); + } + + internal static Exception AttestationProtocolNotSupported() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_AttestationProtocolNotSupported)); + } + + internal static Exception EnclaveTypeNotReturned() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_EnclaveTypeNotReturned)); + } + #endregion Always Encrypted - SQL connection related error messages + + #region Always Encrypted - Extensibility related error messages + + internal static Exception CanOnlyCallOnce() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.TCE_CanOnlyCallOnce)); + } + + internal static Exception NullCustomKeyStoreProviderDictionary() + { + return ADP.ArgumentNull(TdsEnums.TCE_PARAM_CLIENT_KEYSTORE_PROVIDERS, StringsHelper.GetString(Strings.TCE_NullCustomKeyStoreProviderDictionary)); + } + + internal static Exception InvalidCustomKeyStoreProviderName(string providerName, string prefix) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCustomKeyStoreProviderName, providerName, prefix), TdsEnums.TCE_PARAM_CLIENT_KEYSTORE_PROVIDERS); + } + + internal static Exception NullProviderValue(string providerName) + { + return ADP.ArgumentNull(TdsEnums.TCE_PARAM_CLIENT_KEYSTORE_PROVIDERS, StringsHelper.GetString(Strings.TCE_NullProviderValue, providerName)); + } + + internal static Exception EmptyProviderName() + { + return ADP.ArgumentNull(TdsEnums.TCE_PARAM_CLIENT_KEYSTORE_PROVIDERS, StringsHelper.GetString(Strings.TCE_EmptyProviderName)); + } + #endregion Always Encrypted - Extensibility related error messages + + #endregion Always Encrypted Errors + + // + // Merged Provider + // + + static internal Exception ContextAllowsLimitedKeywords() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ContextAllowsLimitedKeywords)); + } + static internal Exception ContextAllowsOnlyTypeSystem2005() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ContextAllowsOnlyTypeSystem2005)); + } + static internal Exception ContextConnectionIsInUse() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ContextConnectionIsInUse)); + } + static internal Exception ContextUnavailableOutOfProc() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ContextUnavailableOutOfProc)); + } + static internal Exception ContextUnavailableWhileInProc() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_ContextUnavailableWhileInProc)); + } + static internal Exception NestedTransactionScopesNotSupported() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_NestedTransactionScopesNotSupported)); + } + static internal Exception NotAvailableOnContextConnection() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_NotAvailableOnContextConnection)); + } + static internal Exception NotificationsNotAvailableOnContextConnection() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_NotificationsNotAvailableOnContextConnection)); + } + + static internal Exception UserInstanceNotAvailableInProc() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_UserInstanceNotAvailableInProc)); + } + static internal Exception ArgumentLengthMismatch(string arg1, string arg2) + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_ArgumentLengthMismatch, arg1, arg2)); + } + static internal Exception InvalidSqlDbTypeOneAllowedType(SqlDbType invalidType, string method, SqlDbType allowedType) + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_InvalidSqlDbTypeWithOneAllowedType, invalidType, method, allowedType)); + } + static internal Exception SqlPipeErrorRequiresSendEnd() + { + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_PipeErrorRequiresSendEnd)); + } + static internal Exception TooManyValues(string arg) + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_TooManyValues), arg); + } + + /// + /// gets a message for SNI error (sniError must be valid, non-zero error code) + /// + internal static string GetSNIErrorMessage(int sniError) + { + Debug.Assert(sniError > 0 && sniError <= (int)SNINativeMethodWrapper.SniSpecialErrors.MaxErrorValue, "SNI error is out of range"); + + string errorMessageId = string.Format("SNI_ERROR_{0}", sniError); + return StringsHelper.GetResourceString(errorMessageId); + } + + // BulkLoad + internal const string WriteToServer = "WriteToServer"; + + // Default values for SqlDependency and SqlNotificationRequest + internal const int SqlDependencyTimeoutDefault = 0; + internal const int SqlDependencyServerTimeout = 5 * 24 * 3600; // 5 days - used to compute default TTL of the dependency + internal const string SqlNotificationServiceDefault = "SqlQueryNotificationService"; + internal const string SqlNotificationStoredProcedureDefault = "SqlQueryNotificationStoredProcedure"; + + // constant strings + internal const string Transaction = "Transaction"; + internal const string Connection = "Connection"; + + private static IEnumerable Map(IEnumerable source, Func selector) + { + if (source == null) + { + throw new ArgumentNullException(nameof(source)); + } + + if (selector == null) + { + throw new ArgumentNullException(nameof(selector)); + } + + foreach (T element in source) + { + yield return selector(element); + } + } + +#if NET6_0_OR_GREATER + internal static Exception SocketDidNotThrow() + { + return new InternalException(StringsHelper.GetString(Strings.SQL_SocketDidNotThrow, nameof(SocketException), nameof(SocketError.WouldBlock))); + } +#else + static internal Exception SnapshotNotSupported(System.Data.IsolationLevel level) + { + return ADP.Argument(StringsHelper.GetString(Strings.SQL_SnapshotNotSupported, typeof(System.Data.IsolationLevel), level.ToString())); + } + static internal Exception UnexpectedSmiEvent(Microsoft.Data.SqlClient.Server.SmiEventSink_Default.UnexpectedEventType eventType) + { + Debug.Assert(false, "UnexpectedSmiEvent: " + eventType.ToString()); // Assert here, because these exceptions will most likely be eaten by the server. + return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_UnexpectedSmiEvent, (int)eventType)); + } +#endif + + } + + sealed internal class SQLMessage + { + private SQLMessage() { /* prevent utility class from being instantiated*/ } + + // The class SQLMessage defines the error messages that are specific to the SqlDataAdapter + // that are caused by a netlib error. The functions will be called and then return the + // appropriate error message from the resource Framework.txt. The SqlDataAdapter will then + // take the error message and then create a SqlError for the message and then place + // that into a SqlException that is either thrown to the user or cached for throwing at + // a later time. This class is used so that there will be compile time checking of error + // messages. The resource Framework.txt will ensure proper string text based on the appropriate + // locale. + + internal static string CultureIdError() + { + return StringsHelper.GetString(Strings.SQL_CultureIdError); + } + internal static string EncryptionNotSupportedByClient() + { + return StringsHelper.GetString(Strings.SQL_EncryptionNotSupportedByClient); + } + internal static string EncryptionNotSupportedByServer() + { + return StringsHelper.GetString(Strings.SQL_EncryptionNotSupportedByServer); + } + internal static string CTAIPNotSupportedByServer() + { + return StringsHelper.GetString(Strings.SQL_CTAIPNotSupportedByServer); + } + internal static string OperationCancelled() + { + return StringsHelper.GetString(Strings.SQL_OperationCancelled); + } + internal static string SevereError() + { + return StringsHelper.GetString(Strings.SQL_SevereError); + } + internal static string SSPIInitializeError() + { + return StringsHelper.GetString(Strings.SQL_SSPIInitializeError); + } + internal static string SSPIGenerateError() + { + return StringsHelper.GetString(Strings.SQL_SSPIGenerateError); + } + internal static string KerberosTicketMissingError() + { + return StringsHelper.GetString(Strings.SQL_KerberosTicketMissingError); + } + internal static string Timeout() + { + return StringsHelper.GetString(Strings.SQL_Timeout_Execution); + } + internal static string Timeout_PreLogin_Begin() + { + return StringsHelper.GetString(Strings.SQL_Timeout_PreLogin_Begin); + } + internal static string Timeout_PreLogin_InitializeConnection() + { + return StringsHelper.GetString(Strings.SQL_Timeout_PreLogin_InitializeConnection); + } + internal static string Timeout_PreLogin_SendHandshake() + { + return StringsHelper.GetString(Strings.SQL_Timeout_PreLogin_SendHandshake); + } + internal static string Timeout_PreLogin_ConsumeHandshake() + { + return StringsHelper.GetString(Strings.SQL_Timeout_PreLogin_ConsumeHandshake); + } + internal static string Timeout_Login_Begin() + { + return StringsHelper.GetString(Strings.SQL_Timeout_Login_Begin); + } + internal static string Timeout_Login_ProcessConnectionAuth() + { + return StringsHelper.GetString(Strings.SQL_Timeout_Login_ProcessConnectionAuth); + } + internal static string Timeout_PostLogin() + { + return StringsHelper.GetString(Strings.SQL_Timeout_PostLogin); + } + internal static string Timeout_FailoverInfo() + { + return StringsHelper.GetString(Strings.SQL_Timeout_FailoverInfo); + } + internal static string Timeout_RoutingDestination() + { + return StringsHelper.GetString(Strings.SQL_Timeout_RoutingDestinationInfo); + } + internal static string Duration_PreLogin_Begin(long PreLoginBeginDuration) + { + return StringsHelper.GetString(Strings.SQL_Duration_PreLogin_Begin, PreLoginBeginDuration); + } + internal static string Duration_PreLoginHandshake(long PreLoginBeginDuration, long PreLoginHandshakeDuration) + { + return StringsHelper.GetString(Strings.SQL_Duration_PreLoginHandshake, PreLoginBeginDuration, PreLoginHandshakeDuration); + } + internal static string Duration_Login_Begin(long PreLoginBeginDuration, long PreLoginHandshakeDuration, long LoginBeginDuration) + { + return StringsHelper.GetString(Strings.SQL_Duration_Login_Begin, PreLoginBeginDuration, PreLoginHandshakeDuration, LoginBeginDuration); + } + internal static string Duration_Login_ProcessConnectionAuth(long PreLoginBeginDuration, long PreLoginHandshakeDuration, long LoginBeginDuration, long LoginAuthDuration) + { + return StringsHelper.GetString(Strings.SQL_Duration_Login_ProcessConnectionAuth, PreLoginBeginDuration, PreLoginHandshakeDuration, LoginBeginDuration, LoginAuthDuration); + } + internal static string Duration_PostLogin(long PreLoginBeginDuration, long PreLoginHandshakeDuration, long LoginBeginDuration, long LoginAuthDuration, long PostLoginDuration) + { + return StringsHelper.GetString(Strings.SQL_Duration_PostLogin, PreLoginBeginDuration, PreLoginHandshakeDuration, LoginBeginDuration, LoginAuthDuration, PostLoginDuration); + } + internal static string UserInstanceFailure() + { + return StringsHelper.GetString(Strings.SQL_UserInstanceFailure); + } + internal static string PreloginError() + { + return StringsHelper.GetString(Strings.Snix_PreLogin); + } + internal static string ExClientConnectionId() + { + return StringsHelper.GetString(Strings.SQL_ExClientConnectionId); + } + internal static string ExErrorNumberStateClass() + { + return StringsHelper.GetString(Strings.SQL_ExErrorNumberStateClass); + } + internal static string ExOriginalClientConnectionId() + { + return StringsHelper.GetString(Strings.SQL_ExOriginalClientConnectionId); + } + internal static string ExRoutingDestination() + { + return StringsHelper.GetString(Strings.SQL_ExRoutingDestination); + } + } + + /// + /// This class holds helper methods to escape Microsoft SQL Server identifiers, such as table, schema, database or other names + /// + internal static class SqlServerEscapeHelper + { + /// + /// Escapes the identifier with square brackets. The input has to be in unescaped form, like the parts received from MultipartIdentifier.ParseMultipartIdentifier. + /// + /// name of the identifier, in unescaped form + /// escapes the name with [], also escapes the last close bracket with double-bracket + internal static string EscapeIdentifier(string name) + { + Debug.Assert(!ADP.IsEmpty(name), "null or empty identifiers are not allowed"); + return "[" + name.Replace("]", "]]") + "]"; + } + + /// + /// Same as above EscapeIdentifier, except that output is written into StringBuilder + /// + internal static void EscapeIdentifier(StringBuilder builder, string name) + { + Debug.Assert(builder != null, "builder cannot be null"); + Debug.Assert(!ADP.IsEmpty(name), "null or empty identifiers are not allowed"); + + builder.Append("["); + builder.Append(name.Replace("]", "]]")); + builder.Append("]"); + } + + /// + /// Escape a string to be used inside TSQL literal, such as N'somename' or 'somename' + /// + internal static string EscapeStringAsLiteral(string input) + { + Debug.Assert(input != null, "input string cannot be null"); + return input.Replace("'", "''"); + } + + /// + /// Escape a string as a TSQL literal, wrapping it around with single quotes. + /// Use this method to escape input strings to prevent SQL injection + /// and to get correct behavior for embedded quotes. + /// + /// unescaped string + /// escaped and quoted literal string + internal static string MakeStringLiteral(string input) + { + if (ADP.IsEmpty(input)) + { + return "''"; + } + else + { + return "'" + EscapeStringAsLiteral(input) + "'"; + } + } + } + + /// + /// This class holds methods invoked on System.Transactions through reflection for Global Transactions + /// + internal static class SysTxForGlobalTransactions + { + private static readonly Lazy _enlistPromotableSinglePhase = new Lazy(() => + typeof(Transaction).GetMethod("EnlistPromotableSinglePhase", new Type[] { typeof(IPromotableSinglePhaseNotification), typeof(Guid) })); + + private static readonly Lazy _setDistributedTransactionIdentifier = new Lazy(() => + typeof(Transaction).GetMethod("SetDistributedTransactionIdentifier", new Type[] { typeof(IPromotableSinglePhaseNotification), typeof(Guid) })); + + private static readonly Lazy _getPromotedToken = new Lazy(() => + typeof(Transaction).GetMethod("GetPromotedToken")); + + /// + /// Enlists the given IPromotableSinglePhaseNotification and Non-MSDTC Promoter type into a transaction + /// + /// The MethodInfo instance to be invoked. Null if the method doesn't exist + public static MethodInfo EnlistPromotableSinglePhase + { + get + { + return _enlistPromotableSinglePhase.Value; + } + } + + /// + /// Sets the given DistributedTransactionIdentifier for a Transaction instance. + /// Needs to be invoked when using a Non-MSDTC Promoter type + /// + /// The MethodInfo instance to be invoked. Null if the method doesn't exist + public static MethodInfo SetDistributedTransactionIdentifier + { + get + { + return _setDistributedTransactionIdentifier.Value; + } + } + + /// + /// Gets the Promoted Token for a Transaction + /// + /// The MethodInfo instance to be invoked. Null if the method doesn't exist + public static MethodInfo GetPromotedToken + { + get + { + return _getPromotedToken.Value; + } + } + } + +#if NETFRAMEWORK + sealed internal class InOutOfProcHelper + { + private static readonly InOutOfProcHelper SingletonInstance = new InOutOfProcHelper(); + + private bool _inProc = false; + + // InOutOfProcHelper detects whether it's running inside the server or not. It does this + // by checking for the existence of a well-known function export on the current process. + // Note that calling conventions, etc. do not matter -- we'll never call the function, so + // only the name match or lack thereof matter. + [ResourceExposure(ResourceScope.None)] + [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)] + private InOutOfProcHelper() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + // SafeNativeMethods.GetModuleHandle calls into kernel32.dll, so return early to avoid + // a System.EntryPointNotFoundException on non-Windows platforms, e.g. Mono. + return; + } + // Don't need to close this handle... + // SxS: we use this method to check if we are running inside the SQL Server process. This call should be safe in SxS environment. + IntPtr handle = Common.SafeNativeMethods.GetModuleHandle(null); + if (IntPtr.Zero != handle) + { + // SQLBU 359301: Currently, the server exports different names for x86 vs. AMD64 and IA64. Supporting both names + // for now gives the server time to unify names across platforms without breaking currently-working ones. + // We can remove the obsolete name once the server is changed. + if (IntPtr.Zero != Common.SafeNativeMethods.GetProcAddress(handle, "_______SQL______Process______Available@0")) + { + _inProc = true; + } + else if (IntPtr.Zero != Common.SafeNativeMethods.GetProcAddress(handle, "______SQL______Process______Available")) + { + _inProc = true; + } + } + } + + internal static bool InProc + { + get + { + return SingletonInstance._inProc; + } + } + } +#endif } + From d7f84eb09dd8e70ac73f190f913e1dd1a9641138 Mon Sep 17 00:00:00 2001 From: David Engel Date: Wed, 12 Jun 2024 12:11:41 -0700 Subject: [PATCH 23/25] Add scope trace for GenerateSspiClientContext (#2497) --- .../Data/ProviderBase/DbConnectionFactory.cs | 2 +- .../netcore/src/Microsoft.Data.SqlClient.csproj | 2 +- .../src/Microsoft/Data/SqlClient/SNI/SNICommon.cs | 6 +++--- .../Microsoft/Data/SqlClient/SNI/SNIMarsHandle.cs | 4 ++-- .../src/Microsoft/Data/SqlClient/TdsParser.cs | 2 +- .../Data/ProviderBase/DbConnectionFactory.cs | 2 +- .../src/Microsoft/Data/SqlClient/SqlConnection.cs | 4 ++-- .../SqlClient/SSPI/ManagedSSPIContextProvider.cs | 2 +- .../SSPI/NegotiateSSPIContextProvider.cs | 3 ++- .../Data/SqlClient/SSPI/SSPIContextProvider.cs | 15 +++++++++------ 10 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/ProviderBase/DbConnectionFactory.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/ProviderBase/DbConnectionFactory.cs index df16ee4d23..e5c76701e4 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/ProviderBase/DbConnectionFactory.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/ProviderBase/DbConnectionFactory.cs @@ -49,7 +49,7 @@ abstract public DbProviderFactory ProviderFactory public void ClearAllPools() { - using (TryEventScope.Create(" connectionPoolGroups = _connectionPoolGroups; foreach (KeyValuePair entry in connectionPoolGroups) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj index c6676e1cf3..a08f87f133 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -20,7 +20,7 @@ $(NoWarn);IL2026;IL2057;IL2072;IL2075 - $([System.IO.Path]::Combine('$(IntermediateOutputPath)','$(TargetFramework)','$(TargetFrameworkMoniker).AssemblyAttributes$(DefaultLanguageSourceExtension)')) + $([System.IO.Path]::Combine('$(IntermediateOutputPath)','$(TargetFrameworkMoniker).AssemblyAttributes$(DefaultLanguageSourceExtension)')) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNICommon.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNICommon.cs index f8f2facb59..c9515d971f 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNICommon.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNICommon.cs @@ -151,7 +151,7 @@ internal class SNICommon /// True if certificate is valid internal static bool ValidateSslServerCertificate(Guid connectionId, string targetServerName, string hostNameInCertificate, X509Certificate serverCert, string validationCertFileName, SslPolicyErrors policyErrors) { - using (TrySNIEventScope.Create("SNICommon.ValidateSslServerCertificate | SNI | SCOPE | INFO | Entering Scope {0} ")) + using (TrySNIEventScope.Create(nameof(SNICommon))) { if (policyErrors == SslPolicyErrors.None) { @@ -292,7 +292,7 @@ internal static bool ValidateSslServerCertificate(Guid connectionId, string targ internal static IPAddress[] GetDnsIpAddresses(string serverName, TimeoutTimer timeout) { - using (TrySNIEventScope.Create(nameof(GetDnsIpAddresses))) + using (TrySNIEventScope.Create(nameof(SNICommon))) { int remainingTimeout = timeout.MillisecondsRemainingInt; SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.INFO, @@ -310,7 +310,7 @@ internal static IPAddress[] GetDnsIpAddresses(string serverName, TimeoutTimer ti internal static IPAddress[] GetDnsIpAddresses(string serverName) { - using (TrySNIEventScope.Create(nameof(GetDnsIpAddresses))) + using (TrySNIEventScope.Create(nameof(SNICommon))) { SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNICommon), EventType.INFO, "Getting DNS host entries for serverName {0}.", args0: serverName); return Dns.GetHostAddresses(serverName); diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIMarsHandle.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIMarsHandle.cs index 8246ce3d6f..b7f682f6d5 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIMarsHandle.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIMarsHandle.cs @@ -94,7 +94,7 @@ public SNIMarsHandle(SNIMarsConnection connection, ushort sessionId, object call /// SMUX header flags private void SendControlPacket(SNISMUXFlags flags) { - using (TrySNIEventScope.Create("SNIMarsHandle.SendControlPacket | SNI | INFO | SCOPE | Entering Scope {0}")) + using (TrySNIEventScope.Create(nameof(SNIMarsHandle))) { SNIPacket packet = RentPacket(headerSize: SNISMUXHeader.HEADER_LENGTH, dataSize: 0); #if DEBUG @@ -195,7 +195,7 @@ public override uint Send(SNIPacket packet) private uint InternalSendAsync(SNIPacket packet) { Debug.Assert(packet.ReservedHeaderSize == SNISMUXHeader.HEADER_LENGTH, "mars handle attempting to send muxed packet without smux reservation in InternalSendAsync"); - using (TrySNIEventScope.Create("SNIMarsHandle.InternalSendAsync | SNI | INFO | SCOPE | Entering Scope {0}")) + using (TrySNIEventScope.Create(nameof(SNIMarsHandle))) { lock (this) { diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs index 8a5ed05abe..337752a068 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -1448,7 +1448,7 @@ internal void ThrowExceptionAndWarning(TdsParserStateObject stateObj, SqlCommand internal SqlError ProcessSNIError(TdsParserStateObject stateObj) { - using (TryEventScope.Create("")) + using (TryEventScope.Create(nameof(TdsParser))) { #if DEBUG // There is an exception here for MARS as its possible that another thread has closed the connection just as we see an error diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/ProviderBase/DbConnectionFactory.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/ProviderBase/DbConnectionFactory.cs index 701719796a..b857323bb1 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/ProviderBase/DbConnectionFactory.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/ProviderBase/DbConnectionFactory.cs @@ -65,7 +65,7 @@ internal int ObjectID public void ClearAllPools() { - using (TryEventScope.Create("")) + using (TryEventScope.Create(nameof(DbConnectionFactory))) { Dictionary connectionPoolGroups = _connectionPoolGroups; foreach (KeyValuePair entry in connectionPoolGroups) diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnection.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnection.cs index b9d2e32daa..a7b0f76c12 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnection.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnection.cs @@ -2759,7 +2759,7 @@ private void IssueSQLDebug(uint option, string machineName, uint pid, uint id, s /// public static void ChangePassword(string connectionString, string newPassword) { - using (TryEventScope.Create("")) + using (TryEventScope.Create(nameof(SqlConnection))) { SqlClientEventSource.Log.TryCorrelationTraceEvent(" ActivityID {0}", ActivityCorrelator.Current); @@ -2802,7 +2802,7 @@ public static void ChangePassword(string connectionString, string newPassword) /// public static void ChangePassword(string connectionString, SqlCredential credential, SecureString newSecurePassword) { - using (TryEventScope.Create("")) + using (TryEventScope.Create(nameof(SqlConnection))) { SqlClientEventSource.Log.TryCorrelationTraceEvent(" ActivityID {0}", ActivityCorrelator.Current); diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/ManagedSSPIContextProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/ManagedSSPIContextProvider.cs index 546ee11366..186be63502 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/ManagedSSPIContextProvider.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/ManagedSSPIContextProvider.cs @@ -16,7 +16,7 @@ internal override void GenerateSspiClientContext(ReadOnlyMemory received, _sspiClientContextStatus ??= new SspiClientContextStatus(); SNIProxy.GenSspiClientContext(_sspiClientContextStatus, received, ref sendBuff, _sniSpnBuffer); - SqlClientEventSource.Log.TryTraceEvent("TdsParserStateObjectManaged.GenerateSspiClientContext | Info | Session Id {0}", _physicalStateObj.SessionId); + SqlClientEventSource.Log.TryTraceEvent("{0}.{1} | Info | Session Id {2}", nameof(ManagedSSPIContextProvider), nameof(GenerateSspiClientContext), _physicalStateObj.SessionId); sendLength = (uint)(sendBuff != null ? sendBuff.Length : 0); } } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NegotiateSSPIContextProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NegotiateSSPIContextProvider.cs index 21ab4a15b7..431cf5cd6f 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NegotiateSSPIContextProvider.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NegotiateSSPIContextProvider.cs @@ -21,7 +21,8 @@ internal override void GenerateSspiClientContext(ReadOnlyMemory received, _negotiateAuth ??= new(new NegotiateAuthenticationClientOptions { Package = "Negotiate", TargetName = Encoding.Unicode.GetString(_sniSpnBuffer[i]) }); sendBuff = _negotiateAuth.GetOutgoingBlob(received.Span, out statusCode)!; // Log session id, status code and the actual SPN used in the negotiation - SqlClientEventSource.Log.TryTraceEvent("TdsParserStateObjectManaged.GenerateSspiClientContext | Info | Session Id {0}, StatusCode={1}, SPN={2}", _physicalStateObj.SessionId, statusCode, _negotiateAuth.TargetName); + SqlClientEventSource.Log.TryTraceEvent("{0}.{1} | Info | Session Id {2}, StatusCode={3}, SPN={4}", nameof(NegotiateSSPIContextProvider), + nameof(GenerateSspiClientContext), _physicalStateObj.SessionId, statusCode, _negotiateAuth.TargetName); if (statusCode == NegotiateAuthenticationStatusCode.Completed || statusCode == NegotiateAuthenticationStatusCode.ContinueNeeded) break; // Successful case, exit the loop with current SPN. else diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/SSPIContextProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/SSPIContextProvider.cs index 256818660e..e9770ebb67 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/SSPIContextProvider.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/SSPIContextProvider.cs @@ -34,13 +34,16 @@ internal void SSPIData(ReadOnlyMemory receivedBuff, ref byte[] sendBuff, r internal void SSPIData(ReadOnlyMemory receivedBuff, ref byte[] sendBuff, ref UInt32 sendLength, byte[][] sniSpnBuffer) { - try + using (TrySNIEventScope.Create(nameof(SSPIContextProvider))) { - GenerateSspiClientContext(receivedBuff, ref sendBuff, ref sendLength, sniSpnBuffer); - } - catch (Exception e) - { - SSPIError(e.Message + Environment.NewLine + e.StackTrace, TdsEnums.GEN_CLIENT_CONTEXT); + try + { + GenerateSspiClientContext(receivedBuff, ref sendBuff, ref sendLength, sniSpnBuffer); + } + catch (Exception e) + { + SSPIError(e.Message + Environment.NewLine + e.StackTrace, TdsEnums.GEN_CLIENT_CONTEXT); + } } } From a240c2432614c156f0f81b9beb7994f2d35ebc52 Mon Sep 17 00:00:00 2001 From: Javad Rahnama Date: Wed, 12 Jun 2024 13:15:39 -0700 Subject: [PATCH 24/25] Address conflicts (#2562) --- .../Data/SqlClient/ActiveDirectoryAuthenticationProvider.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ActiveDirectoryAuthenticationProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ActiveDirectoryAuthenticationProvider.cs index d9ceb49c2d..acf224204a 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ActiveDirectoryAuthenticationProvider.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ActiveDirectoryAuthenticationProvider.cs @@ -572,9 +572,7 @@ private static TokenCredentialData CreateTokenCredentialInstance(TokenCredential DefaultAzureCredentialOptions defaultAzureCredentialOptions = new() { AuthorityHost = new Uri(tokenCredentialKey._authority), - SharedTokenCacheTenantId = tokenCredentialKey._audience, - VisualStudioCodeTenantId = tokenCredentialKey._audience, - VisualStudioTenantId = tokenCredentialKey._audience, + TenantId = tokenCredentialKey._audience, ExcludeInteractiveBrowserCredential = true // Force disabled, even though it's disabled by default to respect driver specifications. }; From d4b2bb32ac2ab2f9ecd12c441733f8d179bf255d Mon Sep 17 00:00:00 2001 From: Javad Rahnama Date: Wed, 12 Jun 2024 14:28:37 -0700 Subject: [PATCH 25/25] Addressing conflict (#2560) --- .../Data/ProviderBase/DbConnectionClosed.cs | 8 +-- .../Data/ProviderBase/DbConnectionInternal.cs | 50 ++++++++--------- .../Data/ProviderBase/DbConnectionPool.cs | 31 +++++------ .../Microsoft/Data/SqlClient/SqlCommand.cs | 6 +- .../Data/SqlClient/SqlConnectionHelper.cs | 13 ++--- .../Data/SqlClient/SqlDelegatedTransaction.cs | 55 +++++++++---------- .../SqlClient/SqlInternalConnectionSmi.cs | 18 +++--- .../SqlClient/SqlInternalConnectionTds.cs | 52 +++++++++--------- 8 files changed, 115 insertions(+), 118 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/ProviderBase/DbConnectionClosed.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/ProviderBase/DbConnectionClosed.cs index ad48b3fa30..99ad6029de 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/ProviderBase/DbConnectionClosed.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/ProviderBase/DbConnectionClosed.cs @@ -9,7 +9,7 @@ namespace Microsoft.Data.ProviderBase using System.Diagnostics; using System.Threading.Tasks; using Microsoft.Data.Common; - using SysTx = System.Transactions; + using System.Transactions; abstract internal class DbConnectionClosed : DbConnectionInternal { @@ -26,12 +26,12 @@ override public string ServerVersion } } - override protected void Activate(SysTx.Transaction transaction) + override protected void Activate(Transaction transaction) { throw ADP.ClosedConnectionError(); } - override public DbTransaction BeginTransaction(IsolationLevel il) + override public DbTransaction BeginTransaction(System.Data.IsolationLevel il) { throw ADP.ClosedConnectionError(); } @@ -51,7 +51,7 @@ override protected void Deactivate() throw ADP.ClosedConnectionError(); } - override public void EnlistTransaction(SysTx.Transaction transaction) + override public void EnlistTransaction(Transaction transaction) { throw ADP.ClosedConnectionError(); } diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/ProviderBase/DbConnectionInternal.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/ProviderBase/DbConnectionInternal.cs index 06b1e04712..b2e4f7d04e 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/ProviderBase/DbConnectionInternal.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/ProviderBase/DbConnectionInternal.cs @@ -15,13 +15,13 @@ namespace Microsoft.Data.ProviderBase using System.Threading.Tasks; using Microsoft.Data.Common; using Microsoft.Data.SqlClient; - using SysTx = System.Transactions; + using System.Transactions; internal abstract class DbConnectionInternal { private static int _objectTypeCount; internal readonly int _objectID = Interlocked.Increment(ref _objectTypeCount); - private SysTx.TransactionCompletedEventHandler _transactionCompletedEventHandler = null; + private TransactionCompletedEventHandler _transactionCompletedEventHandler = null; internal static readonly StateChangeEventArgs StateChangeClosed = new StateChangeEventArgs(ConnectionState.Open, ConnectionState.Closed); internal static readonly StateChangeEventArgs StateChangeOpen = new StateChangeEventArgs(ConnectionState.Closed, ConnectionState.Open); @@ -43,13 +43,13 @@ internal abstract class DbConnectionInternal private DateTime _createTime; // when the connection was created. - private SysTx.Transaction _enlistedTransaction; // [usage must be thread-safe] the transaction that we're enlisted in, either manually or automatically + private Transaction _enlistedTransaction; // [usage must be thread-safe] the transaction that we're enlisted in, either manually or automatically // _enlistedTransaction is a clone, so that transaction information can be queried even if the original transaction object is disposed. // However, there are times when we need to know if the original transaction object was disposed, so we keep a reference to it here. // This field should only be assigned a value at the same time _enlistedTransaction is updated. // Also, this reference should not be disposed, since we aren't taking ownership of it. - private SysTx.Transaction _enlistedTransactionOriginal; + private Transaction _enlistedTransactionOriginal; #if DEBUG private int _activateCount; // debug only counter to verify activate/deactivates are in sync. @@ -83,7 +83,7 @@ internal bool CanBePooled } } - protected internal SysTx.Transaction EnlistedTransaction + protected internal Transaction EnlistedTransaction { get { @@ -91,7 +91,7 @@ protected internal SysTx.Transaction EnlistedTransaction } set { - SysTx.Transaction currentEnlistedTransaction = _enlistedTransaction; + Transaction currentEnlistedTransaction = _enlistedTransaction; if (((null == currentEnlistedTransaction) && (null != value)) || ((null != currentEnlistedTransaction) && !currentEnlistedTransaction.Equals(value))) { // WebData 20000024 @@ -104,8 +104,8 @@ protected internal SysTx.Transaction EnlistedTransaction // SQLBUDT #230558 we need to use a clone of the transaction // when we store it, or we'll end up keeping it past the // duration of the using block of the TransactionScope - SysTx.Transaction valueClone = null; - SysTx.Transaction previousTransactionClone = null; + Transaction valueClone = null; + Transaction previousTransactionClone = null; try { if (null != value) @@ -188,7 +188,7 @@ protected bool EnlistedTransactionDisposed { bool disposed; - SysTx.Transaction currentEnlistedTransactionOriginal = _enlistedTransactionOriginal; + Transaction currentEnlistedTransactionOriginal = _enlistedTransactionOriginal; if (currentEnlistedTransactionOriginal != null) { disposed = currentEnlistedTransactionOriginal.TransactionInformation == null; @@ -385,9 +385,9 @@ public ConnectionState State internal virtual bool IsAccessTokenExpired => false; - abstract protected void Activate(SysTx.Transaction transaction); + abstract protected void Activate(Transaction transaction); - internal void ActivateConnection(SysTx.Transaction transaction) + internal void ActivateConnection(Transaction transaction) { // Internal method called from the connection pooler so we don't expose // the Activate method publicly. @@ -415,7 +415,7 @@ internal void AddWeakReference(object value, int tag) _referenceCollection.Add(value, tag); } - abstract public DbTransaction BeginTransaction(IsolationLevel il); + abstract public DbTransaction BeginTransaction(System.Data.IsolationLevel il); virtual public void ChangeDatabase(string value) { @@ -654,7 +654,7 @@ public virtual void Dispose() // Dispose of the _enlistedTransaction since it is a clone // of the original reference. // VSDD 780271 - _enlistedTransaction can be changed by another thread (TX end event) - SysTx.Transaction enlistedTransaction = Interlocked.Exchange(ref _enlistedTransaction, null); + Transaction enlistedTransaction = Interlocked.Exchange(ref _enlistedTransaction, null); if (enlistedTransaction != null) { enlistedTransaction.Dispose(); @@ -681,7 +681,7 @@ protected internal void UnDoomThisConnection() _connectionIsDoomed = false; } - abstract public void EnlistTransaction(SysTx.Transaction transaction); + abstract public void EnlistTransaction(Transaction transaction); virtual protected internal DataTable GetSchema(DbConnectionFactory factory, DbConnectionPoolGroup poolGroup, DbConnection outerConnection, string collectionName, string[] restrictions) { @@ -865,21 +865,21 @@ internal void RemoveWeakReference(object value) // Cleanup connection's transaction-specific structures (currently used by Delegated transaction). // This is a separate method because cleanup can be triggered in multiple ways for a delegated // transaction. - virtual protected void CleanupTransactionOnCompletion(SysTx.Transaction transaction) + virtual protected void CleanupTransactionOnCompletion(Transaction transaction) { } internal void DetachCurrentTransactionIfEnded() { - SysTx.Transaction enlistedTransaction = EnlistedTransaction; + Transaction enlistedTransaction = EnlistedTransaction; if (enlistedTransaction != null) { bool transactionIsDead; try { - transactionIsDead = (SysTx.TransactionStatus.Active != enlistedTransaction.TransactionInformation.Status); + transactionIsDead = (TransactionStatus.Active != enlistedTransaction.TransactionInformation.Status); } - catch (SysTx.TransactionException) + catch (TransactionException) { // If the transaction is being processed (i.e. is part way through a rollback\commit\etc then TransactionInformation.Status will throw an exception) transactionIsDead = true; @@ -892,7 +892,7 @@ internal void DetachCurrentTransactionIfEnded() } // Detach transaction from connection. - internal void DetachTransaction(SysTx.Transaction transaction, bool isExplicitlyReleasing) + internal void DetachTransaction(Transaction transaction, bool isExplicitlyReleasing) { SqlClientEventSource.Log.TryPoolerTraceEvent(" {0}, Transaction Completed. (pooledCount={1})", ObjectID, _pooledCount); @@ -906,7 +906,7 @@ internal void DetachTransaction(SysTx.Transaction transaction, bool isExplicitly DbConnection owner = Owner; if (isExplicitlyReleasing || UnbindOnTransactionCompletion || owner is null) { - SysTx.Transaction currentEnlistedTransaction = _enlistedTransaction; + Transaction currentEnlistedTransaction = _enlistedTransaction; if (currentEnlistedTransaction != null && transaction.Equals(currentEnlistedTransaction)) { // We need to remove the transaction completed event handler to cease listening for the transaction to end. @@ -924,7 +924,7 @@ internal void DetachTransaction(SysTx.Transaction transaction, bool isExplicitly } // Handle transaction detach, pool cleanup and other post-transaction cleanup tasks associated with - internal void CleanupConnectionOnTransactionCompletion(SysTx.Transaction transaction) + internal void CleanupConnectionOnTransactionCompletion(Transaction transaction) { DetachTransaction(transaction, false); @@ -935,9 +935,9 @@ internal void CleanupConnectionOnTransactionCompletion(SysTx.Transaction transac } } - void TransactionCompletedEvent(object sender, SysTx.TransactionEventArgs e) + void TransactionCompletedEvent(object sender, TransactionEventArgs e) { - SysTx.Transaction transaction = e.Transaction; + Transaction transaction = e.Transaction; SqlClientEventSource.Log.TryPoolerTraceEvent(" {0}, Transaction Completed. (pooledCount = {1})", ObjectID, _pooledCount); CleanupTransactionOnCompletion(transaction); @@ -947,9 +947,9 @@ void TransactionCompletedEvent(object sender, SysTx.TransactionEventArgs e) // TODO: Review whether we need the unmanaged code permission when we have the new object model available. [SecurityPermission(SecurityAction.Assert, Flags = SecurityPermissionFlag.UnmanagedCode)] - private void TransactionOutcomeEnlist(SysTx.Transaction transaction) + private void TransactionOutcomeEnlist(Transaction transaction) { - _transactionCompletedEventHandler ??= new SysTx.TransactionCompletedEventHandler(TransactionCompletedEvent); + _transactionCompletedEventHandler ??= new TransactionCompletedEventHandler(TransactionCompletedEvent); transaction.TransactionCompleted += _transactionCompletedEventHandler; } diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/ProviderBase/DbConnectionPool.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/ProviderBase/DbConnectionPool.cs index f39be43eee..62fb98df2a 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/ProviderBase/DbConnectionPool.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/ProviderBase/DbConnectionPool.cs @@ -19,8 +19,7 @@ namespace Microsoft.Data.ProviderBase using System.Threading.Tasks; using Microsoft.Data.Common; using Microsoft.Data.SqlClient; - - using SysTx = System.Transactions; + using System.Transactions; sealed internal class DbConnectionPool { @@ -36,8 +35,8 @@ private enum State // copy as part of the value. sealed private class TransactedConnectionList : List { - private SysTx.Transaction _transaction; - internal TransactedConnectionList(int initialAllocation, SysTx.Transaction tx) : base(initialAllocation) + private Transaction _transaction; + internal TransactedConnectionList(int initialAllocation, Transaction tx) : base(initialAllocation) { _transaction = tx; } @@ -69,7 +68,7 @@ public PendingGetConnection(long dueTime, DbConnection owner, TaskCompletionSour sealed private class TransactedConnectionPool { - Dictionary _transactedCxns; + Dictionary _transactedCxns; DbConnectionPool _pool; @@ -80,7 +79,7 @@ internal TransactedConnectionPool(DbConnectionPool pool) { Debug.Assert(null != pool, "null pool?"); _pool = pool; - _transactedCxns = new Dictionary(); + _transactedCxns = new Dictionary(); SqlClientEventSource.Log.TryPoolerTraceEvent(" {0}, Constructed for connection pool {1}", ObjectID, _pool.ObjectID); } @@ -100,7 +99,7 @@ internal DbConnectionPool Pool } } - internal DbConnectionInternal GetTransactedObject(SysTx.Transaction transaction) + internal DbConnectionInternal GetTransactedObject(Transaction transaction) { Debug.Assert(null != transaction, "null transaction?"); @@ -145,7 +144,7 @@ internal DbConnectionInternal GetTransactedObject(SysTx.Transaction transaction) return transactedObject; } - internal void PutTransactedObject(SysTx.Transaction transaction, DbConnectionInternal transactedObject) + internal void PutTransactedObject(Transaction transaction, DbConnectionInternal transactedObject) { Debug.Assert(null != transaction, "null transaction?"); Debug.Assert(null != transactedObject, "null transactedObject?"); @@ -179,7 +178,7 @@ internal void PutTransactedObject(SysTx.Transaction transaction, DbConnectionInt { // create the transacted pool, making sure to clone the associated transaction // for use as a key in our internal dictionary of transactions and connections - SysTx.Transaction transactionClone = null; + Transaction transactionClone = null; TransactedConnectionList newConnections = null; try @@ -243,7 +242,7 @@ internal void PutTransactedObject(SysTx.Transaction transaction, DbConnectionInt } - internal void TransactionEnded(SysTx.Transaction transaction, DbConnectionInternal transactedObject) + internal void TransactionEnded(Transaction transaction, DbConnectionInternal transactedObject) { SqlClientEventSource.Log.TryPoolerTraceEvent(" {0}, Transaction {1}, Connection {2}, Transaction Completed", ObjectID, transaction.GetHashCode(), transactedObject.ObjectID); TransactedConnectionList connections; @@ -1014,7 +1013,7 @@ private void DeactivateObject(DbConnectionInternal obj) // the transaction asynchronously completing on a second // thread. - SysTx.Transaction transaction = obj.EnlistedTransaction; + Transaction transaction = obj.EnlistedTransaction; if (null != transaction) { // NOTE: we're not locking on _state, so it's possible that its @@ -1212,7 +1211,7 @@ void WaitForPendingOpen() bool allowCreate = true; bool onlyOneCheckConnection = false; - ADP.SetCurrentTransaction(next.Completion.Task.AsyncState as System.Transactions.Transaction); + ADP.SetCurrentTransaction(next.Completion.Task.AsyncState as Transaction); timeout = !TryGetConnection(next.Owner, delay, allowCreate, onlyOneCheckConnection, next.UserOptions, out connection); } #if DEBUG @@ -1336,7 +1335,7 @@ internal bool TryGetConnection(DbConnection owningObject, TaskCompletionSource {0}, Getting connection.", ObjectID); @@ -1554,7 +1553,7 @@ private bool TryGetConnection(DbConnection owningObject, uint waitForMultipleObj return true; } - private void PrepareConnection(DbConnection owningObject, DbConnectionInternal obj, SysTx.Transaction transaction) + private void PrepareConnection(DbConnection owningObject, DbConnectionInternal obj, Transaction transaction) { lock (obj) { // Protect against Clear and ReclaimEmancipatedObjects, which call IsEmancipated, which is affected by PrePush and PostPop @@ -1631,7 +1630,7 @@ private DbConnectionInternal GetFromGeneralPool() return (obj); } - private DbConnectionInternal GetFromTransactedPool(out SysTx.Transaction transaction) + private DbConnectionInternal GetFromTransactedPool(out Transaction transaction) { transaction = ADP.GetCurrentTransaction(); DbConnectionInternal obj = null; @@ -1973,7 +1972,7 @@ internal void Shutdown() // that is implemented inside DbConnectionPool. This method's counterpart (PutTransactedObject) should // only be called from DbConnectionPool.DeactivateObject and thus the plumbing to provide access to // other objects is unnecessary (hence the asymmetry of Ended but no Begin) - internal void TransactionEnded(SysTx.Transaction transaction, DbConnectionInternal transactedObject) + internal void TransactionEnded(Transaction transaction, DbConnectionInternal transactedObject) { Debug.Assert(null != transaction, "null transaction?"); Debug.Assert(null != transactedObject, "null transactedObject?"); diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlCommand.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlCommand.cs index 94cd927c1d..30338925cc 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlCommand.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlCommand.cs @@ -22,7 +22,7 @@ using Microsoft.Data.Common; using Microsoft.Data.Sql; using Microsoft.Data.SqlClient.Server; -using SysTx = System.Transactions; +using System.Transactions; using System.Collections.Concurrent; // NOTE: The current Microsoft.VSDesigner editor attributes are implemented for System.Data.SqlClient, and are not publicly available. @@ -4046,7 +4046,7 @@ private void RunExecuteNonQuerySmi(bool sendToPipe) try { long transactionId; - SysTx.Transaction transaction; + Transaction transaction; innerConnection.GetCurrentTransactionPair(out transactionId, out transaction); SqlClientEventSource.Log.TryAdvancedTraceEvent(" {0}, innerConnection={1}, transactionId=0x{2}, cmdBehavior={3}.", ObjectID, innerConnection.ObjectID, transactionId, (int)CommandBehavior.Default); @@ -5696,7 +5696,7 @@ private SqlDataReader RunExecuteReaderSmi(CommandBehavior cmdBehavior, RunBehavi requestExecutor = SetUpSmiRequest(innerConnection); long transactionId; - SysTx.Transaction transaction; + Transaction transaction; innerConnection.GetCurrentTransactionPair(out transactionId, out transaction); SqlClientEventSource.Log.TryAdvancedTraceEvent(" {0}, innerConnection={1}, transactionId=0x{2}, commandBehavior={(int)cmdBehavior}.", ObjectID, innerConnection.ObjectID, transactionId); diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnectionHelper.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnectionHelper.cs index 07d44f020c..dcbd0738cb 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnectionHelper.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnectionHelper.cs @@ -12,8 +12,7 @@ namespace Microsoft.Data.SqlClient using System.Threading; using Microsoft.Data.Common; using Microsoft.Data.ProviderBase; - - using SysTx = System.Transactions; + using System.Transactions; public sealed partial class SqlConnection : DbConnection { @@ -242,11 +241,11 @@ private void EnlistDistributedTransactionHelper(System.EnterpriseServices.ITrans permissionSet.Demand(); SqlClientEventSource.Log.TryTraceEvent(" {0}, Connection enlisting in a transaction.", ObjectID); - SysTx.Transaction indigoTransaction = null; + Transaction indigoTransaction = null; if (null != transaction) { - indigoTransaction = SysTx.TransactionInterop.GetTransactionFromDtcTransaction((SysTx.IDtcTransaction)transaction); + indigoTransaction = TransactionInterop.GetTransactionFromDtcTransaction((IDtcTransaction)transaction); } RepairInnerConnection(); @@ -263,7 +262,7 @@ private void EnlistDistributedTransactionHelper(System.EnterpriseServices.ITrans } /// - override public void EnlistTransaction(SysTx.Transaction transaction) + override public void EnlistTransaction(Transaction transaction) { SqlConnection.ExecutePermission.Demand(); SqlClientEventSource.Log.TryTraceEvent(" {0}, Connection enlisting in a transaction.", ObjectID); @@ -277,7 +276,7 @@ override public void EnlistTransaction(SysTx.Transaction transaction) // NOTE: since transaction enlistment involves round trips to the // server, we don't want to lock here, we'll handle the race conditions // elsewhere. - SysTx.Transaction enlistedTransaction = innerConnection.EnlistedTransaction; + Transaction enlistedTransaction = innerConnection.EnlistedTransaction; if (enlistedTransaction != null) { // Allow calling enlist if already enlisted (no-op) @@ -287,7 +286,7 @@ override public void EnlistTransaction(SysTx.Transaction transaction) } // Allow enlisting in a different transaction if the enlisted transaction has completed. - if (enlistedTransaction.TransactionInformation.Status == SysTx.TransactionStatus.Active) + if (enlistedTransaction.TransactionInformation.Status == TransactionStatus.Active) { throw ADP.TransactionPresent(); } diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.cs index e11ec36e79..ffe44e328c 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.cs @@ -8,13 +8,12 @@ using System.Runtime.CompilerServices; using System.Threading; using Microsoft.Data.Common; - -using SysTx = System.Transactions; +using System.Transactions; namespace Microsoft.Data.SqlClient { - sealed internal class SqlDelegatedTransaction : SysTx.IPromotableSinglePhaseNotification + sealed internal class SqlDelegatedTransaction : IPromotableSinglePhaseNotification { private static int _objectTypeCount; private readonly int _objectID = Interlocked.Increment(ref _objectTypeCount); @@ -34,19 +33,19 @@ internal int ObjectID // may be initiated here AFTER the connection lock is released, but should NOT fall under this class's locking strategy. private SqlInternalConnection _connection; // the internal connection that is the root of the transaction - private IsolationLevel _isolationLevel; // the IsolationLevel of the transaction we delegated to the server + private System.Data.IsolationLevel _isolationLevel; // the IsolationLevel of the transaction we delegated to the server private SqlInternalTransaction _internalTransaction; // the SQL Server transaction we're delegating to - private SysTx.Transaction _atomicTransaction; + private Transaction _atomicTransaction; private bool _active; // Is the transaction active? - internal SqlDelegatedTransaction(SqlInternalConnection connection, SysTx.Transaction tx) + internal SqlDelegatedTransaction(SqlInternalConnection connection, Transaction tx) { Debug.Assert(null != connection, "null connection?"); _connection = connection; _atomicTransaction = tx; _active = false; - SysTx.IsolationLevel systxIsolationLevel = tx.IsolationLevel; + System.Transactions.IsolationLevel systxIsolationLevel = tx.IsolationLevel; // We need to map the System.Transactions IsolationLevel to the one // that System.Data uses and communicates to SqlServer. We could @@ -57,27 +56,27 @@ internal SqlDelegatedTransaction(SqlInternalConnection connection, SysTx.Transac // place. switch (systxIsolationLevel) { - case SysTx.IsolationLevel.ReadCommitted: - _isolationLevel = IsolationLevel.ReadCommitted; + case System.Transactions.IsolationLevel.ReadCommitted: + _isolationLevel = System.Data.IsolationLevel.ReadCommitted; break; - case SysTx.IsolationLevel.ReadUncommitted: - _isolationLevel = IsolationLevel.ReadUncommitted; + case System.Transactions.IsolationLevel.ReadUncommitted: + _isolationLevel = System.Data.IsolationLevel.ReadUncommitted; break; - case SysTx.IsolationLevel.RepeatableRead: - _isolationLevel = IsolationLevel.RepeatableRead; + case System.Transactions.IsolationLevel.RepeatableRead: + _isolationLevel = System.Data.IsolationLevel.RepeatableRead; break; - case SysTx.IsolationLevel.Serializable: - _isolationLevel = IsolationLevel.Serializable; + case System.Transactions.IsolationLevel.Serializable: + _isolationLevel = System.Data.IsolationLevel.Serializable; break; - case SysTx.IsolationLevel.Snapshot: - _isolationLevel = IsolationLevel.Snapshot; + case System.Transactions.IsolationLevel.Snapshot: + _isolationLevel = System.Data.IsolationLevel.Snapshot; break; default: throw SQL.UnknownSysTxIsolationLevel(systxIsolationLevel); } } - internal SysTx.Transaction Transaction + internal Transaction Transaction { get { return _atomicTransaction; } } @@ -191,7 +190,7 @@ public Byte[] Promote() // Now that we've acquired the lock, make sure we still have valid state for this operation. ValidateActiveOnConnection(connection); - connection.ExecuteTransaction(SqlInternalConnection.TransactionRequest.Promote, null, IsolationLevel.Unspecified, _internalTransaction, true); + connection.ExecuteTransaction(SqlInternalConnection.TransactionRequest.Promote, null, System.Data.IsolationLevel.Unspecified, _internalTransaction, true); returnValue = connection.PromotedDTCToken; // For Global Transactions, we need to set the Transaction Id since we use a Non-MSDTC Promoter type. @@ -260,12 +259,12 @@ public Byte[] Promote() try { // Safely access Transction status - as it's possible Transaction is not in right state. - if(Transaction?.TransactionInformation?.Status == SysTx.TransactionStatus.Aborted) + if(Transaction?.TransactionInformation?.Status == System.Transactions.TransactionStatus.Aborted) { throw SQL.PromotionFailed(promoteException); } } - catch(SysTx.TransactionException te) + catch(TransactionException te) { SqlClientEventSource.Log.TryTraceEvent("SqlDelegatedTransaction.Promote | RES | CPOOL | Object Id {0}, Client Connection Id {1}, Transaction exception occurred: {2}.", ObjectID, usersConnection?.ClientConnectionId, te.Message); // Throw promote exception if transaction state is unknown. @@ -287,7 +286,7 @@ public Byte[] Promote() } // Called by transaction to initiate abort sequence - public void Rollback(SysTx.SinglePhaseEnlistment enlistment) + public void Rollback(SinglePhaseEnlistment enlistment) { Debug.Assert(null != enlistment, "null enlistment?"); SqlInternalConnection connection = GetValidConnection(); @@ -315,7 +314,7 @@ public void Rollback(SysTx.SinglePhaseEnlistment enlistment) // If we haven't already rolled back (or aborted) then tell the SQL Server to roll back if (!_internalTransaction.IsAborted) { - connection.ExecuteTransaction(SqlInternalConnection.TransactionRequest.Rollback, null, IsolationLevel.Unspecified, _internalTransaction, true); + connection.ExecuteTransaction(SqlInternalConnection.TransactionRequest.Rollback, null, System.Data.IsolationLevel.Unspecified, _internalTransaction, true); } } catch (SqlException e) @@ -382,7 +381,7 @@ public void Rollback(SysTx.SinglePhaseEnlistment enlistment) } // Called by the transaction to initiate commit sequence - public void SinglePhaseCommit(SysTx.SinglePhaseEnlistment enlistment) + public void SinglePhaseCommit(SinglePhaseEnlistment enlistment) { Debug.Assert(null != enlistment, "null enlistment?"); SqlInternalConnection connection = GetValidConnection(); @@ -428,7 +427,7 @@ public void SinglePhaseCommit(SysTx.SinglePhaseEnlistment enlistment) _active = false; // set to inactive first, doesn't matter how the rest completes, this transaction is done. _connection = null; // Set prior to ExecuteTransaction call in case this initiates a TransactionEnd event - connection.ExecuteTransaction(SqlInternalConnection.TransactionRequest.Commit, null, IsolationLevel.Unspecified, _internalTransaction, true); + connection.ExecuteTransaction(SqlInternalConnection.TransactionRequest.Commit, null, System.Data.IsolationLevel.Unspecified, _internalTransaction, true); commitException = null; } catch (SqlException e) @@ -461,7 +460,7 @@ public void SinglePhaseCommit(SysTx.SinglePhaseEnlistment enlistment) else if (_internalTransaction.IsAborted) { // The transaction was aborted, report that to - // SysTx. + // System.Transactions. enlistment.Aborted(commitException); } else @@ -520,7 +519,7 @@ public void SinglePhaseCommit(SysTx.SinglePhaseEnlistment enlistment) // ended event via the internal connection. If it occurs without a prior Rollback or SinglePhaseCommit call, // it indicates the transaction was ended externally (generally that one the the DTC participants aborted // the transaction). - internal void TransactionEnded(SysTx.Transaction transaction) + internal void TransactionEnded(Transaction transaction) { SqlInternalConnection connection = _connection; @@ -547,7 +546,7 @@ internal void TransactionEnded(SysTx.Transaction transaction) private SqlInternalConnection GetValidConnection() { SqlInternalConnection connection = _connection; - if (null == connection && _atomicTransaction.TransactionInformation.Status != SysTx.TransactionStatus.Aborted) + if (null == connection && _atomicTransaction.TransactionInformation.Status != TransactionStatus.Aborted) { throw ADP.ObjectDisposed(this); } diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionSmi.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionSmi.cs index aa1a766861..88b9aa2430 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionSmi.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionSmi.cs @@ -8,7 +8,7 @@ using System.Diagnostics; using Microsoft.Data.Common; using Microsoft.Data.SqlClient.Server; -using SysTx = System.Transactions; +using System.Transactions; namespace Microsoft.Data.SqlClient { @@ -222,20 +222,20 @@ protected override bool UnbindOnTransactionCompletion // Context transactions SHOULD be considered enlisted. // This works for now only because we can't unenlist from the context transaction // DON'T START USING THIS ANYWHERE EXCEPT IN InternalTransaction and in InternalConnectionSmi!!! - private SysTx.Transaction ContextTransaction + private Transaction ContextTransaction { get; set; } - private SysTx.Transaction InternalEnlistedTransaction + private Transaction InternalEnlistedTransaction { get { // Workaround to access context transaction without rewriting connection pool & internalconnections properly. // This SHOULD be a simple wrapper around EnlistedTransaction. // This works for now only because we can't unenlist from the context transaction - SysTx.Transaction tx = EnlistedTransaction; + Transaction tx = EnlistedTransaction; if (null == tx) { @@ -246,7 +246,7 @@ private SysTx.Transaction InternalEnlistedTransaction } } - override protected void Activate(SysTx.Transaction transaction) + override protected void Activate(Transaction transaction) { Debug.Assert(false, "Activating an internal SMI connection?"); // we should never be activating, because that would indicate we're being pooled. } @@ -266,8 +266,8 @@ internal void Activate() internal void AutomaticEnlistment() { - SysTx.Transaction currentSystemTransaction = ADP.GetCurrentTransaction(); // NOTE: Must be first to ensure _smiContext.ContextTransaction is set! - SysTx.Transaction contextTransaction = _smiContext.ContextTransaction; // returns the transaction that was handed to SysTx that wraps the ContextTransactionId. + Transaction currentSystemTransaction = ADP.GetCurrentTransaction(); // NOTE: Must be first to ensure _smiContext.ContextTransaction is set! + Transaction contextTransaction = _smiContext.ContextTransaction; // returns the transaction that was handed to SysTx that wraps the ContextTransactionId. long contextTransactionId = _smiContext.ContextTransactionId; SqlClientEventSource.Log.TryAdvancedTraceEvent(" {0}, contextTransactionId=0x{1}, contextTransaction={2}, currentSystemTransaction={3}.", ObjectID, contextTransactionId, (null != contextTransaction) ? contextTransaction.GetHashCode() : 0, (null != currentSystemTransaction) ? currentSystemTransaction.GetHashCode() : 0); @@ -357,7 +357,7 @@ override public void Dispose() override internal void ExecuteTransaction( TransactionRequest transactionRequest, string transactionName, - IsolationLevel iso, + System.Data.IsolationLevel iso, SqlInternalTransaction internalTransaction, bool isDelegateControlRequest) { @@ -429,7 +429,7 @@ override protected byte[] GetDTCAddress() return whereAbouts; } - internal void GetCurrentTransactionPair(out long transactionId, out SysTx.Transaction transaction) + internal void GetCurrentTransactionPair(out long transactionId, out Transaction transaction) { // SQLBU 214740: Transaction state could change between obtaining tranid and transaction // due to background SqlDelegatedTransaction processing. Lock the connection to prevent that. diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs index 612aab532e..cc80af6767 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs @@ -18,7 +18,7 @@ using Microsoft.Data.Common; using Microsoft.Data.ProviderBase; using Microsoft.Identity.Client; -using SysTx = System.Transactions; +using System.Transactions; namespace Microsoft.Data.SqlClient @@ -952,7 +952,7 @@ internal void CheckEnlistedTransactionBinding() { // If we are enlisted in a transaction, check that transaction is active. // When using explicit transaction unbinding, also verify that the enlisted transaction is the current transaction. - SysTx.Transaction enlistedTransaction = EnlistedTransaction; + Transaction enlistedTransaction = EnlistedTransaction; if (enlistedTransaction != null) { @@ -960,16 +960,16 @@ internal void CheckEnlistedTransactionBinding() if (requireExplicitTransactionUnbind) { - SysTx.Transaction currentTransaction = SysTx.Transaction.Current; + Transaction currentTransaction = Transaction.Current; - if (SysTx.TransactionStatus.Active != enlistedTransaction.TransactionInformation.Status || !enlistedTransaction.Equals(currentTransaction)) + if (TransactionStatus.Active != enlistedTransaction.TransactionInformation.Status || !enlistedTransaction.Equals(currentTransaction)) { throw ADP.TransactionConnectionMismatch(); } } else // implicit transaction unbind { - if (SysTx.TransactionStatus.Active != enlistedTransaction.TransactionInformation.Status) + if (TransactionStatus.Active != enlistedTransaction.TransactionInformation.Status) { if (EnlistedTransactionDisposed) { @@ -1012,7 +1012,7 @@ internal override bool IsConnectionAlive(bool throwOnException) // POOLING METHODS //////////////////////////////////////////////////////////////////////////////////////// - override protected void Activate(SysTx.Transaction transaction) + override protected void Activate(Transaction transaction) { FailoverPermissionDemand(); // Demand for unspecified failover pooled connections @@ -1146,12 +1146,12 @@ override internal void DisconnectTransaction(SqlInternalTransaction internalTran } } - internal void ExecuteTransaction(TransactionRequest transactionRequest, string name, IsolationLevel iso) + internal void ExecuteTransaction(TransactionRequest transactionRequest, string name, System.Data.IsolationLevel iso) { ExecuteTransaction(transactionRequest, name, iso, null, false); } - override internal void ExecuteTransaction(TransactionRequest transactionRequest, string name, IsolationLevel iso, SqlInternalTransaction internalTransaction, bool isDelegateControlRequest) + override internal void ExecuteTransaction(TransactionRequest transactionRequest, string name, System.Data.IsolationLevel iso, SqlInternalTransaction internalTransaction, bool isDelegateControlRequest) { if (IsConnectionDoomed) { // doomed means we can't do anything else... @@ -1189,35 +1189,35 @@ override internal void ExecuteTransaction(TransactionRequest transactionRequest, internal void ExecuteTransactionPre2005( TransactionRequest transactionRequest, string transactionName, - IsolationLevel iso, + System.Data.IsolationLevel iso, SqlInternalTransaction internalTransaction) { StringBuilder sqlBatch = new StringBuilder(); switch (iso) { - case IsolationLevel.Unspecified: + case System.Data.IsolationLevel.Unspecified: break; - case IsolationLevel.ReadCommitted: + case System.Data.IsolationLevel.ReadCommitted: sqlBatch.Append(TdsEnums.TRANS_READ_COMMITTED); sqlBatch.Append(";"); break; - case IsolationLevel.ReadUncommitted: + case System.Data.IsolationLevel.ReadUncommitted: sqlBatch.Append(TdsEnums.TRANS_READ_UNCOMMITTED); sqlBatch.Append(";"); break; - case IsolationLevel.RepeatableRead: + case System.Data.IsolationLevel.RepeatableRead: sqlBatch.Append(TdsEnums.TRANS_REPEATABLE_READ); sqlBatch.Append(";"); break; - case IsolationLevel.Serializable: + case System.Data.IsolationLevel.Serializable: sqlBatch.Append(TdsEnums.TRANS_SERIALIZABLE); sqlBatch.Append(";"); break; - case IsolationLevel.Snapshot: - throw SQL.SnapshotNotSupported(IsolationLevel.Snapshot); + case System.Data.IsolationLevel.Snapshot: + throw SQL.SnapshotNotSupported(System.Data.IsolationLevel.Snapshot); - case IsolationLevel.Chaos: + case System.Data.IsolationLevel.Chaos: throw SQL.NotSupportedIsolationLevel(iso); default: @@ -1278,7 +1278,7 @@ internal void ExecuteTransactionPre2005( internal void ExecuteTransaction2005( TransactionRequest transactionRequest, string transactionName, - IsolationLevel iso, + System.Data.IsolationLevel iso, SqlInternalTransaction internalTransaction, bool isDelegateControlRequest) { @@ -1287,25 +1287,25 @@ internal void ExecuteTransaction2005( switch (iso) { - case IsolationLevel.Unspecified: + case System.Data.IsolationLevel.Unspecified: isoLevel = TdsEnums.TransactionManagerIsolationLevel.Unspecified; break; - case IsolationLevel.ReadCommitted: + case System.Data.IsolationLevel.ReadCommitted: isoLevel = TdsEnums.TransactionManagerIsolationLevel.ReadCommitted; break; - case IsolationLevel.ReadUncommitted: + case System.Data.IsolationLevel.ReadUncommitted: isoLevel = TdsEnums.TransactionManagerIsolationLevel.ReadUncommitted; break; - case IsolationLevel.RepeatableRead: + case System.Data.IsolationLevel.RepeatableRead: isoLevel = TdsEnums.TransactionManagerIsolationLevel.RepeatableRead; break; - case IsolationLevel.Serializable: + case System.Data.IsolationLevel.Serializable: isoLevel = TdsEnums.TransactionManagerIsolationLevel.Serializable; break; - case IsolationLevel.Snapshot: + case System.Data.IsolationLevel.Snapshot: isoLevel = TdsEnums.TransactionManagerIsolationLevel.Snapshot; break; - case IsolationLevel.Chaos: + case System.Data.IsolationLevel.Chaos: throw SQL.NotSupportedIsolationLevel(iso); default: throw ADP.InvalidIsolationLevel(iso); @@ -1508,7 +1508,7 @@ private void CompleteLogin(bool enlistOK) if (enlistOK && ConnectionOptions.Enlist && _routingInfo == null) { _parser._physicalStateObj.SniContext = SniContext.Snix_AutoEnlist; - SysTx.Transaction tx = ADP.GetCurrentTransaction(); + Transaction tx = ADP.GetCurrentTransaction(); Enlist(tx); } _parser._physicalStateObj.SniContext = SniContext.Snix_Login;