diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/ISniNativeMethods.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/ISniNativeMethods.cs index 7c4ee2486a..82f5226084 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/ISniNativeMethods.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/ISniNativeMethods.cs @@ -6,6 +6,7 @@ using System.Runtime.InteropServices; using System.Text; using Microsoft.Data.SqlClient; +using Microsoft.Data.SqlClient.NativeSni; namespace Interop.Windows.Sni { diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniNativeMethods.netcore.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniNativeMethods.netcore.cs index dc78405f41..0918cb2ba2 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniNativeMethods.netcore.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniNativeMethods.netcore.cs @@ -8,6 +8,7 @@ using System.Runtime.InteropServices; using System.Text; using Microsoft.Data.SqlClient; +using Microsoft.Data.SqlClient.NativeSni; namespace Interop.Windows.Sni { diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniNativeMethodsArm64.netfx.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniNativeMethodsArm64.netfx.cs index a450e706ad..a20039cbd9 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniNativeMethodsArm64.netfx.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniNativeMethodsArm64.netfx.cs @@ -8,6 +8,7 @@ using System.Runtime.InteropServices; using System.Text; using Microsoft.Data.SqlClient; +using Microsoft.Data.SqlClient.NativeSni; namespace Interop.Windows.Sni { diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniNativeMethodsNotSupported.netfx.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniNativeMethodsNotSupported.netfx.cs index 7139ee0b08..7e7a142098 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniNativeMethodsNotSupported.netfx.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniNativeMethodsNotSupported.netfx.cs @@ -9,18 +9,19 @@ using System.Text; using Microsoft.Data.Common; using Microsoft.Data.SqlClient; +using Microsoft.Data.SqlClient.NativeSni; namespace Interop.Windows.Sni { internal sealed class SniNativeMethodsNotSupported : ISniNativeMethods { private readonly string _architecture; - + public SniNativeMethodsNotSupported(Architecture architecture) { _architecture = architecture.ToString(); } - + public uint SniAddProvider(SNIHandle pConn, Provider provider, ref AuthProviderInfo pInfo) => throw ADP.SNIPlatformNotSupported(_architecture); diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniNativeMethodsX64.netfx.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniNativeMethodsX64.netfx.cs index 293e0432c5..f95bb06032 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniNativeMethodsX64.netfx.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniNativeMethodsX64.netfx.cs @@ -8,6 +8,7 @@ using System.Runtime.InteropServices; using System.Text; using Microsoft.Data.SqlClient; +using Microsoft.Data.SqlClient.NativeSni; namespace Interop.Windows.Sni { diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniNativeMethodsX86.netfx.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniNativeMethodsX86.netfx.cs index 187acb3fe7..a2f1842b9c 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniNativeMethodsX86.netfx.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniNativeMethodsX86.netfx.cs @@ -8,6 +8,7 @@ using System.Runtime.InteropServices; using System.Text; using Microsoft.Data.SqlClient; +using Microsoft.Data.SqlClient.NativeSni; namespace Interop.Windows.Sni { diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniNativeWrapper.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniNativeWrapper.cs index 5d4ba1e83a..9a9e430cbd 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniNativeWrapper.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniNativeWrapper.cs @@ -9,6 +9,7 @@ using System.Text; using Interop.Windows.Sni; using Microsoft.Data.Common; +using Microsoft.Data.SqlClient.NativeSni; using Microsoft.Data.SqlClient.Utilities; #if NETFRAMEWORK @@ -20,13 +21,13 @@ namespace Microsoft.Data.SqlClient internal static class SniNativeWrapper { #region Member Variables - + private const int SniIpv6AddrStringBufferLength = 48; - + #if NET private const int SniOpenTimeOut = -1; #endif - + #if NETFRAMEWORK private static readonly ISniNativeMethods s_nativeMethods = RuntimeInformation.ProcessArchitecture switch { @@ -38,11 +39,11 @@ internal static class SniNativeWrapper #else private static readonly SniNativeMethods s_nativeMethods = new SniNativeMethods(); #endif - + private static int s_sniMaxComposedSpnLength = -1; - + #endregion - + internal static int SniMaxComposedSpnLength { get @@ -56,10 +57,10 @@ internal static int SniMaxComposedSpnLength } #region Public Methods - + internal static uint SniAddProvider(SNIHandle pConn, Provider provNum, ref AuthProviderInfo pInfo) => s_nativeMethods.SniAddProvider(pConn, provNum, ref pInfo); - + #if NETFRAMEWORK internal static uint SniAddProvider(SNIHandle pConn, Provider providerEnum, @@ -78,19 +79,19 @@ internal static uint SniAddProvider(SNIHandle pConn, return ret; } #endif - + internal static uint SniAddProvider(SNIHandle pConn, Provider provNum, ref uint pInfo) => s_nativeMethods.SniAddProvider(pConn, provNum, ref pInfo); - + internal static uint SniCheckConnection(SNIHandle pConn) => s_nativeMethods.SniCheckConnection(pConn); - + internal static uint SniClose(IntPtr pConn) => s_nativeMethods.SniClose(pConn); - + internal static uint SniGetConnectionId(SNIHandle pConn, ref Guid connId) => s_nativeMethods.SniGetInfoWrapper(pConn, QueryType.SNI_QUERY_CONN_CONNID, out connId); - + internal static uint SniGetConnectionIpString(SNIHandle pConn, ref string connIpStr) { StringBuilder addrBuffer = new StringBuilder(SniIpv6AddrStringBufferLength); @@ -105,13 +106,13 @@ internal static uint SniGetConnectionIpString(SNIHandle pConn, ref string connIp return ret; } - + internal static uint SniGetConnectionPort(SNIHandle pConn, ref ushort portNum) => s_nativeMethods.SniGetInfoWrapper(pConn, QueryType.SNI_QUERY_CONN_PEERPORT, out portNum); - + internal static void SniGetLastError(out SniError pErrorStruct) => s_nativeMethods.SniGetLastError(out pErrorStruct); - + internal static uint SniGetProviderNumber(SNIHandle pConn, ref Provider provNum) => s_nativeMethods.SniGetInfoWrapper(pConn, QueryType.SNI_QUERY_CONN_PROVIDERNUM, out provNum); @@ -128,7 +129,7 @@ internal static uint SniIsTokenRestricted(IntPtr token, out bool isRestricted) return result; } - + internal static uint SniOpenMarsSession( ConsumerInfo consumerInfo, SNIHandle parent, @@ -169,12 +170,12 @@ internal static unsafe uint SniOpenSyncEx( bool fSync, int timeout, bool fParallel, - + #if NETFRAMEWORK int transparentNetworkResolutionStateNo, int totalTimeout, #endif - + SqlConnectionIPAddressPreference ipPreference, SQLDNSInfo cachedDnsInfo, string hostNameInCertificate) @@ -285,13 +286,13 @@ internal static unsafe uint SniOpenSyncEx( internal static void SniPacketAllocate(SafeHandle pConn, IoType ioType, ref IntPtr pPacket) => pPacket = s_nativeMethods.SniPacketAllocateWrapper(pConn, ioType); - + internal static uint SniPacketGetData(IntPtr packet, byte[] readBuffer, ref uint dataSize) => s_nativeMethods.SniPacketGetDataWrapper(packet, readBuffer, (uint)readBuffer.Length, out dataSize); - + internal static void SniPacketRelease(IntPtr pPacket) => s_nativeMethods.SniPacketRelease(pPacket); - + internal static unsafe void SniPacketSetData(SNIPacket packet, byte[] data, int length) { fixed (byte* pData = data) @@ -299,25 +300,25 @@ internal static unsafe void SniPacketSetData(SNIPacket packet, byte[] data, int s_nativeMethods.SniPacketSetData(packet, pData, (uint)length); } } - + internal static void SniPacketReset(SNIHandle pConn, IoType ioType, SNIPacket pPacket, ConsumerNumber consNum) => s_nativeMethods.SniPacketReset(pConn, ioType, pPacket, consNum); - + internal static uint SniQueryInfo(QueryType qType, ref uint pbQInfo) => s_nativeMethods.SniQueryInfo(qType, ref pbQInfo); - + internal static uint SniQueryInfo(QueryType qType, ref IntPtr pbQInfo) => s_nativeMethods.SniQueryInfo(qType, ref pbQInfo); - + internal static uint SniReadAsync(SNIHandle pConn, ref IntPtr ppNewPacket) => s_nativeMethods.SniReadAsync(pConn, ref ppNewPacket); - + internal static uint SniReadSyncOverAsync(SNIHandle pConn, ref IntPtr ppNewPacket, int timeout) => s_nativeMethods.SniReadSyncOverAsync(pConn, ref ppNewPacket, timeout); - + internal static uint SniRemoveProvider(SNIHandle pConn, Provider provNum) => s_nativeMethods.SniRemoveProvider(pConn, provNum); - + internal static unsafe uint SniSecGenClientContext( SNIHandle pConnectionObject, ReadOnlySpan inBuff, @@ -353,22 +354,22 @@ internal static unsafe uint SniSecGenClientContext( ObjectPools.BufferWriter.Return(serverWriter); } } - + internal static uint SniSecInitPackage(ref uint pcbMaxToken) => s_nativeMethods.SniSecInitPackage(ref pcbMaxToken); - + internal static void SniServerEnumClose(IntPtr packet) => s_nativeMethods.SniServerEnumClose(packet); - + internal static IntPtr SniServerEnumOpen() => s_nativeMethods.SniServerEnumOpen(); - + internal static int SniServerEnumRead(IntPtr packet, char[] readBuffer, int bufferLength, out bool more) => s_nativeMethods.SniServerEnumRead(packet, readBuffer, bufferLength, out more); - + internal static uint SniSetInfo(SNIHandle pConn, QueryType qType, ref uint pbQInfo) => s_nativeMethods.SniSetInfo(pConn, qType, ref pbQInfo); - + internal static uint SniTerminate() => s_nativeMethods.SniTerminate(); @@ -430,7 +431,7 @@ internal static uint SniWritePacket(SNIHandle pConn, SNIPacket packet, bool sync sync ? s_nativeMethods.SniWriteSyncOverAsync(pConn, packet) : s_nativeMethods.SniWriteAsyncWrapper(pConn, packet); - + #endregion #region Private Methods @@ -446,7 +447,7 @@ private static void MarshalConsumerInfo(ConsumerInfo consumerInfo, ref SniConsum : IntPtr.Zero; nativeConsumerInfo.ConsumerKey = consumerInfo.key; } - + #endregion } } 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 8e4883465a..3cd9baf408 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs @@ -25,6 +25,7 @@ using Microsoft.Win32; using IsolationLevel = System.Data.IsolationLevel; using Microsoft.Data.SqlClient.Internal; +using Microsoft.Data.SqlClient.Parser; #if NETFRAMEWORK using System.Reflection; 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 4e2c710150..692ecd2a0b 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumeratorNativeHelper.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumeratorNativeHelper.cs @@ -13,6 +13,7 @@ using Microsoft.Data.SqlClient; using static Microsoft.Data.Sql.SqlDataSourceEnumeratorUtil; using Microsoft.Data.SqlClient.Internal; +using Microsoft.Data.SqlClient.Parser; namespace Microsoft.Data.Sql { @@ -109,7 +110,7 @@ internal static DataTable ParseServerEnumString(string serverInstances) SqlClientEventSource.Log.TryTraceEvent(" Number of received server instances are {2}", nameof(SqlDataSourceEnumeratorNativeHelper), nameof(ParseServerEnumString), serverinstanceslist.Length); - // Every row comes in the format "serverName\instanceName;Clustered:[Yes|No];Version:.." + // Every row comes in the format "serverName\instanceName;Clustered:[Yes|No];Version:.." // Every row is terminated by a null character. // Process one row at a time foreach (string instance in serverinstanceslist) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ActiveDirectoryAuthenticationTimeoutRetryHelper.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ActiveDirectoryAuthenticationTimeoutRetryHelper.cs index 2b05333c88..3f3bf5f5ac 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ActiveDirectoryAuthenticationTimeoutRetryHelper.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ActiveDirectoryAuthenticationTimeoutRetryHelper.cs @@ -6,6 +6,7 @@ using System.ComponentModel; using System.Security.Cryptography; using System.Text; +using Microsoft.Data.SqlClient.Parser.Login; namespace Microsoft.Data.SqlClient { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AlwaysEncryptedHelperClasses.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AlwaysEncryptedHelperClasses.cs index cb37486a42..2677eea220 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AlwaysEncryptedHelperClasses.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AlwaysEncryptedHelperClasses.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// 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. @@ -191,7 +191,7 @@ internal SqlTceCipherInfoEntry(int ordinal = 0) } } - /// + /// /// Represents a table with various CEKs used in a resultset. Each entry corresponds to one (unique) CEK. The CEK /// may have been encrypted using multiple master keys (giving us multiple CEK values). All these values form one single /// entry in this table. @@ -229,17 +229,6 @@ internal int Size } } - internal sealed partial class _SqlMetaDataSet - { - internal readonly SqlTceCipherInfoTable cekTable; // table of "column encryption keys" used for this metadataset - - internal _SqlMetaDataSet(int count, SqlTceCipherInfoTable cipherTable) - : this(count) - { - cekTable = cipherTable; - } - } - /// /// Represents Encryption related information of the cipher data. /// @@ -428,44 +417,6 @@ internal bool IsAlgorithmInitialized() } } - internal partial class SqlMetaDataPriv - { - internal bool isEncrypted; // TCE encrypted? - internal SqlMetaDataPriv baseTI; // for encrypted columns, represents the TYPE_INFO for plaintext value - internal SqlCipherMetadata cipherMD; // Cipher related metadata for encrypted columns. - - /// - /// Is the algorithm handle for the cipher encryption initialized ? - /// - /// - internal bool IsAlgorithmInitialized() - { - if (cipherMD != null) - { - return cipherMD.IsAlgorithmInitialized(); - } - - return false; - } - - /// - /// Returns the normalization rule version byte. - /// - /// - internal byte NormalizationRuleVersion - { - get - { - if (cipherMD != null) - { - return cipherMD.NormalizationRuleVersion; - } - - return 0x00; - } - } - } - /// /// Class encapsulating additional information when sending encrypted input parameters. /// diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Connection/ConnectionCapabilities.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Connection/ConnectionCapabilities.cs index ebc2ff6bbc..9d251e2cbd 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Connection/ConnectionCapabilities.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Connection/ConnectionCapabilities.cs @@ -5,6 +5,7 @@ using Microsoft.Data.SqlClient.Internal; using System; using System.Text; +using Microsoft.Data.SqlClient.Parser; #nullable enable diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Connection/ServerInfo.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Connection/ServerInfo.cs index 4999e47b1a..49e6167b49 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Connection/ServerInfo.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Connection/ServerInfo.cs @@ -4,6 +4,8 @@ using System.Diagnostics; using System.Globalization; +using Microsoft.Data.SqlClient.Parser; +using Microsoft.Data.SqlClient.Parser.Tokens; namespace Microsoft.Data.SqlClient.Connection { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Connection/SqlConnectionInternal.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Connection/SqlConnectionInternal.cs index e5d4a61a5f..c4dd11d07a 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Connection/SqlConnectionInternal.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Connection/SqlConnectionInternal.cs @@ -17,6 +17,9 @@ using Microsoft.Data.SqlClient.ConnectionPool; using Microsoft.Data.SqlClient.Diagnostics; using Microsoft.Data.SqlClient.Internal; +using Microsoft.Data.SqlClient.Parser; +using Microsoft.Data.SqlClient.Parser.Login; +using Microsoft.Data.SqlClient.Parser.Tokens; using Microsoft.Data.SqlClient.Utilities; using IsolationLevel = System.Data.IsolationLevel; @@ -2036,7 +2039,7 @@ internal void OnLoginAck() _currentSessionData._tdsVersion = Capabilities.TdsVersion; } } - + /// /// Selects the that governs the login phase based on /// . diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalDb/LocalDbApi.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalDb/LocalDbApi.cs index da1e613c44..e00c395493 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalDb/LocalDbApi.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalDb/LocalDbApi.cs @@ -11,6 +11,7 @@ using Interop.Windows.Kernel32; using Interop.Windows.Sni; using Microsoft.Data.SqlClient.Internal; +using Microsoft.Data.SqlClient.Parser; #if NETFRAMEWORK using System.Collections.Generic; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/LocalDB.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/LocalDB.netcore.cs index 8878faa232..4f11339084 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/LocalDB.netcore.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/LocalDB.netcore.cs @@ -12,6 +12,7 @@ using Microsoft.Win32; using Microsoft.Data.SqlClient.Internal; using Microsoft.Data.Common; +using Microsoft.Data.SqlClient.Parser; namespace Microsoft.Data.SqlClient.ManagedSni { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniCommon.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniCommon.netcore.cs index 5a5877ea94..e4daa34502 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniCommon.netcore.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniCommon.netcore.cs @@ -13,6 +13,7 @@ using Microsoft.Data.Common; using Microsoft.Data.ProviderBase; using Microsoft.Data.SqlClient.Internal; +using Microsoft.Data.SqlClient.Parser; namespace Microsoft.Data.SqlClient.ManagedSni { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniError.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniError.netcore.cs index 2c20eb4cbe..1c15d941ba 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniError.netcore.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniError.netcore.cs @@ -7,6 +7,7 @@ using System; using System.ComponentModel; using System.Net.Sockets; +using Microsoft.Data.SqlClient.Parser; namespace Microsoft.Data.SqlClient.ManagedSni { @@ -16,7 +17,7 @@ namespace Microsoft.Data.SqlClient.ManagedSni internal class SniError { // Error numbers from native SNI implementation - // This is signed int representation of the error code 0x80090325 + // This is signed int representation of the error code 0x80090325 internal const int CertificateValidationErrorCode = -2146893019; public readonly SniProviders provider; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniHandle.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniHandle.netcore.cs index bcd814270c..aedcfcb2c1 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniHandle.netcore.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniHandle.netcore.cs @@ -11,6 +11,7 @@ using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; +using Microsoft.Data.SqlClient.Parser; namespace Microsoft.Data.SqlClient.ManagedSni { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniLoadHandle.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniLoadHandle.netcore.cs index b4b963fc02..fd2fdf6d36 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniLoadHandle.netcore.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniLoadHandle.netcore.cs @@ -5,6 +5,8 @@ #if NET using System; +using Microsoft.Data.SqlClient.Parser; +using Microsoft.Data.SqlClient.Parser.Login; #nullable enable diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniMarsConnection.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniMarsConnection.netcore.cs index 240e62666e..44ee0678f1 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniMarsConnection.netcore.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniMarsConnection.netcore.cs @@ -10,6 +10,7 @@ using System.Security.Authentication; using System.Threading; using Microsoft.Data.SqlClient.Internal; +using Microsoft.Data.SqlClient.Parser; namespace Microsoft.Data.SqlClient.ManagedSni { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniMarsHandle.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniMarsHandle.netcore.cs index 46063f9484..e43bdff83a 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniMarsHandle.netcore.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniMarsHandle.netcore.cs @@ -10,6 +10,7 @@ using System.Security.Authentication; using System.Threading; using Microsoft.Data.SqlClient.Internal; +using Microsoft.Data.SqlClient.Parser; namespace Microsoft.Data.SqlClient.ManagedSni { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniNpHandle.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniNpHandle.netcore.cs index e7ef8ad890..701d428b25 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniNpHandle.netcore.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniNpHandle.netcore.cs @@ -14,6 +14,7 @@ using System.Threading; using Microsoft.Data.ProviderBase; using Microsoft.Data.SqlClient.Internal; +using Microsoft.Data.SqlClient.Parser; namespace Microsoft.Data.SqlClient.ManagedSni { @@ -383,7 +384,7 @@ public override void DisableSsl() private bool ValidateServerCertificate(object sender, X509Certificate serverCertificate, X509Chain chain, SslPolicyErrors policyErrors) { using (SqlClientSNIEventScope.Create(nameof(SniNpHandle))) - { + { if (!_validateCert) { SqlClientEventSource.Log.TrySNITraceEvent(nameof(SniNpHandle), EventType.INFO, "Connection Id {0}, Certificate validation not requested.", args0: ConnectionId); @@ -392,7 +393,7 @@ private bool ValidateServerCertificate(object sender, X509Certificate serverCert SqlClientEventSource.Log.TrySNITraceEvent(nameof(SniNpHandle), EventType.INFO, "Connection Id {0}, Proceeding to SSL certificate validation.", args0: ConnectionId); return SniCommon.ValidateSslServerCertificate(_connectionId, _targetServer, _hostNameInCertificate, serverCertificate, _serverCertificateFilename, policyErrors); - } + } } /// diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniPacket.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniPacket.netcore.cs index aaf72cd54f..675641d18c 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniPacket.netcore.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniPacket.netcore.cs @@ -12,6 +12,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.Data.SqlClient.Internal; +using Microsoft.Data.SqlClient.Parser; namespace Microsoft.Data.SqlClient.ManagedSni { @@ -52,7 +53,7 @@ public enum Direction public int RefCount; public string Stack; } - + internal List _history = null; #endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniProxy.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniProxy.netcore.cs index b5254cde75..1f77f86ff3 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniProxy.netcore.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniProxy.netcore.cs @@ -12,6 +12,7 @@ using System.Text; using Microsoft.Data.ProviderBase; using Microsoft.Data.SqlClient.Internal; +using Microsoft.Data.SqlClient.Parser; namespace Microsoft.Data.SqlClient.ManagedSni { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniTcpHandle.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniTcpHandle.netcore.cs index 176420db87..e69280e43b 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniTcpHandle.netcore.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniTcpHandle.netcore.cs @@ -17,6 +17,7 @@ using Microsoft.Data.Common; using Microsoft.Data.ProviderBase; using Microsoft.Data.SqlClient.Internal; +using Microsoft.Data.SqlClient.Parser; namespace Microsoft.Data.SqlClient.ManagedSni { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SslOverTdsStream.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SslOverTdsStream.netcore.cs index ea25c2b9af..9f4f46f0d6 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SslOverTdsStream.netcore.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SslOverTdsStream.netcore.cs @@ -11,6 +11,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.Data.SqlClient.Internal; +using Microsoft.Data.SqlClient.Parser; namespace Microsoft.Data.SqlClient.ManagedSni { @@ -58,7 +59,7 @@ public void FinishHandshake() } /// - /// Set stream length. + /// Set stream length. /// /// Length public override void SetLength(long value) => throw new NotSupportedException(); @@ -411,7 +412,7 @@ public override async ValueTask WriteAsync(ReadOnlyMemory buffer, Cancella private static void SetupPreLoginPacketHeader(byte[] buffer, int dataLength, int remainingLength) { - // We can only send 4088 bytes in one packet. Header[1] is set to 1 if this is a + // We can only send 4088 bytes in one packet. Header[1] is set to 1 if this is a // partial packet (whether or not count != 0). buffer[7] = 0; // touch this first for the jit bounds check buffer[0] = PRELOGIN_PACKET_TYPE; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/NativeSni/SNIHandle.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/NativeSni/SNIHandle.cs new file mode 100644 index 0000000000..c6b7bf0283 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/NativeSni/SNIHandle.cs @@ -0,0 +1,122 @@ +// 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.Runtime.InteropServices; +using Interop.Windows.Sni; +using Microsoft.Data.SqlClient.Parser; + +namespace Microsoft.Data.SqlClient.NativeSni; + +internal sealed class SNIHandle : SafeHandle + { + private readonly uint _status = TdsEnums.SNI_UNINITIALIZED; + private readonly bool _fSync = false; + + // creates a physical connection + internal SNIHandle( + ConsumerInfo myInfo, + string serverName, + ref string spn, + int timeout, + out byte[] instanceName, + bool flushCache, + bool fSync, + bool fParallel, +#if NETFRAMEWORK + TransparentNetworkResolutionState transparentNetworkResolutionState, + int totalTimeout, +#endif + SqlConnectionIPAddressPreference ipPreference, + SQLDNSInfo cachedDNSInfo, + string hostNameInCertificate) + : base(IntPtr.Zero, true) + { + _fSync = fSync; + instanceName = new byte[256]; // Size as specified by netlibs. + // Option ignoreSniOpenTimeout is no longer available + //if (ignoreSniOpenTimeout) + //{ + // // UNDONE: ITEM12001110 (DB Mirroring Reconnect) Old behavior of not truly honoring timeout presevered + // // for non-failover scenarios to avoid breaking changes as part of a QFE. Consider fixing timeout + // // handling in next full release and removing ignoreSniOpenTimeout parameter. + // timeout = Timeout.Infinite; // -1 == native SNIOPEN_TIMEOUT_VALUE / INFINITE + //} + + #if NETFRAMEWORK + int transparentNetworkResolutionStateNo = (int)transparentNetworkResolutionState; + _status = SniNativeWrapper.SniOpenSyncEx( + myInfo, + serverName, + ref base.handle, + ref spn, + instanceName, + flushCache, + fSync, + timeout, + fParallel, + transparentNetworkResolutionStateNo, + totalTimeout, + ipPreference, + cachedDNSInfo, + hostNameInCertificate); + #else + _status = SniNativeWrapper.SniOpenSyncEx( + myInfo, + serverName, + ref base.handle, + ref spn, + instanceName, + flushCache, + fSync, + timeout, + fParallel, + ipPreference, + cachedDNSInfo, + hostNameInCertificate); + #endif + } + + // constructs SNI Handle for MARS session + internal SNIHandle(ConsumerInfo myInfo, SNIHandle parent, SqlConnectionIPAddressPreference ipPreference, SQLDNSInfo cachedDNSInfo) : base(IntPtr.Zero, true) + { + try + { } + finally + { + _status = SniNativeWrapper.SniOpenMarsSession(myInfo, parent, ref base.handle, parent._fSync, ipPreference, cachedDNSInfo); + } + } + + public override bool IsInvalid + { + get + { + return (IntPtr.Zero == base.handle); + } + } + + protected override bool ReleaseHandle() + { + // NOTE: The SafeHandle class guarantees this will be called exactly once. + IntPtr ptr = base.handle; + base.handle = IntPtr.Zero; + if (IntPtr.Zero != ptr) + { + if (0 != SniNativeWrapper.SniClose(ptr)) + { + return false; // SNIClose should never fail. + } + } + return true; + } + + internal uint Status + { + get + { + return _status; + } + } + } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserSafeHandles.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/NativeSni/SNILoadHandle.cs similarity index 53% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserSafeHandles.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/NativeSni/SNILoadHandle.cs index 63e392ac2b..066e429dc6 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserSafeHandles.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/NativeSni/SNILoadHandle.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// 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. @@ -8,15 +8,12 @@ using Interop.Windows.Sni; using Microsoft.Data.SqlClient.Internal; using Microsoft.Data.SqlClient.LocalDb; +using Microsoft.Data.SqlClient.Parser; +using Microsoft.Data.SqlClient.Parser.Login; -#if NETFRAMEWORK -using System.Runtime.CompilerServices; -using Microsoft.Data.Common; -#endif +namespace Microsoft.Data.SqlClient.NativeSni; -namespace Microsoft.Data.SqlClient -{ - internal sealed partial class SNILoadHandle : SafeHandle +internal sealed partial class SNILoadHandle : SafeHandle { // Explicit static ctor avoids 'beforefieldinit', which can otherwise let the runtime // eagerly run SingletonInstance's native initialization on non-Windows platforms. @@ -136,148 +133,3 @@ private static void WriteDispatcher(IntPtr key, IntPtr packet, uint error) } } } - - internal sealed class SNIHandle : SafeHandle - { - private readonly uint _status = TdsEnums.SNI_UNINITIALIZED; - private readonly bool _fSync = false; - - // creates a physical connection - internal SNIHandle( - ConsumerInfo myInfo, - string serverName, - ref string spn, - int timeout, - out byte[] instanceName, - bool flushCache, - bool fSync, - bool fParallel, -#if NETFRAMEWORK - TransparentNetworkResolutionState transparentNetworkResolutionState, - int totalTimeout, -#endif - SqlConnectionIPAddressPreference ipPreference, - SQLDNSInfo cachedDNSInfo, - string hostNameInCertificate) - : base(IntPtr.Zero, true) - { - _fSync = fSync; - instanceName = new byte[256]; // Size as specified by netlibs. - // Option ignoreSniOpenTimeout is no longer available - //if (ignoreSniOpenTimeout) - //{ - // // UNDONE: ITEM12001110 (DB Mirroring Reconnect) Old behavior of not truly honoring timeout presevered - // // for non-failover scenarios to avoid breaking changes as part of a QFE. Consider fixing timeout - // // handling in next full release and removing ignoreSniOpenTimeout parameter. - // timeout = Timeout.Infinite; // -1 == native SNIOPEN_TIMEOUT_VALUE / INFINITE - //} - - #if NETFRAMEWORK - int transparentNetworkResolutionStateNo = (int)transparentNetworkResolutionState; - _status = SniNativeWrapper.SniOpenSyncEx( - myInfo, - serverName, - ref base.handle, - ref spn, - instanceName, - flushCache, - fSync, - timeout, - fParallel, - transparentNetworkResolutionStateNo, - totalTimeout, - ipPreference, - cachedDNSInfo, - hostNameInCertificate); - #else - _status = SniNativeWrapper.SniOpenSyncEx( - myInfo, - serverName, - ref base.handle, - ref spn, - instanceName, - flushCache, - fSync, - timeout, - fParallel, - ipPreference, - cachedDNSInfo, - hostNameInCertificate); - #endif - } - - // constructs SNI Handle for MARS session - internal SNIHandle(ConsumerInfo myInfo, SNIHandle parent, SqlConnectionIPAddressPreference ipPreference, SQLDNSInfo cachedDNSInfo) : base(IntPtr.Zero, true) - { - try - { } - finally - { - _status = SniNativeWrapper.SniOpenMarsSession(myInfo, parent, ref base.handle, parent._fSync, ipPreference, cachedDNSInfo); - } - } - - public override bool IsInvalid - { - get - { - return (IntPtr.Zero == base.handle); - } - } - - protected override bool ReleaseHandle() - { - // NOTE: The SafeHandle class guarantees this will be called exactly once. - IntPtr ptr = base.handle; - base.handle = IntPtr.Zero; - if (IntPtr.Zero != ptr) - { - if (0 != SniNativeWrapper.SniClose(ptr)) - { - return false; // SNIClose should never fail. - } - } - return true; - } - - internal uint Status - { - get - { - return _status; - } - } - } - - internal sealed class SNIPacket : SafeHandle - { - internal SNIPacket(SafeHandle sniHandle) : base(IntPtr.Zero, true) - { - SniNativeWrapper.SniPacketAllocate(sniHandle, IoType.WRITE, ref base.handle); - if (IntPtr.Zero == base.handle) - { - throw SQL.SNIPacketAllocationFailure(); - } - } - - public override bool IsInvalid - { - get - { - return (IntPtr.Zero == base.handle); - } - } - - protected override bool ReleaseHandle() - { - // NOTE: The SafeHandle class guarantees this will be called exactly once. - IntPtr ptr = base.handle; - base.handle = IntPtr.Zero; - if (IntPtr.Zero != ptr) - { - SniNativeWrapper.SniPacketRelease(ptr); - } - return true; - } - } -} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/NativeSni/SNIPacket.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/NativeSni/SNIPacket.cs new file mode 100644 index 0000000000..e5ec578e90 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/NativeSni/SNIPacket.cs @@ -0,0 +1,42 @@ +// 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.Runtime.InteropServices; +using Interop.Windows.Sni; +using Microsoft.Data.SqlClient.Parser; + +namespace Microsoft.Data.SqlClient.NativeSni; + +internal sealed class SNIPacket : SafeHandle +{ + internal SNIPacket(SafeHandle sniHandle) : base(IntPtr.Zero, true) + { + SniNativeWrapper.SniPacketAllocate(sniHandle, IoType.WRITE, ref base.handle); + if (IntPtr.Zero == base.handle) + { + throw SQL.SNIPacketAllocationFailure(); + } + } + + public override bool IsInvalid + { + get + { + return (IntPtr.Zero == base.handle); + } + } + + protected override bool ReleaseHandle() + { + // NOTE: The SafeHandle class guarantees this will be called exactly once. + IntPtr ptr = base.handle; + base.handle = IntPtr.Zero; + if (IntPtr.Zero != ptr) + { + SniNativeWrapper.SniPacketRelease(ptr); + } + return true; + } +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/CallbackType.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/CallbackType.cs new file mode 100644 index 0000000000..2e7b6f2db2 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/CallbackType.cs @@ -0,0 +1,13 @@ +// 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. + +#nullable enable + +namespace Microsoft.Data.SqlClient.Parser; + +internal enum CallbackType +{ + Read = 0, + Write = 1 +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/DescribeParameterEncryptionResultSet1.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/DescribeParameterEncryptionResultSet1.cs new file mode 100644 index 0000000000..3b10974a03 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/DescribeParameterEncryptionResultSet1.cs @@ -0,0 +1,23 @@ +// 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.Parser; + +// Fields in the first resultset of "sp_describe_parameter_encryption". +// We expect the server to return the fields in the resultset in the same order as mentioned below. +// If the server changes the below order, then transparent parameter encryption will break. +internal enum DescribeParameterEncryptionResultSet1 +{ + KeyOrdinal = 0, + DbId, + KeyId, + KeyVersion, + KeyMdVersion, + EncryptedKey, + ProviderName, + KeyPath, + KeyEncryptionAlgorithm, + IsRequestedByEnclave, + KeySignature, +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/DescribeParameterEncryptionResultSet2.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/DescribeParameterEncryptionResultSet2.cs new file mode 100644 index 0000000000..85f2e6785e --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/DescribeParameterEncryptionResultSet2.cs @@ -0,0 +1,18 @@ +// 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.Parser; + +// Fields in the second resultset of "sp_describe_parameter_encryption" +// We expect the server to return the fields in the resultset in the same order as mentioned below. +// If the server changes the below order, then transparent parameter encryption will break. +internal enum DescribeParameterEncryptionResultSet2 +{ + ParameterOrdinal = 0, + ParameterName, + ColumnEncryptionAlgorithm, + ColumnEncryptionType, + ColumnEncryptionKeyOrdinal, + NormalizationRuleVersion, +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/DescribeParameterEncryptionResultSet3.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/DescribeParameterEncryptionResultSet3.cs new file mode 100644 index 0000000000..e18adb0ef6 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/DescribeParameterEncryptionResultSet3.cs @@ -0,0 +1,13 @@ +// 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.Parser; + +// Fields in the third resultset of "sp_describe_parameter_encryption". +// We expect the server to return the fields in the resultset in the same order as mentioned below. +// If the server changes the below order, then transparent parameter encryption will break. +internal enum DescribeParameterEncryptionResultSet3 +{ + AttestationInfo = 0, +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/LastIOTimer.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/LastIOTimer.cs new file mode 100644 index 0000000000..34ab9b42e5 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/LastIOTimer.cs @@ -0,0 +1,10 @@ +// 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.Parser; + +internal sealed class LastIOTimer +{ + internal long _value; +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Login/EncryptionOptions.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Login/EncryptionOptions.cs new file mode 100644 index 0000000000..cc6fc23686 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Login/EncryptionOptions.cs @@ -0,0 +1,22 @@ +// 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. + +#nullable enable + +namespace Microsoft.Data.SqlClient.Parser.Login; + +internal enum EncryptionOptions +{ + OFF, + ON, + NOT_SUP, + REQ, + LOGIN, + OPTIONS_MASK = 0x3f, + + #if NETFRAMEWORK + CTAIP = 0x40, + CLIENT_CERT = 0x80, + #endif +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Login/FederatedAuthenticationFeatureExtensionData.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Login/FederatedAuthenticationFeatureExtensionData.cs new file mode 100644 index 0000000000..60b2b8dacb --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Login/FederatedAuthenticationFeatureExtensionData.cs @@ -0,0 +1,17 @@ +// 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.Parser.Login; + +/// +/// Class encapsulating the data to be sent to the server as part of Federated Authentication +/// Feature Extension. +/// +internal class FederatedAuthenticationFeatureExtensionData +{ + internal TdsEnums.FedAuthLibrary libraryType; + internal bool fedAuthRequiredPreLoginResponse; + internal SqlAuthenticationMethod authentication; + internal byte[] accessToken; +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Login/PreLoginHandshakeStatus.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Login/PreLoginHandshakeStatus.cs new file mode 100644 index 0000000000..21a203140b --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Login/PreLoginHandshakeStatus.cs @@ -0,0 +1,13 @@ +// 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. + +#nullable enable + +namespace Microsoft.Data.SqlClient.Parser.Login; + +internal enum PreLoginHandshakeStatus +{ + Successful, + InstanceFailure +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Login/PreLoginOptions.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Login/PreLoginOptions.cs new file mode 100644 index 0000000000..1bf659d6a9 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Login/PreLoginOptions.cs @@ -0,0 +1,20 @@ +// 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. + +#nullable enable + +namespace Microsoft.Data.SqlClient.Parser.Login; + +internal enum PreLoginOptions +{ + VERSION, + ENCRYPT, + INSTANCE, + THREADID, + MARS, + TRACEID, + FEDAUTHREQUIRED, + NUMOPT, + LASTOPT = 255 +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Login/SqlFedAuthToken.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Login/SqlFedAuthToken.cs new file mode 100644 index 0000000000..b901009b78 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Login/SqlFedAuthToken.cs @@ -0,0 +1,35 @@ +// 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. + +#nullable enable + +using System.Text; + +namespace Microsoft.Data.SqlClient.Parser.Login; + +internal sealed class SqlFedAuthToken +{ + internal SqlFedAuthToken(byte[] accessToken, long expirationFileTime) + { + AccessToken = accessToken; + DataLen = (uint)AccessToken.Length; + ExpirationFileTime = expirationFileTime; + } + + /// + /// Convert from a SqlAuthenticationToken. + /// + internal SqlFedAuthToken(SqlAuthenticationToken token) + { + AccessToken = Encoding.Unicode.GetBytes(token.AccessToken); + DataLen = (uint)AccessToken.Length; + ExpirationFileTime = token.ExpiresOn.ToFileTime(); + } + + internal byte[] AccessToken { get; } + + internal uint DataLen { get; } + + internal long ExpirationFileTime { get; } +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Login/SqlLogin.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Login/SqlLogin.cs new file mode 100644 index 0000000000..cff173a441 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Login/SqlLogin.cs @@ -0,0 +1,31 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Security; +using Microsoft.Data.Common.ConnectionString; + +namespace Microsoft.Data.SqlClient.Parser.Login; + +internal sealed class SqlLogin +{ + internal SqlAuthenticationMethod authentication = SqlAuthenticationMethod.NotSpecified; // Authentication type + internal int timeout; // login timeout + internal bool userInstance = false; // user instance + internal string hostName = ""; // client machine name + internal string userName = ""; // user id + internal string password = ""; // password + internal string applicationName = ""; // application name + internal string serverName = ""; // server name + internal string language = ""; // initial language + internal string database = ""; // initial database + internal string attachDBFilename = ""; // DB filename to be attached + internal bool useReplication = false; // user login for replication + internal string newPassword = ""; // new password for reset password + internal bool useSSPI = false; // use integrated security + internal int packetSize = DbConnectionStringDefaults.PacketSize; // packet size + internal bool readOnlyIntent = false; // read-only intent + internal SqlCredential credential; // user id and password in SecureString + internal SecureString newSecurePassword; + internal RegisteredApplication appId = RegisteredApplication.Unknown; // middleware application identity +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Packet.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Packet.cs similarity index 96% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Packet.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Packet.cs index ac23f2c129..5bb274de00 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Packet.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Packet.cs @@ -4,13 +4,12 @@ using System; using System.Diagnostics; -using System.Runtime.CompilerServices; -namespace Microsoft.Data.SqlClient +namespace Microsoft.Data.SqlClient.Parser { /// /// Contains a buffer for a partial or full packet and methods to get information about the status of - /// the packet that the buffer represents.
+ /// the packet that the buffer represents.
/// This class is used to contain partial packet data and helps ensure that the packet data is completely /// received before a full packet is made available to the rest of the library ///
@@ -112,8 +111,8 @@ public int RequiredLength /// /// returns a boolean value indicating whether the contains enough - /// data for a valid tds header, has a set and that the - /// is greater than or equal to the + tds header length.
+ /// data for a valid tds header, has a set and that the + /// is greater than or equal to the + tds header length.
///
public bool ContainsCompletePacket => _dataLength != UnknownDataLength && (TdsEnums.HEADER_LEN + _dataLength) <= _totalLength; @@ -185,5 +184,5 @@ partial void CheckDisposedImpl() } } } -#endif +#endif } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/PacketHandle.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/PacketHandle.netcore.cs similarity index 97% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/PacketHandle.netcore.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/PacketHandle.netcore.cs index 4bce65d8f3..d42ea509b5 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/PacketHandle.netcore.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/PacketHandle.netcore.cs @@ -6,8 +6,9 @@ #if NET using System; +using Microsoft.Data.SqlClient.NativeSni; -namespace Microsoft.Data.SqlClient +namespace Microsoft.Data.SqlClient.Parser { /// /// This structure is used for transporting packet handle references between the diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/PacketHandle.netfx.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/PacketHandle.netfx.cs similarity index 96% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/PacketHandle.netfx.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/PacketHandle.netfx.cs index ac636f3b86..7ac8d04a9e 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/PacketHandle.netfx.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/PacketHandle.netfx.cs @@ -6,8 +6,9 @@ #if NETFRAMEWORK using System; +using Microsoft.Data.SqlClient.NativeSni; -namespace Microsoft.Data.SqlClient +namespace Microsoft.Data.SqlClient.Parser { /// /// This structure is used for transporting packet handle references between the diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/ParsingErrorState.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/ParsingErrorState.cs new file mode 100644 index 0000000000..221844327c --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/ParsingErrorState.cs @@ -0,0 +1,37 @@ +// 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.Parser; + +internal enum ParsingErrorState +{ + Undefined = 0, + FedAuthInfoLengthTooShortForCountOfInfoIds = 1, + FedAuthInfoLengthTooShortForData = 2, + FedAuthInfoFailedToReadCountOfInfoIds = 3, + FedAuthInfoFailedToReadTokenStream = 4, + FedAuthInfoInvalidOffset = 5, + FedAuthInfoFailedToReadData = 6, + FedAuthInfoDataNotUnicode = 7, + FedAuthInfoDoesNotContainStsurlAndSpn = 8, + FedAuthInfoNotReceived = 9, + FedAuthNotAcknowledged = 10, + FedAuthFeatureAckContainsExtraData = 11, + FedAuthFeatureAckUnknownLibraryType = 12, + UnrequestedFeatureAckReceived = 13, + UnknownFeatureAck = 14, + InvalidTdsTokenReceived = 15, + SessionStateLengthTooShort = 16, + SessionStateInvalidStatus = 17, + CorruptedTdsStream = 18, + ProcessSniPacketFailed = 19, + FedAuthRequiredPreLoginResponseInvalidValue = 20, + TceUnknownVersion = 21, + TceInvalidVersion = 22, + TceInvalidOrdinalIntoCipherInfoTable = 23, + DataClassificationInvalidVersion = 24, + DataClassificationNotExpected = 25, + DataClassificationInvalidLabelIndex = 26, + DataClassificationInvalidInformationTypeIndex = 27 +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/RunBehavior.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/RunBehavior.cs new file mode 100644 index 0000000000..3f782b86a3 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/RunBehavior.cs @@ -0,0 +1,15 @@ +// 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. + +#nullable enable + +namespace Microsoft.Data.SqlClient.Parser; + +internal enum RunBehavior +{ + UntilDone = 1, // 0001 binary + ReturnImmediately = 2, // 0010 binary + Clean = 5, // 0101 binary - Clean AND UntilDone + Attention = 13 // 1101 binary - Clean AND UntilDone AND Attention +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SessionHandle.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/SessionHandle.netcore.cs similarity index 95% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SessionHandle.netcore.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/SessionHandle.netcore.cs index 019bed388b..ce091f8de9 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SessionHandle.netcore.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/SessionHandle.netcore.cs @@ -5,7 +5,9 @@ // @TODO: Merge with other implementations (and/or introduce polymorphism to handle this indirection) #if NET -namespace Microsoft.Data.SqlClient +using Microsoft.Data.SqlClient.NativeSni; + +namespace Microsoft.Data.SqlClient.Parser { /// /// This structure is used for transporting packet handle references between the diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SessionHandle.netfx.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/SessionHandle.netfx.cs similarity index 94% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SessionHandle.netfx.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/SessionHandle.netfx.cs index 16d665aa9f..9175b01d60 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SessionHandle.netfx.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/SessionHandle.netfx.cs @@ -5,7 +5,9 @@ // @TODO: Merge with other implementations (and/or introduce polymorphism to handle this indirection) #if NETFRAMEWORK -namespace Microsoft.Data.SqlClient +using Microsoft.Data.SqlClient.NativeSni; + +namespace Microsoft.Data.SqlClient.Parser { /// /// This structure is used for transporting packet handle references between the diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/SniContext.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/SniContext.cs new file mode 100644 index 0000000000..c1ca675a62 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/SniContext.cs @@ -0,0 +1,23 @@ +// 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.Parser; + +internal enum SniContext +{ + Undefined = 0, + Snix_Connect, + Snix_PreLoginBeforeSuccessfulWrite, + Snix_PreLogin, + Snix_LoginSspi, + Snix_ProcessSspi, + Snix_Login, + Snix_EnableMars, + Snix_AutoEnlist, + Snix_GetMarsSession, + Snix_Execute, + Snix_Read, + Snix_Close, + Snix_SendRows, +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/SslProtocolHelpers.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/SslProtocolHelpers.cs new file mode 100644 index 0000000000..16abf8f085 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/SslProtocolHelpers.cs @@ -0,0 +1,98 @@ +// 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.Security.Authentication; + +namespace Microsoft.Data.SqlClient.Parser; + +internal static class SslProtocolsHelper +{ + private static string ToFriendlyName(this SslProtocols protocol) + { + string name; + + /* The SslProtocols.Tls13 is supported by netcoreapp3.1 and later + * This driver does not support this version yet! + if ((protocol & SslProtocols.Tls13) == SslProtocols.Tls13) + { + name = "TLS 1.3"; + }*/ + + #pragma warning disable CA5397 // Do not use deprecated SslProtocols values + #pragma warning disable CA5398 // Avoid hardcoded SslProtocols values + if ((protocol & SslProtocols.Tls12) != SslProtocols.None) + { + name = "TLS 1.2"; + } + #if NET8_0_OR_GREATER + #pragma warning disable SYSLIB0039 // Type or member is obsolete: TLS 1.0 & 1.1 are deprecated + #endif + else if ((protocol & SslProtocols.Tls11) != SslProtocols.None) + { + name = "TLS 1.1"; + } + else if ((protocol & SslProtocols.Tls) != SslProtocols.None) + { + name = "TLS 1.0"; + } + #if NET8_0_OR_GREATER + #pragma warning restore SYSLIB0039 // Type or member is obsolete: SSL and TLS 1.0 & 1.1 is deprecated + #endif + #pragma warning disable CS0618 // Type or member is obsolete: SSL is deprecated + else if ((protocol & SslProtocols.Ssl3) != SslProtocols.None) + { + name = "SSL 3.0"; + } + else if ((protocol & SslProtocols.Ssl2) != SslProtocols.None) + #pragma warning restore CS0618 // Type or member is obsolete: SSL and TLS 1.0 & 1.1 is deprecated + { + name = "SSL 2.0"; + } + #pragma warning restore CA5397 // Do not use deprecated SslProtocols values + #pragma warning restore CA5398 // Avoid hardcoded SslProtocols values + else + { + #if !NETFRAMEWORK + name = protocol.ToString(); + #else + throw new ArgumentException(StringsHelper.GetString(StringsHelper.net_invalid_enum, "NativeProtocols"), "NativeProtocols"); + #endif + } + + return name; + } + + /// + /// check the negotiated secure protocol if it's under TLS 1.2 + /// + /// + /// Localized warning message + public static string GetProtocolWarning(this SslProtocols protocol) + { + string message = string.Empty; + + #if NET8_0_OR_GREATER + #pragma warning disable SYSLIB0039 // Type or member is obsolete: TLS 1.0 & 1.1 are deprecated + #endif + #pragma warning disable CS0618 // Type or member is obsolete : SSL is deprecated + #pragma warning disable CA5397 // Do not use deprecated SslProtocols values + #pragma warning disable CA5398 // Avoid hardcoded SslProtocols values + if ((protocol & (SslProtocols.Ssl2 | SslProtocols.Ssl3 | SslProtocols.Tls | SslProtocols.Tls11)) != SslProtocols.None) + #pragma warning restore CA5398 // Avoid hardcoded SslProtocols values + #pragma warning restore CA5397 // Do not use deprecated SslProtocols values + #pragma warning restore CS0618 // Type or member is obsolete : SSL is deprecated + #if NET8_0_OR_GREATER + #pragma warning restore SYSLIB0039 // Type or member is obsolete: SSL and TLS 1.0 & 1.1 is deprecated + #endif + { + #if !NETFRAMEWORK + message = StringsHelper.Format(Strings.SEC_ProtocolWarning, protocol.ToFriendlyName()); + #else + message = StringsHelper.GetString(Strings.SEC_ProtocolWarning, protocol.ToFriendlyName()); + #endif + } + return message; + } +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsEnums.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsEnums.cs new file mode 100644 index 0000000000..84d530cb23 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsEnums.cs @@ -0,0 +1,692 @@ +// 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; + +namespace Microsoft.Data.SqlClient.Parser; + +/// +/// Class of variables for the Tds connection. +/// +internal static class TdsEnums +{ + // internal tdsparser constants + public static readonly decimal SQL_SMALL_MONEY_MIN = new(-214748.3648); + public static readonly decimal SQL_SMALL_MONEY_MAX = new(214748.3647); + +#if NETFRAMEWORK + // sql debugging constants, sdci is the structure passed in + public const string SDCI_MAPFILENAME = "SqlClientSSDebug"; + public const byte SDCI_MAX_MACHINENAME = 32; + public const byte SDCI_MAX_DLLNAME = 16; + public const byte SDCI_MAX_DATA = 255; + public const int SQLDEBUG_OFF = 0; + public const int SQLDEBUG_ON = 1; + public const int SQLDEBUG_CONTEXT = 2; + public const string SP_SDIDEBUG = "sp_sdidebug"; + public static readonly string[] SQLDEBUG_MODE_NAMES = new string[3] { + "off", + "on", + "context" + }; +#endif + + // HACK!!! + // Constant for SqlDbType.SmallVarBinary... store internal variable here instead of on + // SqlDbType so that it is not surfaced to the user!!! Related to dtc and the fact that + // the TransactionManager TDS stream is the only token left that uses VarBinarys instead of + // BigVarBinarys. + public const SqlDbType SmallVarBinary = (SqlDbType)(SqlDbType.Variant) + 1; + + // network protocol string constants + public const string TCP = "tcp"; + public const string NP = "np"; + public const string RPC = "rpc"; + public const string BV = "bv"; + public const string ADSP = "adsp"; + public const string SPX = "spx"; + public const string VIA = "via"; + public const string LPC = "lpc"; + public const string ADMIN = "admin"; + + // network function string constants + public const string INIT_SSPI_PACKAGE = "InitSSPIPackage"; + public const string INIT_SESSION = "InitSession"; + public const string CONNECTION_GET_SVR_USER = "ConnectionGetSvrUser"; + public const string GEN_CLIENT_CONTEXT = "GenClientContext"; + + // tdsparser packet handling constants + public const byte SOFTFLUSH = 0; + public const byte HARDFLUSH = 1; + public const byte IGNORE = 2; + + // header constants + public const int HEADER_LEN = 8; + public const int HEADER_LEN_FIELD_OFFSET = 2; + public const int SPID_OFFSET = 4; + public const int SQL2005_HEADER_LEN = 12; //2005 headers also include a MARS session id + public const int MARS_ID_OFFSET = 8; + public const int HEADERTYPE_QNOTIFICATION = 1; + public const int HEADERTYPE_MARS = 2; + public const int HEADERTYPE_TRACE = 3; + + // other various constants + public const int SUCCEED = 1; + public const int FAIL = 0; + public const short TYPE_SIZE_LIMIT = 8000; + public const int MIN_PACKET_SIZE = 512; + // Login packet can be no greater than 4k until server sends us env-change + // increasing packet size. + public const int DEFAULT_LOGIN_PACKET_SIZE = 4096; + public const int MAX_PRELOGIN_PAYLOAD_LENGTH = 1024; + public const int MAX_PACKET_SIZE = 32768; + public const int MAX_SERVER_USER_NAME = 256; // obtained from luxor + + // Maximum allowed data length for token payloads (feature ext ack, + // session state, fedauth info). Prevents a malicious server from causing + // unbounded memory allocation via spoofed token length fields. + internal const int MaxTokenDataLength = 1 << 20; // 1 MB + + // Maximum allowed data length for a DTC promote transaction propagation token. + internal const int MaxPromoteTransactionLength = 1 << 16; // 64 KB + + // Maximum valid wire size for datetime types (DateTimeOffset = 5 time + 3 date + 2 offset). + internal const int MaxDateTimeLength = 10; + + // Severity 0 - 10 indicates informational (non-error) messages + // Severity 11 - 16 indicates errors that can be corrected by user (syntax errors, etc...) + // Severity 17 - 19 indicates failure due to insufficient resources in the server + // (max locks exceeded, not enough memory, other internal server limits reached, etc..) + // Severity 20 - 25 Severe problems with the server, connection terminated. + public const byte MIN_ERROR_CLASS = 11; // webdata 100667: This should actually be 11 + public const byte MAX_USER_CORRECTABLE_ERROR_CLASS = 16; + public const byte FATAL_ERROR_CLASS = 20; + + // Message types + public const byte MT_SQL = 1; // SQL command batch + public const byte MT_LOGIN = 2; // Login message for pre-7.0 + public const byte MT_RPC = 3; // Remote procedure call + public const byte MT_TOKENS = 4; // Table response data stream + public const byte MT_BINARY = 5; // Unformatted binary response data (UNUSED) + public const byte MT_ATTN = 6; // Attention (break) signal + public const byte MT_BULK = 7; // Bulk load data + public const byte MT_FEDAUTH = 8; // Authentication token for federated authentication + public const byte MT_CLOSE = 9; // Close subchannel (UNUSED) + public const byte MT_ERROR = 10; // Protocol error detected + public const byte MT_ACK = 11; // Protocol acknowledgement (UNUSED) + public const byte MT_ECHO = 12; // Echo data (UNUSED) + public const byte MT_LOGOUT = 13; // Logout message (UNUSED) + public const byte MT_TRANS = 14; // Transaction Manager Interface + public const byte MT_OLEDB = 15; // ? (UNUSED) + public const byte MT_LOGIN7 = 16; // Login message for 7.0 or later + public const byte MT_SSPI = 17; // SSPI message + public const byte MT_PRELOGIN = 18; // Pre-login handshake + + // Message status bits + public const byte ST_EOM = 0x1; // Packet is end-of-message + public const byte ST_AACK = 0x2; // Packet acknowledges attention (server to client) + public const byte ST_IGNORE = 0x2; // Ignore this event (client to server) + public const byte ST_BATCH = 0x4; // Message is part of a batch. + public const byte ST_RESET_CONNECTION = 0x8; // Exec sp_reset_connection prior to processing message + public const byte ST_RESET_CONNECTION_PRESERVE_TRANSACTION = 0x10; // reset prior to processing, with preserving local tx + + // TDS control tokens + public const byte SQLCOLFMT = 0xa1; + public const byte SQLPROCID = 0x7c; + public const byte SQLCOLNAME = 0xa0; + public const byte SQLTABNAME = 0xa4; + public const byte SQLCOLINFO = 0xa5; + public const byte SQLALTNAME = 0xa7; + public const byte SQLALTFMT = 0xa8; + public const byte SQLERROR = 0xaa; + public const byte SQLINFO = 0xab; + public const byte SQLRETURNVALUE = 0xac; + public const byte SQLRETURNSTATUS = 0x79; + public const byte SQLRETURNTOK = 0xdb; + public const byte SQLALTCONTROL = 0xaf; + public const byte SQLROW = 0xd1; + public const byte SQLNBCROW = 0xd2; // same as ROW with null-bit-compression support + /// + /// Deprecated in TDS7.4 (2010) + /// + public const byte SQLALTROW = 0xd3; + public const byte SQLDONE = 0xfd; + public const byte SQLDONEPROC = 0xfe; + public const byte SQLDONEINPROC = 0xff; + public const byte SQLOFFSET = 0x78; + public const byte SQLORDER = 0xa9; + public const byte SQLDEBUG_CMD = 0x60; + public const byte SQLLOGINACK = 0xad; + public const byte SQLFEATUREEXTACK = 0xae; // TDS 7.4 - feature ack + public const byte SQLSESSIONSTATE = 0xe4; // TDS 7.4 - connection resiliency session state + public const byte SQLENVCHANGE = 0xe3; // Environment change notification + public const byte SQLSECLEVEL = 0xed; // Security level token ??? + public const byte SQLROWCRC = 0x39; // ROWCRC datastream??? + public const byte SQLCOLMETADATA = 0x81; // Column metadata including name + /// + /// Deprecated in TDS7.4 (2010) + /// + public const byte SQLALTMETADATA = 0x88; // Alt column metadata including name + public const byte SQLSSPI = 0xed; // SSPI data + public const byte SQLFEDAUTHINFO = 0xee; // Info for client to generate fed auth token + public const byte SQLRESCOLSRCS = 0xa2; + public const byte SQLDATACLASSIFICATION = 0xa3; + + // Environment change notification streams + // TYPE on TDS ENVCHANGE token stream (from sql\ntdbms\include\odsapi.h) + // + public const byte ENV_DATABASE = 1; // Database changed + public const byte ENV_LANG = 2; // Language changed + public const byte ENV_CHARSET = 3; // Character set changed + public const byte ENV_PACKETSIZE = 4; // Packet size changed + public const byte ENV_LOCALEID = 5; // Unicode data sorting locale id + public const byte ENV_COMPFLAGS = 6; // Unicode data sorting comparison flags + public const byte ENV_COLLATION = 7; // SQL Collation + // The following are environment change tokens valid for 2005 or later. + public const byte ENV_BEGINTRAN = 8; // Transaction began + public const byte ENV_COMMITTRAN = 9; // Transaction committed + public const byte ENV_ROLLBACKTRAN = 10; // Transaction rolled back + public const byte ENV_ENLISTDTC = 11; // Enlisted in Distributed Transaction + public const byte ENV_DEFECTDTC = 12; // Defected from Distributed Transaction + public const byte ENV_LOGSHIPNODE = 13; // Realtime Log shipping primary node + public const byte ENV_PROMOTETRANSACTION = 15; // Promote Transaction + public const byte ENV_TRANSACTIONMANAGERADDRESS = 16; // Transaction Manager Address + public const byte ENV_TRANSACTIONENDED = 17; // Transaction Ended + public const byte ENV_SPRESETCONNECTIONACK = 18; // SP_Reset_Connection ack + public const byte ENV_USERINSTANCE = 19; // User Instance + public const byte ENV_ROUTING = 20; // Routing (ROR) information + public const byte ENV_ENHANCEDROUTING = 21; // Enhanced Routing (ROR) information + + // done status stream bit masks + public const int DONE_MORE = 0x0001; // more command results coming + public const int DONE_ERROR = 0x0002; // error in command batch + public const int DONE_INXACT = 0x0004; // transaction in progress + public const int DONE_PROC = 0x0008; // done from stored proc + public const int DONE_COUNT = 0x0010; // count in done info + public const int DONE_ATTN = 0x0020; // oob ack + public const int DONE_INPROC = 0x0040; // like DONE_PROC except proc had error + public const int DONE_RPCINBATCH = 0x0080; // Done from RPC in batch + public const int DONE_SRVERROR = 0x0100; // Severe error in which resultset should be discarded + public const int DONE_FMTSENT = 0x8000; // fmt message sent, done_inproc req'd + + // Feature Extension + public const byte FEATUREEXT_TERMINATOR = 0xFF; + public const byte FEATUREEXT_SRECOVERY = 0x01; + public const byte FEATUREEXT_FEDAUTH = 0x02; + // 0x03 is for x_eFeatureExtensionId_Rcs + public const byte FEATUREEXT_TCE = 0x04; + public const byte FEATUREEXT_GLOBALTRANSACTIONS = 0x05; + // 0x06 is for x_eFeatureExtensionId_LoginToken + // 0x07 is for x_eFeatureExtensionId_ClientSideTelemetry + public const byte FEATUREEXT_AZURESQLSUPPORT = 0x08; + public const byte FEATUREEXT_DATACLASSIFICATION = 0x09; + public const byte FEATUREEXT_UTF8SUPPORT = 0x0A; + public const byte FEATUREEXT_SQLDNSCACHING = 0x0B; + public const byte FEATUREEXT_JSONSUPPORT = 0x0D; + public const byte FEATUREEXT_VECTORSUPPORT = 0x0E; + public const byte FEATUREEXT_ENHANCEDROUTINGSUPPORT = 0x0F; + public const byte FEATUREEXT_USERAGENT = 0x10; + + [Flags] + public enum FeatureExtension : uint + { + None = 0, + SessionRecovery = 1 << (TdsEnums.FEATUREEXT_SRECOVERY - 1), + FedAuth = 1 << (TdsEnums.FEATUREEXT_FEDAUTH - 1), + Tce = 1 << (TdsEnums.FEATUREEXT_TCE - 1), + GlobalTransactions = 1 << (TdsEnums.FEATUREEXT_GLOBALTRANSACTIONS - 1), + AzureSQLSupport = 1 << (TdsEnums.FEATUREEXT_AZURESQLSUPPORT - 1), + DataClassification = 1 << (TdsEnums.FEATUREEXT_DATACLASSIFICATION - 1), + UTF8Support = 1 << (TdsEnums.FEATUREEXT_UTF8SUPPORT - 1), + SQLDNSCaching = 1 << (TdsEnums.FEATUREEXT_SQLDNSCACHING - 1), + JsonSupport = 1 << (TdsEnums.FEATUREEXT_JSONSUPPORT - 1), + VectorSupport = 1 << (TdsEnums.FEATUREEXT_VECTORSUPPORT - 1), + EnhancedRoutingSupport = 1 << (TdsEnums.FEATUREEXT_ENHANCEDROUTINGSUPPORT - 1), + UserAgent = 1 << (TdsEnums.FEATUREEXT_USERAGENT - 1) + } + + public const uint UTF8_IN_TDSCOLLATION = 0x4000000; + + public const byte FEDAUTHLIB_LIVEID = 0X00; + public const byte FEDAUTHLIB_SECURITYTOKEN = 0x01; + public const byte FEDAUTHLIB_MSAL = 0x02; + public const byte FEDAUTHLIB_RESERVED = 0X7F; + + public enum FedAuthLibrary : byte + { + LiveId = FEDAUTHLIB_LIVEID, + SecurityToken = FEDAUTHLIB_SECURITYTOKEN, + MSAL = FEDAUTHLIB_MSAL, + Default = FEDAUTHLIB_RESERVED + } + + public const byte MSALWORKFLOW_ACTIVEDIRECTORYPASSWORD = 0x01; + public const byte MSALWORKFLOW_ACTIVEDIRECTORYINTEGRATED = 0x02; + public const byte MSALWORKFLOW_ACTIVEDIRECTORYINTERACTIVE = 0x03; + public const byte MSALWORKFLOW_ACTIVEDIRECTORYSERVICEPRINCIPAL = 0x01; // Using the Password byte as that is the closest we have + public const byte MSALWORKFLOW_ACTIVEDIRECTORYDEVICECODEFLOW = 0x03; // Using the Interactive byte as that is the closest we have + public const byte MSALWORKFLOW_ACTIVEDIRECTORYMANAGEDIDENTITY = 0x03; // Using the Interactive byte as that's supported for Identity based authentication + public const byte MSALWORKFLOW_ACTIVEDIRECTORYDEFAULT = 0x03; // Using the Interactive byte as that is the closest we have to non-password based authentication modes + public const byte MSALWORKFLOW_ACTIVEDIRECTORYTOKENCREDENTIAL = 0x03; // Using the Interactive byte as that is the closest we have to non-password based authentication modes + public const byte MSALWORKFLOW_ACTIVEDIRECTORYWORKLOADIDENTITY = 0x03; // Using the Interactive byte as that's supported for Identity based authentication + + public enum ActiveDirectoryWorkflow : byte + { + Password = MSALWORKFLOW_ACTIVEDIRECTORYPASSWORD, + Integrated = MSALWORKFLOW_ACTIVEDIRECTORYINTEGRATED, + Interactive = MSALWORKFLOW_ACTIVEDIRECTORYINTERACTIVE, + ServicePrincipal = MSALWORKFLOW_ACTIVEDIRECTORYSERVICEPRINCIPAL, + DeviceCodeFlow = MSALWORKFLOW_ACTIVEDIRECTORYDEVICECODEFLOW, + ManagedIdentity = MSALWORKFLOW_ACTIVEDIRECTORYMANAGEDIDENTITY, + Default = MSALWORKFLOW_ACTIVEDIRECTORYDEFAULT, + WorkloadIdentity = MSALWORKFLOW_ACTIVEDIRECTORYWORKLOADIDENTITY, + } + + // The string used for username in the error message when Authentication = Active Directory Integrated with FedAuth is used, if authentication fails. + public const string NTAUTHORITYANONYMOUSLOGON = @"NT Authority\Anonymous Logon"; + + // Loginrec defines + public const byte MAX_LOG_NAME = 30; // TDS 4.2 login rec max name length + public const byte MAX_PROG_NAME = 10; // max length of loginrec program name + public const byte SEC_COMP_LEN = 8; // length of security compartments + public const byte MAX_PK_LEN = 6; // max length of TDS packet size + public const byte MAX_NIC_SIZE = 6; // The size of a MAC or client address + public const byte SQLVARIANT_SIZE = 2; // size of the fixed portion of a sql variant (type, cbPropBytes) + public const byte VERSION_SIZE = 4; // size of the tds version (4 unsigned bytes) + public const int CLIENT_PROG_VER = 0x06000000; // Client interface version + public const int SQL2005_LOG_REC_FIXED_LEN = 0x5e; + // misc + public const int TEXT_TIME_STAMP_LEN = 8; + public const int COLLATION_INFO_LEN = 4; + + // Versions to be used on login for SQL Server 2005, SQL Server 2008 R2, TDS 7.x and TDS 8.0 + public const uint SQL2005_VERSION = 0x72_09_0002; + public const uint SQL2008_VERSION = 0x73_0B_0003; + public const uint TDS7X_VERSION = 0x74_00_0004; + public const uint TDS80_VERSION = 0x08_00_0000; + public const string TDS8_Protocol = "tds/8.0"; //TDS8 + + public const int ORDER_68000 = 1; + public const int USE_DB_ON = 1; + public const int INIT_DB_FATAL = 1; + public const int SET_LANG_ON = 1; + public const int INIT_LANG_FATAL = 1; + public const int ODBC_ON = 1; + public const int SSPI_ON = 1; + public const int REPL_ON = 3; + + + // send the read-only intent to the server + public const int READONLY_INTENT_ON = 1; + + // Token masks + public const byte SQLLenMask = 0x30; // mask to check for length tokens + public const byte SQLFixedLen = 0x30; // Mask to check for fixed token + public const byte SQLVarLen = 0x20; // Value to check for variable length token + public const byte SQLZeroLen = 0x10; // Value to check for zero length token + public const byte SQLVarCnt = 0x00; // Value to check for variable count token + + // Token masks for COLINFO status + public const byte SQLDifferentName = 0x20; // column name different than select list name + public const byte SQLExpression = 0x4; // column was result of an expression + public const byte SQLKey = 0x8; // column is part of the key for the table + public const byte SQLHidden = 0x10; // column not part of select list but added because part of key + + // Token masks for COLMETADATA flags + // first byte + public const byte Nullable = 0x1; + public const byte Identity = 0x10; + public const byte Updatability = 0xb; // mask off bits 3 and 4 + // second byte + public const byte ClrFixedLen = 0x1; // Fixed length CLR type + public const byte IsColumnSet = 0x4; // Column is an XML representation of an aggregation of other columns + public const byte IsEncrypted = 0x8; // Column is encrypted using TCE + + // null values + public const uint VARLONGNULL = 0xffffffff; // null value for text and image types + public const int VARNULL = 0xffff; // null value for character and binary types + public const int MAXSIZE = 8000; // max size for any column + public const byte FIXEDNULL = 0; + public const ulong UDTNULL = 0xffffffffffffffff; + + // SQL Server Data Type Tokens. + public const int SQLVOID = 0x1f; + public const int SQLTEXT = 0x23; + public const int SQLVARBINARY = 0x25; + public const int SQLINTN = 0x26; + public const int SQLVARCHAR = 0x27; + public const int SQLBINARY = 0x2d; + public const int SQLIMAGE = 0x22; + public const int SQLCHAR = 0x2f; + public const int SQLINT1 = 0x30; + public const int SQLBIT = 0x32; + public const int SQLINT2 = 0x34; + public const int SQLINT4 = 0x38; + public const int SQLMONEY = 0x3c; + public const int SQLDATETIME = 0x3d; + public const int SQLFLT8 = 0x3e; + public const int SQLFLTN = 0x6d; + public const int SQLMONEYN = 0x6e; + public const int SQLDATETIMN = 0x6f; + public const int SQLFLT4 = 0x3b; + public const int SQLMONEY4 = 0x7a; + public const int SQLDATETIM4 = 0x3a; + public const int SQLDECIMALN = 0x6a; + public const int SQLNUMERICN = 0x6c; + public const int SQLUNIQUEID = 0x24; + public const int SQLBIGCHAR = 0xaf; + public const int SQLBIGVARCHAR = 0xa7; + public const int SQLBIGBINARY = 0xad; + public const int SQLBIGVARBINARY = 0xa5; + public const int SQLBITN = 0x68; + public const int SQLNCHAR = 0xef; + public const int SQLNVARCHAR = 0xe7; + public const int SQLNTEXT = 0x63; + public const int SQLUDT = 0xF0; + + // aggregate operator type TDS tokens, used by compute statements: + public const int AOPCNTB = 0x09; + public const int AOPSTDEV = 0x30; + public const int AOPSTDEVP = 0x31; + public const int AOPVAR = 0x32; + public const int AOPVARP = 0x33; + + public const int AOPCNT = 0x4b; + public const int AOPSUM = 0x4d; + public const int AOPAVG = 0x4f; + public const int AOPMIN = 0x51; + public const int AOPMAX = 0x52; + public const int AOPANY = 0x53; + public const int AOPNOOP = 0x56; + + // SQL Server user-defined type tokens we care about + public const int SQLTIMESTAMP = 0x50; + + public const int MAX_NUMERIC_LEN = 0x11; // 17 bytes of data for max numeric/decimal length + public const int DEFAULT_NUMERIC_PRECISION = 0x1D; // 29 is the default max numeric precision(Decimal.MaxValue) if not user set + public const int SQL70_DEFAULT_NUMERIC_PRECISION = 0x1C; // 28 is the default max numeric precision for 7.0 (Decimal.MaxValue doesn't work for 7.0) + public const int MAX_NUMERIC_PRECISION = 0x26; // 38 is max numeric precision; + public const byte UNKNOWN_PRECISION_SCALE = 0xff; // -1 is value for unknown precision or scale + + // The following datatypes are specific to 2005 (version 9) or later + public const int SQLINT8 = 0x7f; + public const int SQLVARIANT = 0x62; + public const int SQLXMLTYPE = 0xf1; + public const int XMLUNICODEBOM = 0xfeff; + public static readonly byte[] XMLUNICODEBOMBYTES = { 0xff, 0xfe }; + + // The following datatypes are specific to 2008 (version 10) or later + public const int SQLTABLE = 0xf3; + public const int SQLDATE = 0x28; + public const int SQLTIME = 0x29; + public const int SQLDATETIME2 = 0x2a; + public const int SQLDATETIMEOFFSET = 0x2b; + + public const int SQLJSON = 0xF4; + public const int SQLVECTOR = 0xF5; + + public const int DEFAULT_VARTIME_SCALE = 7; + + //Partially length prefixed datatypes constants. These apply to XMLTYPE, BIGVARCHRTYPE, + // NVARCHARTYPE, and BIGVARBINTYPE. Valid for 2005 or later + + public const ulong SQL_PLP_NULL = 0xffffffffffffffff; // Represents null value + public const ulong SQL_PLP_UNKNOWNLEN = 0xfffffffffffffffe; // Data coming in chunks, total length unknown + public const int SQL_PLP_CHUNK_TERMINATOR = 0x00000000; // Represents end of chunked data. + public const ushort SQL_USHORTVARMAXLEN = 0xffff; // Second ushort in TDS stream is this value if one of max types + + // TVPs require some new in-value control tokens: + public const byte TVP_ROWCOUNT_ESTIMATE = 0x12; + public const byte TVP_ROW_TOKEN = 0x01; + public const byte TVP_END_TOKEN = 0x00; + public const ushort TVP_NOMETADATA_TOKEN = 0xFFFF; + public const byte TVP_ORDER_UNIQUE_TOKEN = 0x10; + + // TvpColumnMetaData flags + public const int TVP_DEFAULT_COLUMN = 0x200; + + // TVP_ORDER_UNIQUE_TOKEN flags + public const byte TVP_ORDERASC_FLAG = 0x1; + public const byte TVP_ORDERDESC_FLAG = 0x2; + public const byte TVP_UNIQUE_FLAG = 0x4; + +#if NETFRAMEWORK + public const bool Is68K = false; + public const bool TraceTDS = false; +#endif + + // RPC function names + public const string SP_EXECUTESQL = "sp_executesql"; // used against 7.0 servers + public const string SP_PREPEXEC = "sp_prepexec"; // used against 7.5 servers + + public const string SP_PREPARE = "sp_prepare"; // used against 7.0 servers + public const string SP_EXECUTE = "sp_execute"; + public const string SP_UNPREPARE = "sp_unprepare"; + public const string SP_PARAMS = "sp_procedure_params_rowset"; + public const string SP_PARAMS_MANAGED = "sp_procedure_params_managed"; + public const string SP_PARAMS_MGD10 = "sp_procedure_params_100_managed"; + + // RPC ProcID's + // NOTE: It is more efficient to call these procs using ProcID's instead of names + public const ushort RPC_PROCID_CURSOR = 1; + public const ushort RPC_PROCID_CURSOROPEN = 2; + public const ushort RPC_PROCID_CURSORPREPARE = 3; + public const ushort RPC_PROCID_CURSOREXECUTE = 4; + public const ushort RPC_PROCID_CURSORPREPEXEC = 5; + public const ushort RPC_PROCID_CURSORUNPREPARE = 6; + public const ushort RPC_PROCID_CURSORFETCH = 7; + public const ushort RPC_PROCID_CURSOROPTION = 8; + public const ushort RPC_PROCID_CURSORCLOSE = 9; + public const ushort RPC_PROCID_EXECUTESQL = 10; + public const ushort RPC_PROCID_PREPARE = 11; + public const ushort RPC_PROCID_EXECUTE = 12; + public const ushort RPC_PROCID_PREPEXEC = 13; + public const ushort RPC_PROCID_PREPEXECRPC = 14; + public const ushort RPC_PROCID_UNPREPARE = 15; + + // Batch RPC flag + public const byte SQL2005_RPCBATCHFLAG = 0xFF; + + // RPC flags + public const byte RPC_RECOMPILE = 0x1; + public const byte RPC_NOMETADATA = 0x2; + + // RPC parameter class + public const byte RPC_PARAM_BYREF = 0x1; + public const byte RPC_PARAM_DEFAULT = 0x2; + public const byte RPC_PARAM_ENCRYPTED = 0x8; + + // SQL parameter list text + public const string PARAM_OUTPUT = "output"; + + // SQL Parameter constants + public const int MAX_PARAMETER_NAME_LENGTH = 128; + + // metadata options (added around an existing sql statement) + + // prefixes + public const string FMTONLY_ON = " SET FMTONLY ON;"; + public const string FMTONLY_OFF = " SET FMTONLY OFF;"; + // suffixes + public const string BROWSE_ON = " SET NO_BROWSETABLE ON;"; + public const string BROWSE_OFF = " SET NO_BROWSETABLE OFF;"; + + // generic table name + public const string TABLE = "Table"; + + public const int EXEC_THRESHOLD = 0x3; // if the number of commands we execute is > than this threshold, than do prep/exec/unprep instead + // of executesql. + + // dbnetlib error values + public const short TIMEOUT_EXPIRED = -2; + public const short ENCRYPTION_NOT_SUPPORTED = 20; + public const short CTAIP_NOT_SUPPORTED = 21; + + // CAUTION: These are not error codes returned by SNI. This is used for backward compatibility + // since netlib (now removed from sqlclient) returned these codes. + + // SQL error values (from sqlerrorcodes.h) + public const int LOGON_FAILED = 18456; + public const int PASSWORD_EXPIRED = 18488; + public const int IMPERSONATION_FAILED = 1346; + public const int P_TOKENTOOLONG = 103; + + // SQL error that indicates retry for Always Encrypted + public const int TCE_CONVERSION_ERROR_CLIENT_RETRY = 33514; + public const int TCE_ENCLAVE_INVALID_SESSION_HANDLE = 33195; + + // SNI\Win32 error values + // NOTE: these are simply windows system error codes, not SNI specific + public const uint SNI_UNINITIALIZED = unchecked((uint)-1); + public const uint SNI_SUCCESS = 0; // The operation completed successfully. + public const uint SNI_ERROR = 1; // Error + public const int SNI_WAIT_TIMEOUT = 258; // The wait operation timed out. + public const uint SNI_SUCCESS_IO_PENDING = 997; // Overlapped I/O operation is in progress. + + // Windows Sockets Error Codes + public const short SNI_WSAECONNRESET = 10054; // An existing connection was forcibly closed by the remote host. + + // SNI internal errors (shouldn't overlap with Win32 / socket errors) + public const uint SNI_QUEUE_FULL = 1048576; // Packet queue is full + + // SNI flags + public const uint SNI_SSL_VALIDATE_CERTIFICATE = 1; // This enables validation of server certificate + public const uint SNI_SSL_USE_SCHANNEL_CACHE = 2; // This enables schannel session cache + public const uint SNI_SSL_IGNORE_CHANNEL_BINDINGS = 0x10; // Used with SSL Provider, sent to SNIAddProvider in case of SQL Authentication & Encrypt. + public const uint SNI_SSL_SEND_ALPN_EXTENSION = 0x4000; // This flag instructs SSL provider to send the ALPN extension in the ClientHello message + + public const string DEFAULT_ENGLISH_CODE_PAGE_STRING = "iso_1"; + public const short DEFAULT_ENGLISH_CODE_PAGE_VALUE = 1252; + public const short CHARSET_CODE_PAGE_OFFSET = 2; + internal const int MAX_SERVERNAME = 255; + + // Sql Statement Tokens in the DONE packet + // (see ntdbms\ntinc\tokens.h) + // + internal const ushort SELECT = 0xc1; + internal const ushort INSERT = 0xc3; + internal const ushort DELETE = 0xc4; + internal const ushort UPDATE = 0xc5; + internal const ushort ABORT = 0xd2; + internal const ushort BEGINXACT = 0xd4; + internal const ushort ENDXACT = 0xd5; + internal const ushort BULKINSERT = 0xf0; + internal const ushort OPENCURSOR = 0x20; + internal const ushort MERGE = 0x117; + + + // Login data validation Rules + // + internal const ushort MAXLEN_HOSTNAME = 128; // the client machine name + internal const ushort MAXLEN_CLIENTID = 128; + internal const ushort MAXLEN_CLIENTSECRET = 128; + internal const ushort MAXLEN_APPNAME = 128; // the client application name + internal const ushort MAXLEN_SERVERNAME = 128; // the server name + internal const ushort MAXLEN_CLIENTINTERFACE = 128; // the interface library name + internal const ushort MAXLEN_LANGUAGE = 128; // the initial language + internal const ushort MAXLEN_DATABASE = 128; // the initial database + internal const ushort MAXLEN_ATTACHDBFILE = 260; // the filename for a database that is to be attached during the connection process + internal const ushort MAXLEN_NEWPASSWORD = 128; // new password for the specified login. + +#if NETFRAMEWORK + internal enum UDTFormatType + { + Native = 1, + UserDefined = 2 + } +#endif + + internal enum TransactionManagerRequestType + { + GetDTCAddress = 0, + Propagate = 1, + Begin = 5, + Promote = 6, + Commit = 7, + Rollback = 8, + Save = 9 + }; + + internal enum TransactionManagerIsolationLevel + { + Unspecified = 0x00, + ReadUncommitted = 0x01, + ReadCommitted = 0x02, + RepeatableRead = 0x03, + Serializable = 0x04, + Snapshot = 0x05 + } + + internal enum GenericType + { + MultiSet = 131, + }; + + // Date, Time, DateTime2, DateTimeOffset specific constants + internal static readonly long[] TICKS_FROM_SCALE = { + 10000000, + 1000000, + 100000, + 10000, + 1000, + 100, + 10, + 1, + }; + + internal const int MAX_TIME_SCALE = 7; // Maximum scale for time-related types + internal const int MAX_TIME_LENGTH = 5; // Maximum length for time + internal const int MAX_DATETIME2_LENGTH = 8; // Maximum length for datetime2 + internal const int WHIDBEY_DATE_LENGTH = 10; + internal static readonly int[] WHIDBEY_TIME_LENGTH = { 8, 10, 11, 12, 13, 14, 15, 16 }; + internal static readonly int[] WHIDBEY_DATETIME2_LENGTH = { 19, 21, 22, 23, 24, 25, 26, 27 }; + internal static readonly int[] WHIDBEY_DATETIMEOFFSET_LENGTH = { 26, 28, 29, 30, 31, 32, 33, 34 }; + + internal enum FedAuthInfoId : byte + { + Stsurl = 0x01, // FedAuthInfoData is token endpoint URL from which to acquire fed auth token + Spn = 0x02, // FedAuthInfoData is the SPN to use for acquiring fed auth token + } + + // Data Classification constants + internal const byte DATA_CLASSIFICATION_NOT_ENABLED = 0x00; + internal const byte DATA_CLASSIFICATION_VERSION_WITHOUT_RANK_SUPPORT = 0x01; + internal const byte DATA_CLASSIFICATION_VERSION_MAX_SUPPORTED = 0x02; + + // JSON Support constants + internal const byte MAX_SUPPORTED_JSON_VERSION = 0x01; + + // Vector Support constants + internal const byte MAX_SUPPORTED_VECTOR_VERSION = 0x01; + internal const int VECTOR_HEADER_SIZE = 8; + + // TCE Related constants + internal const byte TCE_NOT_ENABLED = 0x00; + 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 + internal const byte MIN_TCE_VERSION_WITH_ENCLAVE_RETRY_SUPPORT = 0x03; + internal const ushort MAX_TCE_CIPHERINFO_SIZE = 2048; // max size of cipherinfo blob + internal const long MAX_TCE_CIPHERTEXT_SIZE = 2147483648; // max size of encrypted blob- currently 2GB. + internal const byte CustomCipherAlgorithmId = 0; // Id used for custom encryption algorithm. + + internal const int AEAD_AES_256_CBC_HMAC_SHA256 = 2; + internal const string ENCLAVE_TYPE_VBS = "VBS"; + internal const string ENCLAVE_TYPE_SGX = "SGX"; +#if ENCLAVE_SIMULATOR + internal const string ENCLAVE_TYPE_SIMULATOR = "SIMULATOR"; +#endif + + // TCE Param names for exec handling + internal const string TCE_PARAM_CIPHERTEXT = "cipherText"; + internal const string TCE_PARAM_CIPHER_ALGORITHM_ID = "cipherAlgorithmId"; + internal const string TCE_PARAM_COLUMNENCRYPTION_KEY = "columnEncryptionKey"; + internal const string TCE_PARAM_ENCRYPTION_ALGORITHM = "encryptionAlgorithm"; + internal const string TCE_PARAM_ENCRYPTIONTYPE = "encryptionType"; + internal const string TCE_PARAM_ENCRYPTIONKEY = "encryptionKey"; + internal const string TCE_PARAM_MASTERKEY_PATH = "masterKeyPath"; + internal const string TCE_PARAM_ENCRYPTED_CEK = "encryptedColumnEncryptionKey"; + internal const string TCE_PARAM_CLIENT_KEYSTORE_PROVIDERS = "clientKeyStoreProviders"; + internal const string TCE_PARAM_FORCE_COLUMN_ENCRYPTION = "ForceColumnEncryption(true)"; +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsOperationStatus.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsOperationStatus.cs new file mode 100644 index 0000000000..b1f4555e6c --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsOperationStatus.cs @@ -0,0 +1,12 @@ +// 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.Parser; + +internal enum TdsOperationStatus +{ + Done = 0, + NeedMoreData = 1, + InvalidData = 2 +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsParameterSetter.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsParameterSetter.cs new file mode 100644 index 0000000000..fca270ace6 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsParameterSetter.cs @@ -0,0 +1,57 @@ +// 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.Diagnostics; +using Microsoft.Data.SqlClient.Server; + +namespace Microsoft.Data.SqlClient.Parser; + +// Simple Getter/Setter for structured parameters to allow using common ValueUtilsSmi code. +// This is a stand-in to having a true SmiRequestExecutor class for TDS. +internal class TdsParameterSetter : SmiTypedGetterSetter +{ + #region Private fields + + private TdsRecordBufferSetter _target; + + #endregion + + #region ctor & control + + internal TdsParameterSetter(TdsParserStateObject stateObj, SmiMetaData md) + { + _target = new TdsRecordBufferSetter(stateObj, md); + } + + #endregion + + #region TypedGetterSetter overrides + + /// + /// Are calls to Get methods allowed? + /// + protected override bool CanGet => false; + + /// + /// Are calls to Set methods allowed? + /// + protected override bool CanSet => true; + + // valid for structured types + // This method called for both get and set. + internal override SmiTypedGetterSetter GetTypedGetterSetter(int ordinal) + { + Debug.Assert(0 == ordinal, "TdsParameterSetter only supports 0 for ordinal. Actual = " + ordinal); + return _target; + } + + // Set value to null + // valid for all types + public override void SetDBNull(int ordinal) + { + Debug.Assert(0 == ordinal, "TdsParameterSetter only supports 0 for ordinal. Actual = " + ordinal); + _target.EndElements(); + } + #endregion +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsParser.cs similarity index 99% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParser.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsParser.cs index a106826662..9c5febc828 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsParser.cs @@ -24,6 +24,8 @@ using Microsoft.Data.SqlClient.Connection; using Microsoft.Data.SqlClient.DataClassification; using Microsoft.Data.SqlClient.LocalDb; +using Microsoft.Data.SqlClient.Parser.Login; +using Microsoft.Data.SqlClient.Parser.Tokens; using Microsoft.Data.SqlClient.Server; using Microsoft.Data.SqlClient.Internal; using Microsoft.Data.SqlClient.Utilities; @@ -35,7 +37,7 @@ using Microsoft.Data.SqlTypes; #endif -namespace Microsoft.Data.SqlClient +namespace Microsoft.Data.SqlClient.Parser { // The TdsParser Object controls reading/writing to the netlib, parsing the tds, // and surfacing objects to the user. diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserSessionPool.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsParserSessionPool.cs similarity index 98% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserSessionPool.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsParserSessionPool.cs index e155f71cb3..f501afa7e3 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserSessionPool.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsParserSessionPool.cs @@ -8,16 +8,16 @@ using Microsoft.Data.Common; using Microsoft.Data.SqlClient.Internal; -namespace Microsoft.Data.SqlClient +namespace Microsoft.Data.SqlClient.Parser { internal class TdsParserSessionPool { // NOTE: This is a very simplistic, lightweight pooler. It wasn't // intended to handle huge number of items, just to keep track // of the session objects to ensure that they're cleaned up in - // a timely manner, to avoid holding on to an unacceptable + // a timely manner, to avoid holding on to an unacceptable // amount of server-side resources in the event that consumers - // let their data readers be GC'd, instead of explicitly + // let their data readers be GC'd, instead of explicitly // closing or disposing of them private const int MaxInactiveCount = 10; // pick something, preferably small... @@ -26,7 +26,7 @@ internal class TdsParserSessionPool private readonly int _objectID = System.Threading.Interlocked.Increment(ref s_objectTypeCount); private readonly TdsParser _parser; // parser that owns us - private readonly List _cache; // collection of all known sessions + private readonly List _cache; // collection of all known sessions private int _cachedCount; // lock-free _cache.Count private TdsParserStateObject[] _freeStateObjects; // collection of all sessions available for reuse private int _freeStateObjectCount; // Number of available free sessions @@ -65,8 +65,8 @@ internal void Deactivate() { lock (_cache) { - // NOTE: The PutSession call below may choose to remove the - // session from the cache, which will throw off our + // NOTE: The PutSession call below may choose to remove the + // session from the cache, which will throw off our // enumerator. We avoid that by simply indexing backward // through the array. diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsParserState.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsParserState.cs new file mode 100644 index 0000000000..aaf7ec7da1 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsParserState.cs @@ -0,0 +1,15 @@ +// 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. + +#nullable enable + +namespace Microsoft.Data.SqlClient.Parser; + +internal enum TdsParserState +{ + Closed, + OpenNotLoggedIn, + OpenLoggedIn, + Broken, +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.Multiplexer.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsParserStateObject.Multiplexer.cs similarity index 99% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.Multiplexer.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsParserStateObject.Multiplexer.cs index 3565afdb4d..327d507c8d 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.Multiplexer.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsParserStateObject.Multiplexer.cs @@ -6,9 +6,9 @@ using System.Diagnostics; using Microsoft.Data.SqlClient.Internal; -namespace Microsoft.Data.SqlClient +namespace Microsoft.Data.SqlClient.Parser { - partial class TdsParserStateObject + internal partial class TdsParserStateObject { private Packet _partialPacket; internal Packet PartialPacket => _partialPacket; @@ -38,11 +38,11 @@ public void ProcessSniPacket(PacketHandle packet, uint error) uint dataSize = 0; bool usedPartialPacket = false; uint getDataError = 0; - + if (PartialPacketContainsCompletePacket()) { Packet partialPacket = _partialPacket; - // the partial packet can contain more than a single packet worth of data so to consume the + // the partial packet can contain more than a single packet worth of data so to consume the // partial packet we must use the CurrentLength not just the RequiredLength and then later // the multiplexer will split out the complete packet for consumption and maintain the // additional data @@ -100,7 +100,7 @@ out recurse // if a partial packet was reconstructed it must be handled first if (consumePartialPacket) { - // the partial packet has been processed by the multiplexer and should now have + // the partial packet has been processed by the multiplexer and should now have // only data from a single packet in it so we should use RequiredLength which // is defined by the packet header here not CurrentLength Debug.Assert(PartialPacket != null && PartialPacket.RequiredLength == PartialPacket.CurrentLength); @@ -214,7 +214,7 @@ private void ClearPartialPacket() { partialPacket.Dispose(); } -#endif +#endif } // this check is used in two places that must be identical so it is diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsParserStateObject.cs similarity index 99% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsParserStateObject.cs index 6d82040ca6..d8aa9355d7 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsParserStateObject.cs @@ -17,26 +17,16 @@ using Microsoft.Data.ProviderBase; using Microsoft.Data.SqlClient.ManagedSni; using Microsoft.Data.SqlClient.Internal; +using Microsoft.Data.SqlClient.Parser.Login; +using Microsoft.Data.SqlClient.Parser.Tokens; using Microsoft.Data.SqlClient.Utilities; #if NETFRAMEWORK using System.Runtime.ConstrainedExecution; #endif -namespace Microsoft.Data.SqlClient +namespace Microsoft.Data.SqlClient.Parser { - internal sealed class LastIOTimer - { - internal long _value; - } - - internal enum TdsOperationStatus : int - { - Done = 0, - NeedMoreData = 1, - InvalidData = 2 - } - internal abstract partial class TdsParserStateObject { private static readonly ContextCallback s_readAsyncCallbackComplete = ReadAsyncCallbackComplete; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObjectFactory.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsParserStateObjectFactory.cs similarity index 95% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObjectFactory.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsParserStateObjectFactory.cs index abe66c38a5..6bf22e3e7e 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObjectFactory.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsParserStateObjectFactory.cs @@ -2,12 +2,14 @@ // 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.SqlClient.NativeSni; +using Microsoft.Data.SqlClient.Parser.Login; + #if NET -using Microsoft.Data.SqlClient.ManagedSni; using Microsoft.Data.SqlClient.Internal; #endif -namespace Microsoft.Data.SqlClient +namespace Microsoft.Data.SqlClient.Parser { internal sealed class TdsParserStateObjectFactory { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObjectManaged.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsParserStateObjectManaged.netcore.cs similarity index 99% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObjectManaged.netcore.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsParserStateObjectManaged.netcore.cs index c3667fda1c..d0a1a9a093 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObjectManaged.netcore.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsParserStateObjectManaged.netcore.cs @@ -14,11 +14,11 @@ using Microsoft.Data.Common; using Microsoft.Data.ProviderBase; using Microsoft.Data.SqlClient.Internal; +using Microsoft.Data.SqlClient.ManagedSni; #nullable enable -// @TODO: If this is in the manages SNI namespace, it should be in the managed SNI folder -namespace Microsoft.Data.SqlClient.ManagedSni +namespace Microsoft.Data.SqlClient.Parser { internal sealed class TdsParserStateObjectManaged : TdsParserStateObject { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsParserStateObjectNative.cs similarity index 99% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsParserStateObjectNative.cs index a57a46658f..7d1dbf4bb1 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsParserStateObjectNative.cs @@ -13,8 +13,9 @@ using Microsoft.Data.Common; using Microsoft.Data.ProviderBase; using Microsoft.Data.SqlClient.Internal; +using Microsoft.Data.SqlClient.NativeSni; -namespace Microsoft.Data.SqlClient +namespace Microsoft.Data.SqlClient.Parser { internal class TdsParserStateObjectNative : TdsParserStateObject { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStaticMethods.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsParserStaticMethods.cs similarity index 99% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStaticMethods.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsParserStaticMethods.cs index 63ba1945cc..c86675c8ad 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStaticMethods.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsParserStaticMethods.cs @@ -6,7 +6,7 @@ using System.Globalization; using Microsoft.Data.Common; -namespace Microsoft.Data.SqlClient +namespace Microsoft.Data.SqlClient.Parser { internal sealed class TdsParserStaticMethods { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsRecordBufferSetter.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsRecordBufferSetter.cs similarity index 99% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsRecordBufferSetter.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsRecordBufferSetter.cs index cae885c67c..fb4dc6ce87 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsRecordBufferSetter.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsRecordBufferSetter.cs @@ -8,7 +8,7 @@ using System.Diagnostics; using Microsoft.Data.SqlClient.Server; -namespace Microsoft.Data.SqlClient +namespace Microsoft.Data.SqlClient.Parser { // TdsRecordBufferSetter handles writing a structured value out to a TDS stream internal class TdsRecordBufferSetter : SmiTypedGetterSetter @@ -215,7 +215,7 @@ internal override void EndElements() Debug.Assert(ReadyForToken == _currentField, "Not on first or last column!"); Debug.Assert(_metaData.IsMultiValued, "Unsupported call for single-valued types"); #endif - + // For TVP types, write no-more-rows token _stateObj.WriteByte(TdsEnums.TVP_END_TOKEN); @@ -258,7 +258,7 @@ private void SkipPossibleDefaultedColumns(int targetColumn) return; } - // Handle readyfortoken by using count of columns in the loop. + // Handle readyfortoken by using count of columns in the loop. targetColumn = _metaData.FieldMetaData.Count; } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsValueSetter.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsValueSetter.cs similarity index 99% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsValueSetter.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsValueSetter.cs index fd9d64943e..93013dac1d 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsValueSetter.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/TdsValueSetter.cs @@ -11,7 +11,7 @@ using Microsoft.Data.Common; using Microsoft.Data.SqlClient.Server; -namespace Microsoft.Data.SqlClient +namespace Microsoft.Data.SqlClient.Parser { // TdsValueSetter handles writing a single value out to a TDS stream // This class can easily be extended to handle multiple versions of TDS by sub-classing and virtualizing @@ -696,7 +696,7 @@ internal void SetDateTimeOffset(DateTimeOffset value) short offset = (short)value.Offset.TotalMinutes; #if NET - // In TDS protocol: + // In TDS protocol: // https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-tds/786f5b8a-f87d-4980-9070-b9b7274c681d // // date is represented as one 3 - byte unsigned integer that represents the number of days since January 1, year 1. @@ -720,7 +720,7 @@ internal void SetDateTimeOffset(DateTimeOffset value) // If length = 8, 8 - 5 = 3 bytes is used for time. // If length = 10, 10 - 5 = 5 bytes is used for time. _stateObj.WriteByteSpan(result.Slice(0, length - 5)); // this writes the time value to the state object using dynamic length based on the scale. - + // Date is represented as 3 bytes. So, 3 bytes are written to the state object. BinaryPrimitives.WriteInt32LittleEndian(result, days); _stateObj.WriteByteSpan(result.Slice(0, 3)); diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Tokens/MultiPartTableName.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Tokens/MultiPartTableName.cs new file mode 100644 index 0000000000..516eced6fd --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Tokens/MultiPartTableName.cs @@ -0,0 +1,87 @@ +// 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 Microsoft.Data.Common; + +namespace Microsoft.Data.SqlClient.Parser.Tokens; + +internal struct MultiPartTableName +{ + private string _multipartName; + private string _serverName; + private string _catalogName; + private string _schemaName; + private string _tableName; + + internal MultiPartTableName(string[] parts) + { + _multipartName = null; + _serverName = parts[0]; + _catalogName = parts[1]; + _schemaName = parts[2]; + _tableName = parts[3]; + } + + internal MultiPartTableName(string multipartName) + { + _multipartName = multipartName; + _serverName = null; + _catalogName = null; + _schemaName = null; + _tableName = null; + } + + internal string ServerName + { + get + { + ParseMultipartName(); + return _serverName; + } + set { _serverName = value; } + } + internal string CatalogName + { + get + { + ParseMultipartName(); + return _catalogName; + } + set { _catalogName = value; } + } + internal string SchemaName + { + get + { + ParseMultipartName(); + return _schemaName; + } + set { _schemaName = value; } + } + internal string TableName + { + get + { + ParseMultipartName(); + return _tableName; + } + set { _tableName = value; } + } + + private void ParseMultipartName() + { + if (_multipartName != null) + { + string[] parts = MultipartIdentifier.ParseMultipartIdentifier(_multipartName, Strings.SQL_TDSParserTableName, false); + _serverName = parts[0]; + _catalogName = parts[1]; + _schemaName = parts[2]; + _tableName = parts[3]; + _multipartName = null; + } + } + + internal static readonly MultiPartTableName Null = new(new string[] { null, null, null, null }); +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Tokens/RoutingInfo.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Tokens/RoutingInfo.cs new file mode 100644 index 0000000000..c40c4cd970 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Tokens/RoutingInfo.cs @@ -0,0 +1,28 @@ +// 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.Parser.Tokens; + +internal class RoutingInfo +{ + internal RoutingInfo(byte protocol, ushort port, string serverName, string databaseName = null) + { + Protocol = protocol; + Port = port; + ServerName = serverName; + DatabaseName = databaseName; + } + + internal byte Protocol { get; private set; } + + internal ushort Port { get; private set; } + + internal string ServerName { get; private set; } + + /// + /// The DatabaseName property is only used when routing via an EnhancedRouting ENVCHANGE token. + /// It is not used when routing via the normal Routing ENVCHANGE token. + /// + internal string DatabaseName { get; private set; } +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Tokens/SqlFedAuthInfo.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Tokens/SqlFedAuthInfo.cs new file mode 100644 index 0000000000..67e9c5529f --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Tokens/SqlFedAuthInfo.cs @@ -0,0 +1,25 @@ +// 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. + +#nullable enable + +namespace Microsoft.Data.SqlClient.Parser.Tokens; + +internal sealed class SqlFedAuthInfo +{ + internal SqlFedAuthInfo(string spn, string stsurl) + { + Spn = spn; + StsUrl = stsurl; + } + + internal string Spn { get; } + + internal string StsUrl { get; } + + public override string ToString() + { + return $"SPN: {Spn}, STSURL: {StsUrl}"; + } +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Tokens/SqlMetaDataPriv.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Tokens/SqlMetaDataPriv.cs new file mode 100644 index 0000000000..60a005a8c6 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Tokens/SqlMetaDataPriv.cs @@ -0,0 +1,123 @@ +// 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.Text; + +namespace Microsoft.Data.SqlClient.Parser.Tokens; + +internal class SqlMetaDataPriv +{ + [Flags] + private enum SqlMetaDataPrivFlags : byte + { + None = 0, + IsNullable = 1 << 1, + IsMultiValued = 1 << 2 + } + + internal SqlDbType type; // SqlDbType enum value + internal byte tdsType; // underlying tds type + internal byte precision = TdsEnums.UNKNOWN_PRECISION_SCALE; // give default of unknown (-1) + internal byte scale = TdsEnums.UNKNOWN_PRECISION_SCALE; // give default of unknown (-1) + private SqlMetaDataPrivFlags flags; + internal int length; + internal SqlCollation collation; + internal int codePage; + internal Encoding encoding; + internal bool isEncrypted; // TCE encrypted? + internal SqlMetaDataPriv baseTI; // for encrypted columns, represents the TYPE_INFO for plaintext value + internal SqlCipherMetadata cipherMD; // Cipher related metadata for encrypted columns. + + internal MetaType metaType; // cached metaType + public SqlMetaDataUdt udt; + public SqlMetaDataXmlSchemaCollection xmlSchemaCollection; + + internal SqlMetaDataPriv() + { + } + + /// + /// Is the algorithm handle for the cipher encryption initialized? + /// + internal bool IsAlgorithmInitialized() + { + if (cipherMD != null) + { + return cipherMD.IsAlgorithmInitialized(); + } + + return false; + } + + public bool IsNullable + { + get => HasFlag(SqlMetaDataPrivFlags.IsNullable); + set => Set(SqlMetaDataPrivFlags.IsNullable, value); + } + + public bool IsMultiValued + { + get => HasFlag(SqlMetaDataPrivFlags.IsMultiValued); + set => Set(SqlMetaDataPrivFlags.IsMultiValued, value); + } + + /// + /// Returns the normalization rule version byte. + /// + /// + internal byte NormalizationRuleVersion + { + get + { + if (cipherMD != null) + { + return cipherMD.NormalizationRuleVersion; + } + + return 0x00; + } + } + + private bool HasFlag(SqlMetaDataPrivFlags flag) + { + return (flags & flag) != 0; + } + + private void Set(SqlMetaDataPrivFlags flag, bool value) + { + flags = value ? flags | flag : flags & ~flag; + } + + internal virtual void CopyFrom(SqlMetaDataPriv original) + { + this.type = original.type; + this.tdsType = original.tdsType; + this.precision = original.precision; + this.scale = original.scale; + this.length = original.length; + this.collation = original.collation; + this.codePage = original.codePage; + this.encoding = original.encoding; + this.metaType = original.metaType; + this.flags = original.flags; + + if (original.udt != null) + { + udt = new SqlMetaDataUdt(); + udt.CopyFrom(original.udt); + } + + if (original.xmlSchemaCollection != null) + { + xmlSchemaCollection = new SqlMetaDataXmlSchemaCollection(); + xmlSchemaCollection.CopyFrom(original.xmlSchemaCollection); + } + + this.isEncrypted = original.isEncrypted; + this.baseTI = original.baseTI; + this.cipherMD = original.cipherMD; + } +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Tokens/SqlMetaDataUdt.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Tokens/SqlMetaDataUdt.cs new file mode 100644 index 0000000000..06367dbda4 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Tokens/SqlMetaDataUdt.cs @@ -0,0 +1,36 @@ +// 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.Diagnostics.CodeAnalysis; + +namespace Microsoft.Data.SqlClient.Parser.Tokens; + +internal sealed class SqlMetaDataUdt +{ + #if NET + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] + #endif + internal Type Type; + + internal string DatabaseName; + + internal string SchemaName; + + internal string TypeName; + + internal string AssemblyQualifiedName; + + public void CopyFrom(SqlMetaDataUdt original) + { + if (original != null) + { + Type = original.Type; + DatabaseName = original.DatabaseName; + SchemaName = original.SchemaName; + TypeName = original.TypeName; + AssemblyQualifiedName = original.AssemblyQualifiedName; + } + } +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Tokens/SqlMetaDataXmlSchemaCollection.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Tokens/SqlMetaDataXmlSchemaCollection.cs new file mode 100644 index 0000000000..e5d609917c --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Tokens/SqlMetaDataXmlSchemaCollection.cs @@ -0,0 +1,22 @@ +// 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.Parser.Tokens; + +internal sealed class SqlMetaDataXmlSchemaCollection +{ + internal string Database; + internal string OwningSchema; + internal string Name; + + public void CopyFrom(SqlMetaDataXmlSchemaCollection original) + { + if (original != null) + { + Database = original.Database; + OwningSchema = original.OwningSchema; + Name = original.Name; + } + } +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Tokens/SqlReturnValue.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Tokens/SqlReturnValue.cs new file mode 100644 index 0000000000..dcac65ac5c --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Tokens/SqlReturnValue.cs @@ -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. + +namespace Microsoft.Data.SqlClient.Parser.Tokens; + +internal sealed class SqlReturnValue : SqlMetaDataPriv +{ + // @TODO: Make auto properties (and rename to match) + internal string parameter; + internal readonly SqlBuffer value; + + #if NETFRAMEWORK + internal ushort parmIndex; //2005 or later only + #endif + + internal SqlReturnValue() : base() + { + value = new SqlBuffer(); + } +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Tokens/_SqlMetaData.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Tokens/_SqlMetaData.cs new file mode 100644 index 0000000000..e83725184c --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Tokens/_SqlMetaData.cs @@ -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. + +using System; +using System.Data; + +namespace Microsoft.Data.SqlClient.Parser.Tokens; + +internal sealed class _SqlMetaData : SqlMetaDataPriv +{ + [Flags] + private enum _SqlMetadataFlags : int + { + None = 0, + + Updatable = 1 << 0, + UpdateableUnknown = 1 << 1, + IsDifferentName = 1 << 2, + IsKey = 1 << 3, + IsHidden = 1 << 4, + IsExpression = 1 << 5, + IsIdentity = 1 << 6, + IsColumnSet = 1 << 7, + + IsUpdatableMask = (Updatable | UpdateableUnknown) // two bit field (0 is read only, 1 is updatable, 2 is updatability unknown) + } + + internal string column; + internal string baseColumn; + internal MultiPartTableName multiPartTableName; + internal readonly int ordinal; + internal byte tableNum; + internal byte op; // for altrow-columns only + internal ushort operand; // for altrow-columns only + private _SqlMetadataFlags flags; + + internal _SqlMetaData(int ordinal) : base() + { + this.ordinal = ordinal; + } + + private bool HasFlag(_SqlMetadataFlags flag) + { + return (flags & flag) != 0; + } + + internal string serverName + { + get + { + return multiPartTableName.ServerName; + } + } + internal string catalogName + { + get + { + return multiPartTableName.CatalogName; + } + } + internal string schemaName + { + get + { + return multiPartTableName.SchemaName; + } + } + internal string tableName + { + get + { + return multiPartTableName.TableName; + } + } + + public byte Updatability + { + get => (byte)(flags & _SqlMetadataFlags.IsUpdatableMask); + set => flags = (_SqlMetadataFlags)((value & (byte)_SqlMetadataFlags.IsUpdatableMask) | ((int)flags & ~(byte)_SqlMetadataFlags.IsUpdatableMask)); + } + + public bool IsReadOnly + { + get => !HasFlag(_SqlMetadataFlags.IsUpdatableMask); + } + + public bool IsDifferentName + { + get => HasFlag(_SqlMetadataFlags.IsDifferentName); + set => Set(_SqlMetadataFlags.IsDifferentName, value); + } + + public bool IsKey + { + get => HasFlag(_SqlMetadataFlags.IsKey); + set => Set(_SqlMetadataFlags.IsKey, value); + } + + public bool IsHidden + { + get => HasFlag(_SqlMetadataFlags.IsHidden); + set => Set(_SqlMetadataFlags.IsHidden, value); + } + + public bool IsExpression + { + get => HasFlag(_SqlMetadataFlags.IsExpression); + set => Set(_SqlMetadataFlags.IsExpression, value); + } + + public bool IsIdentity + { + get => HasFlag(_SqlMetadataFlags.IsIdentity); + set => Set(_SqlMetadataFlags.IsIdentity, value); + } + + public bool IsColumnSet + { + get => HasFlag(_SqlMetadataFlags.IsColumnSet); + set => Set(_SqlMetadataFlags.IsColumnSet, value); + } + + private void Set(_SqlMetadataFlags flag, bool value) + { + flags = value ? flags | flag : flags & ~flag; + } + + internal bool Is2008DateTimeType + { + get + { + return SqlDbType.Date == type || SqlDbType.Time == type || SqlDbType.DateTime2 == type || SqlDbType.DateTimeOffset == type; + } + } + + internal bool IsLargeUdt + { + get + { + return type == SqlDbType.Udt && length == int.MaxValue; + } + } + + public object Clone() + { + _SqlMetaData result = new _SqlMetaData(ordinal); + result.CopyFrom(this); + result.column = column; + result.baseColumn = baseColumn; + result.multiPartTableName = multiPartTableName; + result.tableNum = tableNum; + result.flags = flags; + result.op = op; + result.operand = operand; + return result; + } +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Tokens/_SqlMetaDataSet.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Tokens/_SqlMetaDataSet.cs new file mode 100644 index 0000000000..dbb420dc72 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Tokens/_SqlMetaDataSet.cs @@ -0,0 +1,144 @@ +// 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.ObjectModel; +using System.Data; +using System.Data.Common; +using System.Diagnostics; + +namespace Microsoft.Data.SqlClient.Parser.Tokens; + +internal sealed class _SqlMetaDataSet +{ + internal readonly SqlTceCipherInfoTable cekTable; // table of "column encryption keys" used for this metadataset + internal ushort id; // for altrow-columns only + + internal DataTable schemaTable; + private readonly _SqlMetaData[] _metaDataArray; + internal ReadOnlyCollection dbColumnSchema; + + private int _hiddenColumnCount; + private int[] _visibleColumnMap; + + internal _SqlMetaDataSet(int count) + { + _hiddenColumnCount = -1; + _metaDataArray = new _SqlMetaData[count]; + for (int i = 0; i < _metaDataArray.Length; ++i) + { + _metaDataArray[i] = new _SqlMetaData(i); + } + } + + internal _SqlMetaDataSet(int count, SqlTceCipherInfoTable cipherTable) + : this(count) + { + cekTable = cipherTable; + } + + private _SqlMetaDataSet(_SqlMetaDataSet original) + { + id = original.id; + _hiddenColumnCount = original._hiddenColumnCount; + _visibleColumnMap = original._visibleColumnMap; + dbColumnSchema = original.dbColumnSchema; + schemaTable = original.schemaTable; + cekTable = original.cekTable; + + if (original._metaDataArray == null) + { + _metaDataArray = null; + } + else + { + _metaDataArray = new _SqlMetaData[original._metaDataArray.Length]; + for (int idx = 0; idx < _metaDataArray.Length; idx++) + { + _metaDataArray[idx] = (_SqlMetaData)original._metaDataArray[idx].Clone(); + } + } + } + + internal int Length + { + get + { + return _metaDataArray.Length; + } + } + + internal int VisibleColumnCount + { + get + { + if (_hiddenColumnCount == -1) + { + SetupHiddenColumns(); + } + return Length - _hiddenColumnCount; + } + } + + internal _SqlMetaData this[int index] + { + get + { + return _metaDataArray[index]; + } + set + { + Debug.Assert(value == null, "used only by SqlBulkCopy"); + _metaDataArray[index] = value; + } + } + + public int GetVisibleColumnIndex(int index) + { + if (_hiddenColumnCount == -1) + { + SetupHiddenColumns(); + } + if (_visibleColumnMap is null) + { + return index; + } + else + { + return _visibleColumnMap[index]; + } + } + + public _SqlMetaDataSet Clone() + { + return new _SqlMetaDataSet(this); + } + + private void SetupHiddenColumns() + { + int hiddenColumnCount = 0; + for (int index = 0; index < Length; index++) + { + if (_metaDataArray[index].IsHidden) + { + hiddenColumnCount += 1; + } + } + + if (hiddenColumnCount > 0) + { + int[] visibleColumnMap = new int[Length - hiddenColumnCount]; + int mapIndex = 0; + for (int metaDataIndex = 0; metaDataIndex < Length; metaDataIndex++) + { + if (!_metaDataArray[metaDataIndex].IsHidden) + { + visibleColumnMap[mapIndex] = metaDataIndex; + mapIndex += 1; + } + } + _visibleColumnMap = visibleColumnMap; + } + _hiddenColumnCount = hiddenColumnCount; + } +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Tokens/_SqlMetaDataSetCollection.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Tokens/_SqlMetaDataSetCollection.cs new file mode 100644 index 0000000000..0c19c8ce58 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/Tokens/_SqlMetaDataSetCollection.cs @@ -0,0 +1,61 @@ +// 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.Diagnostics; + +namespace Microsoft.Data.SqlClient.Parser.Tokens; + +internal sealed class _SqlMetaDataSetCollection +{ + private readonly List<_SqlMetaDataSet> _altMetaDataSetArray; + internal _SqlMetaDataSet metaDataSet; + + internal _SqlMetaDataSetCollection() + { + _altMetaDataSetArray = new List<_SqlMetaDataSet>(); + } + + internal void SetAltMetaData(_SqlMetaDataSet altMetaDataSet) + { + // If altmetadata with same id is found, override it rather than adding a new one + int newId = altMetaDataSet.id; + for (int i = 0; i < _altMetaDataSetArray.Count; i++) + { + if (_altMetaDataSetArray[i].id == newId) + { + // override the existing metadata with the same id + _altMetaDataSetArray[i] = altMetaDataSet; + return; + } + } + + // if we did not find metadata to override, add as new + _altMetaDataSetArray.Add(altMetaDataSet); + } + + internal _SqlMetaDataSet GetAltMetaData(int id) + { + foreach (_SqlMetaDataSet altMetaDataSet in _altMetaDataSetArray) + { + if (altMetaDataSet.id == id) + { + return altMetaDataSet; + } + } + Debug.Fail("Can't match up altMetaDataSet with given id"); + return null; + } + + public object Clone() + { + _SqlMetaDataSetCollection result = new _SqlMetaDataSetCollection() { metaDataSet = metaDataSet?.Clone() }; + + foreach (_SqlMetaDataSet set in _altMetaDataSetArray) + { + result._altMetaDataSetArray.Add(set.Clone()); + } + return result; + } +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/_SqlRPC.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/_SqlRPC.cs new file mode 100644 index 0000000000..a6bab47c50 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Parser/_SqlRPC.cs @@ -0,0 +1,67 @@ +// 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.Parser; + +internal sealed class _SqlRPC +{ + internal string rpcName; + internal ushort ProcID; // Used instead of name + internal ushort options; + + internal SqlParameter[] systemParams; + internal byte[] systemParamOptions; + internal int systemParamCount; + + internal SqlParameterCollection userParams; + internal long[] userParamMap; + internal int userParamCount; + + internal int? recordsAffected; + internal int cumulativeRecordsAffected; + + internal int errorsIndexStart; + internal int errorsIndexEnd; + internal SqlErrorCollection errors; + + internal int warningsIndexStart; + internal int warningsIndexEnd; + internal SqlErrorCollection warnings; + + internal bool needsFetchParameterEncryptionMetadata; + + internal SqlBatchCommand batchCommand; + + internal string GetCommandTextOrRpcName() + { + if (TdsEnums.RPC_PROCID_EXECUTESQL == ProcID) + { + // Param 0 is the actual sql executing + return (string)systemParams[0].Value; + } + else + { + return rpcName; + } + } + + internal SqlParameter GetParameterByIndex(int index, out byte options) + { + SqlParameter retval; + + if (index < systemParamCount) + { + retval = systemParams[index]; + options = systemParamOptions[index]; + } + else + { + long data = userParamMap[index - systemParamCount]; + int paramIndex = (int)(data & int.MaxValue); + options = (byte)((data >> 32) & 0xFF); + retval = userParams[paramIndex]; + } + return retval; + } +} 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 94e7652874..ac07dc5c08 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 @@ -1,10 +1,12 @@ -// Licensed to the .NET Foundation under one or more agreements. +// 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.Buffers; using System.Diagnostics; +using Microsoft.Data.SqlClient.Parser; +using Microsoft.Data.SqlClient.NativeSni; #nullable enable 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 c48f9ada8b..10ebde4840 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 @@ -7,6 +7,7 @@ using System.Diagnostics; using Microsoft.Data.SqlClient.Connection; using Microsoft.Data.SqlClient.Internal; +using Microsoft.Data.SqlClient.Parser; #nullable enable diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/MetadataUtilsSmi.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/MetadataUtilsSmi.cs index 3adfd58f94..3993b660c5 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/MetadataUtilsSmi.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/MetadataUtilsSmi.cs @@ -10,6 +10,7 @@ using System.Diagnostics; using System.Globalization; using Microsoft.Data.Common; +using Microsoft.Data.SqlClient.Parser; namespace Microsoft.Data.SqlClient.Server { @@ -27,7 +28,7 @@ internal static class MetaDataUtilsSmi /// /// Standard type inference map to get SqlDbType when all you know is the value's type (typecode) - /// This map's index is off by one (add one to typecode locate correct entry) in order + /// This map's index is off by one (add one to typecode locate correct entry) in order /// to support ExtendedSqlDbType.Invalid /// This array is meant to be accessed from InferSqlDbTypeFromTypeCode. /// @@ -77,7 +78,7 @@ internal static class MetaDataUtilsSmi SqlDbType.DateTimeOffset, // System.DateTimeOffset #if NET SqlDbType.Date, // System.DateOnly - SqlDbType.Time, // System.TimeOnly + SqlDbType.Time, // System.TimeOnly #endif }; @@ -164,7 +165,7 @@ internal static bool IsAnsiType(SqlDbType type) => type == SqlDbType.Char || type == SqlDbType.Text; // Does this type use PLP format values? - internal static bool IsPlpFormat(SmiMetaData metaData) => + internal static bool IsPlpFormat(SmiMetaData metaData) => metaData.MaxLength == SmiMetaData.UnlimitedMaxLengthIndicator || metaData.SqlDbType == SqlDbType.Image || metaData.SqlDbType == SqlDbType.NText || @@ -174,7 +175,7 @@ internal static bool IsPlpFormat(SmiMetaData metaData) => // If we know we're only going to use this object to assign to a specific SqlDbType back end object, // we can save some processing time by only checking for the few valid types that can be assigned to the dbType. // This assumes a switch statement over SqlDbType is faster than getting the ClrTypeCode and iterating over a - // series of if statements, or using a hash table. + // series of if statements, or using a hash table. // NOTE: the form of these checks is taking advantage of a feature of the JIT compiler that is supposed to // optimize checks of the form '(xxx.GetType() == typeof( YYY ))'. The JIT team claimed at one point that // this doesn't even instantiate a Type instance, thus was the fastest method for individual comparisons. @@ -403,7 +404,7 @@ internal static ExtendedClrTypeCode DetermineExtendedTypeCodeForUseWithSqlDbType // SqlDbType doesn't help us here, call general-purpose function extendedCode = DetermineExtendedTypeCode(value); - // Some types aren't allowed for Variants but are for the general-purpose function. + // Some types aren't allowed for Variants but are for the general-purpose function. // Match behavior of other types and return invalid in these cases. if (ExtendedClrTypeCode.SqlXml == extendedCode) { @@ -516,7 +517,7 @@ internal static SqlDbType InferSqlDbTypeFromTypeCode(ExtendedClrTypeCode typeCod return s_extendedTypeCodeToSqlDbTypeMap[(int)typeCode + 1]; } - // Infer SqlDbType from Type in the general case. 2008-only (or later) features that need to + // Infer SqlDbType from Type in the general case. 2008-only (or later) features that need to // infer types should use InferSqlDbTypeFromType_2008. internal static SqlDbType InferSqlDbTypeFromType(Type type) { @@ -534,7 +535,7 @@ internal static SqlDbType InferSqlDbTypeFromType(Type type) return returnType; } - // Inference rules changed for 2008-or-later-only cases. Only features that are guaranteed to be + // Inference rules changed for 2008-or-later-only cases. Only features that are guaranteed to be // running against 2008 and don't have backward compat issues should call this code path. // example: TVP's are a new 2008 feature (no back compat issues) so can infer DATETIME2 // when mapping System.DateTime from DateTable or DbDataReader. DATETIME2 is better because @@ -736,7 +737,7 @@ internal static SmiExtendedMetaData SmiMetaDataFromDataColumn(DataColumn column, scale = 0; } - // In Net Core, since DataColumn.Locale is not accessible because it is internal and in a separate assembly, + // In Net Core, since DataColumn.Locale is not accessible because it is internal and in a separate assembly, // we try to get the Locale from the parent CultureInfo columnLocale = parent != null ? parent.Locale : CultureInfo.CurrentCulture; 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 b6f8834f6b..f2b3bc17d9 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 @@ -13,6 +13,7 @@ using System.Reflection; using System.Xml; using Microsoft.Data.Common; +using Microsoft.Data.SqlClient.Parser; using Microsoft.Data.SqlTypes; #if NET @@ -55,14 +56,14 @@ internal static class ValueUtilsSmi // These methods implement common semantics for getters & setters // All access to underlying Smi getters/setters must validate parameters // in these methods - // + // // The idea for the getters is that there are two types associated with the field/column, - // the one the user asks for (implicitly via a strongly-typed getter) and the one the data + // the one the user asks for (implicitly via a strongly-typed getter) and the one the data // is stored in (SmiMetaData). // When a strong getter is invoked, we try one of two ways to get the value // 1) go directly to the source for the requested type if possible - // 2) instantiate the value based on the stored type (GetValue), then ask the Clr + // 2) instantiate the value based on the stored type (GetValue), then ask the Clr // to convert. internal static bool IsDBNull(ITypedGettersV3 getters, int ordinal) { @@ -1643,7 +1644,7 @@ SqlBuffer.StorageType storageType typeCode != ExtendedClrTypeCode.DbDataReader && typeCode != ExtendedClrTypeCode.IEnumerableOfSqlDataRecord ) || - CanAccessSetterDirectly(metaData, typeCode), + CanAccessSetterDirectly(metaData, typeCode), "Un-validated type '" + typeCode + "' for metaData: " + metaData.SqlDbType ); @@ -1669,7 +1670,7 @@ SqlBuffer.StorageType storageType } // Implements SqlClient 2.0-compatible SetValue() semantics + VS2008 extensions - // Assumes caller already validated basic type against the metadata, other than trimming lengths and + // Assumes caller already validated basic type against the metadata, other than trimming lengths and // checking individual field values (TVPs) internal static void SetCompatibleValueV200( SmiTypedGetterSetter setters, @@ -1688,7 +1689,7 @@ ParameterPeekAheadValue peekAhead typeCode != ExtendedClrTypeCode.DbDataReader && typeCode != ExtendedClrTypeCode.IEnumerableOfSqlDataRecord ) || - CanAccessSetterDirectly(metaData, typeCode), + CanAccessSetterDirectly(metaData, typeCode), "Un-validated type '" + typeCode + "' for metaData: " + metaData.SqlDbType ); @@ -1915,9 +1916,9 @@ internal static void FillCompatibleSettersFromReader(SmiTypedGetterSetter setter break; default: - // In order for us to get here we would have to have an - // invalid instance of SqlDbType, or one would have to add - // new member to SqlDbType without adding a case in this + // In order for us to get here we would have to have an + // invalid instance of SqlDbType, or one would have to add + // new member to SqlDbType without adding a case in this // switch, hence the assert. Debug.Fail("unsupported DbType:" + metaData[i].SqlDbType.ToString()); throw ADP.NotSupported(); @@ -2110,7 +2111,7 @@ internal static void FillCompatibleSettersFromRecord(SmiTypedGetterSetter setter } } } - + // // Common utility code to get lengths correct for trimming // @@ -2254,7 +2255,7 @@ private static void SetSqlBinary_LengthChecked(ITypedSettersV3 setters, int ordi private static void SetBytes_FromRecord(ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, SqlDataRecord record, int offset) { - // Deal with large values by sending bufferLength of NoLengthLimit (== assume + // Deal with large values by sending bufferLength of NoLengthLimit (== assume // CheckXetParameters will ignore requested-length checks in this case long bufferLength = record.GetBytes(ordinal, 0, null, 0, 0); if (bufferLength > int.MaxValue) @@ -2299,7 +2300,7 @@ private static void SetBytes_FromRecord(ITypedSettersV3 setters, int ordinal, Sm private static void SetBytes_FromReader(ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, DbDataReader reader, int offset) { - // Deal with large values by sending bufferLength of NoLengthLimit (== assume + // Deal with large values by sending bufferLength of NoLengthLimit (== assume // CheckXetParameters will ignore requested-length checks in this case) int length = CheckXetParameters(metaData.SqlDbType, metaData.MaxLength, actualLength: NoLengthLimit, fieldOffset: 0, bufferLength: NoLengthLimit, bufferOffset: offset, length: NoLengthLimit); @@ -2335,7 +2336,7 @@ private static void SetSqlBytes_LengthChecked(ITypedSettersV3 setters, int ordin int length = 0; if (!value.IsNull) { - // Deal with large values by sending bufferLength of NoLengthLimit (== assume + // Deal with large values by sending bufferLength of NoLengthLimit (== assume // CheckXetParameters will ignore requested-length checks in this case long bufferLength = value.Length; if (bufferLength > int.MaxValue) @@ -2423,7 +2424,7 @@ private static void SetCharsOrString_FromReader(ITypedSettersV3 setters, int ord // Use chunking via SetChars to transfer a value from a reader to a gettersetter private static void SetChars_FromReader(ITypedSettersV3 setters, int ordinal, SmiMetaData metaData, DbDataReader reader, int offset) { - // Deal with large values by sending bufferLength of NoLengthLimit (== assume + // Deal with large values by sending bufferLength of NoLengthLimit (== assume // CheckXetParameters will ignore requested-length checks in this case) int length = CheckXetParameters(metaData.SqlDbType, metaData.MaxLength, actualLength: NoLengthLimit, fieldOffset: 0, bufferLength: NoLengthLimit , bufferOffset: offset, length: NoLengthLimit ); @@ -2758,7 +2759,7 @@ int length /*DOnly*/{ _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, X , _ , X , _ , },/*DateOnly*/ /*TOnly*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , X , _ , _ , },/*TimeOnly*/ #endif -/*Strm */{ _ , X , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , X , _, _ , _ , _ , _ , },/*Stream*/ +/*Strm */{ _ , X , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , X , _, _ , _ , _ , _ , },/*Stream*/ /*TxRdr*/{ _ , _ , _ , X , _ , _ , _ , _ , _ , _ , X , X , X , _ , _ , _ , _ , _ , X , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*TextReader*/ /*XmlRd*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*XmlReader*/ // BI, Bin, Bit, Ch, DT, Dec, Fl, Im, Int, Mny, NCh, NTx, NVC, Rl, UI, SDT, SI, SMn, Txt, TS, TI, VBn, VCh, Var, 24, Xml, 26, 27, 28, Udt, St, Dat, Tm, DT2, DTO @@ -2814,7 +2815,7 @@ int length /*DOnly*/{ _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _, X , _ , X , _ , },/*DateOnly*/ /*TOnly*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , X , _ , _ , _ , _ , _ , _ , _, _ , X , _ , _ , },/*TimeOnly*/ #endif -/*Strm */{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*Stream*/ +/*Strm */{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*Stream*/ /*TxRdr*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*TextReader*/ /*XmlRd*/{ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _, _ , _ , _ , _ , },/*XmlReader*/ // BI, Bin, Bit, Ch, DT, Dec, Fl, Im, Int, Mny, NCh, NTx, NVC, Rl, UI, SDT, SI, SMn, Txt, TS, TI, VBn, VCh, Var, 24, Xml, 26, 27, 28, Udt, St, Dat, Tm, DT2, DTO @@ -3021,9 +3022,9 @@ private static string GetString_Unchecked(ITypedGettersV3 getters, int ordinal) { Debug.Assert(!IsDBNull_Unchecked(getters, ordinal)); - // Note: depending on different getters, the result string may be truncated, e.g. for + // Note: depending on different getters, the result string may be truncated, e.g. for // Inproc process, the getter is InProcRecordBuffer (implemented in SqlAcess), string will be - // truncated to 4000 (if length is more than 4000). If MemoryRecordBuffer getter is used, data + // truncated to 4000 (if length is more than 4000). If MemoryRecordBuffer getter is used, data // is not truncated. Please refer VSDD 479655 for more detailed information regarding the string length. string result = getters.GetString(ordinal); return result; @@ -3437,7 +3438,7 @@ private static void SetSqlMoney_Unchecked(ITypedSettersV3 setters, int ordinal, #else long longValue = SqlTypeWorkarounds.SqlMoneyToLong(value); #endif - + setters.SetInt64(ordinal, longValue); } } @@ -3598,7 +3599,7 @@ ParameterPeekAheadValue peekAhead } setters.EndElements(); - + } finally { @@ -3642,7 +3643,7 @@ DataTable value { object cellValue = row[i]; - // Only determine cell types for first row, to save expensive + // Only determine cell types for first row, to save expensive if (ExtendedClrTypeCode.Invalid == cellTypes[i]) { cellTypes[i] = MetaDataUtilsSmi.DetermineExtendedTypeCodeForUseWithSqlDbType( 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 e61bf3e404..3373330cf0 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBuffer.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBuffer.cs @@ -7,6 +7,7 @@ using System.Diagnostics; using System.Globalization; using System.Runtime.InteropServices; +using Microsoft.Data.SqlClient.Parser; using Microsoft.Data.SqlTypes; namespace Microsoft.Data.SqlClient @@ -922,7 +923,7 @@ internal SqlMoney SqlMoney { return SqlMoney.Null; } - + #if NET return SqlMoney.FromTdsValue(_value._int64); #else @@ -1274,7 +1275,7 @@ internal Type GetTypeFromStorageType(bool isSqlType) } } - return null; // need to return the value as an object of some CLS type + return null; // need to return the value as an object of some CLS type } internal static SqlBuffer[] CreateBufferArray(int length) @@ -1484,7 +1485,7 @@ private static void FillInTimeInfo(ref TimeInfo timeInfo, ReadOnlySpan tim } timeInfo._ticks = tickUnits * TdsEnums.TICKS_FROM_SCALE[scale]; - // Once the deserialization has been completed using the value scale, we need to set the actual denormalized scale, + // Once the deserialization has been completed using the value scale, we need to set the actual denormalized scale, // coming from the data type, on the original result, so that it has the proper scale setting. // This only applies for values that got serialized/deserialized for encryption. Otherwise, both scales should be equal. timeInfo._scale = denormalizedScale; @@ -1505,16 +1506,16 @@ private void ThrowIfNull() } // [Field]As method explanation: // these methods are used to bridge generic to non-generic access to value type fields on the storage struct - // where typeof(T) == typeof(field) - // 1) RyuJIT will recognize the pattern of (T)(object)T as being redundant and eliminate - // the T and object casts leaving T, so while this looks like it will put every value type instance in a box the + // where typeof(T) == typeof(field) + // 1) RyuJIT will recognize the pattern of (T)(object)T as being redundant and eliminate + // the T and object casts leaving T, so while this looks like it will put every value type instance in a box the // generated assembly will be short and direct // 2) another jit may not recognize the pattern and should emit the code as seen. this will box and then unbox the // value type which is no worse than the mechanism that this code replaces // where typeof(T) != typeof(field) // the jit will emit all the cast operations as written. this will put the value into a box and then attempt to - // cast it, because it is an object no conversions are used and this will generate the desired InvalidCastException - // for example users cannot widen a short to an int preserving external expectations + // cast it, because it is an object no conversions are used and this will generate the desired InvalidCastException + // for example users cannot widen a short to an int preserving external expectations internal T ByteAs() { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs index 2e7668aa55..4dd0e5f3c4 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBulkCopy.cs @@ -17,6 +17,8 @@ using Microsoft.Data.Common; using Microsoft.Data.SqlClient.Connection; using Microsoft.Data.SqlClient.Internal; +using Microsoft.Data.SqlClient.Parser; +using Microsoft.Data.SqlClient.Parser.Tokens; using Microsoft.Data.SqlClient.Utilities; namespace Microsoft.Data.SqlClient diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCachedBuffer.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCachedBuffer.cs index 5810db6d5a..9d5fd35951 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCachedBuffer.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCachedBuffer.cs @@ -8,6 +8,8 @@ using System.IO; using System.Runtime.CompilerServices; using System.Xml; +using Microsoft.Data.SqlClient.Parser; +using Microsoft.Data.SqlClient.Parser.Tokens; using Microsoft.Data.SqlTypes; namespace Microsoft.Data.SqlClient diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCollation.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCollation.cs index 5dd68bba2b..39148025a8 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCollation.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCollation.cs @@ -4,6 +4,7 @@ using System.Data.SqlTypes; using System.Diagnostics; +using Microsoft.Data.SqlClient.Parser; using Microsoft.Data.SqlTypes; namespace Microsoft.Data.SqlClient @@ -203,7 +204,7 @@ public static SqlCollation FromLCIDAndSort(int lcid, SqlCompareOptions sqlCompar { uint info = 0; byte sortId = 0; - + Debug.Assert((sqlCompareOptions & SqlTypeWorkarounds.SqlStringValidSqlCompareOptionMask) == sqlCompareOptions, "invalid set_SqlCompareOptions value"); uint compare = 0; if ((sqlCompareOptions & SqlCompareOptions.IgnoreCase) == SqlCompareOptions.IgnoreCase) @@ -227,7 +228,7 @@ public static SqlCollation FromLCIDAndSort(int lcid, SqlCompareOptions sqlCompar compare |= BinarySort; } info = (info & MaskLcid) | compare; - + int lcidValue = lcid & (int)MaskLcid; Debug.Assert(lcidValue == lcid, "invalid set_LCID value"); @@ -238,7 +239,7 @@ public static SqlCollation FromLCIDAndSort(int lcid, SqlCompareOptions sqlCompar // combine the current compare options with the new locale ID and its first supported version info = (info & MaskCompareOpt) | unchecked((uint)lcidValue) | unchecked((uint)versionBits); - + return new SqlCollation(info, sortId); } } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Batch.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Batch.cs index da7d1e2ed7..4e4bb0eba2 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Batch.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Batch.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Data; using System.Diagnostics; +using Microsoft.Data.SqlClient.Parser; namespace Microsoft.Data.SqlClient { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Encryption.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Encryption.cs index 3b0fc6e93f..1a9fcd5a6d 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Encryption.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Encryption.cs @@ -14,6 +14,7 @@ using System.Threading.Tasks; using Microsoft.Data.Common; using Microsoft.Data.SqlClient.Connection; +using Microsoft.Data.SqlClient.Parser; using Microsoft.Data.SqlClient.Utilities; namespace Microsoft.Data.SqlClient diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.NonQuery.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.NonQuery.cs index ef3e8afe25..260d009b59 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.NonQuery.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.NonQuery.cs @@ -12,6 +12,7 @@ using Microsoft.Data.ProviderBase; using Microsoft.Data.SqlClient.Connection; using Microsoft.Data.SqlClient.Internal; +using Microsoft.Data.SqlClient.Parser; using Microsoft.Data.SqlClient.Utilities; #if NETFRAMEWORK diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Reader.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Reader.cs index 2b5f568c60..7d054f593b 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Reader.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Reader.cs @@ -13,6 +13,7 @@ using Microsoft.Data.ProviderBase; using Microsoft.Data.SqlClient.Connection; using Microsoft.Data.SqlClient.Internal; +using Microsoft.Data.SqlClient.Parser; using Microsoft.Data.SqlClient.Utilities; #if NETFRAMEWORK diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Scalar.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Scalar.cs index fa53eb14ee..f3b00fb26e 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Scalar.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Scalar.cs @@ -8,6 +8,7 @@ using System.Threading.Tasks; using Microsoft.Data.Common; using Microsoft.Data.SqlClient.Internal; +using Microsoft.Data.SqlClient.Parser; namespace Microsoft.Data.SqlClient { @@ -24,11 +25,11 @@ public override object ExecuteScalar() #if NETFRAMEWORK SqlConnection.ExecutePermission.Demand(); #endif - + // Reset _pendingCancel upon entry into any Execute - used to synchronize state // between entry into Execute* API and the thread obtaining the stateObject. _pendingCancel = false; - + using var diagnosticScope = s_diagnosticListener.CreateCommandScope(this, _transaction); using var eventScope = SqlClientEventScope.Create($"SqlCommand.ExecuteScalar | API | Object Id {ObjectID}"); @@ -42,7 +43,7 @@ public override object ExecuteScalar() ActivityCorrelator.Current, _activeConnection?.ClientConnectionId, CommandText); - + SqlStatistics statistics = null; bool success = false; int? sqlExceptionNumber = null; @@ -85,12 +86,12 @@ public override Task ExecuteScalarAsync(CancellationToken cancellationTo // Do not use retry logic here as ExecuteReaderAsyncInternal handles retry logic return ExecuteScalarAsyncInternal(cancellationToken); } - + internal Task ExecuteScalarBatchAsync(CancellationToken cancellationToken) { Guid operationId = s_diagnosticListener.WriteCommandBefore(this, _transaction); _parentOperationStarted = true; - + // @TODO: This code is almost identical to ExecuteScalarAsyncInternal - we can definitely refactor it! return ExecuteReaderAsync(cancellationToken).ContinueWith(executeTask => { @@ -170,9 +171,9 @@ internal Task ExecuteScalarBatchAsync(CancellationToken cancellationToke }, TaskScheduler.Default).Unwrap(); } - + #endregion - + #region Private Methods private static object CompleteExecuteScalar(SqlDataReader reader, bool returnLastResult) @@ -222,7 +223,7 @@ private async Task ExecuteScalarUntilEndAsync( return result; } - + private Task ExecuteScalarAsyncInternal(CancellationToken cancellationToken) { SqlClientEventSource.Log.TryCorrelationTraceEvent( @@ -263,20 +264,20 @@ private Task ExecuteScalarAsyncInternal(CancellationToken cancellationTo this, _transaction, executeTask.Exception.InnerException); - + source.SetException(executeTask.Exception.InnerException); } else { SqlDataReader reader = executeTask.Result; - + // @TODO: Use continue with state? reader.ReadAsync(cancellationToken).ContinueWith(async readTask => { // @TODO: This seems a bit confusing with unnecessary extra dispose calls and try/finally blocks try { - + if (readTask.IsCanceled) { reader.Dispose(); @@ -285,13 +286,13 @@ private Task ExecuteScalarAsyncInternal(CancellationToken cancellationTo else if (readTask.IsFaulted) { reader.Dispose(); - + s_diagnosticListener.WriteCommandError( operationId, this, _transaction, readTask.Exception.InnerException); - + source.SetException(readTask.Exception.InnerException); } else @@ -327,13 +328,13 @@ private Task ExecuteScalarAsyncInternal(CancellationToken cancellationTo if (exception is not null) { s_diagnosticListener.WriteCommandError(operationId, this, _transaction, exception); - + source.SetException(exception); } else { s_diagnosticListener.WriteCommandAfter(operationId, this, _transaction); - + source.SetResult(result); } } @@ -348,12 +349,12 @@ private Task ExecuteScalarAsyncInternal(CancellationToken cancellationTo } _parentOperationStarted = false; - + return source.Task; }, TaskScheduler.Default).Unwrap(); } - + #endregion } } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Xml.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Xml.cs index e17aaf79e0..292bf25f05 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Xml.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Xml.cs @@ -13,6 +13,7 @@ using Microsoft.Data.SqlClient.Connection; using Microsoft.Data.SqlClient.Server; using Microsoft.Data.SqlClient.Internal; +using Microsoft.Data.SqlClient.Parser; using Microsoft.Data.SqlClient.Utilities; #if NETFRAMEWORK diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.cs index 7757927203..422f2bd778 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.cs @@ -20,6 +20,8 @@ using Microsoft.Data.SqlClient.Connection; using Microsoft.Data.SqlClient.Diagnostics; using Microsoft.Data.SqlClient.Internal; +using Microsoft.Data.SqlClient.Parser; +using Microsoft.Data.SqlClient.Parser.Tokens; #if NETFRAMEWORK using System.Security.Permissions; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommandColumnEncryptionSetting.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommandColumnEncryptionSetting.cs new file mode 100644 index 0000000000..6aaa5fd2eb --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommandColumnEncryptionSetting.cs @@ -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. + +namespace Microsoft.Data.SqlClient; + +/// +public enum SqlCommandColumnEncryptionSetting +{ + /// + UseConnectionSetting = 0, + + /// + Enabled, + + /// + ResultSetOnly, + + /// + Disabled, +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnection.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnection.cs index feea131130..4f62234bce 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnection.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnection.cs @@ -24,6 +24,8 @@ using Microsoft.Data.SqlClient.ConnectionPool; using Microsoft.Data.SqlClient.Diagnostics; using Microsoft.Data.SqlClient.Internal; +using Microsoft.Data.SqlClient.Parser; +using Microsoft.Data.SqlClient.Parser.Tokens; using Microsoft.Data.SqlClient.Utilities; using Microsoft.SqlServer.Server; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionAttestationProtocol.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionAttestationProtocol.cs new file mode 100644 index 0000000000..64e56e7238 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionAttestationProtocol.cs @@ -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. + +namespace Microsoft.Data.SqlClient; + +/// +public enum SqlConnectionAttestationProtocol +{ + /// + NotSpecified = 0, + + /// + AAS = 1, + + /// + None = 2, + + /// + HGS = 3 +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionColumnEncryptionSetting.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionColumnEncryptionSetting.cs new file mode 100644 index 0000000000..9aeb3aa99b --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionColumnEncryptionSetting.cs @@ -0,0 +1,15 @@ +// 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; + +/// +public enum SqlConnectionColumnEncryptionSetting +{ + /// + Disabled = 0, + + /// + Enabled, +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionIPAddressPreference.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionIPAddressPreference.cs new file mode 100644 index 0000000000..2c4c5e8363 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionIPAddressPreference.cs @@ -0,0 +1,18 @@ +// 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; + +/// +public enum SqlConnectionIPAddressPreference +{ + /// + IPv4First = 0, // default + + /// + IPv6First = 1, + + /// + UsePlatformDefault = 2 +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionOptions.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionOptions.cs index cb573908ad..a2bc770f49 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionOptions.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionOptions.cs @@ -17,6 +17,7 @@ using Microsoft.Data.Common; using Microsoft.Data.Common.ConnectionString; using Microsoft.Data.SqlClient.LocalDb; +using Microsoft.Data.SqlClient.Parser; namespace Microsoft.Data.SqlClient { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionOverrides.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionOverrides.cs new file mode 100644 index 0000000000..dd50f6f7b1 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionOverrides.cs @@ -0,0 +1,17 @@ +// 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 Microsoft.Data.SqlClient; + +/// +[Flags] +public enum SqlConnectionOverrides +{ + /// + None = 0, + /// + OpenWithoutRetry = 1, +} 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 bb4871ed4a..734b016c7f 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionStringBuilder.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionStringBuilder.cs @@ -16,6 +16,7 @@ using System.Reflection; using Microsoft.Data.Common; using Microsoft.Data.Common.ConnectionString; +using Microsoft.Data.SqlClient.Parser; namespace Microsoft.Data.SqlClient { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCredential.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCredential.cs index 3859b0b000..dcaea1fe96 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCredential.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCredential.cs @@ -4,6 +4,7 @@ using System.Security; using Microsoft.Data.Common; +using Microsoft.Data.SqlClient.Parser; namespace Microsoft.Data.SqlClient { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDataReader.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDataReader.cs index efc31a77fb..3ab2c28e46 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDataReader.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDataReader.cs @@ -29,6 +29,8 @@ using Microsoft.Data.SqlClient.Server; using Microsoft.Data.SqlTypes; using Microsoft.Data.SqlClient.Internal; +using Microsoft.Data.SqlClient.Parser; +using Microsoft.Data.SqlClient.Parser.Tokens; namespace Microsoft.Data.SqlClient { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDbColumn.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDbColumn.cs index bebe02b575..d370545b24 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDbColumn.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDbColumn.cs @@ -5,6 +5,8 @@ using System; using System.Data; using System.Data.Common; +using Microsoft.Data.SqlClient.Parser; +using Microsoft.Data.SqlClient.Parser.Tokens; namespace Microsoft.Data.SqlClient { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnums.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnums.cs index 70ab7dfa68..805b76f5cb 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnums.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnums.cs @@ -16,6 +16,7 @@ using System.IO; using System.Xml; using Microsoft.Data.Common; +using Microsoft.Data.SqlClient.Parser; using Microsoft.Data.SqlTypes; using Microsoft.SqlServer.Server; @@ -120,7 +121,7 @@ private static bool _IsAnsiType(SqlDbType type) => type == SqlDbType.Char || type == SqlDbType.VarChar || type == SqlDbType.Text; // is this type size expressed as count of characters or bytes? - private static bool _IsSizeInCharacters(SqlDbType type) => + private static bool _IsSizeInCharacters(SqlDbType type) => type == SqlDbType.NChar || type == SqlDbType.NVarChar || type == SqlDbType.Xml || @@ -317,7 +318,7 @@ internal static MetaType GetMaxMetaTypeFromMetaType(MetaType mt) // internal static MetaType GetMetaTypeFromType(Type dataType) => GetMetaTypeFromValue(dataType, null, false, true); - internal static MetaType GetMetaTypeFromValue(object value, bool streamAllowed = true) => + internal static MetaType GetMetaTypeFromValue(object value, bool streamAllowed = true) => GetMetaTypeFromValue(value.GetType(), value, true, streamAllowed); private static MetaType GetMetaTypeFromValue(Type dataType, object value, bool inferLen, bool streamAllowed) @@ -694,7 +695,7 @@ private static void AssertIsUserDefinedTypeInstance(object sqlValue, string fail Debug.Assert(attributes.Length > 0, failedAssertMessage); } - // devnote: This method should not be used with SqlDbType.Date and SqlDbType.DateTime2. + // devnote: This method should not be used with SqlDbType.Date and SqlDbType.DateTime2. // With these types the values should be used directly as CLR types instead of being converted to a SqlValue internal static object GetSqlValueFromComVariant(object comVal) { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnvChange.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnvChange.cs index f441892f29..d627442aa9 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnvChange.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlEnvChange.cs @@ -4,6 +4,7 @@ using System; using System.Buffers; +using Microsoft.Data.SqlClient.Parser.Tokens; namespace Microsoft.Data.SqlClient { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalTransaction.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalTransaction.cs index 96ccc8a8af..15b6c06374 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalTransaction.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalTransaction.cs @@ -9,6 +9,7 @@ using Microsoft.Data.Common; using Microsoft.Data.SqlClient.Connection; using Microsoft.Data.SqlClient.Internal; +using Microsoft.Data.SqlClient.Parser; namespace Microsoft.Data.SqlClient { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.DataTypes.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.DataTypes.cs index 55b3363261..a6d8675366 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.DataTypes.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.DataTypes.cs @@ -6,6 +6,7 @@ using System.Data.Common; using System.Diagnostics; using Microsoft.Data.Common; +using Microsoft.Data.SqlClient.Parser; #nullable enable 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 b0fc3fd911..e8ade71ea6 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlParameter.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlParameter.cs @@ -18,6 +18,8 @@ using System.Threading; using System.Xml; using Microsoft.Data.Common; +using Microsoft.Data.SqlClient.Parser; +using Microsoft.Data.SqlClient.Parser.Tokens; using Microsoft.Data.SqlClient.Server; using Microsoft.Data.SqlTypes; @@ -375,7 +377,7 @@ private SqlParameter(SqlParameter source) : this() /// /// Indicates if the parameter encryption metadata received by sp_describe_parameter_encryption. - /// For unencrypted parameters, the encryption metadata should still be sent (and will indicate + /// For unencrypted parameters, the encryption metadata should still be sent (and will indicate /// that no encryption is needed). /// internal bool HasReceivedMetadata @@ -610,10 +612,10 @@ public SqlDbType SqlDbType { MetaType metatype = _metaType; // HACK!!! - // We didn't want to expose SmallVarBinary on SqlDbType so we - // stuck it at the end of SqlDbType in v1.0, except that now + // We didn't want to expose SmallVarBinary on SqlDbType so we + // stuck it at the end of SqlDbType in v1.0, except that now // we have new data types after that and it's smack dab in the - // middle of the valid range. To prevent folks from setting + // middle of the valid range. To prevent folks from setting // this invalid value we have to have this code here until we // can take the time to fix it later. if (TdsEnums.SmallVarBinary == value) @@ -887,7 +889,7 @@ public override string SourceColumn set => _sourceColumn = value; } - /// + /// [ResCategory(nameof(Strings.DataCategory_Update))] #if NET [ResDescription(nameof(Strings.SqlParameter_SourceColumnNullMapping))] @@ -1742,7 +1744,7 @@ internal SmiParameterMetaData MetaDataForSmi(out ParameterPeekAheadValue peekAhe long actualLen = GetActualSize(); long maxLen = Size; - // GetActualSize returns bytes length, but smi expects char length for + // GetActualSize returns bytes length, but smi expects char length for // character types, so adjust if (!mt.IsLong) { @@ -2045,7 +2047,7 @@ internal void Validate(int index, bool isCommandProc) GetCoercedValue(); } - if (metaType.SqlDbType == SqlDbTypeExtensions.Vector && + if (metaType.SqlDbType == SqlDbTypeExtensions.Vector && (_value == null || _value == DBNull.Value) && (Direction == ParameterDirection.Output || Direction == ParameterDirection.InputOutput)) { @@ -2106,15 +2108,15 @@ internal MetaType ValidateTypeLengths() // Bug: VSTFDevDiv #636867 // Notes: - // 'actualSizeInBytes' is the size of value passed; + // 'actualSizeInBytes' is the size of value passed; // 'sizeInCharacters' is the parameter size; - // 'actualSizeInBytes' is in bytes; - // 'this.Size' is in charaters; - // 'sizeInCharacters' is in characters; + // 'actualSizeInBytes' is in bytes; + // 'this.Size' is in charaters; + // 'sizeInCharacters' is in characters; // 'TdsEnums.TYPE_SIZE_LIMIT' is in bytes; // For Non-NCharType and for non-2005 or greater variables, size should be maintained; // Reverting changes from bug VSTFDevDiv # 479739 as it caused an regression; - // Modifed variable names from 'size' to 'sizeInCharacters', 'actualSize' to 'actualSizeInBytes', and + // Modifed variable names from 'size' to 'sizeInCharacters', 'actualSize' to 'actualSizeInBytes', and // 'maxSize' to 'maxSizeInBytes' // The idea is to // 1) revert the regression from bug 479739 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 79ebc60d27..4041f8b31c 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlSecurityUtility.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlSecurityUtility.cs @@ -10,6 +10,7 @@ using System.Text; using Microsoft.Data.Common; using Microsoft.Data.SqlClient.AlwaysEncrypted; +using Microsoft.Data.SqlClient.Parser; namespace Microsoft.Data.SqlClient { diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlTransaction.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlTransaction.cs index 5e654659a1..3ecaafda81 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlTransaction.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlTransaction.cs @@ -12,6 +12,7 @@ using Microsoft.Data.SqlClient.Connection; using Microsoft.Data.SqlClient.Diagnostics; using Microsoft.Data.SqlClient.Internal; +using Microsoft.Data.SqlClient.Parser; #if NETFRAMEWORK using System.Runtime.CompilerServices; #endif @@ -106,7 +107,7 @@ public override void Commit() ObjectId, ActivityCorrelator.Current, Connection?.ClientConnectionId); - + try { statistics = SqlStatistics.StartTimer(Statistics); @@ -187,7 +188,7 @@ public override void Rollback() ObjectId, ActivityCorrelator.Current, Connection?.ClientConnectionId); - + try { 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 c9388a42f1..7143e75e29 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlUtil.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlUtil.cs @@ -17,6 +17,7 @@ using Interop.Common.Sni; using Microsoft.Data.Common; using Microsoft.Data.SqlClient.Connection; +using Microsoft.Data.SqlClient.Parser; #if NET using System.Net.Sockets; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs deleted file mode 100644 index 2590c28690..0000000000 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs +++ /dev/null @@ -1,856 +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; -using Microsoft.Data.Common.ConnectionString; - -namespace Microsoft.Data.SqlClient -{ - /// Class of variables for the Tds connection. - /// - internal static class TdsEnums - { - // internal tdsparser constants - public static readonly decimal SQL_SMALL_MONEY_MIN = new(-214748.3648); - public static readonly decimal SQL_SMALL_MONEY_MAX = new(214748.3647); - -#if NETFRAMEWORK - // sql debugging constants, sdci is the structure passed in - public const string SDCI_MAPFILENAME = "SqlClientSSDebug"; - public const byte SDCI_MAX_MACHINENAME = 32; - public const byte SDCI_MAX_DLLNAME = 16; - public const byte SDCI_MAX_DATA = 255; - public const int SQLDEBUG_OFF = 0; - public const int SQLDEBUG_ON = 1; - public const int SQLDEBUG_CONTEXT = 2; - public const string SP_SDIDEBUG = "sp_sdidebug"; - public static readonly string[] SQLDEBUG_MODE_NAMES = new string[3] { - "off", - "on", - "context" - }; -#endif - - // HACK!!! - // Constant for SqlDbType.SmallVarBinary... store internal variable here instead of on - // SqlDbType so that it is not surfaced to the user!!! Related to dtc and the fact that - // the TransactionManager TDS stream is the only token left that uses VarBinarys instead of - // BigVarBinarys. - public const SqlDbType SmallVarBinary = (SqlDbType)(SqlDbType.Variant) + 1; - - // network protocol string constants - public const string TCP = "tcp"; - public const string NP = "np"; - public const string RPC = "rpc"; - public const string BV = "bv"; - public const string ADSP = "adsp"; - public const string SPX = "spx"; - public const string VIA = "via"; - public const string LPC = "lpc"; - public const string ADMIN = "admin"; - - // network function string constants - public const string INIT_SSPI_PACKAGE = "InitSSPIPackage"; - public const string INIT_SESSION = "InitSession"; - public const string CONNECTION_GET_SVR_USER = "ConnectionGetSvrUser"; - public const string GEN_CLIENT_CONTEXT = "GenClientContext"; - - // tdsparser packet handling constants - public const byte SOFTFLUSH = 0; - public const byte HARDFLUSH = 1; - public const byte IGNORE = 2; - - // header constants - public const int HEADER_LEN = 8; - public const int HEADER_LEN_FIELD_OFFSET = 2; - public const int SPID_OFFSET = 4; - public const int SQL2005_HEADER_LEN = 12; //2005 headers also include a MARS session id - public const int MARS_ID_OFFSET = 8; - public const int HEADERTYPE_QNOTIFICATION = 1; - public const int HEADERTYPE_MARS = 2; - public const int HEADERTYPE_TRACE = 3; - - // other various constants - public const int SUCCEED = 1; - public const int FAIL = 0; - public const short TYPE_SIZE_LIMIT = 8000; - public const int MIN_PACKET_SIZE = 512; - // Login packet can be no greater than 4k until server sends us env-change - // increasing packet size. - public const int DEFAULT_LOGIN_PACKET_SIZE = 4096; - public const int MAX_PRELOGIN_PAYLOAD_LENGTH = 1024; - public const int MAX_PACKET_SIZE = 32768; - public const int MAX_SERVER_USER_NAME = 256; // obtained from luxor - - // Maximum allowed data length for token payloads (feature ext ack, - // session state, fedauth info). Prevents a malicious server from causing - // unbounded memory allocation via spoofed token length fields. - internal const int MaxTokenDataLength = 1 << 20; // 1 MB - - // Maximum allowed data length for a DTC promote transaction propagation token. - internal const int MaxPromoteTransactionLength = 1 << 16; // 64 KB - - // Maximum valid wire size for datetime types (DateTimeOffset = 5 time + 3 date + 2 offset). - internal const int MaxDateTimeLength = 10; - - // Severity 0 - 10 indicates informational (non-error) messages - // Severity 11 - 16 indicates errors that can be corrected by user (syntax errors, etc...) - // Severity 17 - 19 indicates failure due to insufficient resources in the server - // (max locks exceeded, not enough memory, other internal server limits reached, etc..) - // Severity 20 - 25 Severe problems with the server, connection terminated. - public const byte MIN_ERROR_CLASS = 11; // webdata 100667: This should actually be 11 - public const byte MAX_USER_CORRECTABLE_ERROR_CLASS = 16; - public const byte FATAL_ERROR_CLASS = 20; - - // Message types - public const byte MT_SQL = 1; // SQL command batch - public const byte MT_LOGIN = 2; // Login message for pre-7.0 - public const byte MT_RPC = 3; // Remote procedure call - public const byte MT_TOKENS = 4; // Table response data stream - public const byte MT_BINARY = 5; // Unformatted binary response data (UNUSED) - public const byte MT_ATTN = 6; // Attention (break) signal - public const byte MT_BULK = 7; // Bulk load data - public const byte MT_FEDAUTH = 8; // Authentication token for federated authentication - public const byte MT_CLOSE = 9; // Close subchannel (UNUSED) - public const byte MT_ERROR = 10; // Protocol error detected - public const byte MT_ACK = 11; // Protocol acknowledgement (UNUSED) - public const byte MT_ECHO = 12; // Echo data (UNUSED) - public const byte MT_LOGOUT = 13; // Logout message (UNUSED) - public const byte MT_TRANS = 14; // Transaction Manager Interface - public const byte MT_OLEDB = 15; // ? (UNUSED) - public const byte MT_LOGIN7 = 16; // Login message for 7.0 or later - public const byte MT_SSPI = 17; // SSPI message - public const byte MT_PRELOGIN = 18; // Pre-login handshake - - // Message status bits - public const byte ST_EOM = 0x1; // Packet is end-of-message - public const byte ST_AACK = 0x2; // Packet acknowledges attention (server to client) - public const byte ST_IGNORE = 0x2; // Ignore this event (client to server) - public const byte ST_BATCH = 0x4; // Message is part of a batch. - public const byte ST_RESET_CONNECTION = 0x8; // Exec sp_reset_connection prior to processing message - public const byte ST_RESET_CONNECTION_PRESERVE_TRANSACTION = 0x10; // reset prior to processing, with preserving local tx - - // TDS control tokens - public const byte SQLCOLFMT = 0xa1; - public const byte SQLPROCID = 0x7c; - public const byte SQLCOLNAME = 0xa0; - public const byte SQLTABNAME = 0xa4; - public const byte SQLCOLINFO = 0xa5; - public const byte SQLALTNAME = 0xa7; - public const byte SQLALTFMT = 0xa8; - public const byte SQLERROR = 0xaa; - public const byte SQLINFO = 0xab; - public const byte SQLRETURNVALUE = 0xac; - public const byte SQLRETURNSTATUS = 0x79; - public const byte SQLRETURNTOK = 0xdb; - public const byte SQLALTCONTROL = 0xaf; - public const byte SQLROW = 0xd1; - public const byte SQLNBCROW = 0xd2; // same as ROW with null-bit-compression support - /// - /// Deprecated in TDS7.4 (2010) - /// - public const byte SQLALTROW = 0xd3; - public const byte SQLDONE = 0xfd; - public const byte SQLDONEPROC = 0xfe; - public const byte SQLDONEINPROC = 0xff; - public const byte SQLOFFSET = 0x78; - public const byte SQLORDER = 0xa9; - public const byte SQLDEBUG_CMD = 0x60; - public const byte SQLLOGINACK = 0xad; - public const byte SQLFEATUREEXTACK = 0xae; // TDS 7.4 - feature ack - public const byte SQLSESSIONSTATE = 0xe4; // TDS 7.4 - connection resiliency session state - public const byte SQLENVCHANGE = 0xe3; // Environment change notification - public const byte SQLSECLEVEL = 0xed; // Security level token ??? - public const byte SQLROWCRC = 0x39; // ROWCRC datastream??? - public const byte SQLCOLMETADATA = 0x81; // Column metadata including name - /// - /// Deprecated in TDS7.4 (2010) - /// - public const byte SQLALTMETADATA = 0x88; // Alt column metadata including name - public const byte SQLSSPI = 0xed; // SSPI data - public const byte SQLFEDAUTHINFO = 0xee; // Info for client to generate fed auth token - public const byte SQLRESCOLSRCS = 0xa2; - public const byte SQLDATACLASSIFICATION = 0xa3; - - // Environment change notification streams - // TYPE on TDS ENVCHANGE token stream (from sql\ntdbms\include\odsapi.h) - // - public const byte ENV_DATABASE = 1; // Database changed - public const byte ENV_LANG = 2; // Language changed - public const byte ENV_CHARSET = 3; // Character set changed - public const byte ENV_PACKETSIZE = 4; // Packet size changed - public const byte ENV_LOCALEID = 5; // Unicode data sorting locale id - public const byte ENV_COMPFLAGS = 6; // Unicode data sorting comparison flags - public const byte ENV_COLLATION = 7; // SQL Collation - // The following are environment change tokens valid for 2005 or later. - public const byte ENV_BEGINTRAN = 8; // Transaction began - public const byte ENV_COMMITTRAN = 9; // Transaction committed - public const byte ENV_ROLLBACKTRAN = 10; // Transaction rolled back - public const byte ENV_ENLISTDTC = 11; // Enlisted in Distributed Transaction - public const byte ENV_DEFECTDTC = 12; // Defected from Distributed Transaction - public const byte ENV_LOGSHIPNODE = 13; // Realtime Log shipping primary node - public const byte ENV_PROMOTETRANSACTION = 15; // Promote Transaction - public const byte ENV_TRANSACTIONMANAGERADDRESS = 16; // Transaction Manager Address - public const byte ENV_TRANSACTIONENDED = 17; // Transaction Ended - public const byte ENV_SPRESETCONNECTIONACK = 18; // SP_Reset_Connection ack - public const byte ENV_USERINSTANCE = 19; // User Instance - public const byte ENV_ROUTING = 20; // Routing (ROR) information - public const byte ENV_ENHANCEDROUTING = 21; // Enhanced Routing (ROR) information - - // done status stream bit masks - public const int DONE_MORE = 0x0001; // more command results coming - public const int DONE_ERROR = 0x0002; // error in command batch - public const int DONE_INXACT = 0x0004; // transaction in progress - public const int DONE_PROC = 0x0008; // done from stored proc - public const int DONE_COUNT = 0x0010; // count in done info - public const int DONE_ATTN = 0x0020; // oob ack - public const int DONE_INPROC = 0x0040; // like DONE_PROC except proc had error - public const int DONE_RPCINBATCH = 0x0080; // Done from RPC in batch - public const int DONE_SRVERROR = 0x0100; // Severe error in which resultset should be discarded - public const int DONE_FMTSENT = 0x8000; // fmt message sent, done_inproc req'd - - // Feature Extension - public const byte FEATUREEXT_TERMINATOR = 0xFF; - public const byte FEATUREEXT_SRECOVERY = 0x01; - public const byte FEATUREEXT_FEDAUTH = 0x02; - // 0x03 is for x_eFeatureExtensionId_Rcs - public const byte FEATUREEXT_TCE = 0x04; - public const byte FEATUREEXT_GLOBALTRANSACTIONS = 0x05; - // 0x06 is for x_eFeatureExtensionId_LoginToken - // 0x07 is for x_eFeatureExtensionId_ClientSideTelemetry - public const byte FEATUREEXT_AZURESQLSUPPORT = 0x08; - public const byte FEATUREEXT_DATACLASSIFICATION = 0x09; - public const byte FEATUREEXT_UTF8SUPPORT = 0x0A; - public const byte FEATUREEXT_SQLDNSCACHING = 0x0B; - public const byte FEATUREEXT_JSONSUPPORT = 0x0D; - public const byte FEATUREEXT_VECTORSUPPORT = 0x0E; - public const byte FEATUREEXT_ENHANCEDROUTINGSUPPORT = 0x0F; - public const byte FEATUREEXT_USERAGENT = 0x10; - - [Flags] - public enum FeatureExtension : uint - { - None = 0, - SessionRecovery = 1 << (TdsEnums.FEATUREEXT_SRECOVERY - 1), - FedAuth = 1 << (TdsEnums.FEATUREEXT_FEDAUTH - 1), - Tce = 1 << (TdsEnums.FEATUREEXT_TCE - 1), - GlobalTransactions = 1 << (TdsEnums.FEATUREEXT_GLOBALTRANSACTIONS - 1), - AzureSQLSupport = 1 << (TdsEnums.FEATUREEXT_AZURESQLSUPPORT - 1), - DataClassification = 1 << (TdsEnums.FEATUREEXT_DATACLASSIFICATION - 1), - UTF8Support = 1 << (TdsEnums.FEATUREEXT_UTF8SUPPORT - 1), - SQLDNSCaching = 1 << (TdsEnums.FEATUREEXT_SQLDNSCACHING - 1), - JsonSupport = 1 << (TdsEnums.FEATUREEXT_JSONSUPPORT - 1), - VectorSupport = 1 << (TdsEnums.FEATUREEXT_VECTORSUPPORT - 1), - EnhancedRoutingSupport = 1 << (TdsEnums.FEATUREEXT_ENHANCEDROUTINGSUPPORT - 1), - UserAgent = 1 << (TdsEnums.FEATUREEXT_USERAGENT - 1) - } - - public const uint UTF8_IN_TDSCOLLATION = 0x4000000; - - public const byte FEDAUTHLIB_LIVEID = 0X00; - public const byte FEDAUTHLIB_SECURITYTOKEN = 0x01; - public const byte FEDAUTHLIB_MSAL = 0x02; - public const byte FEDAUTHLIB_RESERVED = 0X7F; - - public enum FedAuthLibrary : byte - { - LiveId = FEDAUTHLIB_LIVEID, - SecurityToken = FEDAUTHLIB_SECURITYTOKEN, - MSAL = FEDAUTHLIB_MSAL, - Default = FEDAUTHLIB_RESERVED - } - - public const byte MSALWORKFLOW_ACTIVEDIRECTORYPASSWORD = 0x01; - public const byte MSALWORKFLOW_ACTIVEDIRECTORYINTEGRATED = 0x02; - public const byte MSALWORKFLOW_ACTIVEDIRECTORYINTERACTIVE = 0x03; - public const byte MSALWORKFLOW_ACTIVEDIRECTORYSERVICEPRINCIPAL = 0x01; // Using the Password byte as that is the closest we have - public const byte MSALWORKFLOW_ACTIVEDIRECTORYDEVICECODEFLOW = 0x03; // Using the Interactive byte as that is the closest we have - public const byte MSALWORKFLOW_ACTIVEDIRECTORYMANAGEDIDENTITY = 0x03; // Using the Interactive byte as that's supported for Identity based authentication - public const byte MSALWORKFLOW_ACTIVEDIRECTORYDEFAULT = 0x03; // Using the Interactive byte as that is the closest we have to non-password based authentication modes - public const byte MSALWORKFLOW_ACTIVEDIRECTORYTOKENCREDENTIAL = 0x03; // Using the Interactive byte as that is the closest we have to non-password based authentication modes - public const byte MSALWORKFLOW_ACTIVEDIRECTORYWORKLOADIDENTITY = 0x03; // Using the Interactive byte as that's supported for Identity based authentication - - public enum ActiveDirectoryWorkflow : byte - { - Password = MSALWORKFLOW_ACTIVEDIRECTORYPASSWORD, - Integrated = MSALWORKFLOW_ACTIVEDIRECTORYINTEGRATED, - Interactive = MSALWORKFLOW_ACTIVEDIRECTORYINTERACTIVE, - ServicePrincipal = MSALWORKFLOW_ACTIVEDIRECTORYSERVICEPRINCIPAL, - DeviceCodeFlow = MSALWORKFLOW_ACTIVEDIRECTORYDEVICECODEFLOW, - ManagedIdentity = MSALWORKFLOW_ACTIVEDIRECTORYMANAGEDIDENTITY, - Default = MSALWORKFLOW_ACTIVEDIRECTORYDEFAULT, - WorkloadIdentity = MSALWORKFLOW_ACTIVEDIRECTORYWORKLOADIDENTITY, - } - - // The string used for username in the error message when Authentication = Active Directory Integrated with FedAuth is used, if authentication fails. - public const string NTAUTHORITYANONYMOUSLOGON = @"NT Authority\Anonymous Logon"; - - // Loginrec defines - public const byte MAX_LOG_NAME = 30; // TDS 4.2 login rec max name length - public const byte MAX_PROG_NAME = 10; // max length of loginrec program name - public const byte SEC_COMP_LEN = 8; // length of security compartments - public const byte MAX_PK_LEN = 6; // max length of TDS packet size - public const byte MAX_NIC_SIZE = 6; // The size of a MAC or client address - public const byte SQLVARIANT_SIZE = 2; // size of the fixed portion of a sql variant (type, cbPropBytes) - public const byte VERSION_SIZE = 4; // size of the tds version (4 unsigned bytes) - public const int CLIENT_PROG_VER = 0x06000000; // Client interface version - public const int SQL2005_LOG_REC_FIXED_LEN = 0x5e; - // misc - public const int TEXT_TIME_STAMP_LEN = 8; - public const int COLLATION_INFO_LEN = 4; - - // Versions to be used on login for SQL Server 2005, SQL Server 2008 R2, TDS 7.x and TDS 8.0 - public const uint SQL2005_VERSION = 0x72_09_0002; - public const uint SQL2008_VERSION = 0x73_0B_0003; - public const uint TDS7X_VERSION = 0x74_00_0004; - public const uint TDS80_VERSION = 0x08_00_0000; - public const string TDS8_Protocol = "tds/8.0"; //TDS8 - - public const int ORDER_68000 = 1; - public const int USE_DB_ON = 1; - public const int INIT_DB_FATAL = 1; - public const int SET_LANG_ON = 1; - public const int INIT_LANG_FATAL = 1; - public const int ODBC_ON = 1; - public const int SSPI_ON = 1; - public const int REPL_ON = 3; - - - // send the read-only intent to the server - public const int READONLY_INTENT_ON = 1; - - // Token masks - public const byte SQLLenMask = 0x30; // mask to check for length tokens - public const byte SQLFixedLen = 0x30; // Mask to check for fixed token - public const byte SQLVarLen = 0x20; // Value to check for variable length token - public const byte SQLZeroLen = 0x10; // Value to check for zero length token - public const byte SQLVarCnt = 0x00; // Value to check for variable count token - - // Token masks for COLINFO status - public const byte SQLDifferentName = 0x20; // column name different than select list name - public const byte SQLExpression = 0x4; // column was result of an expression - public const byte SQLKey = 0x8; // column is part of the key for the table - public const byte SQLHidden = 0x10; // column not part of select list but added because part of key - - // Token masks for COLMETADATA flags - // first byte - public const byte Nullable = 0x1; - public const byte Identity = 0x10; - public const byte Updatability = 0xb; // mask off bits 3 and 4 - // second byte - public const byte ClrFixedLen = 0x1; // Fixed length CLR type - public const byte IsColumnSet = 0x4; // Column is an XML representation of an aggregation of other columns - public const byte IsEncrypted = 0x8; // Column is encrypted using TCE - - // null values - public const uint VARLONGNULL = 0xffffffff; // null value for text and image types - public const int VARNULL = 0xffff; // null value for character and binary types - public const int MAXSIZE = 8000; // max size for any column - public const byte FIXEDNULL = 0; - public const ulong UDTNULL = 0xffffffffffffffff; - - // SQL Server Data Type Tokens. - public const int SQLVOID = 0x1f; - public const int SQLTEXT = 0x23; - public const int SQLVARBINARY = 0x25; - public const int SQLINTN = 0x26; - public const int SQLVARCHAR = 0x27; - public const int SQLBINARY = 0x2d; - public const int SQLIMAGE = 0x22; - public const int SQLCHAR = 0x2f; - public const int SQLINT1 = 0x30; - public const int SQLBIT = 0x32; - public const int SQLINT2 = 0x34; - public const int SQLINT4 = 0x38; - public const int SQLMONEY = 0x3c; - public const int SQLDATETIME = 0x3d; - public const int SQLFLT8 = 0x3e; - public const int SQLFLTN = 0x6d; - public const int SQLMONEYN = 0x6e; - public const int SQLDATETIMN = 0x6f; - public const int SQLFLT4 = 0x3b; - public const int SQLMONEY4 = 0x7a; - public const int SQLDATETIM4 = 0x3a; - public const int SQLDECIMALN = 0x6a; - public const int SQLNUMERICN = 0x6c; - public const int SQLUNIQUEID = 0x24; - public const int SQLBIGCHAR = 0xaf; - public const int SQLBIGVARCHAR = 0xa7; - public const int SQLBIGBINARY = 0xad; - public const int SQLBIGVARBINARY = 0xa5; - public const int SQLBITN = 0x68; - public const int SQLNCHAR = 0xef; - public const int SQLNVARCHAR = 0xe7; - public const int SQLNTEXT = 0x63; - public const int SQLUDT = 0xF0; - - // aggregate operator type TDS tokens, used by compute statements: - public const int AOPCNTB = 0x09; - public const int AOPSTDEV = 0x30; - public const int AOPSTDEVP = 0x31; - public const int AOPVAR = 0x32; - public const int AOPVARP = 0x33; - - public const int AOPCNT = 0x4b; - public const int AOPSUM = 0x4d; - public const int AOPAVG = 0x4f; - public const int AOPMIN = 0x51; - public const int AOPMAX = 0x52; - public const int AOPANY = 0x53; - public const int AOPNOOP = 0x56; - - // SQL Server user-defined type tokens we care about - public const int SQLTIMESTAMP = 0x50; - - public const int MAX_NUMERIC_LEN = 0x11; // 17 bytes of data for max numeric/decimal length - public const int DEFAULT_NUMERIC_PRECISION = 0x1D; // 29 is the default max numeric precision(Decimal.MaxValue) if not user set - public const int SQL70_DEFAULT_NUMERIC_PRECISION = 0x1C; // 28 is the default max numeric precision for 7.0 (Decimal.MaxValue doesn't work for 7.0) - public const int MAX_NUMERIC_PRECISION = 0x26; // 38 is max numeric precision; - public const byte UNKNOWN_PRECISION_SCALE = 0xff; // -1 is value for unknown precision or scale - - // The following datatypes are specific to 2005 (version 9) or later - public const int SQLINT8 = 0x7f; - public const int SQLVARIANT = 0x62; - public const int SQLXMLTYPE = 0xf1; - public const int XMLUNICODEBOM = 0xfeff; - public static readonly byte[] XMLUNICODEBOMBYTES = { 0xff, 0xfe }; - - // The following datatypes are specific to 2008 (version 10) or later - public const int SQLTABLE = 0xf3; - public const int SQLDATE = 0x28; - public const int SQLTIME = 0x29; - public const int SQLDATETIME2 = 0x2a; - public const int SQLDATETIMEOFFSET = 0x2b; - - public const int SQLJSON = 0xF4; - public const int SQLVECTOR = 0xF5; - - public const int DEFAULT_VARTIME_SCALE = 7; - - //Partially length prefixed datatypes constants. These apply to XMLTYPE, BIGVARCHRTYPE, - // NVARCHARTYPE, and BIGVARBINTYPE. Valid for 2005 or later - - public const ulong SQL_PLP_NULL = 0xffffffffffffffff; // Represents null value - public const ulong SQL_PLP_UNKNOWNLEN = 0xfffffffffffffffe; // Data coming in chunks, total length unknown - public const int SQL_PLP_CHUNK_TERMINATOR = 0x00000000; // Represents end of chunked data. - public const ushort SQL_USHORTVARMAXLEN = 0xffff; // Second ushort in TDS stream is this value if one of max types - - // TVPs require some new in-value control tokens: - public const byte TVP_ROWCOUNT_ESTIMATE = 0x12; - public const byte TVP_ROW_TOKEN = 0x01; - public const byte TVP_END_TOKEN = 0x00; - public const ushort TVP_NOMETADATA_TOKEN = 0xFFFF; - public const byte TVP_ORDER_UNIQUE_TOKEN = 0x10; - - // TvpColumnMetaData flags - public const int TVP_DEFAULT_COLUMN = 0x200; - - // TVP_ORDER_UNIQUE_TOKEN flags - public const byte TVP_ORDERASC_FLAG = 0x1; - public const byte TVP_ORDERDESC_FLAG = 0x2; - public const byte TVP_UNIQUE_FLAG = 0x4; - -#if NETFRAMEWORK - public const bool Is68K = false; - public const bool TraceTDS = false; -#endif - - // RPC function names - public const string SP_EXECUTESQL = "sp_executesql"; // used against 7.0 servers - public const string SP_PREPEXEC = "sp_prepexec"; // used against 7.5 servers - - public const string SP_PREPARE = "sp_prepare"; // used against 7.0 servers - public const string SP_EXECUTE = "sp_execute"; - public const string SP_UNPREPARE = "sp_unprepare"; - public const string SP_PARAMS = "sp_procedure_params_rowset"; - public const string SP_PARAMS_MANAGED = "sp_procedure_params_managed"; - public const string SP_PARAMS_MGD10 = "sp_procedure_params_100_managed"; - - // RPC ProcID's - // NOTE: It is more efficient to call these procs using ProcID's instead of names - public const ushort RPC_PROCID_CURSOR = 1; - public const ushort RPC_PROCID_CURSOROPEN = 2; - public const ushort RPC_PROCID_CURSORPREPARE = 3; - public const ushort RPC_PROCID_CURSOREXECUTE = 4; - public const ushort RPC_PROCID_CURSORPREPEXEC = 5; - public const ushort RPC_PROCID_CURSORUNPREPARE = 6; - public const ushort RPC_PROCID_CURSORFETCH = 7; - public const ushort RPC_PROCID_CURSOROPTION = 8; - public const ushort RPC_PROCID_CURSORCLOSE = 9; - public const ushort RPC_PROCID_EXECUTESQL = 10; - public const ushort RPC_PROCID_PREPARE = 11; - public const ushort RPC_PROCID_EXECUTE = 12; - public const ushort RPC_PROCID_PREPEXEC = 13; - public const ushort RPC_PROCID_PREPEXECRPC = 14; - public const ushort RPC_PROCID_UNPREPARE = 15; - - // Batch RPC flag - public const byte SQL2005_RPCBATCHFLAG = 0xFF; - - // RPC flags - public const byte RPC_RECOMPILE = 0x1; - public const byte RPC_NOMETADATA = 0x2; - - // RPC parameter class - public const byte RPC_PARAM_BYREF = 0x1; - public const byte RPC_PARAM_DEFAULT = 0x2; - public const byte RPC_PARAM_ENCRYPTED = 0x8; - - // SQL parameter list text - public const string PARAM_OUTPUT = "output"; - - // SQL Parameter constants - public const int MAX_PARAMETER_NAME_LENGTH = 128; - - // metadata options (added around an existing sql statement) - - // prefixes - public const string FMTONLY_ON = " SET FMTONLY ON;"; - public const string FMTONLY_OFF = " SET FMTONLY OFF;"; - // suffixes - public const string BROWSE_ON = " SET NO_BROWSETABLE ON;"; - public const string BROWSE_OFF = " SET NO_BROWSETABLE OFF;"; - - // generic table name - public const string TABLE = "Table"; - - public const int EXEC_THRESHOLD = 0x3; // if the number of commands we execute is > than this threshold, than do prep/exec/unprep instead - // of executesql. - - // dbnetlib error values - public const short TIMEOUT_EXPIRED = -2; - public const short ENCRYPTION_NOT_SUPPORTED = 20; - public const short CTAIP_NOT_SUPPORTED = 21; - - // CAUTION: These are not error codes returned by SNI. This is used for backward compatibility - // since netlib (now removed from sqlclient) returned these codes. - - // SQL error values (from sqlerrorcodes.h) - public const int LOGON_FAILED = 18456; - public const int PASSWORD_EXPIRED = 18488; - public const int IMPERSONATION_FAILED = 1346; - public const int P_TOKENTOOLONG = 103; - - // SQL error that indicates retry for Always Encrypted - public const int TCE_CONVERSION_ERROR_CLIENT_RETRY = 33514; - public const int TCE_ENCLAVE_INVALID_SESSION_HANDLE = 33195; - - // SNI\Win32 error values - // NOTE: these are simply windows system error codes, not SNI specific - public const uint SNI_UNINITIALIZED = unchecked((uint)-1); - public const uint SNI_SUCCESS = 0; // The operation completed successfully. - public const uint SNI_ERROR = 1; // Error - public const int SNI_WAIT_TIMEOUT = 258; // The wait operation timed out. - public const uint SNI_SUCCESS_IO_PENDING = 997; // Overlapped I/O operation is in progress. - - // Windows Sockets Error Codes - public const short SNI_WSAECONNRESET = 10054; // An existing connection was forcibly closed by the remote host. - - // SNI internal errors (shouldn't overlap with Win32 / socket errors) - public const uint SNI_QUEUE_FULL = 1048576; // Packet queue is full - - // SNI flags - public const uint SNI_SSL_VALIDATE_CERTIFICATE = 1; // This enables validation of server certificate - public const uint SNI_SSL_USE_SCHANNEL_CACHE = 2; // This enables schannel session cache - public const uint SNI_SSL_IGNORE_CHANNEL_BINDINGS = 0x10; // Used with SSL Provider, sent to SNIAddProvider in case of SQL Authentication & Encrypt. - public const uint SNI_SSL_SEND_ALPN_EXTENSION = 0x4000; // This flag instructs SSL provider to send the ALPN extension in the ClientHello message - - public const string DEFAULT_ENGLISH_CODE_PAGE_STRING = "iso_1"; - public const short DEFAULT_ENGLISH_CODE_PAGE_VALUE = 1252; - public const short CHARSET_CODE_PAGE_OFFSET = 2; - internal const int MAX_SERVERNAME = 255; - - // Sql Statement Tokens in the DONE packet - // (see ntdbms\ntinc\tokens.h) - // - internal const ushort SELECT = 0xc1; - internal const ushort INSERT = 0xc3; - internal const ushort DELETE = 0xc4; - internal const ushort UPDATE = 0xc5; - internal const ushort ABORT = 0xd2; - internal const ushort BEGINXACT = 0xd4; - internal const ushort ENDXACT = 0xd5; - internal const ushort BULKINSERT = 0xf0; - internal const ushort OPENCURSOR = 0x20; - internal const ushort MERGE = 0x117; - - - // Login data validation Rules - // - internal const ushort MAXLEN_HOSTNAME = 128; // the client machine name - internal const ushort MAXLEN_CLIENTID = 128; - internal const ushort MAXLEN_CLIENTSECRET = 128; - internal const ushort MAXLEN_APPNAME = 128; // the client application name - internal const ushort MAXLEN_SERVERNAME = 128; // the server name - internal const ushort MAXLEN_CLIENTINTERFACE = 128; // the interface library name - internal const ushort MAXLEN_LANGUAGE = 128; // the initial language - internal const ushort MAXLEN_DATABASE = 128; // the initial database - internal const ushort MAXLEN_ATTACHDBFILE = 260; // the filename for a database that is to be attached during the connection process - internal const ushort MAXLEN_NEWPASSWORD = 128; // new password for the specified login. - -#if NETFRAMEWORK - internal enum UDTFormatType - { - Native = 1, - UserDefined = 2 - } -#endif - - internal enum TransactionManagerRequestType - { - GetDTCAddress = 0, - Propagate = 1, - Begin = 5, - Promote = 6, - Commit = 7, - Rollback = 8, - Save = 9 - }; - - internal enum TransactionManagerIsolationLevel - { - Unspecified = 0x00, - ReadUncommitted = 0x01, - ReadCommitted = 0x02, - RepeatableRead = 0x03, - Serializable = 0x04, - Snapshot = 0x05 - } - - internal enum GenericType - { - MultiSet = 131, - }; - - // Date, Time, DateTime2, DateTimeOffset specific constants - internal static readonly long[] TICKS_FROM_SCALE = { - 10000000, - 1000000, - 100000, - 10000, - 1000, - 100, - 10, - 1, - }; - - internal const int MAX_TIME_SCALE = 7; // Maximum scale for time-related types - internal const int MAX_TIME_LENGTH = 5; // Maximum length for time - internal const int MAX_DATETIME2_LENGTH = 8; // Maximum length for datetime2 - internal const int WHIDBEY_DATE_LENGTH = 10; - internal static readonly int[] WHIDBEY_TIME_LENGTH = { 8, 10, 11, 12, 13, 14, 15, 16 }; - internal static readonly int[] WHIDBEY_DATETIME2_LENGTH = { 19, 21, 22, 23, 24, 25, 26, 27 }; - internal static readonly int[] WHIDBEY_DATETIMEOFFSET_LENGTH = { 26, 28, 29, 30, 31, 32, 33, 34 }; - - internal enum FedAuthInfoId : byte - { - Stsurl = 0x01, // FedAuthInfoData is token endpoint URL from which to acquire fed auth token - Spn = 0x02, // FedAuthInfoData is the SPN to use for acquiring fed auth token - } - - // Data Classification constants - internal const byte DATA_CLASSIFICATION_NOT_ENABLED = 0x00; - internal const byte DATA_CLASSIFICATION_VERSION_WITHOUT_RANK_SUPPORT = 0x01; - internal const byte DATA_CLASSIFICATION_VERSION_MAX_SUPPORTED = 0x02; - - // JSON Support constants - internal const byte MAX_SUPPORTED_JSON_VERSION = 0x01; - - // Vector Support constants - internal const byte MAX_SUPPORTED_VECTOR_VERSION = 0x01; - internal const int VECTOR_HEADER_SIZE = 8; - - // TCE Related constants - internal const byte TCE_NOT_ENABLED = 0x00; - 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 - internal const byte MIN_TCE_VERSION_WITH_ENCLAVE_RETRY_SUPPORT = 0x03; - internal const ushort MAX_TCE_CIPHERINFO_SIZE = 2048; // max size of cipherinfo blob - internal const long MAX_TCE_CIPHERTEXT_SIZE = 2147483648; // max size of encrypted blob- currently 2GB. - internal const byte CustomCipherAlgorithmId = 0; // Id used for custom encryption algorithm. - - internal const int AEAD_AES_256_CBC_HMAC_SHA256 = 2; - internal const string ENCLAVE_TYPE_VBS = "VBS"; - internal const string ENCLAVE_TYPE_SGX = "SGX"; -#if ENCLAVE_SIMULATOR - internal const string ENCLAVE_TYPE_SIMULATOR = "SIMULATOR"; -#endif - - // TCE Param names for exec handling - internal const string TCE_PARAM_CIPHERTEXT = "cipherText"; - internal const string TCE_PARAM_CIPHER_ALGORITHM_ID = "cipherAlgorithmId"; - internal const string TCE_PARAM_COLUMNENCRYPTION_KEY = "columnEncryptionKey"; - internal const string TCE_PARAM_ENCRYPTION_ALGORITHM = "encryptionAlgorithm"; - internal const string TCE_PARAM_ENCRYPTIONTYPE = "encryptionType"; - internal const string TCE_PARAM_ENCRYPTIONKEY = "encryptionKey"; - internal const string TCE_PARAM_MASTERKEY_PATH = "masterKeyPath"; - internal const string TCE_PARAM_ENCRYPTED_CEK = "encryptedColumnEncryptionKey"; - internal const string TCE_PARAM_CLIENT_KEYSTORE_PROVIDERS = "clientKeyStoreProviders"; - internal const string TCE_PARAM_FORCE_COLUMN_ENCRYPTION = "ForceColumnEncryption(true)"; - } - - internal enum SniContext - { - Undefined = 0, - Snix_Connect, - Snix_PreLoginBeforeSuccessfulWrite, - Snix_PreLogin, - Snix_LoginSspi, - Snix_ProcessSspi, - Snix_Login, - Snix_EnableMars, - Snix_AutoEnlist, - Snix_GetMarsSession, - Snix_Execute, - Snix_Read, - Snix_Close, - Snix_SendRows, - } - - internal enum ParsingErrorState - { - Undefined = 0, - FedAuthInfoLengthTooShortForCountOfInfoIds = 1, - FedAuthInfoLengthTooShortForData = 2, - FedAuthInfoFailedToReadCountOfInfoIds = 3, - FedAuthInfoFailedToReadTokenStream = 4, - FedAuthInfoInvalidOffset = 5, - FedAuthInfoFailedToReadData = 6, - FedAuthInfoDataNotUnicode = 7, - FedAuthInfoDoesNotContainStsurlAndSpn = 8, - FedAuthInfoNotReceived = 9, - FedAuthNotAcknowledged = 10, - FedAuthFeatureAckContainsExtraData = 11, - FedAuthFeatureAckUnknownLibraryType = 12, - UnrequestedFeatureAckReceived = 13, - UnknownFeatureAck = 14, - InvalidTdsTokenReceived = 15, - SessionStateLengthTooShort = 16, - SessionStateInvalidStatus = 17, - CorruptedTdsStream = 18, - ProcessSniPacketFailed = 19, - FedAuthRequiredPreLoginResponseInvalidValue = 20, - TceUnknownVersion = 21, - TceInvalidVersion = 22, - TceInvalidOrdinalIntoCipherInfoTable = 23, - DataClassificationInvalidVersion = 24, - DataClassificationNotExpected = 25, - DataClassificationInvalidLabelIndex = 26, - DataClassificationInvalidInformationTypeIndex = 27 - } - - /// - public enum SqlConnectionAttestationProtocol - { - /// - NotSpecified = 0, - - /// - AAS = 1, - - /// - None = 2, - - /// - HGS = 3 - } - - /// - public enum SqlConnectionIPAddressPreference - { - /// - IPv4First = 0, // default - - /// - IPv6First = 1, - - /// - UsePlatformDefault = 2 - } - - /// - public enum SqlConnectionColumnEncryptionSetting - { - /// - Disabled = 0, - - /// - Enabled, - } - - /// - [Flags] - public enum SqlConnectionOverrides - { - /// - None = 0, - /// - OpenWithoutRetry = 1, - } - - /// - public enum SqlCommandColumnEncryptionSetting - { - - /// - UseConnectionSetting = 0, - - /// - Enabled, - - /// - ResultSetOnly, - - /// - Disabled, - } - // This enum indicates the state of TransparentNetworkIPResolution - // The first attempt when TNIR is on should be sequential. If the first attempt fails next attempts should be parallel. - internal enum TransparentNetworkResolutionState - { - DisabledMode = 0, - SequentialMode, - ParallelMode - }; - - // Fields in the first resultset of "sp_describe_parameter_encryption". - // We expect the server to return the fields in the resultset in the same order as mentioned below. - // If the server changes the below order, then transparent parameter encryption will break. - internal enum DescribeParameterEncryptionResultSet1 - { - KeyOrdinal = 0, - DbId, - KeyId, - KeyVersion, - KeyMdVersion, - EncryptedKey, - ProviderName, - KeyPath, - KeyEncryptionAlgorithm, - IsRequestedByEnclave, - KeySignature, - } - - // Fields in the second resultset of "sp_describe_parameter_encryption" - // We expect the server to return the fields in the resultset in the same order as mentioned below. - // If the server changes the below order, then transparent parameter encryption will break. - internal enum DescribeParameterEncryptionResultSet2 - { - ParameterOrdinal = 0, - ParameterName, - ColumnEncryptionAlgorithm, - ColumnEncryptionType, - ColumnEncryptionKeyOrdinal, - NormalizationRuleVersion, - } - - // Fields in the third resultset of "sp_describe_parameter_encryption". - // We expect the server to return the fields in the resultset in the same order as mentioned below. - // If the server changes the below order, then transparent parameter encryption will break. - internal enum DescribeParameterEncryptionResultSet3 - { - AttestationInfo = 0, - } -} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParameterSetter.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParameterSetter.cs deleted file mode 100644 index 9f0bd70c9c..0000000000 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParameterSetter.cs +++ /dev/null @@ -1,58 +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.Diagnostics; -using Microsoft.Data.SqlClient.Server; - -namespace Microsoft.Data.SqlClient -{ - // Simple Getter/Setter for structured parameters to allow using common ValueUtilsSmi code. - // This is a stand-in to having a true SmiRequestExecutor class for TDS. - internal class TdsParameterSetter : SmiTypedGetterSetter - { - #region Private fields - - private TdsRecordBufferSetter _target; - - #endregion - - #region ctor & control - - internal TdsParameterSetter(TdsParserStateObject stateObj, SmiMetaData md) - { - _target = new TdsRecordBufferSetter(stateObj, md); - } - - #endregion - - #region TypedGetterSetter overrides - - /// - /// Are calls to Get methods allowed? - /// - protected override bool CanGet => false; - - /// - /// Are calls to Set methods allowed? - /// - protected override bool CanSet => true; - - // valid for structured types - // This method called for both get and set. - internal override SmiTypedGetterSetter GetTypedGetterSetter(int ordinal) - { - Debug.Assert(0 == ordinal, "TdsParameterSetter only supports 0 for ordinal. Actual = " + ordinal); - return _target; - } - - // Set value to null - // valid for all types - public override void SetDBNull(int ordinal) - { - Debug.Assert(0 == ordinal, "TdsParameterSetter only supports 0 for ordinal. Actual = " + ordinal); - _target.EndElements(); - } - #endregion - } -} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserHelperClasses.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserHelperClasses.cs deleted file mode 100644 index fa59185462..0000000000 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserHelperClasses.cs +++ /dev/null @@ -1,872 +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.Collections.ObjectModel; -using System.Data; -using System.Data.Common; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Security; -using System.Security.Authentication; -using System.Text; -using Microsoft.Data.Common; -using Microsoft.Data.Common.ConnectionString; - -namespace Microsoft.Data.SqlClient -{ - internal enum CallbackType - { - Read = 0, - Write = 1 - } - - internal enum EncryptionOptions - { - OFF, - ON, - NOT_SUP, - REQ, - LOGIN, - OPTIONS_MASK = 0x3f, -#if NETFRAMEWORK - CTAIP = 0x40, - CLIENT_CERT = 0x80, -#endif - } - - internal enum PreLoginHandshakeStatus - { - Successful, - InstanceFailure - } - - internal enum PreLoginOptions - { - VERSION, - ENCRYPT, - INSTANCE, - THREADID, - MARS, - TRACEID, - FEDAUTHREQUIRED, - NUMOPT, - LASTOPT = 255 - } - - internal enum RunBehavior - { - UntilDone = 1, // 0001 binary - ReturnImmediately = 2, // 0010 binary - Clean = 5, // 0101 binary - Clean AND UntilDone - Attention = 13 // 1101 binary - Clean AND UntilDone AND Attention - } - - internal enum TdsParserState - { - Closed, - OpenNotLoggedIn, - OpenLoggedIn, - Broken, - } - - /// - /// Class encapsulating the data to be sent to the server as part of Federated Authentication Feature Extension. - /// - internal class FederatedAuthenticationFeatureExtensionData - { - internal TdsEnums.FedAuthLibrary libraryType; - internal bool fedAuthRequiredPreLoginResponse; - internal SqlAuthenticationMethod authentication; - internal byte[] accessToken; - } - - internal class RoutingInfo - { - internal byte Protocol { get; private set; } - internal ushort Port { get; private set; } - internal string ServerName { get; private set; } - - /// - /// The DatabaseName property is only used when routing via an EnhancedRouting ENVCHANGE token. - /// It is not used when routing via the normal Routing ENVCHANGE token. - /// - internal string DatabaseName { get; private set; } - - internal RoutingInfo(byte protocol, ushort port, string serverName, string databaseName = null) - { - Protocol = protocol; - Port = port; - ServerName = serverName; - DatabaseName = databaseName; - } - } - - internal sealed class SqlLogin - { - internal SqlAuthenticationMethod authentication = SqlAuthenticationMethod.NotSpecified; // Authentication type - internal int timeout; // login timeout - internal bool userInstance = false; // user instance - internal string hostName = ""; // client machine name - internal string userName = ""; // user id - internal string password = ""; // password - internal string applicationName = ""; // application name - internal string serverName = ""; // server name - internal string language = ""; // initial language - internal string database = ""; // initial database - internal string attachDBFilename = ""; // DB filename to be attached - internal bool useReplication = false; // user login for replication - internal string newPassword = ""; // new password for reset password - internal bool useSSPI = false; // use integrated security - internal int packetSize = DbConnectionStringDefaults.PacketSize; // packet size - internal bool readOnlyIntent = false; // read-only intent - internal SqlCredential credential; // user id and password in SecureString - internal SecureString newSecurePassword; - internal RegisteredApplication appId = RegisteredApplication.Unknown; // middleware application identity - } - - #nullable enable - - internal sealed class SqlFedAuthInfo - { - internal SqlFedAuthInfo(string spn, string stsurl) - { - Spn = spn; - StsUrl = stsurl; - } - - internal string Spn { get; } - internal string StsUrl { get; } - - public override string ToString() - { - return $"SPN: {Spn}, STSURL: {StsUrl}"; - } - } - - internal sealed class SqlFedAuthToken - { - internal SqlFedAuthToken( - byte[] accessToken, - long expirationFileTime) - { - AccessToken = accessToken; - DataLen = (uint)AccessToken.Length; - ExpirationFileTime = expirationFileTime; - } - - /// - /// Convert from a SqlAuthenticationToken. - /// - internal SqlFedAuthToken(SqlAuthenticationToken token) - { - AccessToken = Encoding.Unicode.GetBytes(token.AccessToken); - DataLen = (uint)AccessToken.Length; - ExpirationFileTime = token.ExpiresOn.ToFileTime(); - } - - internal byte[] AccessToken { get; } - internal uint DataLen { get; } - internal long ExpirationFileTime { get; } - } - - #nullable disable - - internal sealed class _SqlMetaData : SqlMetaDataPriv - { - [Flags] - private enum _SqlMetadataFlags : int - { - None = 0, - - Updatable = 1 << 0, - UpdateableUnknown = 1 << 1, - IsDifferentName = 1 << 2, - IsKey = 1 << 3, - IsHidden = 1 << 4, - IsExpression = 1 << 5, - IsIdentity = 1 << 6, - IsColumnSet = 1 << 7, - - IsUpdatableMask = (Updatable | UpdateableUnknown) // two bit field (0 is read only, 1 is updatable, 2 is updatability unknown) - } - - internal string column; - internal string baseColumn; - internal MultiPartTableName multiPartTableName; - internal readonly int ordinal; - internal byte tableNum; - internal byte op; // for altrow-columns only - internal ushort operand; // for altrow-columns only - private _SqlMetadataFlags flags; - - internal _SqlMetaData(int ordinal) : base() - { - this.ordinal = ordinal; - } - - private bool HasFlag(_SqlMetadataFlags flag) - { - return (flags & flag) != 0; - } - - internal string serverName - { - get - { - return multiPartTableName.ServerName; - } - } - internal string catalogName - { - get - { - return multiPartTableName.CatalogName; - } - } - internal string schemaName - { - get - { - return multiPartTableName.SchemaName; - } - } - internal string tableName - { - get - { - return multiPartTableName.TableName; - } - } - - public byte Updatability - { - get => (byte)(flags & _SqlMetadataFlags.IsUpdatableMask); - set => flags = (_SqlMetadataFlags)((value & (byte)_SqlMetadataFlags.IsUpdatableMask) | ((int)flags & ~(byte)_SqlMetadataFlags.IsUpdatableMask)); - } - - public bool IsReadOnly - { - get => !HasFlag(_SqlMetadataFlags.IsUpdatableMask); - } - - public bool IsDifferentName - { - get => HasFlag(_SqlMetadataFlags.IsDifferentName); - set => Set(_SqlMetadataFlags.IsDifferentName, value); - } - - public bool IsKey - { - get => HasFlag(_SqlMetadataFlags.IsKey); - set => Set(_SqlMetadataFlags.IsKey, value); - } - - public bool IsHidden - { - get => HasFlag(_SqlMetadataFlags.IsHidden); - set => Set(_SqlMetadataFlags.IsHidden, value); - } - - public bool IsExpression - { - get => HasFlag(_SqlMetadataFlags.IsExpression); - set => Set(_SqlMetadataFlags.IsExpression, value); - } - - public bool IsIdentity - { - get => HasFlag(_SqlMetadataFlags.IsIdentity); - set => Set(_SqlMetadataFlags.IsIdentity, value); - } - - public bool IsColumnSet - { - get => HasFlag(_SqlMetadataFlags.IsColumnSet); - set => Set(_SqlMetadataFlags.IsColumnSet, value); - } - - private void Set(_SqlMetadataFlags flag, bool value) - { - flags = value ? flags | flag : flags & ~flag; - } - - internal bool Is2008DateTimeType - { - get - { - return SqlDbType.Date == type || SqlDbType.Time == type || SqlDbType.DateTime2 == type || SqlDbType.DateTimeOffset == type; - } - } - - internal bool IsLargeUdt - { - get - { - return type == SqlDbType.Udt && length == int.MaxValue; - } - } - - public object Clone() - { - _SqlMetaData result = new _SqlMetaData(ordinal); - result.CopyFrom(this); - result.column = column; - result.baseColumn = baseColumn; - result.multiPartTableName = multiPartTableName; - result.tableNum = tableNum; - result.flags = flags; - result.op = op; - result.operand = operand; - return result; - } - } - - internal sealed partial class _SqlMetaDataSet - { - internal ushort id; // for altrow-columns only - - internal DataTable schemaTable; - private readonly _SqlMetaData[] _metaDataArray; - internal ReadOnlyCollection dbColumnSchema; - - private int _hiddenColumnCount; - private int[] _visibleColumnMap; - - internal _SqlMetaDataSet(int count) - { - _hiddenColumnCount = -1; - _metaDataArray = new _SqlMetaData[count]; - for (int i = 0; i < _metaDataArray.Length; ++i) - { - _metaDataArray[i] = new _SqlMetaData(i); - } - } - - private _SqlMetaDataSet(_SqlMetaDataSet original) - { - id = original.id; - _hiddenColumnCount = original._hiddenColumnCount; - _visibleColumnMap = original._visibleColumnMap; - dbColumnSchema = original.dbColumnSchema; - schemaTable = original.schemaTable; - cekTable = original.cekTable; - - if (original._metaDataArray == null) - { - _metaDataArray = null; - } - else - { - _metaDataArray = new _SqlMetaData[original._metaDataArray.Length]; - for (int idx = 0; idx < _metaDataArray.Length; idx++) - { - _metaDataArray[idx] = (_SqlMetaData)original._metaDataArray[idx].Clone(); - } - } - } - - internal int Length - { - get - { - return _metaDataArray.Length; - } - } - - internal int VisibleColumnCount - { - get - { - if (_hiddenColumnCount == -1) - { - SetupHiddenColumns(); - } - return Length - _hiddenColumnCount; - } - } - - internal _SqlMetaData this[int index] - { - get - { - return _metaDataArray[index]; - } - set - { - Debug.Assert(value == null, "used only by SqlBulkCopy"); - _metaDataArray[index] = value; - } - } - - public int GetVisibleColumnIndex(int index) - { - if (_hiddenColumnCount == -1) - { - SetupHiddenColumns(); - } - if (_visibleColumnMap is null) - { - return index; - } - else - { - return _visibleColumnMap[index]; - } - } - - public _SqlMetaDataSet Clone() - { - return new _SqlMetaDataSet(this); - } - - private void SetupHiddenColumns() - { - int hiddenColumnCount = 0; - for (int index = 0; index < Length; index++) - { - if (_metaDataArray[index].IsHidden) - { - hiddenColumnCount += 1; - } - } - - if (hiddenColumnCount > 0) - { - int[] visibleColumnMap = new int[Length - hiddenColumnCount]; - int mapIndex = 0; - for (int metaDataIndex = 0; metaDataIndex < Length; metaDataIndex++) - { - if (!_metaDataArray[metaDataIndex].IsHidden) - { - visibleColumnMap[mapIndex] = metaDataIndex; - mapIndex += 1; - } - } - _visibleColumnMap = visibleColumnMap; - } - _hiddenColumnCount = hiddenColumnCount; - } - } - - internal sealed class _SqlMetaDataSetCollection - { - private readonly List<_SqlMetaDataSet> _altMetaDataSetArray; - internal _SqlMetaDataSet metaDataSet; - - internal _SqlMetaDataSetCollection() - { - _altMetaDataSetArray = new List<_SqlMetaDataSet>(); - } - - internal void SetAltMetaData(_SqlMetaDataSet altMetaDataSet) - { - // If altmetadata with same id is found, override it rather than adding a new one - int newId = altMetaDataSet.id; - for (int i = 0; i < _altMetaDataSetArray.Count; i++) - { - if (_altMetaDataSetArray[i].id == newId) - { - // override the existing metadata with the same id - _altMetaDataSetArray[i] = altMetaDataSet; - return; - } - } - - // if we did not find metadata to override, add as new - _altMetaDataSetArray.Add(altMetaDataSet); - } - - internal _SqlMetaDataSet GetAltMetaData(int id) - { - foreach (_SqlMetaDataSet altMetaDataSet in _altMetaDataSetArray) - { - if (altMetaDataSet.id == id) - { - return altMetaDataSet; - } - } - Debug.Fail("Can't match up altMetaDataSet with given id"); - return null; - } - - public object Clone() - { - _SqlMetaDataSetCollection result = new _SqlMetaDataSetCollection() { metaDataSet = metaDataSet?.Clone() }; - - foreach (_SqlMetaDataSet set in _altMetaDataSetArray) - { - result._altMetaDataSetArray.Add(set.Clone()); - } - return result; - } - } - - internal partial class SqlMetaDataPriv - { - [Flags] - private enum SqlMetaDataPrivFlags : byte - { - None = 0, - IsNullable = 1 << 1, - IsMultiValued = 1 << 2 - } - - internal SqlDbType type; // SqlDbType enum value - internal byte tdsType; // underlying tds type - internal byte precision = TdsEnums.UNKNOWN_PRECISION_SCALE; // give default of unknown (-1) - internal byte scale = TdsEnums.UNKNOWN_PRECISION_SCALE; // give default of unknown (-1) - private SqlMetaDataPrivFlags flags; - internal int length; - internal SqlCollation collation; - internal int codePage; - internal Encoding encoding; - - internal MetaType metaType; // cached metaType - public SqlMetaDataUdt udt; - public SqlMetaDataXmlSchemaCollection xmlSchemaCollection; - - internal SqlMetaDataPriv() - { - } - - public bool IsNullable - { - get => HasFlag(SqlMetaDataPrivFlags.IsNullable); - set => Set(SqlMetaDataPrivFlags.IsNullable, value); - } - - public bool IsMultiValued - { - get => HasFlag(SqlMetaDataPrivFlags.IsMultiValued); - set => Set(SqlMetaDataPrivFlags.IsMultiValued, value); - } - - private bool HasFlag(SqlMetaDataPrivFlags flag) - { - return (flags & flag) != 0; - } - - private void Set(SqlMetaDataPrivFlags flag, bool value) - { - flags = value ? flags | flag : flags & ~flag; - } - - internal virtual void CopyFrom(SqlMetaDataPriv original) - { - this.type = original.type; - this.tdsType = original.tdsType; - this.precision = original.precision; - this.scale = original.scale; - this.length = original.length; - this.collation = original.collation; - this.codePage = original.codePage; - this.encoding = original.encoding; - this.metaType = original.metaType; - this.flags = original.flags; - - if (original.udt != null) - { - udt = new SqlMetaDataUdt(); - udt.CopyFrom(original.udt); - } - - if (original.xmlSchemaCollection != null) - { - xmlSchemaCollection = new SqlMetaDataXmlSchemaCollection(); - xmlSchemaCollection.CopyFrom(original.xmlSchemaCollection); - } - - this.isEncrypted = original.isEncrypted; - this.baseTI = original.baseTI; - this.cipherMD = original.cipherMD; - } - } - - internal sealed class SqlMetaDataXmlSchemaCollection - { - internal string Database; - internal string OwningSchema; - internal string Name; - - public void CopyFrom(SqlMetaDataXmlSchemaCollection original) - { - if (original != null) - { - Database = original.Database; - OwningSchema = original.OwningSchema; - Name = original.Name; - } - } - } - - internal sealed class SqlMetaDataUdt - { -#if NET - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] -#endif - internal Type Type; - internal string DatabaseName; - internal string SchemaName; - internal string TypeName; - internal string AssemblyQualifiedName; - - public void CopyFrom(SqlMetaDataUdt original) - { - if (original != null) - { - Type = original.Type; - DatabaseName = original.DatabaseName; - SchemaName = original.SchemaName; - TypeName = original.TypeName; - AssemblyQualifiedName = original.AssemblyQualifiedName; - } - } - } - - internal sealed class _SqlRPC - { - internal string rpcName; - internal ushort ProcID; // Used instead of name - internal ushort options; - - internal SqlParameter[] systemParams; - internal byte[] systemParamOptions; - internal int systemParamCount; - - internal SqlParameterCollection userParams; - internal long[] userParamMap; - internal int userParamCount; - - internal int? recordsAffected; - internal int cumulativeRecordsAffected; - - internal int errorsIndexStart; - internal int errorsIndexEnd; - internal SqlErrorCollection errors; - - internal int warningsIndexStart; - internal int warningsIndexEnd; - internal SqlErrorCollection warnings; - - internal bool needsFetchParameterEncryptionMetadata; - - internal SqlBatchCommand batchCommand; - - internal string GetCommandTextOrRpcName() - { - if (TdsEnums.RPC_PROCID_EXECUTESQL == ProcID) - { - // Param 0 is the actual sql executing - return (string)systemParams[0].Value; - } - else - { - return rpcName; - } - } - - internal SqlParameter GetParameterByIndex(int index, out byte options) - { - SqlParameter retval; - - if (index < systemParamCount) - { - retval = systemParams[index]; - options = systemParamOptions[index]; - } - else - { - long data = userParamMap[index - systemParamCount]; - int paramIndex = (int)(data & int.MaxValue); - options = (byte)((data >> 32) & 0xFF); - retval = userParams[paramIndex]; - } - return retval; - } - } - - internal sealed class SqlReturnValue : SqlMetaDataPriv - { - // @TODO: Make auto properties (and rename to match) - internal string parameter; - internal readonly SqlBuffer value; -#if NETFRAMEWORK - internal ushort parmIndex; //2005 or later only -#endif - - internal SqlReturnValue() : base() - { - value = new SqlBuffer(); - } - } - - internal struct MultiPartTableName - { - private string _multipartName; - private string _serverName; - private string _catalogName; - private string _schemaName; - private string _tableName; - - internal MultiPartTableName(string[] parts) - { - _multipartName = null; - _serverName = parts[0]; - _catalogName = parts[1]; - _schemaName = parts[2]; - _tableName = parts[3]; - } - - internal MultiPartTableName(string multipartName) - { - _multipartName = multipartName; - _serverName = null; - _catalogName = null; - _schemaName = null; - _tableName = null; - } - - internal string ServerName - { - get - { - ParseMultipartName(); - return _serverName; - } - set { _serverName = value; } - } - internal string CatalogName - { - get - { - ParseMultipartName(); - return _catalogName; - } - set { _catalogName = value; } - } - internal string SchemaName - { - get - { - ParseMultipartName(); - return _schemaName; - } - set { _schemaName = value; } - } - internal string TableName - { - get - { - ParseMultipartName(); - return _tableName; - } - set { _tableName = value; } - } - - private void ParseMultipartName() - { - if (_multipartName != null) - { - string[] parts = MultipartIdentifier.ParseMultipartIdentifier(_multipartName, Strings.SQL_TDSParserTableName, false); - _serverName = parts[0]; - _catalogName = parts[1]; - _schemaName = parts[2]; - _tableName = parts[3]; - _multipartName = null; - } - } - - internal static readonly MultiPartTableName Null = new(new string[] { null, null, null, null }); - } - - internal static class SslProtocolsHelper - { - private static string ToFriendlyName(this SslProtocols protocol) - { - string name; - - /* The SslProtocols.Tls13 is supported by netcoreapp3.1 and later - * This driver does not support this version yet! - if ((protocol & SslProtocols.Tls13) == SslProtocols.Tls13) - { - name = "TLS 1.3"; - }*/ -#pragma warning disable CA5397 // Do not use deprecated SslProtocols values -#pragma warning disable CA5398 // Avoid hardcoded SslProtocols values - if ((protocol & SslProtocols.Tls12) != SslProtocols.None) - { - name = "TLS 1.2"; - } -#if NET8_0_OR_GREATER -#pragma warning disable SYSLIB0039 // Type or member is obsolete: TLS 1.0 & 1.1 are deprecated -#endif - else if ((protocol & SslProtocols.Tls11) != SslProtocols.None) - { - name = "TLS 1.1"; - } - else if ((protocol & SslProtocols.Tls) != SslProtocols.None) - { - name = "TLS 1.0"; - } -#if NET8_0_OR_GREATER -#pragma warning restore SYSLIB0039 // Type or member is obsolete: SSL and TLS 1.0 & 1.1 is deprecated -#endif -#pragma warning disable CS0618 // Type or member is obsolete: SSL is deprecated - else if ((protocol & SslProtocols.Ssl3) != SslProtocols.None) - { - name = "SSL 3.0"; - } - else if ((protocol & SslProtocols.Ssl2) != SslProtocols.None) -#pragma warning restore CS0618 // Type or member is obsolete: SSL and TLS 1.0 & 1.1 is deprecated - { - name = "SSL 2.0"; - } -#pragma warning restore CA5397 // Do not use deprecated SslProtocols values -#pragma warning restore CA5398 // Avoid hardcoded SslProtocols values - else - { -#if !NETFRAMEWORK - name = protocol.ToString(); -#else - throw new ArgumentException(StringsHelper.GetString(StringsHelper.net_invalid_enum, "NativeProtocols"), "NativeProtocols"); -#endif - } - - return name; - } - - /// - /// check the negotiated secure protocol if it's under TLS 1.2 - /// - /// - /// Localized warning message - public static string GetProtocolWarning(this SslProtocols protocol) - { - string message = string.Empty; -#if NET8_0_OR_GREATER -#pragma warning disable SYSLIB0039 // Type or member is obsolete: TLS 1.0 & 1.1 are deprecated -#endif -#pragma warning disable CS0618 // Type or member is obsolete : SSL is deprecated -#pragma warning disable CA5397 // Do not use deprecated SslProtocols values -#pragma warning disable CA5398 // Avoid hardcoded SslProtocols values - if ((protocol & (SslProtocols.Ssl2 | SslProtocols.Ssl3 | SslProtocols.Tls | SslProtocols.Tls11)) != SslProtocols.None) -#pragma warning restore CA5398 // Avoid hardcoded SslProtocols values -#pragma warning restore CA5397 // Do not use deprecated SslProtocols values -#pragma warning restore CS0618 // Type or member is obsolete : SSL is deprecated -#if NET8_0_OR_GREATER -#pragma warning restore SYSLIB0039 // Type or member is obsolete: SSL and TLS 1.0 & 1.1 is deprecated -#endif - { -#if !NETFRAMEWORK - message = StringsHelper.Format(Strings.SEC_ProtocolWarning, protocol.ToFriendlyName()); -#else - message = StringsHelper.GetString(Strings.SEC_ProtocolWarning, protocol.ToFriendlyName()); -#endif - } - return message; - } - } -} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TransactionRequest.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TransactionRequest.cs index 756ffbf2e5..fb759a1229 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TransactionRequest.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TransactionRequest.cs @@ -2,6 +2,8 @@ // 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.SqlClient.Parser; + namespace Microsoft.Data.SqlClient; /// diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TransparentNetworkResolutionState.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TransparentNetworkResolutionState.cs new file mode 100644 index 0000000000..2004f7aaa0 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TransparentNetworkResolutionState.cs @@ -0,0 +1,14 @@ +// 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; + +// This enum indicates the state of TransparentNetworkIPResolution +// The first attempt when TNIR is on should be sequential. If the first attempt fails next attempts should be parallel. +internal enum TransparentNetworkResolutionState +{ + DisabledMode = 0, + SequentialMode, + ParallelMode +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlTypes/SqlVector.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlTypes/SqlVector.cs index ce16e5b445..60a0c67a6d 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlTypes/SqlVector.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlTypes/SqlVector.cs @@ -10,6 +10,7 @@ using System.Text.Json; using Microsoft.Data.Common; using Microsoft.Data.SqlClient; +using Microsoft.Data.SqlClient.Parser; #nullable enable diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.FunctionalTests.csproj b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.FunctionalTests.csproj index 897a063d0c..76cf8cb35e 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.FunctionalTests.csproj +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.FunctionalTests.csproj @@ -20,8 +20,8 @@ - - + + diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/MultiplexerTests.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/MultiplexerTests.cs index efa7962d28..d491dacc3d 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/MultiplexerTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/MultiplexerTests.cs @@ -11,6 +11,7 @@ using System.Linq; using System.Text; using System.Text.RegularExpressions; +using Microsoft.Data.SqlClient.Parser; using Xunit; namespace Microsoft.Data.SqlClient.Tests @@ -40,7 +41,7 @@ public static IEnumerable IsAsync() [ExcludeFromCodeCoverage] public static IEnumerable OnlyAsync() { yield return new object[] { true }; } - + [ConditionalTheory(nameof(IsUsingModernProcessSni)), MemberData(nameof(IsAsync))] public static void PassThroughSinglePacket(bool isAsync) { @@ -126,7 +127,7 @@ public static void Reconstruct2Packets_Full_FullPart_Part(bool isAsync) var input = SplitPackets(38, expected, (8 + 30), // full - (8 + 10) + (8 + 12), // full, part next + (8 + 10) + (8 + 12), // full, part next 18 // part end ); @@ -381,7 +382,7 @@ private static void WritePacket(Span buffer, int dataSize, byte dataValue, header[1] = 0; // Status, 0 - normal message BinaryPrimitives.TryWriteInt16BigEndian(header.Slice(TdsEnums.HEADER_LEN_FIELD_OFFSET, 2), (short)(TdsEnums.HEADER_LEN + dataSize)); // total length - BinaryPrimitives.TryWriteInt16BigEndian(header.Slice(TdsEnums.SPID_OFFSET, 2), short.MaxValue); // SPID + BinaryPrimitives.TryWriteInt16BigEndian(header.Slice(TdsEnums.SPID_OFFSET, 2), short.MaxValue); // SPID header[TdsEnums.HEADER_LEN_FIELD_OFFSET + 4] = id; // PacketID header[TdsEnums.HEADER_LEN_FIELD_OFFSET + 5] = 0; // Window @@ -510,7 +511,7 @@ public static int SumPacketLengths(List list) [ExcludeFromCodeCoverage] public static List LoadPacketBinFiles(string directoryName) { - // expects a set of files contained in a directory with the name + // expects a set of files contained in a directory with the name // formatted as packet_{number}_{dataSize}.bin each packet will be // loaded into a byte[] diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/TdsParserStateObject.TestHarness.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/TdsParserStateObject.TestHarness.cs index f2eb2b15f4..6bbd3e7ed7 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/TdsParserStateObject.TestHarness.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/TdsParserStateObject.TestHarness.cs @@ -8,7 +8,7 @@ using Microsoft.Data.SqlClient.Tests; using Microsoft.Data.SqlClient.Tests.Common; -namespace Microsoft.Data.SqlClient +namespace Microsoft.Data.SqlClient.Parser { internal struct PacketHandle { diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/Common/SystemDataInternals/ConnectionHelper.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/Common/SystemDataInternals/ConnectionHelper.cs index d511a956b7..6353ab3b56 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/Common/SystemDataInternals/ConnectionHelper.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/Common/SystemDataInternals/ConnectionHelper.cs @@ -49,12 +49,12 @@ internal static class ConnectionHelper s_SQLDNSInfo.GetProperty("Port", BindingFlags.Instance | BindingFlags.Public); // TdsParser - private static readonly Type s_tdsParser = s_MicrosoftDotData.GetType("Microsoft.Data.SqlClient.TdsParser"); + private static readonly Type s_tdsParser = s_MicrosoftDotData.GetType("Microsoft.Data.SqlClient.Parser.TdsParser"); private static readonly FieldInfo s_tdsParser_physicalStateObj = s_tdsParser.GetField("_physicalStateObj", BindingFlags.Instance | BindingFlags.NonPublic); // TdsParserStateObject - private static readonly Type s_tdsParserStateObject = s_MicrosoftDotData.GetType("Microsoft.Data.SqlClient.TdsParserStateObject"); + private static readonly Type s_tdsParserStateObject = s_MicrosoftDotData.GetType("Microsoft.Data.SqlClient.Parser.TdsParserStateObject"); private static readonly FieldInfo s_tdsParserStateObject_enforcedTimeoutDelayInMilliSeconds = s_tdsParserStateObject.GetField("_enforcedTimeoutDelayInMilliSeconds", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo s_tdsParserStateObject_enforceTimeoutDelay = @@ -117,7 +117,7 @@ public static bool IsTransactionRoot(object internalConnection) VerifyObjectIsInternalConnection(internalConnection); return (bool)s_dbConnectionInternal_IsTransationRoot.GetValue(internalConnection, null); } - + public static bool IsTxRootWaitingForTxEnd(object internalConnection) { VerifyObjectIsInternalConnection(internalConnection); diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/Common/SystemDataInternals/TdsParserHelper.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/Common/SystemDataInternals/TdsParserHelper.cs index 123fd04f17..6f5c555ec9 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/Common/SystemDataInternals/TdsParserHelper.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/Common/SystemDataInternals/TdsParserHelper.cs @@ -10,7 +10,7 @@ namespace Microsoft.Data.SqlClient.ManualTesting.Tests.SystemDataInternals internal static class TdsParserHelper { private static Assembly s_systemDotData = Assembly.Load(new AssemblyName(typeof(SqlConnection).GetTypeInfo().Assembly.FullName)); - private static Type s_tdsParser = s_systemDotData.GetType("Microsoft.Data.SqlClient.TdsParser"); + private static Type s_tdsParser = s_systemDotData.GetType("Microsoft.Data.SqlClient.Parser.TdsParser"); private static FieldInfo s_tdsParserPhysicalStateObject = s_tdsParser.GetField("_physicalStateObj", BindingFlags.Instance | BindingFlags.NonPublic); private static void VerifyObjectIsTdsParser(object parser) diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/ConnectionPool/DbConnectionPoolAccessTokenTest.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/ConnectionPool/DbConnectionPoolAccessTokenTest.cs index a6826e6ed7..91ebf9d2b6 100644 --- a/src/Microsoft.Data.SqlClient/tests/UnitTests/ConnectionPool/DbConnectionPoolAccessTokenTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/ConnectionPool/DbConnectionPoolAccessTokenTest.cs @@ -11,6 +11,7 @@ using System.Transactions; using Microsoft.Data.ProviderBase; using Microsoft.Data.SqlClient.ConnectionPool; +using Microsoft.Data.SqlClient.Parser.Login; using Microsoft.Data.SqlClient.Tests.Common; using Microsoft.SqlServer.TDS.PreLogin; using Microsoft.SqlServer.TDS.Servers; diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/Common/AdapterUtilTest.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/Common/AdapterUtilTest.cs index 0ee9f808b0..d165016a7f 100644 --- a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/Common/AdapterUtilTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/Common/AdapterUtilTest.cs @@ -4,6 +4,7 @@ using System; using Microsoft.Data.SqlClient; +using Microsoft.Data.SqlClient.Parser; using Xunit; namespace Microsoft.Data.Common.UnitTests; diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/ManagedSni/SniPacketTests.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/ManagedSni/SniPacketTests.cs index 89923c5813..1c2201d601 100644 --- a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/ManagedSni/SniPacketTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/ManagedSni/SniPacketTests.cs @@ -9,6 +9,7 @@ using System.Security.Authentication; using System.Threading.Tasks; using Microsoft.Data.SqlClient.ManagedSni; +using Microsoft.Data.SqlClient.Parser; using Microsoft.Data.SqlClient.UnitTests.Utilities; using Xunit; diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/SqlBulkCopyVariantTests.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/SqlBulkCopyVariantTests.cs index 11cb88d158..dd1e7bc9ba 100644 --- a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/SqlBulkCopyVariantTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/SqlBulkCopyVariantTests.cs @@ -6,6 +6,8 @@ using System.Collections.Generic; using System.Data.SqlTypes; using System.Reflection; +using Microsoft.Data.SqlClient.Parser; +using Microsoft.Data.SqlClient.Parser.Tokens; using Xunit; namespace Microsoft.Data.SqlClient.UnitTests diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/SqlMetaDataFactoryDataTypesTest.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/SqlMetaDataFactoryDataTypesTest.cs index 4a0742e17d..16c1ac4ab3 100644 --- a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/SqlMetaDataFactoryDataTypesTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/SqlMetaDataFactoryDataTypesTest.cs @@ -7,6 +7,7 @@ using System.IO; using System.Linq; using System.Reflection; +using Microsoft.Data.SqlClient.Parser; using Xunit; namespace Microsoft.Data.SqlClient.UnitTests; diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/SqlMetaDataSetTest.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/SqlMetaDataSetTest.cs index 37ce70d2c8..e9ee4694bd 100644 --- a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/SqlMetaDataSetTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/SqlMetaDataSetTest.cs @@ -2,6 +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. +using Microsoft.Data.SqlClient.Parser.Tokens; using Xunit; namespace Microsoft.Data.SqlClient.UnitTests @@ -266,4 +267,4 @@ public void SqlMetaDataSet_Clone_PreservesFullAlwaysEncryptedMetadata() Assert.True(original[1].isEncrypted); } } -} \ No newline at end of file +} diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/StateSnapshotPacketRecyclingTests.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/StateSnapshotPacketRecyclingTests.cs index 54169dce1e..523509b7f9 100644 --- a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/StateSnapshotPacketRecyclingTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/StateSnapshotPacketRecyclingTests.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; +using Microsoft.Data.SqlClient.Parser; using Xunit; namespace Microsoft.Data.SqlClient.UnitTests diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/TdsParserStateObjectNativeTests.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/TdsParserStateObjectNativeTests.cs index 3b33634ac7..2adefede23 100644 --- a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/TdsParserStateObjectNativeTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/TdsParserStateObjectNativeTests.cs @@ -4,6 +4,7 @@ #if NETFRAMEWORK || WINDOWS +using Microsoft.Data.SqlClient.Parser; using Xunit; namespace Microsoft.Data.SqlClient.UnitTests diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/SimulatedServerTests/FeatureExtAckBoundsTests.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/SimulatedServerTests/FeatureExtAckBoundsTests.cs index 4753717c98..bc33fa0535 100644 --- a/src/Microsoft.Data.SqlClient/tests/UnitTests/SimulatedServerTests/FeatureExtAckBoundsTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/SimulatedServerTests/FeatureExtAckBoundsTests.cs @@ -5,6 +5,7 @@ using System; using System.IO; using System.Linq; +using Microsoft.Data.SqlClient.Parser; using Microsoft.SqlServer.TDS; using Microsoft.SqlServer.TDS.FeatureExtAck; using Microsoft.SqlServer.TDS.Servers; diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/SimulatedServerTests/IsolationLevelResetTests.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/SimulatedServerTests/IsolationLevelResetTests.cs index ba90c51fc0..e357380616 100644 --- a/src/Microsoft.Data.SqlClient/tests/UnitTests/SimulatedServerTests/IsolationLevelResetTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/SimulatedServerTests/IsolationLevelResetTests.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using Microsoft.Data.ProviderBase; using Microsoft.Data.SqlClient.Connection; +using Microsoft.Data.SqlClient.Parser; using Microsoft.Data.SqlClient.Tests.Common; using Microsoft.Extensions.Time.Testing; using Microsoft.SqlServer.TDS.Servers; diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/SimulatedServerTests/TdsTokenBoundsTests.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/SimulatedServerTests/TdsTokenBoundsTests.cs index cab3ca83db..0c168a4b0b 100644 --- a/src/Microsoft.Data.SqlClient/tests/UnitTests/SimulatedServerTests/TdsTokenBoundsTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/SimulatedServerTests/TdsTokenBoundsTests.cs @@ -5,6 +5,7 @@ using System; using System.IO; using System.Linq; +using Microsoft.Data.SqlClient.Parser; using Microsoft.SqlServer.TDS; using Microsoft.SqlServer.TDS.ColMetadata; using Microsoft.SqlServer.TDS.Done; diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/TdsParserDecimalTests.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/TdsParserDecimalTests.cs index 57a4f2cfd8..1951645e52 100644 --- a/src/Microsoft.Data.SqlClient/tests/UnitTests/TdsParserDecimalTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/TdsParserDecimalTests.cs @@ -7,6 +7,7 @@ using System.Data.SqlTypes; using System.Globalization; using System.Reflection; +using Microsoft.Data.SqlClient.Parser; using Microsoft.Data.SqlClient.Tests.Common; using Xunit; diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/TdsParserInternalsTest.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/TdsParserInternalsTest.cs index a922507935..efe7449024 100644 --- a/src/Microsoft.Data.SqlClient/tests/UnitTests/TdsParserInternalsTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/TdsParserInternalsTest.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Reflection; using System.Text; +using Microsoft.Data.SqlClient.Parser; using Xunit; #nullable enable @@ -16,7 +17,7 @@ public class TdsParserInternalsTest private readonly TdsParser _parser = new(false, false); // TODO(ADO-37888): Avoid reflection by exposing a way for tests to intercept outbound TDS packets. - // Helper function to extract private _physicalStateObj fields raw buffer and no. of bytes written so far + // Helper function to extract private _physicalStateObj fields raw buffer and no. of bytes written so far private static (byte[] buffer, int count) ExtractOutputBuffer(TdsParser parser) { FieldInfo stateField = typeof(TdsParser)