From 01cfa53523caa2297a360f3bc0156c448e9adb4e Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Thu, 20 Nov 2025 17:57:31 -0600 Subject: [PATCH 01/36] Add pre-processor constants for target OS --- .../src/Microsoft.Data.SqlClient.csproj | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/src/Microsoft.Data.SqlClient.csproj index 75b9377df2..fdc34b7b94 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/src/Microsoft.Data.SqlClient.csproj @@ -4,7 +4,23 @@ true - + + + + + $(OS) + + + + + + + + + _UNIX + _WINDOWS + + From 1defe9f2493fbfd02ee34fe258666ca8e5be78f9 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Thu, 20 Nov 2025 18:00:11 -0600 Subject: [PATCH 02/36] Add #if _WINDOWS to the Interop/Windows files --- .../src/Interop/Windows/Handles/SafeLibraryHandle.netcore.cs | 4 ++-- .../src/Interop/Windows/Kernel32/FileTypes.cs | 4 ++++ .../src/Interop/Windows/Kernel32/IoControlCodeAccess.cs | 4 ++++ .../src/Interop/Windows/Kernel32/IoControlTransferType.cs | 4 ++++ .../src/Interop/Windows/Kernel32/Kernel32.cs | 4 ++++ .../src/Interop/Windows/Kernel32/Kernel32Safe.netfx.cs | 2 +- .../src/Interop/Windows/NtDll/CreateDisposition.cs | 4 ++++ .../src/Interop/Windows/NtDll/CreateOptions.cs | 4 ++++ .../src/Interop/Windows/NtDll/DesiredAccess.cs | 4 ++++ .../src/Interop/Windows/NtDll/FileFullEaInformation.cs | 4 ++++ .../src/Interop/Windows/NtDll/ImpersonationLevel.cs | 4 ++++ .../src/Interop/Windows/NtDll/IoStatusBlock.cs | 4 ++++ .../src/Interop/Windows/NtDll/NtDll.cs | 4 ++++ .../src/Interop/Windows/NtDll/ObjectAttributeFlags.cs | 4 ++++ .../src/Interop/Windows/NtDll/ObjectAttributes.cs | 4 ++++ .../src/Interop/Windows/NtDll/SecurityQualityOfService.cs | 4 ++++ .../src/Interop/Windows/Secur32/ContextAttribute.netfx.cs | 4 ++++ .../src/Interop/Windows/Secur32/CredHandle.netfx.cs | 2 +- .../src/Interop/Windows/Secur32/Secur32.netfx.cs | 2 +- .../src/Interop/Windows/Sni/AuthProviderInfo.cs | 4 ++++ .../src/Interop/Windows/Sni/ConsumerInfo.cs | 4 ++++ .../src/Interop/Windows/Sni/ConsumerNumber.cs | 4 ++++ .../src/Interop/Windows/Sni/Delegates.cs | 4 ++++ .../src/Interop/Windows/Sni/ISniNativeMethods.cs | 4 ++++ .../src/Interop/Windows/Sni/IoType.cs | 4 ++++ .../src/Interop/Windows/Sni/Prefix.cs | 4 ++++ .../src/Interop/Windows/Sni/Provider.cs | 4 ++++ .../src/Interop/Windows/Sni/QueryType.cs | 4 ++++ .../src/Interop/Windows/Sni/SniClientConsumerInfo.cs | 4 ++++ .../src/Interop/Windows/Sni/SniConsumerInfo.cs | 4 ++++ .../src/Interop/Windows/Sni/SniDnsCacheInfo.cs | 4 ++++ .../src/Interop/Windows/Sni/SniError.cs | 4 ++++ .../src/Interop/Windows/Sni/SniNativeMethods.netcore.cs | 2 +- .../src/Interop/Windows/Sni/SniNativeMethodsArm64.netfx.cs | 2 +- .../Interop/Windows/Sni/SniNativeMethodsNotSupported.netfx.cs | 2 +- .../src/Interop/Windows/Sni/SniNativeMethodsX64.netfx.cs | 2 +- .../src/Interop/Windows/Sni/SniNativeMethodsX86.netfx.cs | 2 +- .../src/Interop/Windows/Sni/SniNativeWrapper.cs | 4 ++++ .../src/Interop/Windows/Sni/SniSslProtocols.cs | 4 ++++ .../Sni/SqlDependencyProcessDispatcherStorage.netfx.cs | 2 +- .../Interop/Windows/Sni/TransparentNetworkResolutionMode.cs | 4 ++++ .../src/Interop/Windows/SystemErrors.cs | 4 ++++ .../src/Interop/Windows/UnicodeString.cs | 4 ++++ 43 files changed, 143 insertions(+), 11 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Handles/SafeLibraryHandle.netcore.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Handles/SafeLibraryHandle.netcore.cs index 47728b3726..64bc92d6d4 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Handles/SafeLibraryHandle.netcore.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Handles/SafeLibraryHandle.netcore.cs @@ -2,9 +2,9 @@ // 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.Win32.SafeHandles; +#if NET && _WINDOWS -#if NET +using Microsoft.Win32.SafeHandles; namespace Interop.Windows.Handles { diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Kernel32/FileTypes.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Kernel32/FileTypes.cs index 59b1c67dcf..8dbbd6fbde 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Kernel32/FileTypes.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Kernel32/FileTypes.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. +#if _WINDOWS + namespace Interop.Windows.Kernel32 { internal class FileTypes @@ -12,3 +14,5 @@ internal class FileTypes internal const int FILE_TYPE_PIPE = 0x0003; } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Kernel32/IoControlCodeAccess.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Kernel32/IoControlCodeAccess.cs index a7f0c52f8a..bbfce78672 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Kernel32/IoControlCodeAccess.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Kernel32/IoControlCodeAccess.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. +#if _WINDOWS + using System; namespace Interop.Windows.Kernel32 @@ -31,3 +33,5 @@ public enum IoControlCodeAccess FILE_WRITE_DATA = 0x02 } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Kernel32/IoControlTransferType.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Kernel32/IoControlTransferType.cs index 6b0e8571af..8099827bc8 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Kernel32/IoControlTransferType.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Kernel32/IoControlTransferType.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. +#if _WINDOWS + namespace Interop.Windows.Kernel32 { /// @@ -35,3 +37,5 @@ public enum IoControlTransferType METHOD_NEITHER } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Kernel32/Kernel32.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Kernel32/Kernel32.cs index 530838ba38..a938fa2fcc 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Kernel32/Kernel32.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Kernel32/Kernel32.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. +#if _WINDOWS + using System; using System.Runtime.InteropServices; using System.Runtime.Versioning; @@ -92,3 +94,5 @@ internal static extern int GetFullPathName( internal static extern bool SetThreadErrorMode(uint dwNewMode, out uint lpOldMode); } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Kernel32/Kernel32Safe.netfx.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Kernel32/Kernel32Safe.netfx.cs index 156d16dbd1..1ab634a0d6 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Kernel32/Kernel32Safe.netfx.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Kernel32/Kernel32Safe.netfx.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if NETFRAMEWORK +#if NETFRAMEWORK && _WINDOWS using System; using System.Runtime.InteropServices; diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/CreateDisposition.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/CreateDisposition.cs index 8f03025bee..7502a94e64 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/CreateDisposition.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/CreateDisposition.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. +#if _WINDOWS + namespace Interop.Windows.NtDll { /// @@ -54,3 +56,5 @@ internal enum CreateDisposition : uint FILE_OVERWRITE_IF = 5 } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/CreateOptions.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/CreateOptions.cs index 39677ab3d5..5c169ec5a0 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/CreateOptions.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/CreateOptions.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. +#if _WINDOWS + using System; namespace Interop.Windows.NtDll @@ -196,3 +198,5 @@ internal enum CreateOptions : uint // FILE_OPEN_FOR_FREE_SPACE_QUERY = 0x00800000 } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/DesiredAccess.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/DesiredAccess.cs index f15fbcf0dc..acf7f9ee0f 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/DesiredAccess.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/DesiredAccess.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. +#if _WINDOWS + using System; namespace Interop.Windows.NtDll @@ -188,3 +190,5 @@ internal enum DesiredAccess : uint FILE_GENERIC_EXECUTE = 0x20000000 // GENERIC_EXECUTE } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/FileFullEaInformation.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/FileFullEaInformation.cs index 76322ce604..5e545ce131 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/FileFullEaInformation.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/FileFullEaInformation.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. +#if _WINDOWS + using System.Runtime.InteropServices; namespace Interop.Windows.NtDll @@ -35,3 +37,5 @@ internal struct FileFullEaInformation } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/ImpersonationLevel.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/ImpersonationLevel.cs index 5386a4094b..70c606e95b 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/ImpersonationLevel.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/ImpersonationLevel.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. +#if _WINDOWS + namespace Interop.Windows.NtDll { /// @@ -39,3 +41,5 @@ internal enum ImpersonationLevel SecurityDelegation = 3, } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/IoStatusBlock.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/IoStatusBlock.cs index 7018ef3abd..0e173186b8 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/IoStatusBlock.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/IoStatusBlock.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. +#if _WINDOWS + using System; using System.Runtime.InteropServices; @@ -42,3 +44,5 @@ public struct IoStatus } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/NtDll.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/NtDll.cs index 8dddda19d3..20b5e314db 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/NtDll.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/NtDll.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. +#if _WINDOWS + using System; using System.IO; using System.Runtime.InteropServices; @@ -118,3 +120,5 @@ private static extern unsafe int NtCreateFile( uint EaLength); } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/ObjectAttributeFlags.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/ObjectAttributeFlags.cs index 31dfd80ead..0f70ffa6cf 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/ObjectAttributeFlags.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/ObjectAttributeFlags.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. +#if _WINDOWS + using System; namespace Interop.Windows.NtDll @@ -52,3 +54,5 @@ internal enum ObjectAttributeFlags : uint // OBJ_VALID_ATTRIBUTES = 0x000001F2 } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/ObjectAttributes.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/ObjectAttributes.cs index f3198f923e..3093763429 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/ObjectAttributes.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/ObjectAttributes.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. +#if _WINDOWS + using System; namespace Interop.Windows.NtDll @@ -58,3 +60,5 @@ public ObjectAttributes( } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/SecurityQualityOfService.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/SecurityQualityOfService.cs index 7f268255d9..0cfa77a2d5 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/SecurityQualityOfService.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/NtDll/SecurityQualityOfService.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. +#if _WINDOWS + using System.Runtime.InteropServices; namespace Interop.Windows.NtDll @@ -48,3 +50,5 @@ public SecurityQualityOfService( public bool IsEffectiveOnly { get; set; } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Secur32/ContextAttribute.netfx.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Secur32/ContextAttribute.netfx.cs index 7b1c3f6372..85fe936600 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Secur32/ContextAttribute.netfx.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Secur32/ContextAttribute.netfx.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. +#if _WINDOWS + namespace Interop.Windows.Secur32 { internal enum ContextAttribute @@ -29,3 +31,5 @@ internal enum ContextAttribute SECPKG_ATTR_UI_INFO = 0x68, // sets SEcPkgContext_UiInfo } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Secur32/CredHandle.netfx.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Secur32/CredHandle.netfx.cs index c410674bc2..f9c9a9d1d9 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Secur32/CredHandle.netfx.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Secur32/CredHandle.netfx.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if NETFRAMEWORK +#if NETFRAMEWORK && _WINDOWS using System; using System.Runtime.InteropServices; diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Secur32/Secur32.netfx.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Secur32/Secur32.netfx.cs index 55a391c79b..1573b015ed 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Secur32/Secur32.netfx.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Secur32/Secur32.netfx.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if NETFRAMEWORK +#if NETFRAMEWORK && _WINDOWS using System; using System.Runtime.InteropServices; diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/AuthProviderInfo.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/AuthProviderInfo.cs index 7b0818b7c5..e273e5fc1b 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/AuthProviderInfo.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/AuthProviderInfo.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. +#if _WINDOWS + using System.Runtime.InteropServices; namespace Interop.Windows.Sni @@ -23,3 +25,5 @@ internal struct AuthProviderInfo public string serverCertFileName; } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/ConsumerInfo.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/ConsumerInfo.cs index 358e35cda0..fcb7b9a20d 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/ConsumerInfo.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/ConsumerInfo.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. +#if _WINDOWS + using System; using System.Runtime.InteropServices; @@ -16,3 +18,5 @@ internal struct ConsumerInfo internal IntPtr key; } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/ConsumerNumber.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/ConsumerNumber.cs index a1d4fdf292..f7b11801c9 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/ConsumerNumber.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/ConsumerNumber.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. +#if _WINDOWS + namespace Interop.Windows.Sni { internal enum ConsumerNumber @@ -12,3 +14,5 @@ internal enum ConsumerNumber SNI_Consumer_Invalid, } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/Delegates.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/Delegates.cs index fd1f2d8e39..720ad481e4 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/Delegates.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/Delegates.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. +#if _WINDOWS + using System; using System.Runtime.InteropServices; @@ -12,3 +14,5 @@ namespace Interop.Windows.Sni internal delegate IntPtr SqlClientCertificateDelegate(IntPtr pCallbackContext); } + +#endif 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 c05c76b188..194e61a4b6 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/ISniNativeMethods.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/ISniNativeMethods.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. +#if _WINDOWS + using System; using System.Runtime.InteropServices; using System.Text; @@ -99,3 +101,5 @@ unsafe uint SniSecGenClientContextWrapper( uint SniWriteSyncOverAsync(SNIHandle pConn, SNIPacket pPacket); } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/IoType.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/IoType.cs index 167a7a23b5..ef02350e84 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/IoType.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/IoType.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. +#if _WINDOWS + namespace Interop.Windows.Sni { internal enum IoType @@ -10,3 +12,5 @@ internal enum IoType WRITE, } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/Prefix.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/Prefix.cs index 45ec71a2cf..52c98bfde9 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/Prefix.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/Prefix.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. +#if _WINDOWS + namespace Interop.Windows.Sni { internal enum Prefix @@ -14,3 +16,5 @@ internal enum Prefix INVALID_PREFIX, } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/Provider.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/Provider.cs index 61b33ebfc1..c9bf7a980c 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/Provider.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/Provider.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. +#if _WINDOWS + namespace Interop.Windows.Sni { internal enum Provider @@ -24,3 +26,5 @@ internal enum Provider INVALID_PROV, } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/QueryType.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/QueryType.cs index 5fca987240..14de40336f 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/QueryType.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/QueryType.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. +#if _WINDOWS + namespace Interop.Windows.Sni { internal enum QueryType @@ -47,3 +49,5 @@ internal enum QueryType #endif } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniClientConsumerInfo.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniClientConsumerInfo.cs index 062c36679f..89199e4417 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniClientConsumerInfo.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniClientConsumerInfo.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. +#if _WINDOWS + using System.Runtime.InteropServices; using Microsoft.Data.SqlClient; @@ -34,3 +36,5 @@ internal unsafe struct SniClientConsumerInfo public SniDnsCacheInfo DNSCacheInfo; } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniConsumerInfo.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniConsumerInfo.cs index 2f084f228d..8cb27dfb5f 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniConsumerInfo.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniConsumerInfo.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. +#if _WINDOWS + using System; using System.Runtime.InteropServices; @@ -21,3 +23,5 @@ internal struct SniConsumerInfo public IntPtr NodeAffinity; } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniDnsCacheInfo.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniDnsCacheInfo.cs index e0e3c91efe..1d5600aec9 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniDnsCacheInfo.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniDnsCacheInfo.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. +#if _WINDOWS + using System.Runtime.InteropServices; namespace Interop.Windows.Sni @@ -19,3 +21,5 @@ internal struct SniDnsCacheInfo public string wszCachedTcpPort; } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniError.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniError.cs index 2e519c15ab..55f64a32d3 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniError.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniError.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. +#if _WINDOWS + using System.Runtime.InteropServices; namespace Interop.Windows.Sni @@ -21,3 +23,5 @@ internal struct SniError internal uint lineNumber; } } + +#endif 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 b780f8f63c..32109770e0 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 @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if NET +#if NET && _WINDOWS using System; using System.Runtime.InteropServices; 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 7839a047cd..c39c1dbefa 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 @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if NETFRAMEWORK +#if NETFRAMEWORK && _WINDOWS using System; using System.Runtime.InteropServices; 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..0d8600f193 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 @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if NETFRAMEWORK +#if NETFRAMEWORK && _WINDOWS using System; using System.Runtime.InteropServices; 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 e899250786..0849e1a22d 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 @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if NETFRAMEWORK +#if NETFRAMEWORK && _WINDOWS using System; using System.Runtime.InteropServices; 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 4c022821dd..270a522aa6 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 @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if NETFRAMEWORK +#if NETFRAMEWORK && _WINDOWS using System; using System.Runtime.InteropServices; 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 60f5f98dcd..a563cf73b9 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniNativeWrapper.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniNativeWrapper.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. + #if _WINDOWS + using System; using System.Buffers; using System.Diagnostics; @@ -455,3 +457,5 @@ private static void MarshalConsumerInfo(ConsumerInfo consumerInfo, ref SniConsum #endregion } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniSslProtocols.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniSslProtocols.cs index cd9bf47ed3..f070082c16 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniSslProtocols.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniSslProtocols.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. +#if _WINDOWS + namespace Interop.Windows.Sni { internal enum SniSslProtocols : uint @@ -30,3 +32,5 @@ internal enum SniSslProtocols : uint SP_PROT_TLS1_3 = SP_PROT_TLS1_3_SERVER | SP_PROT_TLS1_3_CLIENT, } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SqlDependencyProcessDispatcherStorage.netfx.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SqlDependencyProcessDispatcherStorage.netfx.cs index dddfcb5e07..19d8b261c3 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SqlDependencyProcessDispatcherStorage.netfx.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SqlDependencyProcessDispatcherStorage.netfx.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if NETFRAMEWORK +#if NETFRAMEWORK && _WINDOWS using System; using System.Diagnostics; diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/TransparentNetworkResolutionMode.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/TransparentNetworkResolutionMode.cs index fe68cd420d..8d1ac82449 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/TransparentNetworkResolutionMode.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/TransparentNetworkResolutionMode.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. +#if _WINDOWS + namespace Interop.Windows.Sni { internal enum TransparentNetworkResolutionMode : byte @@ -11,3 +13,5 @@ internal enum TransparentNetworkResolutionMode : byte ParallelMode } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/SystemErrors.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/SystemErrors.cs index 40819ef4d9..2265ee1427 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/SystemErrors.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/SystemErrors.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. +#if _WINDOWS + namespace Interop.Windows { // https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382.aspx @@ -20,3 +22,5 @@ internal class SystemErrors internal const int ERROR_MR_MID_NOT_FOUND = 317; } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/UnicodeString.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/UnicodeString.cs index 7fc87decbf..07ff56dbb4 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/UnicodeString.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/UnicodeString.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. +#if _WINDOWS + using System.Runtime.InteropServices; namespace Interop.Windows @@ -34,3 +36,5 @@ public UnicodeString(char* buffer, int length) } } } + +#endif From 725928a9d2d0c0863a3f88d9fee37e88a6b44022 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Thu, 20 Nov 2025 18:36:50 -0600 Subject: [PATCH 03/36] Split out the netfx methods and junk from AdapterUtil --- .../src/Microsoft/Data/Common/AdapterUtil.cs | 194 -------------- .../Data/Common/AdapterUtil.netfx.cs | 244 ++++++++++++++++++ 2 files changed, 244 insertions(+), 194 deletions(-) create mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.netfx.cs 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 b37f97ac17..75daeaa47c 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs @@ -1397,200 +1397,6 @@ internal static Exception InvalidMixedUsageOfAccessTokenCallbackAndIntegratedSec internal static readonly IntPtr s_ptrZero = IntPtr.Zero; #if NETFRAMEWORK -#region netfx project only - internal static Task CreatedTaskWithException(Exception ex) - { - TaskCompletionSource completion = new(); - completion.SetException(ex); - return completion.Task; - } - - // - // Helper Functions - // - internal static void CheckArgumentLength(string value, string parameterName) - { - CheckArgumentNull(value, parameterName); - if (0 == value.Length) - { - throw Argument(StringsHelper.GetString(Strings.ADP_EmptyString, parameterName)); // MDAC 94859 - } - } - - // IDbConnection.BeginTransaction, OleDbTransaction.Begin - internal static ArgumentOutOfRangeException InvalidIsolationLevel(IsolationLevel value) - { -#if DEBUG - switch (value) - { - case IsolationLevel.Unspecified: - case IsolationLevel.Chaos: - case IsolationLevel.ReadUncommitted: - case IsolationLevel.ReadCommitted: - case IsolationLevel.RepeatableRead: - case IsolationLevel.Serializable: - case IsolationLevel.Snapshot: - Debug.Assert(false, "valid IsolationLevel " + value.ToString()); - break; - } -#endif - return InvalidEnumerationValue(typeof(IsolationLevel), (int)value); - } - - // DBDataPermissionAttribute.KeyRestrictionBehavior - internal static ArgumentOutOfRangeException InvalidKeyRestrictionBehavior(KeyRestrictionBehavior value) - { -#if DEBUG - switch (value) - { - case KeyRestrictionBehavior.PreventUsage: - case KeyRestrictionBehavior.AllowOnly: - Debug.Assert(false, "valid KeyRestrictionBehavior " + value.ToString()); - break; - } -#endif - return InvalidEnumerationValue(typeof(KeyRestrictionBehavior), (int)value); - } - - // IDataParameter.Direction - internal static ArgumentOutOfRangeException InvalidParameterDirection(ParameterDirection value) - { -#if DEBUG - switch (value) - { - case ParameterDirection.Input: - case ParameterDirection.Output: - case ParameterDirection.InputOutput: - case ParameterDirection.ReturnValue: - Debug.Assert(false, "valid ParameterDirection " + value.ToString()); - break; - } -#endif - return InvalidEnumerationValue(typeof(ParameterDirection), (int)value); - } - - // - // DbConnectionOptions, DataAccess - // - internal static ArgumentException InvalidKeyname(string parameterName) - { - return Argument(StringsHelper.GetString(Strings.ADP_InvalidKey), parameterName); - } - internal static ArgumentException InvalidValue(string parameterName) - { - return Argument(StringsHelper.GetString(Strings.ADP_InvalidValue), parameterName); - } - internal static Exception InvalidMixedUsageOfAccessTokenAndCredential() - { - return ADP.InvalidOperation(StringsHelper.GetString(Strings.ADP_InvalidMixedUsageOfAccessTokenAndCredential)); - } - - // - // DBDataPermission, DataAccess, Odbc - // - internal static Exception InvalidXMLBadVersion() - { - return Argument(StringsHelper.GetString(Strings.ADP_InvalidXMLBadVersion)); - } - internal static Exception NotAPermissionElement() - { - return Argument(StringsHelper.GetString(Strings.ADP_NotAPermissionElement)); - } - internal static Exception PermissionTypeMismatch() - { - return Argument(StringsHelper.GetString(Strings.ADP_PermissionTypeMismatch)); - } - - // - // DbDataReader - // - internal static Exception NumericToDecimalOverflow() - { - return InvalidCast(StringsHelper.GetString(Strings.ADP_NumericToDecimalOverflow)); - } - - // - // DbDataAdapter - // - internal static InvalidOperationException ComputerNameEx(int lastError) - { - return InvalidOperation(StringsHelper.GetString(Strings.ADP_ComputerNameEx, lastError)); - } - - // - // SNI - // - internal static PlatformNotSupportedException SNIPlatformNotSupported(string platform) => new(StringsHelper.GetString(Strings.SNI_PlatformNotSupportedNetFx, platform)); - - // global constant strings - internal const float FailoverTimeoutStepForTnir = 0.125F; // Fraction of timeout to use in case of Transparent Network IP resolution. - internal const int MinimumTimeoutForTnirMs = 500; // The first login attempt in Transparent network IP Resolution - - internal static readonly int s_ptrSize = IntPtr.Size; - internal static readonly IntPtr s_invalidPtr = new(-1); // use for INVALID_HANDLE - - internal static readonly bool s_isWindowsNT = (PlatformID.Win32NT == Environment.OSVersion.Platform); - internal static readonly bool s_isPlatformNT5 = (ADP.s_isWindowsNT && (Environment.OSVersion.Version.Major >= 5)); - - [FileIOPermission(SecurityAction.Assert, AllFiles = FileIOPermissionAccess.PathDiscovery)] - [ResourceExposure(ResourceScope.Machine)] - [ResourceConsumption(ResourceScope.Machine)] - internal static string GetFullPath(string filename) - { // MDAC 77686 - return Path.GetFullPath(filename); - } - - // TODO: cache machine name and listen to longhorn event to reset it - internal static string GetComputerNameDnsFullyQualified() - { - const int ComputerNameDnsFullyQualified = 3; // winbase.h, enum COMPUTER_NAME_FORMAT - const int ERROR_MORE_DATA = 234; // winerror.h - - string value; - if (s_isPlatformNT5) - { - int length = 0; // length parameter must be zero if buffer is null - // query for the required length - // VSTFDEVDIV 479551 - ensure that GetComputerNameEx does not fail with unexpected values and that the length is positive - int getComputerNameExError = 0; - if (0 == Kernel32Safe.GetComputerNameEx(ComputerNameDnsFullyQualified, null, ref length)) - { - getComputerNameExError = Marshal.GetLastWin32Error(); - } - if ((getComputerNameExError != 0 && getComputerNameExError != ERROR_MORE_DATA) || length <= 0) - { - throw ADP.ComputerNameEx(getComputerNameExError); - } - - StringBuilder buffer = new(length); - length = buffer.Capacity; - if (0 == Kernel32Safe.GetComputerNameEx(ComputerNameDnsFullyQualified, buffer, ref length)) - { - throw ADP.ComputerNameEx(Marshal.GetLastWin32Error()); - } - - // Note: In Longhorn you'll be able to rename a machine without - // rebooting. Therefore, don't cache this machine name. - value = buffer.ToString(); - } - else - { - value = ADP.MachineName(); - } - return value; - } - - internal static IntPtr IntPtrOffset(IntPtr pbase, int offset) - { - if (4 == ADP.s_ptrSize) - { - return (IntPtr)checked(pbase.ToInt32() + offset); - } - Debug.Assert(8 == ADP.s_ptrSize, "8 != IntPtr.Size"); // MDAC 73747 - return (IntPtr)checked(pbase.ToInt64() + offset); - } - -#endregion #else #region netcore project only diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.netfx.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.netfx.cs new file mode 100644 index 0000000000..ed3307d452 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.netfx.cs @@ -0,0 +1,244 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#if NETFRAMEWORK + +using System; +using System.Data; +using System.Diagnostics; +using System.IO; +using System.Runtime.InteropServices; +using System.Runtime.Versioning; +using System.Security.Permissions; +using System.Text; +using System.Threading.Tasks; +using Interop.Windows.Kernel32; + +namespace Microsoft.Data.Common +{ + internal static partial class ADP + { + #region Constants + + /// + /// Fraction of timeout to use in case of Transparent Network IP resolution. + /// + internal const float FailoverTimeoutStepForTnir = 0.125F; + + /// + /// The first login attempt in Transparent network IP Resolution. + /// + internal const int MinimumTimeoutForTnirMs = 500; + + /// + /// Use for INVALID_HANDLE + /// + // @TODO: Use naming rules + internal static readonly IntPtr s_invalidPtr = new(-1); + + // @TODO: Use naming rules + // @TODO: All values but Unix and Windows32NT are used today, for netfx this should always be Win32NT. We can likely hard code this to true for netfx. + internal static readonly bool s_isWindowsNT = Environment.OSVersion.Platform == PlatformID.Win32NT; + + // @TODO: Use naming rules + // @TODO: We don't support anything other than this, so I don't know why we need this anymore. + internal static readonly bool s_isPlatformNT5 = s_isWindowsNT && Environment.OSVersion.Version.Major >= 5; + + // @TODO: Get rid of this and use IntPtr.Size; + // @TODO: Use naming rules + internal static readonly int s_ptrSize = IntPtr.Size; + + #endregion + + #region Utility Methods + + internal static void CheckArgumentLength(string value, string parameterName) + { + CheckArgumentNull(value, parameterName); + if (value.Length == 0) + { + throw Argument(StringsHelper.GetString(Strings.ADP_EmptyString, parameterName)); + } + } + + // @TODO: Replace usages with Task.FromException. + internal static Task CreatedTaskWithException(Exception ex) + { + TaskCompletionSource completion = new(); + completion.SetException(ex); + return completion.Task; + } + + // TODO: cache machine name and listen to longhorn event to reset it + internal static string GetComputerNameDnsFullyQualified() + { + // winbase.h, enum COMPUTER_NAME_FORMAT + const int ComputerNameDnsFullyQualified = 3; + + // winerror.h + // @TODO: Use naming rules + const int ERROR_MORE_DATA = 234; + + string value; + if (s_isPlatformNT5) + { + // Length parameter must be zero if buffer is null + int length = 0; + + // Query for the required length + int getComputerNameExError = 0; + if (Kernel32Safe.GetComputerNameEx(ComputerNameDnsFullyQualified, null, ref length) == 0) + { + getComputerNameExError = Marshal.GetLastWin32Error(); + } + + // Ensure that GetComputerNameEx does not fail with unexpected values and that the + // length is positive + if ((getComputerNameExError != 0 && getComputerNameExError != ERROR_MORE_DATA) || length <= 0) + { + throw ComputerNameEx(getComputerNameExError); + } + + StringBuilder buffer = new(length); + length = buffer.Capacity; + if (Kernel32Safe.GetComputerNameEx(ComputerNameDnsFullyQualified, buffer, ref length) == 0) + { + throw ComputerNameEx(Marshal.GetLastWin32Error()); + } + + // Note: In Longhorn you'll be able to rename a machine without + // rebooting. Therefore, don't cache this machine name. + value = buffer.ToString(); + } + else + { + value = MachineName(); + } + return value; + } + + // @TODO: ........ why do we need this? + [FileIOPermission(SecurityAction.Assert, AllFiles = FileIOPermissionAccess.PathDiscovery)] + [ResourceExposure(ResourceScope.Machine)] + [ResourceConsumption(ResourceScope.Machine)] + internal static string GetFullPath(string filename) => + Path.GetFullPath(filename); + + internal static IntPtr IntPtrOffset(IntPtr pbase, int offset) + { + if (s_ptrSize == 4) + { + return (IntPtr)checked(pbase.ToInt32() + offset); + } + + Debug.Assert(s_ptrSize == 8, "8 != IntPtr.Size"); + + return (IntPtr)checked(pbase.ToInt64() + offset); + } + + #endregion + + #region Exception Throwing Methods (sorted by users) + + // IDbConnection.BeginTransaction + internal static ArgumentOutOfRangeException InvalidIsolationLevel(IsolationLevel value) + { + // @TODO: Use a one line debug assert? + #if DEBUG + switch (value) + { + case IsolationLevel.Unspecified: + case IsolationLevel.Chaos: + case IsolationLevel.ReadUncommitted: + case IsolationLevel.ReadCommitted: + case IsolationLevel.RepeatableRead: + case IsolationLevel.Serializable: + case IsolationLevel.Snapshot: + Debug.Assert(false, "valid IsolationLevel " + value.ToString()); + break; + } + #endif + + return InvalidEnumerationValue(typeof(IsolationLevel), (int)value); + } + + #region DbConnectionOptions, DataAccess + + internal static ArgumentException InvalidKeyname(string parameterName) => + Argument(StringsHelper.GetString(Strings.ADP_InvalidKey), parameterName); + + internal static Exception InvalidMixedUsageOfAccessTokenAndCredential() => + InvalidOperation(StringsHelper.GetString(Strings.ADP_InvalidMixedUsageOfAccessTokenAndCredential)); + + internal static ArgumentException InvalidValue(string parameterName) => + Argument(StringsHelper.GetString(Strings.ADP_InvalidValue), parameterName); + + #endregion + + // DbDataAdapter + internal static InvalidOperationException ComputerNameEx(int lastError) => + InvalidOperation(StringsHelper.GetString(Strings.ADP_ComputerNameEx, lastError)); + + // DBDataPermissionAttribute.KeyRestrictionBehavior + internal static ArgumentOutOfRangeException InvalidKeyRestrictionBehavior(KeyRestrictionBehavior value) + { + // @TODO: Use a one line debug assert? + #if DEBUG + switch (value) + { + case KeyRestrictionBehavior.PreventUsage: + case KeyRestrictionBehavior.AllowOnly: + Debug.Assert(false, "valid KeyRestrictionBehavior " + value.ToString()); + break; + } + #endif + + return InvalidEnumerationValue(typeof(KeyRestrictionBehavior), (int)value); + } + + #region DbDataPermission, DataAccess + + internal static Exception InvalidXMLBadVersion() => + Argument(StringsHelper.GetString(Strings.ADP_InvalidXMLBadVersion)); + + internal static Exception NotAPermissionElement() => + Argument(StringsHelper.GetString(Strings.ADP_NotAPermissionElement)); + + internal static Exception PermissionTypeMismatch() => + Argument(StringsHelper.GetString(Strings.ADP_PermissionTypeMismatch)); + + #endregion + + // DbDataReader + internal static Exception NumericToDecimalOverflow() => + InvalidCast(StringsHelper.GetString(Strings.ADP_NumericToDecimalOverflow)); + + // IDataParameter.Direction + internal static ArgumentOutOfRangeException InvalidParameterDirection(ParameterDirection value) + { + // @TODO: Use a one line debug assert? + #if DEBUG + switch (value) + { + case ParameterDirection.Input: + case ParameterDirection.Output: + case ParameterDirection.InputOutput: + case ParameterDirection.ReturnValue: + Debug.Assert(false, "valid ParameterDirection " + value.ToString()); + break; + } + #endif + + return InvalidEnumerationValue(typeof(ParameterDirection), (int)value); + } + + // SNI + internal static PlatformNotSupportedException SNIPlatformNotSupported(string platform) => + new(StringsHelper.GetString(Strings.SNI_PlatformNotSupportedNetFx, platform)); + + #endregion + } +} + +#endif From 5e5064eaed9fdd3cf7ed41da05fd18212c9cf8cf Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Thu, 20 Nov 2025 18:52:08 -0600 Subject: [PATCH 04/36] Split netcore junk from AdapterUtil into a separate file. Oh wait, two methods that had separate implementations were identical... --- .../src/Microsoft/Data/Common/AdapterUtil.cs | 106 ++++++++---------- .../Data/Common/AdapterUtil.netcore.cs | 26 +++++ .../Data/Common/AdapterUtil.netfx.cs | 41 ------- 3 files changed, 70 insertions(+), 103 deletions(-) create mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.netcore.cs 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 75daeaa47c..05bb20385b 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs @@ -4,15 +4,17 @@ using System; using System.Collections; +using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Data.SqlTypes; using System.Diagnostics; using System.Globalization; using System.IO; +using System.Reflection; using System.Runtime.CompilerServices; - using System.Security; +using System.Security.Authentication; using System.Security.Permissions; using System.Text; using System.Threading; @@ -20,19 +22,9 @@ using System.Transactions; using Microsoft.Data.Common.ConnectionString; using Microsoft.Data.SqlClient; -using IsolationLevel = System.Data.IsolationLevel; using Microsoft.Identity.Client; using Microsoft.SqlServer.Server; -using System.Security.Authentication; -using System.Collections.Generic; - -#if NETFRAMEWORK -using System.Reflection; -using System.Runtime.ConstrainedExecution; -using System.Runtime.InteropServices; -using System.Runtime.Versioning; -using Interop.Windows.Kernel32; -#endif +using IsolationLevel = System.Data.IsolationLevel; namespace Microsoft.Data.Common { @@ -76,6 +68,7 @@ internal static partial class ADP /// internal static InvalidUdtException CreateInvalidUdtException(Type udtType, string resourceReasonName) { + // @TODO: Can we adopt the netcore version? InvalidUdtException e = #if NETFRAMEWORK (InvalidUdtException)s_method.Invoke(null, new object[] { udtType, resourceReasonName }); @@ -954,6 +947,27 @@ private static string ConnectionStateMsg(ConnectionState state) }; } + internal static ArgumentOutOfRangeException InvalidIsolationLevel(IsolationLevel value) + { + // @TODO: Use single line debug assert? + #if DEBUG + switch (value) + { + case IsolationLevel.Unspecified: + case IsolationLevel.Chaos: + case IsolationLevel.ReadUncommitted: + case IsolationLevel.ReadCommitted: + case IsolationLevel.RepeatableRead: + case IsolationLevel.Serializable: + case IsolationLevel.Snapshot: + Debug.Fail("valid IsolationLevel " + value.ToString()); + break; + } + #endif + + return InvalidEnumerationValue(typeof(IsolationLevel), (int)value); + } + internal static InvalidOperationException NoConnectionString() => InvalidOperation(StringsHelper.GetString(Strings.ADP_NoConnectionString)); @@ -1296,6 +1310,24 @@ internal static ArgumentException UnknownDataTypeCode(Type dataType, TypeCode ty internal static ArgumentException InvalidOffsetValue(int value) => Argument(StringsHelper.GetString(Strings.ADP_InvalidOffsetValue, value.ToString(CultureInfo.InvariantCulture))); + internal static ArgumentOutOfRangeException InvalidParameterDirection(ParameterDirection value) + { + // @TODO: Use single line debug assert? + #if DEBUG + switch (value) + { + case ParameterDirection.Input: + case ParameterDirection.Output: + case ParameterDirection.InputOutput: + case ParameterDirection.ReturnValue: + Debug.Fail("valid ParameterDirection " + value.ToString()); + break; + } + #endif + + return InvalidEnumerationValue(typeof(ParameterDirection), (int)value); + } + internal static ArgumentException InvalidSizeValue(int value) => Argument(StringsHelper.GetString(Strings.ADP_InvalidSizeValue, value.ToString(CultureInfo.InvariantCulture))); @@ -1396,55 +1428,5 @@ internal static Exception InvalidMixedUsageOfAccessTokenCallbackAndIntegratedSec #endregion internal static readonly IntPtr s_ptrZero = IntPtr.Zero; -#if NETFRAMEWORK -#else -#region netcore project only - - // - // COM+ exceptions - // - internal static PlatformNotSupportedException DbTypeNotSupported(string dbType) => new(StringsHelper.GetString(Strings.SQL_DbTypeNotSupportedOnThisPlatform, dbType)); - - // IDbConnection.BeginTransaction, OleDbTransaction.Begin - internal static ArgumentOutOfRangeException InvalidIsolationLevel(IsolationLevel value) - { -#if DEBUG - switch (value) - { - case IsolationLevel.Unspecified: - case IsolationLevel.Chaos: - case IsolationLevel.ReadUncommitted: - case IsolationLevel.ReadCommitted: - case IsolationLevel.RepeatableRead: - case IsolationLevel.Serializable: - case IsolationLevel.Snapshot: - Debug.Fail("valid IsolationLevel " + value.ToString()); - break; - } -#endif - return InvalidEnumerationValue(typeof(IsolationLevel), (int)value); - } - - // ConnectionUtil - internal static Exception IncorrectPhysicalConnectionType() => new ArgumentException(StringsHelper.GetString(StringsHelper.SNI_IncorrectPhysicalConnectionType)); - - // IDataParameter.Direction - internal static ArgumentOutOfRangeException InvalidParameterDirection(ParameterDirection value) - { -#if DEBUG - switch (value) - { - case ParameterDirection.Input: - case ParameterDirection.Output: - case ParameterDirection.InputOutput: - case ParameterDirection.ReturnValue: - Debug.Fail("valid ParameterDirection " + value.ToString()); - break; - } -#endif - return InvalidEnumerationValue(typeof(ParameterDirection), (int)value); - } -#endregion -#endif } } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.netcore.cs new file mode 100644 index 0000000000..4b28afac43 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.netcore.cs @@ -0,0 +1,26 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#if NET + +using System; +using System.Data; +using System.Diagnostics; +using IsolationLevel = System.Data.IsolationLevel; + +namespace Microsoft.Data.Common +{ + internal static partial class ADP + { + // COM+ + internal static PlatformNotSupportedException DbTypeNotSupported(string dbType) => + new(StringsHelper.GetString(Strings.SQL_DbTypeNotSupportedOnThisPlatform, dbType)); + + // ConnectionUtil + internal static Exception IncorrectPhysicalConnectionType() => + new ArgumentException(StringsHelper.GetString(Strings.SNI_IncorrectPhysicalConnectionType)); + } +} + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.netfx.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.netfx.cs index ed3307d452..5400eb9b0d 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.netfx.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.netfx.cs @@ -141,28 +141,6 @@ internal static IntPtr IntPtrOffset(IntPtr pbase, int offset) #region Exception Throwing Methods (sorted by users) - // IDbConnection.BeginTransaction - internal static ArgumentOutOfRangeException InvalidIsolationLevel(IsolationLevel value) - { - // @TODO: Use a one line debug assert? - #if DEBUG - switch (value) - { - case IsolationLevel.Unspecified: - case IsolationLevel.Chaos: - case IsolationLevel.ReadUncommitted: - case IsolationLevel.ReadCommitted: - case IsolationLevel.RepeatableRead: - case IsolationLevel.Serializable: - case IsolationLevel.Snapshot: - Debug.Assert(false, "valid IsolationLevel " + value.ToString()); - break; - } - #endif - - return InvalidEnumerationValue(typeof(IsolationLevel), (int)value); - } - #region DbConnectionOptions, DataAccess internal static ArgumentException InvalidKeyname(string parameterName) => @@ -214,25 +192,6 @@ internal static Exception PermissionTypeMismatch() => internal static Exception NumericToDecimalOverflow() => InvalidCast(StringsHelper.GetString(Strings.ADP_NumericToDecimalOverflow)); - // IDataParameter.Direction - internal static ArgumentOutOfRangeException InvalidParameterDirection(ParameterDirection value) - { - // @TODO: Use a one line debug assert? - #if DEBUG - switch (value) - { - case ParameterDirection.Input: - case ParameterDirection.Output: - case ParameterDirection.InputOutput: - case ParameterDirection.ReturnValue: - Debug.Assert(false, "valid ParameterDirection " + value.ToString()); - break; - } - #endif - - return InvalidEnumerationValue(typeof(ParameterDirection), (int)value); - } - // SNI internal static PlatformNotSupportedException SNIPlatformNotSupported(string platform) => new(StringsHelper.GetString(Strings.SNI_PlatformNotSupportedNetFx, platform)); From f5e7ac986f1d2a9e684d91641636705ce518fed1 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Fri, 21 Nov 2025 11:53:51 -0600 Subject: [PATCH 05/36] Merge the unix and windows version of AdapterUtil back into the main partial. This file is too big to come up with a consistent way to split all this stuff up. --- .../Microsoft/Data/Common/AdapterUtil.Unix.cs | 24 --------- .../Data/Common/AdapterUtil.Windows.cs | 54 ------------------- .../src/Microsoft/Data/Common/AdapterUtil.cs | 54 ++++++++++++++++++- 3 files changed, 52 insertions(+), 80 deletions(-) delete mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.Unix.cs delete mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.Windows.cs diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.Unix.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.Unix.cs deleted file mode 100644 index 8b84feecfc..0000000000 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.Unix.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Data.Common -{ - /// - /// The class ADP defines the exceptions that are specific to the Adapters. - /// The class contains functions that take the proper informational variables and then construct - /// the appropriate exception with an error string obtained from the resource framework. - /// The exception is then returned to the caller, so that the caller may then throw from its - /// location so that the catcher of the exception will have the appropriate call stack. - /// This class is used so that there will be compile time checking of error messages. - /// The resource Framework.txt will ensure proper string text based on the appropriate locale. - /// - internal static partial class ADP - { - internal static object LocalMachineRegistryValue(string subkey, string queryvalue) - { - // No registry in non-Windows environments - return null; - } - } -} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.Windows.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.Windows.cs deleted file mode 100644 index 6fbdfcb343..0000000000 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.Windows.cs +++ /dev/null @@ -1,54 +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.Runtime.InteropServices; -using System.Runtime.Versioning; -using System.Security; -using System.Security.Permissions; -using Microsoft.Win32; - -namespace Microsoft.Data.Common -{ - /// - /// The class ADP defines the exceptions that are specific to the Adapters. - /// The class contains functions that take the proper informational variables and then construct - /// the appropriate exception with an error string obtained from the resource framework. - /// The exception is then returned to the caller, so that the caller may then throw from its - /// location so that the catcher of the exception will have the appropriate call stack. - /// This class is used so that there will be compile time checking of error messages. - /// The resource Framework.txt will ensure proper string text based on the appropriate locale. - /// - internal static partial class ADP - { - [ResourceExposure(ResourceScope.Machine)] - [ResourceConsumption(ResourceScope.Machine)] - internal static object LocalMachineRegistryValue(string subkey, string queryvalue) - { // MDAC 77697 -#if NETFRAMEWORK - (new RegistryPermission(RegistryPermissionAccess.Read, "HKEY_LOCAL_MACHINE\\" + subkey)).Assert(); // MDAC 62028 -#endif - try - { - using (RegistryKey key = Registry.LocalMachine.OpenSubKey(subkey, false)) - { - return key?.GetValue(queryvalue); - } - } - catch (SecurityException e) - { - // Even though we assert permission - it's possible there are - // ACL's on registry that cause SecurityException to be thrown. - ADP.TraceExceptionWithoutRethrow(e); - return null; - } -#if NETFRAMEWORK - finally - { - RegistryPermission.RevertAssert(); - } -#endif - } - } -} 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 05bb20385b..48c99d4439 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs @@ -11,11 +11,9 @@ using System.Diagnostics; using System.Globalization; using System.IO; -using System.Reflection; using System.Runtime.CompilerServices; using System.Security; using System.Security.Authentication; -using System.Security.Permissions; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -26,6 +24,17 @@ using Microsoft.SqlServer.Server; using IsolationLevel = System.Data.IsolationLevel; +#if NETFRAMEWORK +using System.Reflection; +using System.Security.Permissions; +using Microsoft.SqlServer.Server; +#endif + +#if _WINDOWS +using System.Runtime.Versioning; +using Microsoft.Win32; +#endif + namespace Microsoft.Data.Common { /// @@ -37,6 +46,7 @@ namespace Microsoft.Data.Common /// This class is used so that there will be compile time checking of error messages. /// The resource Framework.txt will ensure proper string text based on the appropriate locale. /// + // @TODO: This file needs to be broken up internal static partial class ADP { // NOTE: Initializing a Task in SQL CLR requires the "UNSAFE" permission set (http://msdn.microsoft.com/en-us/library/ms172338.aspx) @@ -427,6 +437,46 @@ internal static ArgumentOutOfRangeException InvalidCommandBehavior(CommandBehavi return InvalidEnumerationValue(typeof(CommandBehavior), (int)value); } + + #if _UNIX + internal static object LocalMachineRegistryValue(string subkey, string queryvalue) + { + // No registry in non-Windows environments + return null; + } + #endif + #if _WINDOWS + [ResourceExposure(ResourceScope.Machine)] + [ResourceConsumption(ResourceScope.Machine)] + internal static object LocalMachineRegistryValue(string subkey, string queryvalue) + { + #if NETFRAMEWORK + new RegistryPermission(RegistryPermissionAccess.Read, $@"HKEY_LOCAL_MACHINE\{subkey}").Assert(); + #endif + + try + { + using (RegistryKey key = Registry.LocalMachine.OpenSubKey(subkey, false)) + { + return key?.GetValue(queryvalue); + } + } + catch (SecurityException e) + { + // Even though we assert permission - it's possible there are + // ACL's on registry that cause SecurityException to be thrown. + ADP.TraceExceptionWithoutRethrow(e); + return null; + } + #if NETFRAMEWORK + finally + { + CodeAccessPermission.RevertAssert(); + } + #endif + } + #endif + internal static void ValidateCommandBehavior(CommandBehavior value) { if (((int)value < 0) || (0x3F < (int)value)) From 06395877235daaa589b502118a90f30672a2115a Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Wed, 19 Nov 2025 13:00:51 -0600 Subject: [PATCH 06/36] Consolidate windows/unix versions of SqlDataSourceEnumerator into one file --- .../Sql/SqlDataSourceEnumerator.Windows.cs | 22 ---------------- .../Data/Sql/SqlDataSourceEnumerator.cs | 25 ++++++++++++++++--- .../SqlDataSourceEnumerator.netcore.Unix.cs | 20 --------------- 3 files changed, 21 insertions(+), 46 deletions(-) delete mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumerator.Windows.cs delete mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumerator.netcore.Unix.cs diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumerator.Windows.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumerator.Windows.cs deleted file mode 100644 index f92e9beb32..0000000000 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumerator.Windows.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. -using System.Data; -using System.Data.Common; -using Microsoft.Data.SqlClient.Server; - -namespace Microsoft.Data.Sql -{ - /// - public sealed partial class SqlDataSourceEnumerator : DbDataSourceEnumerator - { - private partial DataTable GetDataSourcesInternal() - { -#if NETFRAMEWORK - return SqlDataSourceEnumeratorNativeHelper.GetDataSources(); -#else - return SqlClient.LocalAppContextSwitches.UseManagedNetworking ? SqlDataSourceEnumeratorManagedHelper.GetDataSources() : SqlDataSourceEnumeratorNativeHelper.GetDataSources(); -#endif - } - } -} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumerator.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumerator.cs index 496c887294..0356d7bcd3 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumerator.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumerator.cs @@ -4,22 +4,39 @@ using System; using System.Data; using System.Data.Common; +using Microsoft.Data.SqlClient.Server; namespace Microsoft.Data.Sql { /// public sealed partial class SqlDataSourceEnumerator : DbDataSourceEnumerator { - private static readonly Lazy s_singletonInstance = new(() => new SqlDataSourceEnumerator()); + private static readonly Lazy s_singletonInstance = + new(() => new SqlDataSourceEnumerator()); - private SqlDataSourceEnumerator() : base(){} + private SqlDataSourceEnumerator() : base() + { + } /// public static SqlDataSourceEnumerator Instance => s_singletonInstance.Value; /// - override public DataTable GetDataSources() => GetDataSourcesInternal(); + public override DataTable GetDataSources() + { + #if NETFRAMEWORK + return SqlDataSourceEnumeratorNativeHelper.GetDataSources(); + #else - private partial DataTable GetDataSourcesInternal(); + #if _UNIX + return SqlDataSourceEnumeratorManagedHelper.GetDataSources(); + #else + return SqlClient.LocalAppContextSwitches.UseManagedNetworking + ? SqlDataSourceEnumeratorManagedHelper.GetDataSources() + : SqlDataSourceEnumeratorNativeHelper.GetDataSources(); + #endif + + #endif + } } } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumerator.netcore.Unix.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumerator.netcore.Unix.cs deleted file mode 100644 index 196e38b579..0000000000 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumerator.netcore.Unix.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -#if NET - -using System.Data; -using System.Data.Common; -using Microsoft.Data.SqlClient.Server; - -namespace Microsoft.Data.Sql -{ - /// - public sealed partial class SqlDataSourceEnumerator : DbDataSourceEnumerator - { - private partial DataTable GetDataSourcesInternal() => SqlDataSourceEnumeratorManagedHelper.GetDataSources(); - } -} - -#endif From cd0158eef05ee21dd5b6762058a13096f7815f4c Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Wed, 19 Nov 2025 13:57:26 -0600 Subject: [PATCH 07/36] Merging DbConnectionPoolIdentity os-specific versions into the generic class. Cleaned up some code (removed redundant parentheses, split some long lines, removed always-false variables) --- .../DbConnectionPoolIdentity.Unix.cs | 14 --- .../DbConnectionPoolIdentity.Windows.cs | 66 ----------- .../DbConnectionPoolIdentity.cs | 107 +++++++++++++++--- 3 files changed, 92 insertions(+), 95 deletions(-) delete mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/DbConnectionPoolIdentity.Unix.cs delete mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/DbConnectionPoolIdentity.Windows.cs diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/DbConnectionPoolIdentity.Unix.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/DbConnectionPoolIdentity.Unix.cs deleted file mode 100644 index 3eadc8761a..0000000000 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/DbConnectionPoolIdentity.Unix.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Data.SqlClient.ConnectionPool -{ - partial class DbConnectionPoolIdentity - { - internal static DbConnectionPoolIdentity GetCurrent() - { - return GetCurrentManaged(); - } - } -} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/DbConnectionPoolIdentity.Windows.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/DbConnectionPoolIdentity.Windows.cs deleted file mode 100644 index 0c6fd07503..0000000000 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/DbConnectionPoolIdentity.Windows.cs +++ /dev/null @@ -1,66 +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.Runtime.Versioning; -using System.Security.Permissions; -using System.Security.Principal; -using Microsoft.Data.SqlClient; - -namespace Microsoft.Data.SqlClient.ConnectionPool -{ - partial class DbConnectionPoolIdentity - { -#if NETFRAMEWORK - [ResourceExposure(ResourceScope.None)] // SxS: this method does not create named objects - [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)] - internal static DbConnectionPoolIdentity GetCurrent() - { - return GetCurrentNative(); - } - - [SecurityPermission(SecurityAction.Assert, Flags = SecurityPermissionFlag.ControlPrincipal)] - internal static WindowsIdentity GetCurrentWindowsIdentity() - { - return WindowsIdentity.GetCurrent(); - } -#else - internal static DbConnectionPoolIdentity GetCurrent() - { - return LocalAppContextSwitches.UseManagedNetworking ? GetCurrentManaged() : GetCurrentNative(); - } -#endif - - private static DbConnectionPoolIdentity GetCurrentNative() - { - DbConnectionPoolIdentity current; - using (WindowsIdentity identity = WindowsIdentity.GetCurrent()) - { - IntPtr token = identity.AccessToken.DangerousGetHandle(); - SecurityIdentifier user = identity.User; - bool isNetwork = user.IsWellKnown(WellKnownSidType.NetworkSid); - string sidString = user.Value; - - // Win32NativeMethods.IsTokenRestricted will raise exception if the native call fails - SniNativeWrapper.SniIsTokenRestricted(token, out bool isRestricted); - - var lastIdentity = s_lastIdentity; - if (lastIdentity != null && - lastIdentity._sidString == sidString && - lastIdentity._isRestricted == isRestricted && - lastIdentity._isNetwork == isNetwork) - { - current = lastIdentity; - } - else - { - current = new DbConnectionPoolIdentity(sidString, isRestricted, isNetwork); - } - } - s_lastIdentity = current; - return current; - } - } -} - diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/DbConnectionPoolIdentity.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/DbConnectionPoolIdentity.cs index 5716146a6b..725ba5dc4f 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/DbConnectionPoolIdentity.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/DbConnectionPoolIdentity.cs @@ -2,11 +2,23 @@ // 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; + +#if NETFRAMEWORK +using System.Runtime.Versioning; +#endif + +#if _WINDOWS +using System.Security.Principal; +#endif + namespace Microsoft.Data.SqlClient.ConnectionPool { - sealed internal partial class DbConnectionPoolIdentity + internal sealed partial class DbConnectionPoolIdentity { - public static readonly DbConnectionPoolIdentity NoIdentity = new DbConnectionPoolIdentity(string.Empty, false, true); + public static readonly DbConnectionPoolIdentity NoIdentity = + new DbConnectionPoolIdentity(sidString: string.Empty, isRestricted: false, isNetwork: true); + private static DbConnectionPoolIdentity s_lastIdentity = null; private readonly string _sidString; @@ -22,49 +34,114 @@ private DbConnectionPoolIdentity(string sidString, bool isRestricted, bool isNet _hashCode = sidString == null ? 0 : sidString.GetHashCode(); } + // @TODO: Make auto-property internal bool IsRestricted { get { return _isRestricted; } } - - override public bool Equals(object value) + public override bool Equals(object value) { - bool result = ((this == NoIdentity) || (this == value)); + bool result = this == NoIdentity || this == value; if (!result && value != null) { - DbConnectionPoolIdentity that = ((DbConnectionPoolIdentity)value); - result = ((_sidString == that._sidString) && (_isRestricted == that._isRestricted) && (_isNetwork == that._isNetwork)); + DbConnectionPoolIdentity that = (DbConnectionPoolIdentity)value; + result = _sidString == that._sidString && + _isRestricted == that._isRestricted && + _isNetwork == that._isNetwork; } + return result; } - override public int GetHashCode() + public override int GetHashCode() { return _hashCode; } + #if NETFRAMEWORK + [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)] + [ResourceExposure(ResourceScope.None)] // SxS: this method does not create named objects + #endif + internal static DbConnectionPoolIdentity GetCurrent() + { + #if NETFRAMEWORK + return GetCurrentNative(); + #else + + #if _UNIX + return GetCurrentManaged(); + #else + return LocalAppContextSwitches.UseManagedNetworking + ? GetCurrentManaged() + : GetCurrentNative(); + #endif + + #endif + } + + #if NETFRAMEWORK + internal static WindowsIdentity GetCurrentWindowsIdentity() => + WindowsIdentity.GetCurrent(); + #endif + private static DbConnectionPoolIdentity GetCurrentManaged() { - DbConnectionPoolIdentity current; - string domainString = System.Environment.UserDomainName; - string sidString = (!string.IsNullOrWhiteSpace(domainString) ? domainString + "\\" : "") + System.Environment.UserName; - bool isNetwork = false; - bool isRestricted = false; + string domainString = Environment.UserDomainName; + string sidString = string.IsNullOrWhiteSpace(domainString) + ? Environment.UserName + : $@"{domainString}\{Environment.UserName}"; var lastIdentity = s_lastIdentity; - if ((lastIdentity != null) && (lastIdentity._sidString == sidString) && (lastIdentity._isRestricted == isRestricted) && (lastIdentity._isNetwork == isNetwork)) + DbConnectionPoolIdentity current; + if (lastIdentity != null && + lastIdentity._sidString == sidString && + !lastIdentity._isRestricted && + !lastIdentity._isNetwork) { current = lastIdentity; } else { - current = new DbConnectionPoolIdentity(sidString, isRestricted, isNetwork); + current = new DbConnectionPoolIdentity(sidString, isRestricted: false, isNetwork: false); + } + + s_lastIdentity = current; + return current; + } + + #if _WINDOWS + private static DbConnectionPoolIdentity GetCurrentNative() + { + DbConnectionPoolIdentity current; + using (WindowsIdentity identity = WindowsIdentity.GetCurrent()) + { + IntPtr token = identity.AccessToken.DangerousGetHandle(); + SecurityIdentifier user = identity.User; + bool isNetwork = user.IsWellKnown(WellKnownSidType.NetworkSid); + string sidString = user.Value; + + // Win32NativeMethods.IsTokenRestricted will raise exception if the native call fails + SniNativeWrapper.SniIsTokenRestricted(token, out bool isRestricted); + + var lastIdentity = s_lastIdentity; + if (lastIdentity != null && + lastIdentity._sidString == sidString && + lastIdentity._isRestricted == isRestricted && + lastIdentity._isNetwork == isNetwork) + { + current = lastIdentity; + } + else + { + current = new DbConnectionPoolIdentity(sidString, isRestricted, isNetwork); + } } s_lastIdentity = current; return current; } + #endif } } From 61fa101ab14bd3b998b2da2558e4ff31fe3ab0c9 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Wed, 19 Nov 2025 14:00:13 -0600 Subject: [PATCH 08/36] Add os #if wrappers to LocalDbApi --- .../LocalDb/{LocalDbApi.Unix.cs => LocalDbApi.unix.cs} | 4 ++++ .../{LocalDbApi.Windows.cs => LocalDbApi.windows.cs} | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) rename src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalDb/{LocalDbApi.Unix.cs => LocalDbApi.unix.cs} (97%) rename src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalDb/{LocalDbApi.Windows.cs => LocalDbApi.windows.cs} (99%) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalDb/LocalDbApi.Unix.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalDb/LocalDbApi.unix.cs similarity index 97% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalDb/LocalDbApi.Unix.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalDb/LocalDbApi.unix.cs index e6f7bcbd1e..b016c7dc97 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalDb/LocalDbApi.Unix.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalDb/LocalDbApi.unix.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. +#if _UNIX + using System; namespace Microsoft.Data.SqlClient.LocalDb @@ -15,3 +17,5 @@ internal static string GetLocalDbMessage(int hrCode) => throw new PlatformNotSupportedException(Strings.LocalDBNotSupported); // LocalDB is not available for Unix and hence it cannot be supported. } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalDb/LocalDbApi.Windows.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalDb/LocalDbApi.windows.cs similarity index 99% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalDb/LocalDbApi.Windows.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalDb/LocalDbApi.windows.cs index e64d4fcf2f..9a922c3286 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalDb/LocalDbApi.Windows.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalDb/LocalDbApi.windows.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. +#if _WINDOWS + using System; using System.Diagnostics; using System.Globalization; @@ -14,8 +16,6 @@ #if NETFRAMEWORK using System.Collections.Generic; using System.Configuration; -using System.Runtime.CompilerServices; -using System.Threading; #endif namespace Microsoft.Data.SqlClient.LocalDb @@ -421,3 +421,5 @@ internal InstanceInfo(string version) #endif } } + +#endif From 9908a501fcca16f379c0ed46d3c31866e1ad68e2 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Wed, 19 Nov 2025 14:10:02 -0600 Subject: [PATCH 09/36] Apply #if wrappers to LocalDB files --- .../{LocalDB.netcore.Unix.cs => LocalDB.netcore.unix.cs} | 2 +- .../{LocalDB.netcore.Windows.cs => LocalDB.netcore.windows.cs} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/{LocalDB.netcore.Unix.cs => LocalDB.netcore.unix.cs} (97%) rename src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/{LocalDB.netcore.Windows.cs => LocalDB.netcore.windows.cs} (99%) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/LocalDB.netcore.Unix.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/LocalDB.netcore.unix.cs similarity index 97% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/LocalDB.netcore.Unix.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/LocalDB.netcore.unix.cs index 8ab05865a2..64ba1da0f8 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/LocalDB.netcore.Unix.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/LocalDB.netcore.unix.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if NET +#if NET && _UNIX using System; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/LocalDB.netcore.Windows.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/LocalDB.netcore.windows.cs similarity index 99% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/LocalDB.netcore.Windows.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/LocalDB.netcore.windows.cs index 6f9452b420..b949e494d7 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/LocalDB.netcore.Windows.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/LocalDB.netcore.windows.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if NET +#if NET && _WINDOWS using System; using System.Runtime.InteropServices; From a2043d3cbc080e04978db18304e388880122dce2 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Wed, 19 Nov 2025 14:22:21 -0600 Subject: [PATCH 10/36] Merge the SslOverTdsStream files together --- .../ManagedSni/SslOverTdsStream.NetCoreApp.cs | 299 ------------------ .../ManagedSni/SslOverTdsStream.netcore.cs | 298 +++++++++++++++++ 2 files changed, 298 insertions(+), 299 deletions(-) delete mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SslOverTdsStream.NetCoreApp.cs diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SslOverTdsStream.NetCoreApp.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SslOverTdsStream.NetCoreApp.cs deleted file mode 100644 index ff3358c50a..0000000000 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SslOverTdsStream.NetCoreApp.cs +++ /dev/null @@ -1,299 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -#if NET - -using System; -using System.Buffers; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.Data.SqlClient.ManagedSni -{ - internal sealed partial class SslOverTdsStream - { - public override int Read(byte[] buffer, int offset, int count) => - Read(buffer.AsSpan(offset, count)); - - public override void Write(byte[] buffer, int offset, int count) => - Write(buffer.AsSpan(offset, count)); - - public override Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) => - ReadAsync(new Memory(buffer, offset, count), cancellationToken).AsTask(); - - public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) => - WriteAsync(new ReadOnlyMemory(buffer, offset, count), cancellationToken).AsTask(); - - public override int Read(Span buffer) - { - using (TrySNIEventScope.Create(nameof(SslOverTdsStream))) - { - if (!_encapsulate) - { - return _stream.Read(buffer); - } - if (_packetBytes > 0) - { - // there are queued bytes from a previous packet available - // work out how many of the remaining bytes we can consume - int wantedCount = Math.Min(buffer.Length, _packetBytes); - int readCount = _stream.Read(buffer.Slice(0, wantedCount)); - if (readCount == 0) - { - // 0 means the connection was closed, tell the caller - return 0; - } - _packetBytes -= readCount; - return readCount; - } - else - { - Span headerBytes = stackalloc byte[TdsEnums.HEADER_LEN]; - - // fetch the packet header to determine how long the packet is - int headerBytesRead = 0; - do - { - int headerBytesReadIteration = _stream.Read(headerBytes.Slice(headerBytesRead, TdsEnums.HEADER_LEN - headerBytesRead)); - if (headerBytesReadIteration == 0) - { - // 0 means the connection was closed, tell the caller - return 0; - } - headerBytesRead += headerBytesReadIteration; - } while (headerBytesRead < TdsEnums.HEADER_LEN); - - // read the packet data size from the header and store it in case it is needed for a subsequent call - _packetBytes = ((headerBytes[TdsEnums.HEADER_LEN_FIELD_OFFSET] << 8) | headerBytes[TdsEnums.HEADER_LEN_FIELD_OFFSET + 1]) - TdsEnums.HEADER_LEN; - - // read as much from the packet as the caller can accept - int packetBytesRead = _stream.Read(buffer.Slice(0, Math.Min(buffer.Length, _packetBytes))); - _packetBytes -= packetBytesRead; - return packetBytesRead; - } - } - } - - public override async ValueTask ReadAsync(Memory buffer, CancellationToken cancellationToken = default) - { - using (TrySNIEventScope.Create(nameof(SslOverTdsStream))) - { - if (!_encapsulate) - { - int read; - { - ValueTask readValueTask = _stream.ReadAsync(buffer, cancellationToken); - if (readValueTask.IsCompletedSuccessfully) - { - read = readValueTask.Result; - } - else - { - read = await readValueTask.ConfigureAwait(false); - } - } - return read; - } - if (_packetBytes > 0) - { - // there are queued bytes from a previous packet available - // work out how many of the remaining bytes we can consume - int wantedCount = Math.Min(buffer.Length, _packetBytes); - - int readCount; - { - ValueTask remainderReadValueTask = _stream.ReadAsync(buffer.Slice(0, wantedCount), cancellationToken); - if (remainderReadValueTask.IsCompletedSuccessfully) - { - readCount = remainderReadValueTask.Result; - } - else - { - readCount = await remainderReadValueTask.ConfigureAwait(false); - } - } - if (readCount == 0) - { - // 0 means the connection was closed, tell the caller - return 0; - } - _packetBytes -= readCount; - return readCount; - } - else - { - byte[] headerBytes = ArrayPool.Shared.Rent(TdsEnums.HEADER_LEN); - - // fetch the packet header to determine how long the packet is - int headerBytesRead = 0; - do - { - int headerBytesReadIteration; - { - ValueTask headerReadValueTask = _stream.ReadAsync(headerBytes.AsMemory(headerBytesRead, (TdsEnums.HEADER_LEN - headerBytesRead)), cancellationToken); - if (headerReadValueTask.IsCompletedSuccessfully) - { - headerBytesReadIteration = headerReadValueTask.Result; - } - else - { - headerBytesReadIteration = await headerReadValueTask.ConfigureAwait(false); - } - } - if (headerBytesReadIteration == 0) - { - // 0 means the connection was closed, cleanup the rented array and then tell the caller - ArrayPool.Shared.Return(headerBytes, clearArray: true); - return 0; - } - headerBytesRead += headerBytesReadIteration; - } while (headerBytesRead < TdsEnums.HEADER_LEN); - - // read the packet data size from the header and store it in case it is needed for a subsequent call - _packetBytes = ((headerBytes[TdsEnums.HEADER_LEN_FIELD_OFFSET] << 8) | headerBytes[TdsEnums.HEADER_LEN_FIELD_OFFSET + 1]) - TdsEnums.HEADER_LEN; - - ArrayPool.Shared.Return(headerBytes, clearArray: true); - - // read as much from the packet as the caller can accept - int packetBytesRead; - { - ValueTask packetReadValueTask = _stream.ReadAsync(buffer.Slice(0, Math.Min(buffer.Length, _packetBytes)), cancellationToken); - if (packetReadValueTask.IsCompletedSuccessfully) - { - packetBytesRead = packetReadValueTask.Result; - } - else - { - packetBytesRead = await packetReadValueTask.ConfigureAwait(false); - } - } - _packetBytes -= packetBytesRead; - return packetBytesRead; - } - } - } - - public override void Write(ReadOnlySpan buffer) - { - using (TrySNIEventScope.Create(nameof(SslOverTdsStream))) - { - // During the SSL negotiation phase, SSL is tunnelled over TDS packet type 0x12. After - // negotiation, the underlying socket only sees SSL frames. - if (!_encapsulate) - { - _stream.Write(buffer); - _stream.Flush(); - return; - } - - ReadOnlySpan remaining = buffer; - byte[] packetBuffer = null; - try - { - while (remaining.Length > 0) - { - int dataLength = Math.Min(PACKET_SIZE_WITHOUT_HEADER, remaining.Length); - int packetLength = TdsEnums.HEADER_LEN + dataLength; - - if (packetBuffer == null) - { - packetBuffer = ArrayPool.Shared.Rent(packetLength); - } - else if (packetBuffer.Length < packetLength) - { - ArrayPool.Shared.Return(packetBuffer, clearArray: true); - packetBuffer = ArrayPool.Shared.Rent(packetLength); - } - - SetupPreLoginPacketHeader(packetBuffer, dataLength, remaining.Length - dataLength); - - Span data = packetBuffer.AsSpan(TdsEnums.HEADER_LEN, dataLength); - remaining.Slice(0, dataLength).CopyTo(data); - - _stream.Write(packetBuffer.AsSpan(0, packetLength)); - _stream.Flush(); - - remaining = remaining.Slice(dataLength); - } - } - finally - { - if (packetBuffer != null) - { - ArrayPool.Shared.Return(packetBuffer, clearArray: true); - } - } - } - } - - public override async ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) - { - using (TrySNIEventScope.Create(nameof(SslOverTdsStream))) - { - if (!_encapsulate) - { - { - ValueTask valueTask = _stream.WriteAsync(buffer, cancellationToken); - if (!valueTask.IsCompletedSuccessfully) - { - await valueTask.ConfigureAwait(false); - } - } - Task flushTask = _stream.FlushAsync(); - if (flushTask.IsCompletedSuccessfully) - { - await flushTask.ConfigureAwait(false); - } - return; - } - - ReadOnlyMemory remaining = buffer; - byte[] packetBuffer = null; - try - { - while (remaining.Length > 0) - { - int dataLength = Math.Min(PACKET_SIZE_WITHOUT_HEADER, remaining.Length); - int packetLength = TdsEnums.HEADER_LEN + dataLength; - - if (packetBuffer == null) - { - packetBuffer = ArrayPool.Shared.Rent(packetLength); - } - else if (packetBuffer.Length < packetLength) - { - ArrayPool.Shared.Return(packetBuffer, clearArray: true); - packetBuffer = ArrayPool.Shared.Rent(packetLength); - } - - SetupPreLoginPacketHeader(packetBuffer, dataLength, remaining.Length - dataLength); - - remaining.Span.Slice(0, dataLength).CopyTo(packetBuffer.AsSpan(TdsEnums.HEADER_LEN, dataLength)); - - { - ValueTask packetWriteValueTask = _stream.WriteAsync(new ReadOnlyMemory(packetBuffer, 0, packetLength), cancellationToken); - if (!packetWriteValueTask.IsCompletedSuccessfully) - { - await packetWriteValueTask.ConfigureAwait(false); - } - } - - await _stream.FlushAsync().ConfigureAwait(false); - - remaining = remaining.Slice(dataLength); - } - } - finally - { - if (packetBuffer != null) - { - ArrayPool.Shared.Return(packetBuffer, clearArray: true); - } - } - } - } - } -} - -#endif 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 ae3dae0c06..1d18e9d63c 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 @@ -5,8 +5,11 @@ #if NET using System; +using System.Buffers; using System.IO; using System.IO.Pipes; +using System.Threading; +using System.Threading.Tasks; namespace Microsoft.Data.SqlClient.ManagedSni { @@ -110,6 +113,301 @@ public override long Position /// public override long Length => throw new NotSupportedException(); + #region Public Methods + + /// + public override int Read(byte[] buffer, int offset, int count) => + Read(buffer.AsSpan(offset, count)); + + /// + public override int Read(Span buffer) + { + using (TrySNIEventScope.Create(nameof(SslOverTdsStream))) + { + if (!_encapsulate) + { + return _stream.Read(buffer); + } + + if (_packetBytes > 0) + { + // there are queued bytes from a previous packet available + // work out how many of the remaining bytes we can consume + int wantedCount = Math.Min(buffer.Length, _packetBytes); + int readCount = _stream.Read(buffer.Slice(0, wantedCount)); + if (readCount == 0) + { + // 0 means the connection was closed, tell the caller + return 0; + } + _packetBytes -= readCount; + return readCount; + } + else + { + Span headerBytes = stackalloc byte[TdsEnums.HEADER_LEN]; + + // fetch the packet header to determine how long the packet is + int headerBytesRead = 0; + do + { + int headerBytesReadIteration = _stream.Read(headerBytes.Slice(headerBytesRead, TdsEnums.HEADER_LEN - headerBytesRead)); + if (headerBytesReadIteration == 0) + { + // 0 means the connection was closed, tell the caller + return 0; + } + headerBytesRead += headerBytesReadIteration; + } while (headerBytesRead < TdsEnums.HEADER_LEN); + + // read the packet data size from the header and store it in case it is needed for a subsequent call + _packetBytes = ((headerBytes[TdsEnums.HEADER_LEN_FIELD_OFFSET] << 8) | headerBytes[TdsEnums.HEADER_LEN_FIELD_OFFSET + 1]) - TdsEnums.HEADER_LEN; + + // read as much from the packet as the caller can accept + int packetBytesRead = _stream.Read(buffer.Slice(0, Math.Min(buffer.Length, _packetBytes))); + _packetBytes -= packetBytesRead; + return packetBytesRead; + } + } + } + + /// + public override Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) => + ReadAsync(new Memory(buffer, offset, count), cancellationToken).AsTask(); + + /// + public override async ValueTask ReadAsync(Memory buffer, CancellationToken cancellationToken = default) + { + using (TrySNIEventScope.Create(nameof(SslOverTdsStream))) + { + if (!_encapsulate) + { + int read; + { + ValueTask readValueTask = _stream.ReadAsync(buffer, cancellationToken); + if (readValueTask.IsCompletedSuccessfully) + { + read = readValueTask.Result; + } + else + { + read = await readValueTask.ConfigureAwait(false); + } + } + return read; + } + + if (_packetBytes > 0) + { + // there are queued bytes from a previous packet available + // work out how many of the remaining bytes we can consume + int wantedCount = Math.Min(buffer.Length, _packetBytes); + + int readCount; + { + ValueTask remainderReadValueTask = _stream.ReadAsync(buffer.Slice(0, wantedCount), cancellationToken); + if (remainderReadValueTask.IsCompletedSuccessfully) + { + readCount = remainderReadValueTask.Result; + } + else + { + readCount = await remainderReadValueTask.ConfigureAwait(false); + } + } + if (readCount == 0) + { + // 0 means the connection was closed, tell the caller + return 0; + } + _packetBytes -= readCount; + return readCount; + } + else + { + byte[] headerBytes = ArrayPool.Shared.Rent(TdsEnums.HEADER_LEN); + + // fetch the packet header to determine how long the packet is + int headerBytesRead = 0; + do + { + int headerBytesReadIteration; + { + ValueTask headerReadValueTask = _stream.ReadAsync(headerBytes.AsMemory(headerBytesRead, (TdsEnums.HEADER_LEN - headerBytesRead)), cancellationToken); + if (headerReadValueTask.IsCompletedSuccessfully) + { + headerBytesReadIteration = headerReadValueTask.Result; + } + else + { + headerBytesReadIteration = await headerReadValueTask.ConfigureAwait(false); + } + } + if (headerBytesReadIteration == 0) + { + // 0 means the connection was closed, cleanup the rented array and then tell the caller + ArrayPool.Shared.Return(headerBytes, clearArray: true); + return 0; + } + headerBytesRead += headerBytesReadIteration; + } while (headerBytesRead < TdsEnums.HEADER_LEN); + + // read the packet data size from the header and store it in case it is needed for a subsequent call + _packetBytes = ((headerBytes[TdsEnums.HEADER_LEN_FIELD_OFFSET] << 8) | headerBytes[TdsEnums.HEADER_LEN_FIELD_OFFSET + 1]) - TdsEnums.HEADER_LEN; + + ArrayPool.Shared.Return(headerBytes, clearArray: true); + + // read as much from the packet as the caller can accept + int packetBytesRead; + { + ValueTask packetReadValueTask = _stream.ReadAsync(buffer.Slice(0, Math.Min(buffer.Length, _packetBytes)), cancellationToken); + if (packetReadValueTask.IsCompletedSuccessfully) + { + packetBytesRead = packetReadValueTask.Result; + } + else + { + packetBytesRead = await packetReadValueTask.ConfigureAwait(false); + } + } + _packetBytes -= packetBytesRead; + return packetBytesRead; + } + } + } + + /// + public override void Write(byte[] buffer, int offset, int count) => + Write(buffer.AsSpan(offset, count)); + + /// + public override void Write(ReadOnlySpan buffer) + { + using (TrySNIEventScope.Create(nameof(SslOverTdsStream))) + { + // During the SSL negotiation phase, SSL is tunnelled over TDS packet type 0x12. After + // negotiation, the underlying socket only sees SSL frames. + if (!_encapsulate) + { + _stream.Write(buffer); + _stream.Flush(); + return; + } + + ReadOnlySpan remaining = buffer; + byte[] packetBuffer = null; + try + { + while (remaining.Length > 0) + { + int dataLength = Math.Min(PACKET_SIZE_WITHOUT_HEADER, remaining.Length); + int packetLength = TdsEnums.HEADER_LEN + dataLength; + + if (packetBuffer == null) + { + packetBuffer = ArrayPool.Shared.Rent(packetLength); + } + else if (packetBuffer.Length < packetLength) + { + ArrayPool.Shared.Return(packetBuffer, clearArray: true); + packetBuffer = ArrayPool.Shared.Rent(packetLength); + } + + SetupPreLoginPacketHeader(packetBuffer, dataLength, remaining.Length - dataLength); + + Span data = packetBuffer.AsSpan(TdsEnums.HEADER_LEN, dataLength); + remaining.Slice(0, dataLength).CopyTo(data); + + _stream.Write(packetBuffer.AsSpan(0, packetLength)); + _stream.Flush(); + + remaining = remaining.Slice(dataLength); + } + } + finally + { + if (packetBuffer != null) + { + ArrayPool.Shared.Return(packetBuffer, clearArray: true); + } + } + } + } + + /// + public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) => + WriteAsync(new ReadOnlyMemory(buffer, offset, count), cancellationToken).AsTask(); + + /// + public override async ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) + { + using (TrySNIEventScope.Create(nameof(SslOverTdsStream))) + { + if (!_encapsulate) + { + { + ValueTask valueTask = _stream.WriteAsync(buffer, cancellationToken); + if (!valueTask.IsCompletedSuccessfully) + { + await valueTask.ConfigureAwait(false); + } + } + Task flushTask = _stream.FlushAsync(); + if (flushTask.IsCompletedSuccessfully) + { + await flushTask.ConfigureAwait(false); + } + return; + } + + ReadOnlyMemory remaining = buffer; + byte[] packetBuffer = null; + try + { + while (remaining.Length > 0) + { + int dataLength = Math.Min(PACKET_SIZE_WITHOUT_HEADER, remaining.Length); + int packetLength = TdsEnums.HEADER_LEN + dataLength; + + if (packetBuffer == null) + { + packetBuffer = ArrayPool.Shared.Rent(packetLength); + } + else if (packetBuffer.Length < packetLength) + { + ArrayPool.Shared.Return(packetBuffer, clearArray: true); + packetBuffer = ArrayPool.Shared.Rent(packetLength); + } + + SetupPreLoginPacketHeader(packetBuffer, dataLength, remaining.Length - dataLength); + + remaining.Span.Slice(0, dataLength).CopyTo(packetBuffer.AsSpan(TdsEnums.HEADER_LEN, dataLength)); + + { + ValueTask packetWriteValueTask = _stream.WriteAsync(new ReadOnlyMemory(packetBuffer, 0, packetLength), cancellationToken); + if (!packetWriteValueTask.IsCompletedSuccessfully) + { + await packetWriteValueTask.ConfigureAwait(false); + } + } + + await _stream.FlushAsync().ConfigureAwait(false); + + remaining = remaining.Slice(dataLength); + } + } + finally + { + if (packetBuffer != null) + { + ArrayPool.Shared.Return(packetBuffer, clearArray: true); + } + } + } + } + + #endregion + 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 From 5cd3bd2facb89ec7657e68c2a34b01a461c77e21 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Wed, 19 Nov 2025 18:04:11 -0600 Subject: [PATCH 11/36] Split PacketHandle.Windows into PacketHandle.netcore.windows and PacketHandle.netfx. --- ...ows.cs => PacketHandle.netcore.windows.cs} | 58 ++++++++---------- .../Data/SqlClient/PacketHandle.netfx.cs | 59 +++++++++++++++++++ 2 files changed, 82 insertions(+), 35 deletions(-) rename src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/{PacketHandle.Windows.cs => PacketHandle.netcore.windows.cs} (56%) create mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/PacketHandle.netfx.cs diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/PacketHandle.Windows.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/PacketHandle.netcore.windows.cs similarity index 56% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/PacketHandle.Windows.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/PacketHandle.netcore.windows.cs index b73f063a9c..4e675fc5b0 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/PacketHandle.Windows.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/PacketHandle.netcore.windows.cs @@ -2,20 +2,24 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +// @TODO: Introduce polymorphism to remove need for this level of indirection +#if NET && _WINDOWS + using System; namespace Microsoft.Data.SqlClient { - // This structure is used for transporting packet handle references between the - // TdsParserStateObject base class and Managed or Native implementations. - // It prevents the native IntPtr type from being boxed and prevents the need to cast from - // object which loses compile time type safety. - // It carries type information so that assertions about the type of handle can be made in the - // implemented abstract methods. - // It is a ref struct so that it can only be used to transport the handles and not store them - - // N.B. If you change this type you must also change the version for the other platform - + /// + /// This structure is used for transporting packet handle references between the + /// TdsParserStateObject base class and Managed or Native implementations. It prevents the + /// native IntPtr type from being boxed and prevents the need to cast from object which loses + /// compile time type safety. It carries type information so that assertions about the type of + /// handle can be made in the implemented abstract methods. + /// + /// + /// It is a ref struct so that it can only be used to transport the handles and not store them. + /// If you change this type you must also change the version for the other platform. + /// internal readonly ref struct PacketHandle { /// @@ -24,28 +28,26 @@ internal readonly ref struct PacketHandle /// packet which has been read from the native SNI layer. /// public const int NativePointerType = 1; + /// /// PacketHandle is transporting a native packet. The NativePacket field is valid. /// A PacketHandle has this type when managed code is directly referencing a packet /// which is due to be passed to the native SNI layer. /// public const int NativePacketType = 2; - - #if NET + /// /// PacketHandle is transporting a managed packet. The ManagedPacket field is valid. /// A PacketHandle used by the managed SNI layer will always have this type. /// public const int ManagedPacketType = 3; + // @TODO: To auto-properties public readonly ManagedSni.SniPacket ManagedPacket; - #endif - public readonly SNIPacket NativePacket; public readonly IntPtr NativePointer; public readonly int Type; - #if NET private PacketHandle(IntPtr nativePointer, SNIPacket nativePacket, ManagedSni.SniPacket managedPacket, int type) { Type = type; @@ -53,30 +55,16 @@ private PacketHandle(IntPtr nativePointer, SNIPacket nativePacket, ManagedSni.Sn NativePointer = nativePointer; NativePacket = nativePacket; } - #else - private PacketHandle(IntPtr nativePointer, SNIPacket nativePacket, int type) - { - Type = type; - NativePointer = nativePointer; - NativePacket = nativePacket; - } - #endif - #if NET public static PacketHandle FromManagedPacket(ManagedSni.SniPacket managedPacket) => - new PacketHandle(default, default, managedPacket, ManagedPacketType); - - public static PacketHandle FromNativePointer(IntPtr nativePointer) => - new PacketHandle(nativePointer, default, default, NativePointerType); + new PacketHandle(nativePointer: IntPtr.Zero, nativePacket: null, managedPacket, ManagedPacketType); public static PacketHandle FromNativePacket(SNIPacket nativePacket) => - new PacketHandle(default, nativePacket, default, NativePacketType); - #else - public static PacketHandle FromNativePointer(IntPtr nativePointer) => - new PacketHandle(nativePointer, default, NativePointerType); + new PacketHandle(nativePointer: IntPtr.Zero, nativePacket, managedPacket: null, NativePacketType); - public static PacketHandle FromNativePacket(SNIPacket nativePacket) => - new PacketHandle(default, nativePacket, NativePacketType); - #endif + public static PacketHandle FromNativePointer(IntPtr nativePointer) => + new PacketHandle(nativePointer, nativePacket: null, managedPacket: null, NativePointerType); } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/PacketHandle.netfx.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/PacketHandle.netfx.cs new file mode 100644 index 0000000000..ac636f3b86 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/PacketHandle.netfx.cs @@ -0,0 +1,59 @@ +// 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. + +// @TODO: Introduce polymorphism to remove need for this level of indirection +#if NETFRAMEWORK + +using System; + +namespace Microsoft.Data.SqlClient +{ + /// + /// This structure is used for transporting packet handle references between the + /// TdsParserStateObject base class and Managed or Native implementations. It prevents the + /// native IntPtr type from being boxed and prevents the need to cast from object which loses + /// compile time type safety. It carries type information so that assertions about the type of + /// handle can be made in the implemented abstract methods. + /// + /// + /// It is a ref struct so that it can only be used to transport the handles and not store them. + /// If you change this type you must also change the version for the other platform. + /// + internal readonly ref struct PacketHandle + { + /// + /// PacketHandle is transporting a native pointer. The NativePointer field is valid. + /// A PacketHandle has this type when managed code is referencing a pointer to a + /// packet which has been read from the native SNI layer. + /// + public const int NativePointerType = 1; + + /// + /// PacketHandle is transporting a native packet. The NativePacket field is valid. + /// A PacketHandle has this type when managed code is directly referencing a packet + /// which is due to be passed to the native SNI layer. + /// + public const int NativePacketType = 2; + + // @TODO: To auto-properties + public readonly SNIPacket NativePacket; + public readonly IntPtr NativePointer; + public readonly int Type; + + private PacketHandle(IntPtr nativePointer, SNIPacket nativePacket, int type) + { + Type = type; + NativePointer = nativePointer; + NativePacket = nativePacket; + } + + public static PacketHandle FromNativePacket(SNIPacket nativePacket) => + new PacketHandle(nativePointer: IntPtr.Zero, nativePacket, NativePacketType); + + public static PacketHandle FromNativePointer(IntPtr nativePointer) => + new PacketHandle(nativePointer, nativePacket: null, NativePointerType); + } +} + +#endif From 8726ed60304c2cf31623de597ad7bc368596aea5 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Wed, 19 Nov 2025 18:08:28 -0600 Subject: [PATCH 12/36] Wrap PacketHandle.netcore.unix in _UNIX --- ...e.Unix.cs => PacketHandle.netcore.unix.cs} | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) rename src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/{PacketHandle.netcore.Unix.cs => PacketHandle.netcore.unix.cs} (64%) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/PacketHandle.netcore.Unix.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/PacketHandle.netcore.unix.cs similarity index 64% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/PacketHandle.netcore.Unix.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/PacketHandle.netcore.unix.cs index 42bf62c5f5..4060edfb38 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/PacketHandle.netcore.Unix.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/PacketHandle.netcore.unix.cs @@ -2,20 +2,23 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if NET +// @TODO: Introduce polymorphism to remove need for this level of indirection +// @TODO: Also, why do we have any other type besides managed defined here? +#if NET && _UNIX namespace Microsoft.Data.SqlClient { - // This structure is used for transporting packet handle references between the - // TdsParserStateObject base class and Managed or Native implementations. - // It prevents the native IntPtr type from being boxed and prevents the need to cast from - // object which loses compile time type safety. - // It carries type information so that assertions about the type of handle can be made in the - // implemented abstract methods. - // It is a ref struct so that it can only be used to transport the handles and not store them - - // N.B. If you change this type you must also change the version for the other platform - + /// + /// This structure is used for transporting packet handle references between the + /// TdsParserStateObject base class and Managed or Native implementations. It prevents the + /// native IntPtr type from being boxed and prevents the need to cast from object which loses + /// compile time type safety. It carries type information so that assertions about the type of + /// handle can be made in the implemented abstract methods. + /// + /// + /// It is a ref struct so that it can only be used to transport the handles and not store them. + /// If you change this type you must also change the version for the other platform. + /// internal readonly ref struct PacketHandle { /// @@ -36,6 +39,7 @@ internal readonly ref struct PacketHandle /// public const int ManagedPacketType = 3; + // @TODO: To auto-properties public readonly ManagedSni.SniPacket ManagedPacket; public readonly int Type; From dc96b5e402869ad0ed5288b4ec922f52559293a3 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Wed, 19 Nov 2025 17:46:12 -0600 Subject: [PATCH 13/36] Split Sessionhandle.Windows into SessionHandle.netcore.Windows and SessionHandle.netfx. This really makes these classes easier to read. --- ...ws.cs => SessionHandle.netcore.windows.cs} | 44 ++++++++----------- .../Data/SqlClient/SessionHandle.netfx.cs | 40 +++++++++++++++++ 2 files changed, 59 insertions(+), 25 deletions(-) rename src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/{SessionHandle.Windows.cs => SessionHandle.netcore.windows.cs} (52%) create mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SessionHandle.netfx.cs diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SessionHandle.Windows.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SessionHandle.netcore.windows.cs similarity index 52% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SessionHandle.Windows.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SessionHandle.netcore.windows.cs index b5b2068961..dcac01c534 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SessionHandle.Windows.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SessionHandle.netcore.windows.cs @@ -2,29 +2,31 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +// @TODO: Merge with other implementations (and/or introduce polymorphism to handle this indirection) +#if NET && _WINDOWS + namespace Microsoft.Data.SqlClient { - // this structure is used for transporting packet handle references between the TdsParserStateObject - // base class and Managed or Native implementations. - // It carries type information so that assertions about the type of handle can be made in the - // implemented abstract methods - // it is a ref struct so that it can only be used to transport the handles and not store them - - // N.B. If you change this type you must also change the version for the other platform - + /// + /// This structure is used for transporting packet handle references between the + /// TdsParserStateObject base class and Managed or Native implementations. It carries type + /// information so that assertions about the type of handle can be made in the implemented + /// abstract methods. + /// + /// + /// It is a ref struct so that it can only be used to transport the handles and not store them. + /// If you change this type you must also change the version for the other platform. + /// internal readonly ref struct SessionHandle { -#if NET public const int NativeHandleType = 1; public const int ManagedHandleType = 2; + // @TODO: Make auto-properties public readonly ManagedSni.SniHandle ManagedHandle; - public readonly int Type; -#endif - public readonly SNIHandle NativeHandle; + public readonly int Type; -#if NET public SessionHandle(ManagedSni.SniHandle managedHandle, SNIHandle nativeHandle, int type) { Type = type; @@ -35,19 +37,11 @@ public SessionHandle(ManagedSni.SniHandle managedHandle, SNIHandle nativeHandle, public bool IsNull => (Type == NativeHandleType) ? NativeHandle is null : ManagedHandle is null; public static SessionHandle FromManagedSession(ManagedSni.SniHandle managedSessionHandle) => - new SessionHandle(managedSessionHandle, default, ManagedHandleType); + new SessionHandle(managedSessionHandle, nativeHandle: null, ManagedHandleType); public static SessionHandle FromNativeHandle(SNIHandle nativeSessionHandle) => - new SessionHandle(default, nativeSessionHandle, NativeHandleType); -#else - public SessionHandle(SNIHandle nativeHandle) - { - NativeHandle = nativeHandle; - } - - public bool IsNull => NativeHandle is null; - - public static SessionHandle FromNativeHandle(SNIHandle nativeSessionHandle) => new SessionHandle(nativeSessionHandle); -#endif + new SessionHandle(managedHandle: null, nativeSessionHandle, NativeHandleType); } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SessionHandle.netfx.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SessionHandle.netfx.cs new file mode 100644 index 0000000000..16d665aa9f --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SessionHandle.netfx.cs @@ -0,0 +1,40 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// @TODO: Merge with other implementations (and/or introduce polymorphism to handle this indirection) +#if NETFRAMEWORK + +namespace Microsoft.Data.SqlClient +{ + /// + /// This structure is used for transporting packet handle references between the + /// TdsParserStateObject base class and Managed or Native implementations. It carries type + /// information so that assertions about the type of handle can be made in the implemented + /// abstract methods. + /// + /// + /// It is a ref struct so that it can only be used to transport the handles and not store them + /// If you change this type you must also change the version for the other platform. + /// + internal readonly ref struct SessionHandle + { + // @TODO: Make internal, auto-property + public readonly SNIHandle NativeHandle; + + public SessionHandle(SNIHandle nativeHandle) + { + NativeHandle = nativeHandle; + } + + public bool IsNull + { + get => NativeHandle is null; + } + + public static SessionHandle FromNativeHandle(SNIHandle nativeSessionHandle) => + new SessionHandle(nativeSessionHandle); + } +} + +#endif From 02fbdef7ba0ca4f28c057b6faf90117de77c1949 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Wed, 19 Nov 2025 17:52:32 -0600 Subject: [PATCH 14/36] Wrap SessionHandle.netcore.unix in _UNIX flag --- ....Unix.cs => SessionHandle.netcore.unix.cs} | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) rename src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/{SessionHandle.netcore.Unix.cs => SessionHandle.netcore.unix.cs} (51%) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SessionHandle.netcore.Unix.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SessionHandle.netcore.unix.cs similarity index 51% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SessionHandle.netcore.Unix.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SessionHandle.netcore.unix.cs index 8465da3684..8f82506bc5 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SessionHandle.netcore.Unix.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SessionHandle.netcore.unix.cs @@ -2,23 +2,28 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if NET +// @TODO: Merge with SessionHandle.windows (and/or introduce polymorphism to handle this indirection) +// @TODO: Also, why do we have native handle type defined in Unix which doesn't ever have a native handle type? +#if NET && _UNIX namespace Microsoft.Data.SqlClient { - // this structure is used for transporting packet handle references between the TdsParserStateObject - // base class and Managed or Native implementations. - // It carries type information so that assertions about the type of handle can be made in the - // implemented abstract methods - // it is a ref struct so that it can only be used to transport the handles and not store them - - // N.B. If you change this type you must also change the version for the other platform - + /// + /// This structure is used for transporting packet handle references between the + /// TdsParserStateObject base class and Managed or Native implementations. It carries type + /// information so that assertions about the type of handle can be made in the implemented + /// abstract methods. + /// + /// + /// It is a ref struct so that it can only be used to transport the handles and not store them. + /// If you change this type you must also change the version for the other platform. + /// internal readonly ref struct SessionHandle { public const int NativeHandleType = 1; public const int ManagedHandleType = 2; + // @TODO: Auto-properties public readonly ManagedSni.SniHandle ManagedHandle; public readonly int Type; From 0c765f8f1bd5df4183464cb3c17974812da6c3e1 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Wed, 19 Nov 2025 18:12:34 -0600 Subject: [PATCH 15/36] Wrap SqlColumnEncryptionCngProvider in _UNIX and _WINDOWS --- ...Unix.cs => SqlColumnEncryptionCngProvider.netcore.unix.cs} | 3 ++- ...r.Windows.cs => SqlColumnEncryptionCngProvider.windows.cs} | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) rename src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/{SqlColumnEncryptionCngProvider.netcore.Unix.cs => SqlColumnEncryptionCngProvider.netcore.unix.cs} (97%) rename src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/{SqlColumnEncryptionCngProvider.Windows.cs => SqlColumnEncryptionCngProvider.windows.cs} (99%) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCngProvider.netcore.Unix.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCngProvider.netcore.unix.cs similarity index 97% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCngProvider.netcore.Unix.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCngProvider.netcore.unix.cs index 7c53b61a78..6ab8567e2a 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCngProvider.netcore.Unix.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCngProvider.netcore.unix.cs @@ -2,7 +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. -#if NET +// @TODO: See if we can throw this when we would create this object +#if NET && _UNIX using System; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCngProvider.Windows.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCngProvider.windows.cs similarity index 99% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCngProvider.Windows.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCngProvider.windows.cs index bd8b2391fa..802472f83e 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCngProvider.Windows.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCngProvider.windows.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. +#if _WINDOWS + using Microsoft.Data.SqlClient.AlwaysEncrypted; using System; using System.Diagnostics.CodeAnalysis; @@ -210,3 +212,5 @@ public override bool VerifyColumnMasterKeyMetadata(string? masterKeyPath, bool a } } } + +#endif From d19082e4cebf31f13e2ff48b879a3d18b967ec5f Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Wed, 19 Nov 2025 18:14:45 -0600 Subject: [PATCH 16/36] Wrap SqlColumnEncryptionCspProvider in _UNIX and _WINDOWS --- ...nix.cs => SqlColumnEncryptionCspProvider.netcore.unix.cs} | 3 ++- ....Windows.cs => SqlColumnEncryptionCspProvider.windows.cs} | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) rename src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/{SqlColumnEncryptionCspProvider.netcore.Unix.cs => SqlColumnEncryptionCspProvider.netcore.unix.cs} (97%) rename src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/{SqlColumnEncryptionCspProvider.Windows.cs => SqlColumnEncryptionCspProvider.windows.cs} (99%) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCspProvider.netcore.Unix.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCspProvider.netcore.unix.cs similarity index 97% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCspProvider.netcore.Unix.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCspProvider.netcore.unix.cs index d28fcf9000..f96841273c 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCspProvider.netcore.Unix.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCspProvider.netcore.unix.cs @@ -2,7 +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. -#if NET +// @TODO: See if we can throw this when we would create this object +#if NET && _UNIX using System; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCspProvider.Windows.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCspProvider.windows.cs similarity index 99% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCspProvider.Windows.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCspProvider.windows.cs index ec2b7554a8..33fe10fe66 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCspProvider.Windows.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCspProvider.windows.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. +#if _WINDOWS + using Microsoft.Data.SqlClient.AlwaysEncrypted; using Microsoft.Win32; using System; @@ -16,7 +18,6 @@ namespace Microsoft.Data.SqlClient /// public class SqlColumnEncryptionCspProvider : SqlColumnEncryptionKeyStoreProvider { - /// public const string ProviderName = @"MSSQL_CSP_PROVIDER"; @@ -213,3 +214,5 @@ public override bool VerifyColumnMasterKeyMetadata(string? masterKeyPath, bool a } } } + +#endif From e44a384036fc1b4c4436ee56862463801e7cd100 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Wed, 19 Nov 2025 18:17:15 -0600 Subject: [PATCH 17/36] Wrap TdsParserSafeHandles.windows in _WINDOWS --- ...afeHandles.Windows.cs => TdsParserSafeHandles.windows.cs} | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) rename src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/{TdsParserSafeHandles.Windows.cs => TdsParserSafeHandles.windows.cs} (99%) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserSafeHandles.Windows.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserSafeHandles.windows.cs similarity index 99% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserSafeHandles.Windows.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserSafeHandles.windows.cs index 749fe5a008..4baf3e1b69 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserSafeHandles.Windows.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserSafeHandles.windows.cs @@ -2,8 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#if _WINDOWS + using System; -using System.Collections.Generic; using System.Diagnostics; using System.Runtime.InteropServices; using Interop.Windows.Sni; @@ -278,3 +279,5 @@ override protected bool ReleaseHandle() } } } + +#endif From 8e3d6836a9969774b11d581e06d9787b58056217 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Wed, 19 Nov 2025 18:34:58 -0600 Subject: [PATCH 18/36] Add _UNIX wrapper to TdsParserStateObjectFactory.unix.cs --- ...ectFactory.Unix.cs => TdsParserStateObjectFactory.unix.cs} | 4 ++++ 1 file changed, 4 insertions(+) rename src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/{TdsParserStateObjectFactory.Unix.cs => TdsParserStateObjectFactory.unix.cs} (97%) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObjectFactory.Unix.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObjectFactory.unix.cs similarity index 97% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObjectFactory.Unix.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObjectFactory.unix.cs index 1f1e45d35f..61817eb0ed 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObjectFactory.Unix.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObjectFactory.unix.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. +#if NET && _UNIX + using Microsoft.Data.SqlClient.ManagedSni; namespace Microsoft.Data.SqlClient @@ -30,3 +32,5 @@ internal TdsParserStateObject CreateSessionObject(TdsParser tdsParser, TdsParser } } } + +#endif From 6a66804d8de18656900200bfa211ecb5fe8e7c39 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Wed, 19 Nov 2025 18:40:29 -0600 Subject: [PATCH 19/36] Wrap TdsParseStateObject[Managed.netcore|Native.windows] in their respective #if's --- .../SqlClient/TdsParserStateObjectManaged.netcore.cs | 6 +++++- ...ndows.cs => TdsParserStateObjectNative.windows.cs} | 11 +++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) rename src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/{TdsParserStateObjectNative.Windows.cs => TdsParserStateObjectNative.windows.cs} (99%) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObjectManaged.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObjectManaged.netcore.cs index 0ebc36c06a..cf9924cc24 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObjectManaged.netcore.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObjectManaged.netcore.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable enable +#if NET using System; using System.Diagnostics; @@ -14,6 +14,8 @@ using Microsoft.Data.Common; using Microsoft.Data.ProviderBase; +#nullable enable + // @TODO: If this is in the manages SNI namespace, it should be in the managed SNI folder namespace Microsoft.Data.SqlClient.ManagedSni { @@ -424,3 +426,5 @@ internal override SspiContextProvider CreateSspiContextProvider() => new NegotiateSspiContextProvider(); } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.Windows.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.windows.cs similarity index 99% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.Windows.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.windows.cs index 4efd94e112..1269cf8827 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.Windows.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.windows.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. +#if _WINDOWS + using System; using System.Collections.Generic; using System.Diagnostics; @@ -209,12 +211,10 @@ protected override void RemovePacketFromPendingList(PacketHandle ptr) _pendingWritePackets.Remove(pointer); _writePacketCache.Add(recoveredPacket); } -#if DEBUG else { Debug.Fail("Removing a packet from the pending list that was never added to it"); } -#endif } } @@ -281,9 +281,10 @@ internal override uint CheckConnection() internal override PacketHandle ReadAsync(SessionHandle handle, out uint error) { -#if NET + #if NET Debug.Assert(handle.Type == SessionHandle.NativeHandleType, "unexpected handle type when requiring NativePointer"); -#endif + #endif + IntPtr readPacketPtr = IntPtr.Zero; error = SniNativeWrapper.SniReadAsync(handle.NativeHandle, ref readPacketPtr); return PacketHandle.FromNativePointer(readPacketPtr); @@ -505,3 +506,5 @@ public void Dispose() } } } + +#endif From c308c11c55934f579bbe6dc01ac99872a7c9d87c Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Wed, 19 Nov 2025 18:46:44 -0600 Subject: [PATCH 20/36] Wrap SqlFileStream files in appropriate #if --- ...FileStream.netcore.Unix.cs => SqlFileStream.netcore.unix.cs} | 2 +- .../{SqlFileStream.Windows.cs => SqlFileStream.windows.cs} | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) rename src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlTypes/{SqlFileStream.netcore.Unix.cs => SqlFileStream.netcore.unix.cs} (99%) rename src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlTypes/{SqlFileStream.Windows.cs => SqlFileStream.windows.cs} (99%) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlTypes/SqlFileStream.netcore.Unix.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlTypes/SqlFileStream.netcore.unix.cs similarity index 99% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlTypes/SqlFileStream.netcore.Unix.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlTypes/SqlFileStream.netcore.unix.cs index 9aac2d9d5e..3ba7e55237 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlTypes/SqlFileStream.netcore.Unix.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlTypes/SqlFileStream.netcore.unix.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if NET +#if NET && _UNIX using System; using System.IO; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlTypes/SqlFileStream.Windows.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlTypes/SqlFileStream.windows.cs similarity index 99% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlTypes/SqlFileStream.Windows.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlTypes/SqlFileStream.windows.cs index c96635e6c7..09e2ed52b8 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlTypes/SqlFileStream.Windows.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlTypes/SqlFileStream.windows.cs @@ -102,6 +102,7 @@ public SqlFileStream( FileOptions options, long allocationSize) { + // @TODO: Adopt netcore style format #if NETFRAMEWORK const string scopeFormat = " {0} access={1} options={2} path='{3}'"; #else From 047dfc438d82f0a7d948f9ffda40392448c6b81e Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Thu, 20 Nov 2025 11:55:56 -0600 Subject: [PATCH 21/36] Remove ILLink.Substitutions.Unix.xml and embed it in LocalAppContextSwitches --- .../Data/SqlClient/LocalAppContextSwitches.cs | 44 ++++++++++++++----- .../Resources/ILLink.Substitutions.Unix.xml | 8 ---- 2 files changed, 33 insertions(+), 19 deletions(-) delete mode 100644 src/Microsoft.Data.SqlClient/src/Resources/ILLink.Substitutions.Unix.xml diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs index f2ca2db2cc..23a40a4df7 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs @@ -8,6 +8,7 @@ namespace Microsoft.Data.SqlClient { internal static partial class LocalAppContextSwitches { + // @TODO: Replace with `bool?` since that's exactly how this is being used private enum Tristate : byte { NotInitialized = 0, @@ -54,21 +55,25 @@ private enum Tristate : byte private static Tristate s_disableTnirByDefault; #endif -#if NET + #if NET static LocalAppContextSwitches() { IAppContextSwitchOverridesSection appContextSwitch = AppConfigManager.FetchConfigurationSection(AppContextSwitchOverridesSection.Name); + try { SqlAppContextSwitchManager.ApplyContextSwitches(appContextSwitch); } catch (Exception e) { + // @TODO: Adopt netcore style of trace logs // Don't throw an exception for an invalid config file SqlClientEventSource.Log.TryTraceEvent(": {1}", nameof(LocalAppContextSwitches), e); } } -#endif + #endif + + // @TODO: Sort by name /// /// In TdsParser, the ProcessSni function changed significantly when the packet @@ -351,7 +356,8 @@ public static bool EnableUserAgent return s_enableUserAgent == Tristate.True; } } -#if NET + + #if NET /// /// .NET Core 2.0 and up supports Globalization Invariant mode, which reduces the size of the required libraries for /// applications which don't need globalization support. SqlClient requires those libraries for core functionality, @@ -363,7 +369,7 @@ public static bool GlobalizationInvariantMode { if (s_globalizationInvariantMode == Tristate.NotInitialized) { - // Check if invariant mode is has been set by the AppContext switch directly + // Check if invariant mode has been set by the AppContext switch directly if (AppContext.TryGetSwitch(GlobalizationInvariantModeString, out bool returnedValue) && returnedValue) { s_globalizationInvariantMode = Tristate.True; @@ -400,7 +406,19 @@ public static bool GlobalizationInvariantMode return s_globalizationInvariantMode == Tristate.True; } } + #else + /// + /// .NET Framework does not support Globalization Invariant mode, so this will always be false. + /// + public static bool GlobalizationInvariantMode + { + get => false; + } + #endif + + #if NET + #if _WINDOWS /// /// When set to true, .NET Core will use the managed SNI implementation instead of the native SNI implementation. /// @@ -437,30 +455,34 @@ public static bool UseManagedNetworking return s_useManagedNetworking == Tristate.True; } } -#else + #else /// - /// .NET Framework does not support Globalization Invariant mode, so this will always be false. + /// .NET Core on Unix does not support the natuve SNI, so this will always be true. /// - public const bool GlobalizationInvariantMode = false; + public const bool UseManagedNetworking = false; + #endif + #else /// /// .NET Framework does not support the managed SNI, so this will always be false. /// public const bool UseManagedNetworking = false; + #endif + #if NETFRAMEWORK /// /// Transparent Network IP Resolution (TNIR) is a revision of the existing MultiSubnetFailover feature. /// TNIR affects the connection sequence of the driver in the case where the first resolved IP of the hostname /// doesn't respond and there are multiple IPs associated with the hostname. - /// + /// /// TNIR interacts with MultiSubnetFailover to provide the following three connection sequences: /// 0: One IP is attempted, followed by all IPs in parallel /// 1: All IPs are attempted in parallel /// 2: All IPs are attempted one after another - /// + /// /// TransparentNetworkIPResolution is enabled by default. MultiSubnetFailover is disabled by default. /// To disable TNIR, you can enable the app context switch. - /// + /// /// This app context switch defaults to 'false'. /// public static bool DisableTnirByDefault @@ -481,6 +503,6 @@ public static bool DisableTnirByDefault return s_disableTnirByDefault == Tristate.True; } } -#endif + #endif } } diff --git a/src/Microsoft.Data.SqlClient/src/Resources/ILLink.Substitutions.Unix.xml b/src/Microsoft.Data.SqlClient/src/Resources/ILLink.Substitutions.Unix.xml deleted file mode 100644 index 4e105d25f0..0000000000 --- a/src/Microsoft.Data.SqlClient/src/Resources/ILLink.Substitutions.Unix.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - From e296c951a7144ab39f00d6932aa136a55b2121a1 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Thu, 20 Nov 2025 13:27:29 -0600 Subject: [PATCH 22/36] Conditionally include ILLink.Substitutions.xml for windows *sigh* --- .../src/Microsoft.Data.SqlClient.csproj | 8 +++++++- ...Substitutions.Windows.xml => ILLink.Substitutions.xml} | 0 2 files changed, 7 insertions(+), 1 deletion(-) rename src/Microsoft.Data.SqlClient/src/Resources/{ILLink.Substitutions.Windows.xml => ILLink.Substitutions.xml} (100%) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/src/Microsoft.Data.SqlClient.csproj index fdc34b7b94..5a96567e7f 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/src/Microsoft.Data.SqlClient.csproj @@ -8,7 +8,7 @@ - $(OS) + $(OS) @@ -21,6 +21,12 @@ _WINDOWS + + + + + diff --git a/src/Microsoft.Data.SqlClient/src/Resources/ILLink.Substitutions.Windows.xml b/src/Microsoft.Data.SqlClient/src/Resources/ILLink.Substitutions.xml similarity index 100% rename from src/Microsoft.Data.SqlClient/src/Resources/ILLink.Substitutions.Windows.xml rename to src/Microsoft.Data.SqlClient/src/Resources/ILLink.Substitutions.xml From 9ad3a359abee1b2f76a9bf8fa40610062aabef47 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Thu, 20 Nov 2025 13:37:38 -0600 Subject: [PATCH 23/36] Make CodeAnalysis be a netfx-only file, remove unused attributes, and add comment explaining why this file exists. --- .../src/System/Diagnostics/CodeAnalysis.cs | 47 ------------------- .../System/Diagnostics/CodeAnalysis.netfx.cs | 20 ++++++++ 2 files changed, 20 insertions(+), 47 deletions(-) delete mode 100644 src/Microsoft.Data.SqlClient/src/System/Diagnostics/CodeAnalysis.cs create mode 100644 src/Microsoft.Data.SqlClient/src/System/Diagnostics/CodeAnalysis.netfx.cs diff --git a/src/Microsoft.Data.SqlClient/src/System/Diagnostics/CodeAnalysis.cs b/src/Microsoft.Data.SqlClient/src/System/Diagnostics/CodeAnalysis.cs deleted file mode 100644 index ffb0003f64..0000000000 --- a/src/Microsoft.Data.SqlClient/src/System/Diagnostics/CodeAnalysis.cs +++ /dev/null @@ -1,47 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace System.Diagnostics.CodeAnalysis -{ - -#if NETFRAMEWORK - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true, Inherited = false)] - internal sealed class MemberNotNullAttribute : Attribute - { - public MemberNotNullAttribute(string member) => Members = new string[] - { - member - }; - - public MemberNotNullAttribute(params string[] members) => Members = members; - - public string[] Members { get; } - } - - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true, Inherited = false)] - internal sealed class MemberNotNullWhenAttribute : Attribute - { - public MemberNotNullWhenAttribute(bool returnValue, string member) - { - ReturnValue = returnValue; - Members = new string[1] { member }; - } - - public MemberNotNullWhenAttribute(bool returnValue, params string[] members) - { - ReturnValue = returnValue; - Members = members; - } - - public bool ReturnValue { get; } - - public string[] Members { get; } - } - - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)] - internal sealed class NotNullAttribute : Attribute - { - } -#endif -} diff --git a/src/Microsoft.Data.SqlClient/src/System/Diagnostics/CodeAnalysis.netfx.cs b/src/Microsoft.Data.SqlClient/src/System/Diagnostics/CodeAnalysis.netfx.cs new file mode 100644 index 0000000000..1bf90ad001 --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/System/Diagnostics/CodeAnalysis.netfx.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. + +#if NETFRAMEWORK + +namespace System.Diagnostics.CodeAnalysis +{ + // These classes are provided to provide compile-time support for Microsoft.CodeAnalysis + // attributes. These attributes are native to netcore and available for netfx as a nuget + // package - but only for net472. As such, until net462 support is dropped, these placeholder + // classes will need to exist if we want to use them for static analysis. + + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)] + internal sealed class NotNullAttribute : Attribute + { + } +} + +#endif From 5674ac0af47feef4e717dd1b12e5c5792ca6ed4e Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Thu, 20 Nov 2025 16:43:05 -0600 Subject: [PATCH 24/36] Rename SqlBatchCommand.Net8OrGreater.cs to SqlBatchCommand.netcore.cs --- ...qlBatchCommand.Net8OrGreater.cs => SqlBatchCommand.netcore.cs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/{SqlBatchCommand.Net8OrGreater.cs => SqlBatchCommand.netcore.cs} (100%) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBatchCommand.Net8OrGreater.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBatchCommand.netcore.cs similarity index 100% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBatchCommand.Net8OrGreater.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBatchCommand.netcore.cs From cffa6d526032949deee489e71948f7a10d4e5562 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Thu, 20 Nov 2025 17:07:48 -0600 Subject: [PATCH 25/36] Wrap SqlDataSourceEnumeratorNativeHelper.cs in windows and rename to indicate that it only applies to Windows. --- ...lper.cs => SqlDataSourceEnumeratorNativeHelper.windows.cs} | 4 ++++ 1 file changed, 4 insertions(+) rename src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/{SqlDataSourceEnumeratorNativeHelper.cs => SqlDataSourceEnumeratorNativeHelper.windows.cs} (99%) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumeratorNativeHelper.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumeratorNativeHelper.windows.cs similarity index 99% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumeratorNativeHelper.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumeratorNativeHelper.windows.cs index d777710eee..3dfe29704b 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumeratorNativeHelper.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Sql/SqlDataSourceEnumeratorNativeHelper.windows.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. +#if _WINDOWS + using System; using System.Data; using System.Diagnostics; @@ -172,3 +174,5 @@ private static DataTable ParseServerEnumString(string serverInstances) } } } + +#endif From 811406f4614ae070f6c787b68ccdef75150eef1c Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Fri, 21 Nov 2025 13:03:08 -0600 Subject: [PATCH 26/36] Bring in all files for the netcore project, re-sort them, make sure logical paths match the actual path --- .../src/Microsoft.Data.SqlClient.csproj | 571 +++++++++--------- 1 file changed, 277 insertions(+), 294 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj index 32b9e76c98..b2a4a826b4 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -40,17 +40,129 @@ - + + + + _UNIX + _WINDOWS + + + - + Interop\Common\Sni\SniErrors.cs + + Interop\Windows\Handles\SafeLibraryHandle.netcore.cs + + + Interop\Windows\Kernel32\FileTypes.cs + + + Interop\Windows\Kernel32\IoControlCodeAccess.cs + + + Interop\Windows\Kernel32\IoControlTransferType.cs + + + Interop\Windows\Kernel32\Kernel32.cs + + + Interop\Windows\NtDll\CreateDisposition.cs + + + Interop\Windows\NtDll\CreateOptions.cs + + + Interop\Windows\NtDll\DesiredAccess.cs + + + Interop\Windows\NtDll\FileFullEaInformation.cs + + + Interop\Windows\NtDll\ImpersonationLevel.cs + + + Interop\Windows\NtDll\IoStatusBlock.cs + + + Interop\Windows\NtDll\NtDll.cs + + + Interop\Windows\NtDll\ObjectAttributeFlags.cs + + + Interop\Windows\NtDll\ObjectAttributes.cs + + + Interop\Windows\NtDll\SecurityQualityOfService.cs + + + Interop\Windows\Sni\AuthProviderInfo.cs + + + Interop\Windows\Sni\ConsumerInfo.cs + + + Interop\Windows\Sni\ConsumerNumber.cs + + + Interop\Windows\Sni\Delegates.cs + + + Interop\Windows\Sni\IoType.cs + + + Interop\Windows\Sni\ISniNativeMethods.cs + + + Interop\Windows\Sni\Prefix.cs + + + Interop\Windows\Sni\Provider.cs + + + Interop\Windows\Sni\QueryType.cs + + + Interop\Windows\Sni\SniClientConsumerInfo.cs + + + Interop\Windows\Sni\SniConsumerInfo.cs + + + Interop\Windows\Sni\SniDnsCacheInfo.cs + + + Interop\Windows\Sni\SniError.cs + + + Interop\Windows\Sni\SniNativeMethods.netcore.cs + + + Interop\Windows\Sni\SniNativeWrapper.cs + + + Interop\Windows\Sni\SniSslProtocols.cs + + + Interop\Windows\Sni\TransparentNetworkResolutionMode.cs + + + Interop\Windows\SystemErrors.cs + + + Interop\Windows\UnicodeString.cs + Microsoft\Data\Common\ActivityCorrelator.cs Microsoft\Data\Common\AdapterUtil.cs + + Microsoft\Data\Common\AdapterUtil.netcore.cs + Microsoft\Data\Common\BitConverterCompatible.cs @@ -93,68 +205,11 @@ Microsoft\Data\OperationAbortedException.cs - - Microsoft\Data\ProviderBase\DbConnectionInternal.cs - - + Microsoft\Data\ProviderBase\DbConnectionClosed.cs - - Microsoft\Data\SqlClient\AlwaysEncrypted\ColumnMasterKeyMetadata.cs - - - Microsoft\Data\SqlClient\AlwaysEncrypted\EncryptedColumnEncryptionKeyParameters.cs - - - Microsoft\Data\SqlClient\ConnectionPool\ChannelDbConnectionPool.cs - - - Microsoft\Data\SqlClient\ConnectionPool\ConnectionPoolSlots.cs - - - Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolAuthenticationContext.cs - - - Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolAuthenticationContextKey.cs - - - Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolGroup.cs - - - Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolGroupProviderInfo.cs - - - Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolIdentity.cs - - - Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolKey.cs - - - Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolOptions.cs - - - Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolProviderInfo.cs - - - Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolState.cs - - - Microsoft\Data\SqlClient\ConnectionPool\IDbConnectionPool.cs - - - Microsoft\Data\SqlClient\ConnectionPool\SqlConnectionPoolGroupProviderInfo.cs - - - Microsoft\Data\SqlClient\ConnectionPool\SqlConnectionPoolKey.cs - - - Microsoft\Data\SqlClient\ConnectionPool\SqlConnectionPoolProviderInfo.cs - - - Microsoft\Data\SqlClient\ConnectionPool\TransactedConnectionPool.cs - - - Microsoft\Data\SqlClient\ConnectionPool\WaitHandleDbConnectionPool.cs + + Microsoft\Data\ProviderBase\DbConnectionInternal.cs Microsoft\Data\ProviderBase\DbMetaDataFactory.cs @@ -168,12 +223,21 @@ Microsoft\Data\ProviderBase\TimeoutTimer.cs + + Microsoft\Data\SqlClient\AlwaysEncrypted\ColumnMasterKeyMetadata.cs + + + Microsoft\Data\SqlClient\AlwaysEncrypted\EncryptedColumnEncryptionKeyParameters.cs + Microsoft\Data\Sql\SqlDataSourceEnumerator.cs Microsoft\Data\Sql\SqlDataSourceEnumeratorManagedHelper.netcore.cs + + Microsoft\Data\Sql\SqlDataSourceEnumeratorNativeHelper.cs + Microsoft\Data\Sql\SqlDataSourceEnumeratorUtil.cs @@ -219,6 +283,57 @@ Microsoft\Data\SqlClient\Connection\SessionStateRecord.cs + + Microsoft\Data\SqlClient\ConnectionPool\ChannelDbConnectionPool.cs + + + Microsoft\Data\SqlClient\ConnectionPool\ConnectionPoolSlots.cs + + + Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolAuthenticationContext.cs + + + Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolAuthenticationContextKey.cs + + + Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolGroup.cs + + + Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolGroupProviderInfo.cs + + + Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolIdentity.cs + + + Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolKey.cs + + + Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolOptions.cs + + + Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolProviderInfo.cs + + + Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolState.cs + + + Microsoft\Data\SqlClient\ConnectionPool\IDbConnectionPool.cs + + + Microsoft\Data\SqlClient\ConnectionPool\SqlConnectionPoolGroupProviderInfo.cs + + + Microsoft\Data\SqlClient\ConnectionPool\SqlConnectionPoolKey.cs + + + Microsoft\Data\SqlClient\ConnectionPool\SqlConnectionPoolProviderInfo.cs + + + Microsoft\Data\SqlClient\ConnectionPool\TransactedConnectionPool.cs + + + Microsoft\Data\SqlClient\ConnectionPool\WaitHandleDbConnectionPool.cs + Microsoft\Data\SqlClient\DataClassification\SensitivityClassification.cs @@ -297,12 +412,27 @@ Microsoft\Data\SqlClient\EnclaveSessionCache.cs + + Microsoft\Data\SqlClient\ISqlVector.cs + Microsoft\Data\SqlClient\LocalAppContextSwitches.cs + + Microsoft\Data\SqlClient\LocalDb\LocalDbApi.unix.cs + + + Microsoft\Data\SqlClient\LocalDb\LocalDbApi.windows.cs + Microsoft\Data\SqlClient\ManagedSni\ConcurrentQueueSemaphore.netcore.cs + + Microsoft\Data\SqlClient\ManagedSni\LocalDB.netcore.unix.cs + + + Microsoft\Data\SqlClient\ManagedSni\LocalDB.netcore.windows.cs + Microsoft\Data\SqlClient\ManagedSni\ResolvedServerSpn.cs @@ -360,9 +490,6 @@ Microsoft\Data\SqlClient\ManagedSni\SslOverTdsStream.netcore.cs - - Microsoft\Data\SqlClient\ManagedSni\SslOverTdsStream.NetCoreApp.cs - Microsoft\Data\SqlClient\ManagedSni\SsrpClient.netcore.cs @@ -375,6 +502,12 @@ Microsoft\Data\SqlClient\Packet.cs + + Microsoft\Data\SqlClient\PacketHandle.netcore.unix.cs + + + Microsoft\Data\SqlClient\PacketHandle.windows.cs + Microsoft\Data\SqlClient\ParameterPeekAheadValue.cs @@ -393,32 +526,38 @@ Microsoft\Data\SqlClient\Reliability\ISqlConfigurableRetryConnectionSection.cs + + Microsoft\Data\SqlClient\Reliability\SqlConfigurableRetryFactory.cs + + + Microsoft\Data\SqlClient\Reliability\SqlConfigurableRetryLogicLoader.cs + + + Microsoft\Data\SqlClient\Reliability\SqlConfigurableRetryLogicManager.cs + + - Microsoft\Data\SqlClient\Reliability\SqlRetryingEventArgs.cs + Microsoft\Data\SqlClient\Reliability\Common\SqlRetryingEventArgs.cs + - Microsoft\Data\SqlClient\Reliability\SqlRetryIntervalBaseEnumerator.cs + Microsoft\Data\SqlClient\Reliability\Common\SqlRetryIntervalBaseEnumerator.cs + - Microsoft\Data\SqlClient\Reliability\SqlRetryLogic.cs + Microsoft\Data\SqlClient\Reliability\Common\SqlRetryLogic.cs + - Microsoft\Data\SqlClient\Reliability\SqlRetryLogicBase.cs + Microsoft\Data\SqlClient\Reliability\Common\SqlRetryLogicBase.cs + - Microsoft\Data\SqlClient\Reliability\SqlRetryLogicBaseProvider.cs + Microsoft\Data\SqlClient\Reliability\Common\SqlRetryLogicBaseProvider.cs + - Microsoft\Data\SqlClient\Reliability\SqlRetryLogicProvider.cs - - - Microsoft\Data\SqlClient\Reliability\SqlConfigurableRetryFactory.cs - - - Microsoft\Data\SqlClient\Reliability\SqlConfigurableRetryLogicLoader.cs - - - Microsoft\Data\SqlClient\Reliability\SqlConfigurableRetryLogicManager.cs + Microsoft\Data\SqlClient\Reliability\Common\SqlRetryLogicProvider.cs Microsoft\Data\SqlClient\Reliability\SqlRetryIntervalEnumerators.cs @@ -483,8 +622,11 @@ Microsoft\Data\SqlClient\Server\ValueUtilsSmi.cs - - Microsoft\Data\SqlClient\ISqlVector.cs + + Microsoft\Data\SqlClient\SessionHandle.netcore.unix.cs + + + Microsoft\Data\SqlClient\SessionHandle.windows.cs Microsoft\Data\SqlClient\SignatureVerificationCache.cs @@ -522,8 +664,8 @@ Microsoft\Data\SqlClient\SqlBatchCommand.cs - - Microsoft\Data\SqlClient\SqlBatchCommand.Net8OrGreater.cs + + Microsoft\Data\SqlClient\SqlBatchCommand.netcore.cs Microsoft\Data\SqlClient\SqlBatchCommandCollection.cs @@ -585,12 +727,21 @@ Microsoft\Data\SqlClient\SqlColumnEncryptionCertificateStoreProvider.cs + + Microsoft\Data\SqlClient\SqlColumnEncryptionCngProvider.netcore.unix.cs + + + Microsoft\Data\SqlClient\SqlColumnEncryptionCngProvider.windows.cs + + + Microsoft\Data\SqlClient\SqlColumnEncryptionCspProvider.netcore.unix.cs + + + Microsoft\Data\SqlClient\SqlColumnEncryptionCspProvider.windows.cs + Microsoft\Data\SqlClient\SqlColumnEncryptionEnclaveProvider.cs - - Microsoft\Data\SqlClient\SqlCommandBuilder.cs - Microsoft\Data\SqlClient\SqlColumnEncryptionKeyStoreProvider.cs @@ -615,6 +766,9 @@ Microsoft\Data\SqlClient\SqlCommand.Xml.cs + + Microsoft\Data\SqlClient\SqlCommandBuilder.cs + Microsoft\Data\SqlClient\SqlCommandSet.cs @@ -774,15 +928,18 @@ Microsoft\Data\SqlClient\SqlUtil.cs + + Microsoft\Data\SqlClient\SSPI\NativeSspiContextProvider.cs + Microsoft\Data\SqlClient\SSPI\NegotiateSspiContextProvider.cs - - Microsoft\Data\SqlClient\SSPI\SspiContextProvider.cs - Microsoft\Data\SqlClient\SSPI\SspiAuthenticationParameters.cs + + Microsoft\Data\SqlClient\SSPI\SspiContextProvider.cs + Microsoft\Data\SqlClient\Utilities\ObjectPool.cs @@ -801,15 +958,27 @@ Microsoft\Data\SqlClient\TdsParserHelperClasses.cs + + Microsoft\Data\SqlClient\TdsParserSafeHandles.windows.cs + Microsoft\Data\SqlClient\TdsParserStateObject.cs Microsoft\Data\SqlClient\TdsParserStateObject.Multiplexer.cs + + Microsoft\Data\SqlClient\TdsParserStateObjectFactory.unix.cs + + + Microsoft\Data\SqlClient\TdsParserStateObjectFactory.windows.cs + Microsoft\Data\SqlClient\TdsParserStateObjectManaged.netcore.cs + + Microsoft\Data\SqlClient\TdsParserStateObjectNative.windows.cs + Microsoft\Data\SqlClient\TdsParserStaticMethods.cs @@ -823,7 +992,13 @@ Microsoft\Data\SqlClient\TdsValueSetter.cs - Microsoft\Data\SqlClient\TransactionRequest.cs + Microsoft\Data\SqlClient\TransactionRequest.cs + + + Microsoft\Data\SqlClient\UserAgent\UserAgentInfo.cs + + + Microsoft\Data\SqlClient\UserAgent\UserAgentInfoDto.cs Microsoft\Data\SqlClient\VirtualSecureModeEnclaveProvider.cs @@ -834,33 +1009,30 @@ Microsoft\Data\SqlDbTypeExtensions.cs + + Microsoft\Data\SqlTypes\SqlFileStream.netcore.unix.cs + + + Microsoft\Data\SqlTypes\SqlFileStream.windows.cs + + + Microsoft\Data\SqlTypes\SqlJson.cs + Microsoft\Data\SQLTypes\SQLResource.cs Microsoft\Data\SqlTypes\SqlTypeWorkarounds.cs - - Microsoft\Data\SqlTypes\SqlJson.cs - Microsoft\Data\SqlTypes\SqlVector.cs - - Microsoft\Data\SqlClient\UserAgent\UserAgentInfo.cs - - - Microsoft\Data\SqlClient\UserAgent\UserAgentInfoDto.cs - Resources\ResCategoryAttribute.cs Resources\ResDescriptionAttribute.cs - - System\Diagnostics\CodeAnalysis.cs - TypeForwards.netcore.cs @@ -868,199 +1040,10 @@ - - Interop\Windows\Handles\SafeLibraryHandle.netcore.cs - - - Interop\Windows\SystemErrors.cs - - - Interop\Windows\Kernel32\FileTypes.cs - - - Interop\Windows\Kernel32\IoControlCodeAccess.cs - - - Interop\Windows\Kernel32\IoControlTransferType.cs - - - Interop\Windows\Kernel32\Kernel32.cs - - - Interop\Windows\NtDll\CreateDisposition.cs - - - Interop\Windows\NtDll\CreateOptions.cs - - - Interop\Windows\NtDll\DesiredAccess.cs - - - Interop\Windows\NtDll\FileFullEaInformation.cs - - - Interop\Windows\NtDll\ImpersonationLevel.cs - - - Interop\Windows\NtDll\IoStatusBlock.cs - - - Interop\Windows\NtDll\NtDll.cs - - - Interop\Windows\NtDll\ObjectAttributeFlags.cs - - - Interop\Windows\NtDll\ObjectAttributes.cs - - - Interop\Windows\NtDll\SecurityQualityOfService.cs - - - Interop\Windows\Sni\AuthProviderInfo.cs - - - Interop\Windows\Sni\ConsumerInfo.cs - - - Interop\Windows\Sni\ConsumerNumber.cs - - - Interop\Windows\Sni\Delegates.cs - - - Interop\Windows\Sni\IoType.cs - - - Interop\Windows\Sni\ISniNativeMethods.cs - - - Interop\Windows\Sni\Prefix.cs - - - Interop\Windows\Sni\Provider.cs - - - Interop\Windows\Sni\QueryType.cs - - - Interop\Windows\Sni\SniClientConsumerInfo.cs - - - Interop\Windows\Sni\SniConsumerInfo.cs - - - Interop\Windows\Sni\SniDnsCacheInfo.cs - - - Interop\Windows\Sni\SniError.cs - - - Interop\Windows\Sni\SniNativeMethods.netcore.cs - - - Interop\Windows\Sni\SniNativeWrapper.cs - - - Interop\Windows\Sni\SniSslProtocols.cs - - - Interop\Windows\Sni\TransparentNetworkResolutionMode.cs - - - Interop\Windows\UnicodeString.cs - - - Microsoft\Data\Common\AdapterUtil.Windows.cs - - - Microsoft\Data\Sql\SqlDataSourceEnumeratorNativeHelper.cs - - - Microsoft\Data\Sql\SqlDataSourceEnumerator.Windows.cs - - - Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolIdentity.Windows.cs - - - Microsoft\Data\SqlClient\LocalDb\LocalDbApi.Windows.cs - - - Microsoft\Data\SqlClient\ManagedSni\LocalDB.netcore.Windows.cs - - - Microsoft\Data\SqlClient\PacketHandle.Windows.cs - - - Microsoft\Data\SqlClient\SessionHandle.Windows.cs - - - Microsoft\Data\SqlClient\SqlColumnEncryptionCngProvider.Windows.cs - - - Microsoft\Data\SqlClient\SqlColumnEncryptionCspProvider.Windows.cs - - - Microsoft\Data\SqlClient\SSPI\NativeSspiContextProvider.cs - - - Microsoft\Data\SqlClient\TdsParserSafeHandles.Windows.cs - - - Microsoft\Data\SqlClient\TdsParserStateObjectFactory.Windows.cs - - - Microsoft\Data\SqlClient\TdsParserStateObjectNative.Windows.cs - - - Microsoft\Data\SqlTypes\SqlFileStream.Windows.cs - - - - ILLink.Substitutions.xml - Resources\ILLink.Substitutions.Windows.xml - - - - - - - Microsoft\Data\Common\AdapterUtil.Unix.cs - - - Microsoft\Data\Sql\SqlDataSourceEnumerator.netcore.Unix.cs - - - Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolIdentity.Unix.cs - - - Microsoft\Data\SqlClient\LocalDb\LocalDbApi.Unix.cs - - - Microsoft\Data\SqlClient\ManagedSni\LocalDB.netcore.Unix.cs - - - Microsoft\Data\SqlClient\PacketHandle.netcore.Unix.cs - - - Microsoft\Data\SqlClient\SessionHandle.netcore.Unix.cs - - - Microsoft\Data\SqlClinet\SqlColumnEncryptionCngProvider.netcore.Unix.cs - - - Microsoft\Data\SqlClinet\SqlColumnEncryptionCspProvider.netcore.Unix.cs - - - Microsoft\Data\SqlClient\TdsParserStateObjectFactory.Unix.cs - - - Microsoft\Data\SqlTypes\SqlFileStream.netcore.Unix.cs - - + ILLink.Substitutions.xml - Resources\ILLink.Substitutions.Unix.xml + Resources\ILLink.Substitutions.windows.xml From 42cecd862cfeeab6b80db2540b35dad166e52bcf Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Mon, 24 Nov 2025 13:56:30 -0600 Subject: [PATCH 27/36] Netcore project embedded resources --- .../src/Microsoft.Data.SqlClient.csproj | 55 ++++++++++--------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj index b2a4a826b4..9d80b135ac 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -1033,49 +1033,53 @@ Resources\ResDescriptionAttribute.cs + + Resources\StringsHelper.cs + TypeForwards.netcore.cs - - + + + + + + Resources\ILLink.Substitutions.xml + - - ILLink.Substitutions.xml - Resources\ILLink.Substitutions.windows.xml + + Resources\Microsoft.Data.SqlCLient.SqlMetaData.xml + Microsoft.Data.SqlClient.SqlMetaData.xml - - - - - Resources\StringsHelper.cs - - - Resources\Strings.Designer.cs - True - True - Strings.resx - + Resources\Strings.resx - Microsoft.Data.SqlClient.Resources.Strings.resources + Microsoft.Data.SqlCLient.Resources.Strings.resources ResXFileCodeGenerator Strings.Designer.cs System - + + + Resources\%(RecursiveDir)%(Filename)%(Extension) - Microsoft.Data.SqlClient.Resources.%(Filename).resources - - - Microsoft.Data.SqlClient.SqlMetaData.xml - Resources\Microsoft.Data.SqlClient.SqlMetaData.xml + Microsoft.Data.SqlCLient.Resources.%(Filename).resources + + + + Resources\Strings.Designer.cs + True + True + Strings.resx + - + @@ -1092,6 +1096,7 @@ + From a907dc9bb925d4d633c1478673a23c5a8ed83e95 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Tue, 25 Nov 2025 16:27:57 -0600 Subject: [PATCH 28/36] Get rid of TargetsWindows/TargetsUnix --- .../netcore/src/Microsoft.Data.SqlClient.csproj | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj index 9d80b135ac..7330072cac 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -4,8 +4,6 @@ net8.0;net9.0 Microsoft.Data.SqlClient is not supported on this platform. $(OS) - true - true false netcoreapp @@ -43,8 +41,8 @@ - _UNIX - _WINDOWS + _UNIX + _WINDOWS From cc0a6eef691f70f545053e989a2ddfcc4de46526 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Tue, 25 Nov 2025 18:09:47 -0600 Subject: [PATCH 29/36] Bring in all files for the netcore project, re-sort them, make sure logical paths match the actual path --- .../netfx/src/Microsoft.Data.SqlClient.csproj | 394 +++++++++--------- .../src/Microsoft/Data/Common/AdapterUtil.cs | 1 - 2 files changed, 201 insertions(+), 194 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj index 36a87b4eb2..529c4a0c05 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj @@ -3,6 +3,7 @@ {407890AC-9876-4FEF-A6F1-F36A876BAADE} net462 + $(OS) true Microsoft.Data.SqlClient AnyCPU @@ -99,10 +100,16 @@ - + + + + _WINDOWS + + + - Interop\Common\SniErrors.cs + Interop\Common\Sni\SniErrors.cs Interop\Windows\Kernel32\FileTypes.cs @@ -113,112 +120,112 @@ Interop\Windows\Kernel32\IoControlTransferType.cs - + Interop\Windows\Kernel32\Kernel32.cs - + Interop\Windows\Kernel32\Kernel32Safe.netfx.cs - + Interop\Windows\NtDll\CreateDisposition.cs - + Interop\Windows\NtDll\CreateOptions.cs - + Interop\Windows\NtDll\DesiredAccess.cs - + Interop\Windows\NtDll\FileFullEaInformation.cs - - Interop\Windows\NtDll\ImpersonaltionLevel.cs + + Interop\Windows\NtDll\ImpersonationLevel.cs Interop\Windows\NtDll\IoStatusBlock.cs - + Interop\Windows\NtDll\NtDll.cs - - Interop\Windows\NtDll\ObjectAttributes.cs + + Interop\Windows\NtDll\ObjectAttributeFlags.cs - - Interop\Windows\NtDll\ObjecAttributes.cs + + Interop\Windows\NtDll\ObjectAttributes.cs - + Interop\Windows\NtDll\SecurityQualityOfService.cs - + Interop\Windows\Secur32\CredHandle.netfx.cs - + Interop\Windows\Secur32\ContextAttribute.netfx.cs - + Interop\Windows\Secur32\Secur32.netfx.cs - + Interop\Windows\Sni\AuthProviderInfo.cs - + Interop\Windows\Sni\ConsumerInfo.cs - + Interop\Windows\Sni\ConsumerNumber.cs - + Interop\Windows\Sni\Delegates.cs - + Interop\Windows\Sni\IoType.cs - + Interop\Windows\Sni\ISniNativeMethods.cs - + Interop\Windows\Sni\Prefix.cs - + Interop\Windows\Sni\Provider.cs - + Interop\Windows\Sni\QueryType.cs - + Interop\Windows\Sni\SniClientConsumerInfo.cs - + Interop\Windows\Sni\SniConsumerInfo.cs - + Interop\Windows\Sni\SniDnsCacheInfo.cs - + Interop\Windows\Sni\SniError.cs - + Interop\Windows\Sni\SniNativeMethodsArm64.netfx.cs - + Interop\Windows\Sni\SniNativeMethodsNotSupported.netfx.cs - + Interop\Windows\Sni\SniNativeMethodsX64.netfx.cs - + Interop\Windows\Sni\SniNativeMethodsX86.netfx.cs - + Interop\Windows\Sni\SniNativeWrapper.cs - - Interop\Windows\Sni\SqlDependencyProcessDispatcherStorage.netfx.cs - - + Interop\Windows\Sni\SniSslProtocols.cs - + + Interop\Windows\Sni\SqlDependencyProcessDispatcherStorage.netfx.cs + + Interop\Windows\Sni\TransparentNetworkResolutionMode.cs @@ -233,8 +240,8 @@ Microsoft\Data\Common\AdapterUtil.cs - - Microsoft\Data\Common\AdapterUtil.Windows.cs + + Microsoft\Data\Common\AdapterUtil.netfx.cs Microsoft\Data\Common\BitConverterCompatible.cs @@ -248,6 +255,9 @@ Microsoft\Data\Common\ConnectionString\DbConnectionOptions.Debug.cs + + Microsoft\Data\Common\ConnectionString\DbConnectionString.netfx.cs + Microsoft\Data\Common\ConnectionString\DbConnectionStringDefaults.cs @@ -257,9 +267,6 @@ Microsoft\Data\Common\ConnectionString\DbConnectionStringSynonyms.cs - - Microsoft\Data\Common\ConnectionString\DbConnectionString.netfx.cs - Microsoft\Data\Common\ConnectionString\DbConnectionStringUtilities.cs @@ -269,6 +276,9 @@ Microsoft\Data\Common\ConnectionString\PoolBlockingUtilities.cs + + Microsoft\Data\SqlClient\ISqlVector.cs + Microsoft\Data\Common\MultipartIdentifier.cs @@ -281,18 +291,81 @@ Microsoft\Data\OperationAbortedException.cs - + Microsoft\Data\ProviderBase\DbConnectionClosed.cs Microsoft\Data\ProviderBase\DbConnectionInternal.cs + + Microsoft\Data\ProviderBase\DbMetaDataFactory.cs + + + Microsoft\Data\ProviderBase\DbReferenceCollection.cs + + + Microsoft\Data\ProviderBase\FieldNameLookup.cs + + + Microsoft\Data\ProviderBase\TimeoutTimer.cs + + + Microsoft\Data\Sql\SqlDataSourceEnumerator.cs + + + Microsoft\Data\Sql\SqlDataSourceEnumeratorNativeHelper.windows.cs + + + Microsoft\Data\Sql\SqlDataSourceEnumeratorUtil.cs + + + Microsoft\Data\Sql\SqlNotificationRequest.cs + + + Microsoft\Data\SqlClient\AAsyncCallContext.cs + + + Microsoft\Data\SqlClient\ActiveDirectoryAuthenticationProvider.cs + + + Microsoft\Data\SqlClient\ActiveDirectoryAuthenticationTimeoutRetryHelper.cs + Microsoft\Data\SqlClient\AlwaysEncrypted\ColumnMasterKeyMetadata.cs Microsoft\Data\SqlClient\AlwaysEncrypted\EncryptedColumnEncryptionKeyParameters.cs + + Microsoft\Data\SqlClient\AlwaysEncryptedEnclaveProviderUtils.cs + + + Microsoft\Data\SqlClient\AlwaysEncryptedHelperClasses.cs + + + Microsoft\Data\SqlClient\AlwaysEncryptedKeyConverter.cs + + + Microsoft\Data\SqlClient\ApplicationIntent.cs + + + Microsoft\Data\SqlClient\AssemblyRef.cs + + + Microsoft\Data\SqlClient\AzureAttestationBasedEnclaveProvider.cs + + + Microsoft\Data\SqlClient\ColumnEncryptionKeyInfo.cs + + + Microsoft\Data\SqlClient\Connection\ServerInfo.cs + + + Microsoft\Data\SqlClient\Connection\SessionData.cs + + + Microsoft\Data\SqlClient\Connection\SessionStateRecord.cs + Microsoft\Data\SqlClient\ConnectionPool\ChannelDbConnectionPool.cs @@ -314,9 +387,6 @@ Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolIdentity.cs - - Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolIdentity.Windows.cs - Microsoft\Data\SqlClient\ConnectionPool\DbConnectionPoolKey.cs @@ -336,7 +406,7 @@ Microsoft\Data\SqlClient\ConnectionPool\SqlConnectionPoolGroupProviderInfo.cs - Microsoft\Data\SqlClient\SqlConnectionPoolKey.cs + Microsoft\Data\SqlClient\ConnectionPool\SqlConnectionPoolKey.cs Microsoft\Data\SqlClient\ConnectionPool\SqlConnectionPoolProviderInfo.cs @@ -347,6 +417,9 @@ Microsoft\Data\SqlClient\ConnectionPool\WaitHandleDbConnectionPool.cs + + Microsoft\Data\SqlClient\DataClassification\SensitivityClassification.cs + Microsoft\Data\SqlClient\Diagnostics\DiagnosticScope.cs @@ -404,93 +477,6 @@ Microsoft\Data\SqlClient\Diagnostics\SqlDiagnosticListener.cs - - Microsoft\Data\ProviderBase\DbMetaDataFactory.cs - - - Microsoft\Data\ProviderBase\DbReferenceCollection.cs - - - Microsoft\Data\ProviderBase\FieldNameLookup.cs - - - Microsoft\Data\ProviderBase\TimeoutTimer.cs - - - Microsoft\Data\Sql\SqlDataSourceEnumerator.Windows.cs - - - Microsoft\Data\Sql\SqlDataSourceEnumeratorNativeHelper.cs - - - Microsoft\Data\Sql\SqlDataSourceEnumeratorUtil.cs - - - Microsoft\Data\Sql\SqlNotificationRequest.cs - - - Resources\ResCategoryAttribute.cs - - - Microsoft\Data\SqlClient\SSPI\NativeSspiContextProvider.cs - - - Microsoft\Data\SqlClient\SSPI\NegotiateSspiContextProvider.cs - - - Microsoft\Data\SqlClient\SSPI\SspiContextProvider.cs - - - Microsoft\Data\SqlClient\SSPI\SspiAuthenticationParameters.cs - - - Microsoft\Data\SqlClient\TdsParser.cs - - - Microsoft\Data\Sql\SqlDataSourceEnumerator.cs - - - Microsoft\Data\SqlClient\AAsyncCallContext.cs - - - Microsoft\Data\SqlClient\ActiveDirectoryAuthenticationTimeoutRetryHelper.cs - - - Microsoft\Data\SqlClient\ApplicationIntent.cs - - - Microsoft\Data\SqlClient\AssemblyRef.cs - - - Microsoft\Data\SqlClient\ActiveDirectoryAuthenticationProvider.cs - - - Microsoft\Data\SqlClient\AlwaysEncryptedEnclaveProviderUtils.cs - - - Microsoft\Data\SqlClient\AlwaysEncryptedHelperClasses.cs - - - Microsoft\Data\SqlClient\AlwaysEncryptedKeyConverter.cs - - - Microsoft\Data\SqlClient\AzureAttestationBasedEnclaveProvider.cs - - - Microsoft\Data\SqlClient\ColumnEncryptionKeyInfo.cs - - - Microsoft\Data\SqlClient\Connection\ServerInfo.cs - - - Microsoft\Data\SqlClient\Connection\SessionData.cs - - - Microsoft\Data\SqlClient\Connection\SessionStateRecord.cs - - - Microsoft\Data\SqlClient\DataClassification\SensitivityClassification.cs - Microsoft\Data\SqlClient\DisposableTemporaryOnStack.cs @@ -509,6 +495,9 @@ Microsoft\Data\SqlClient\EnclaveSessionCache.cs + + Microsoft\Data\SqlClient\LocalAppContextSwitches.cs + Microsoft\Data\SqlClient\LocalDb\LocalDbApi.Windows.cs @@ -521,9 +510,6 @@ Microsoft\Data\SqlClient\LocalDb\LocalDbInstancesCollection.netfx.cs - - Microsoft\Data\SqlClient\LocalAppContextSwitches.cs - Microsoft\Data\SqlClient\ManagedSni\ResolvedServerSpn.cs @@ -536,8 +522,8 @@ Microsoft\Data\SqlClient\Packet.cs - - Microsoft\Data\SqlClient\PacketHandle.Windows.cs + + Microsoft\Data\SqlClient\PacketHandle.netfx.cs Microsoft\Data\SqlClient\ParameterPeekAheadValue.cs @@ -548,32 +534,38 @@ Microsoft\Data\SqlClient\Reliability\AppConfigManager.cs - - Microsoft\Data\SqlClient\Reliability\IAppContextSwitchOverridesSection.cs - - - Microsoft\Data\SqlClient\Reliability\ISqlConfigurableRetryCommandSection.cs - - - Microsoft\Data\SqlClient\Reliability\ISqlConfigurableRetryConnectionSection.cs - + - Microsoft\Data\SqlClient\Reliability\SqlRetryingEventArgs.cs + Microsoft\Data\SqlClient\Reliability\Common\SqlRetryingEventArgs.cs + - Microsoft\Data\SqlClient\Reliability\SqlRetryIntervalBaseEnumerator.cs + Microsoft\Data\SqlClient\Reliability\Common\SqlRetryIntervalBaseEnumerator.cs + - Microsoft\Data\SqlClient\Reliability\SqlRetryLogic.cs + Microsoft\Data\SqlClient\Reliability\Common\SqlRetryLogic.cs + - Microsoft\Data\SqlClient\Reliability\SqlRetryLogicBase.cs + Microsoft\Data\SqlClient\Reliability\Common\SqlRetryLogicBase.cs + - Microsoft\Data\SqlClient\Reliability\SqlRetryLogicBaseProvider.cs + Microsoft\Data\SqlClient\Reliability\Common\SqlRetryLogicBaseProvider.cs + - Microsoft\Data\SqlClient\Reliability\SqlRetryLogicProvider.cs + Microsoft\Data\SqlClient\Reliability\Common\SqlRetryLogicProvider.cs + + + Microsoft\Data\SqlClient\Reliability\IAppContextSwitchOverridesSection.cs + + + Microsoft\Data\SqlClient\Reliability\ISqlConfigurableRetryCommandSection.cs + + + Microsoft\Data\SqlClient\Reliability\ISqlConfigurableRetryConnectionSection.cs Microsoft\Data\SqlClient\Reliability\SqlConfigurableRetryFactory.cs @@ -624,7 +616,7 @@ Microsoft\Data\SqlClient\Server\SmiTypedGetterSetter.cs - Microsoft\Data\SqlClient\Server\SmiXetterAccess.cs + Microsoft\Data\SqlClient\Server\SmiXetterAccessMap.cs Microsoft\Data\SqlClient\Server\SmiXetterTypeCode.cs @@ -650,18 +642,12 @@ Microsoft\Data\SqlClient\Server\SqlSer.cs - - Microsoft\Data\SqlClient\ISqlVector.cs - - - Microsoft\Data\SqlClient\SessionHandle.Windows.cs + + Microsoft\Data\SqlClient\SessionHandle.netfx.cs Microsoft\Data\SqlClient\SignatureVerificationCache.cs - - Microsoft\Data\SqlClient\SortOrder.cs - Microsoft\Data\SqlClient\SqlAeadAes256CbcHmac256Algorithm.cs @@ -680,18 +666,18 @@ Microsoft\Data\SqlClient\SqlAuthenticationProviderManager.cs - - Microsoft\Data\SqlClient\SqlBuffer.cs - - - Microsoft\Data\SqlClient\SqlBulkCopy.cs - Microsoft\Data\SqlClient\SqlAuthenticationToken.cs Microsoft\Data\SqlClient\SqlBatchCommand.cs + + Microsoft\Data\SqlClient\SqlBuffer.cs + + + Microsoft\Data\SqlClient\SqlBulkCopy.cs + Microsoft\Data\SqlClient\SqlBulkCopyColumnMapping.cs @@ -750,10 +736,10 @@ Microsoft\Data\SqlClient\SqlColumnEncryptionCertificateStoreProvider.cs - Microsoft\Data\SqlClient\SqlColumnEncryptionCngProvider.cs + Microsoft\Data\SqlClient\SqlColumnEncryptionCngProvider.Windows.cs - Microsoft\Data\SqlClient\SqlColumnEncryptionCspProvider.cs + Microsoft\Data\SqlClient\SqlColumnEncryptionCspProvider.Windows.cs Microsoft\Data\SqlClient\SqlColumnEncryptionEnclaveProvider.cs @@ -887,12 +873,12 @@ Microsoft\Data\SqlClient\SqlNotificationType.cs - - Microsoft\Data\SqlClient\SqlParameterCollection.cs - Microsoft\Data\SqlClient\SqlParameter.cs + + Microsoft\Data\SqlClient\SqlParameterCollection.cs + Microsoft\Data\SqlClient\SqlQueryMetadataCache.cs @@ -917,14 +903,14 @@ Microsoft\Data\SqlClient\SqlSequentialStream.cs - - Microsoft\Data\SqlClient\SqlStream.cs + + Microsoft\Data\SqlClient\SqlSequentialTextReader.cs Microsoft\Data\SqlClient\SqlStatistics.cs - - Microsoft\Data\SqlClient\SqlSequentialTextReader.cs + + Microsoft\Data\SqlClient\SqlStream.cs Microsoft\Data\SqlClient\SqlSymmetricKeyCache.cs @@ -938,12 +924,30 @@ Microsoft\Data\SqlClient\SqlUtil.cs + + Microsoft\Data\SqlClient\SSPI\NativeSspiContextProvider.cs + + + Microsoft\Data\SqlClient\SSPI\NegotiateSspiContextProvider.cs + + + Microsoft\Data\SqlClient\SSPI\SspiAuthenticationParameters.cs + + + Microsoft\Data\SqlClient\SSPI\SspiContextProvider.cs + + + Microsoft\Data\SqlClient\SortOrder.cs + Microsoft\Data\SqlClient\TdsEnums.cs Microsoft\Data\SqlClient\TdsParameterSetter.cs + + Microsoft\Data\SqlClient\TdsParser.cs + Microsoft\Data\SqlClient\TdsParserSafeHandles.Windows.cs @@ -975,7 +979,7 @@ Microsoft\Data\SqlClient\TdsValueSetter.cs - Microsoft\Data\SqlClient\TransactionRequest.cs + Microsoft\Data\SqlClient\TransactionRequest.cs Microsoft\Data\SqlClient\Utilities\BufferWriterExtensions.netfx.cs @@ -996,13 +1000,7 @@ Microsoft\Data\SqlDbTypeExtensions.cs - Microsoft\Data\SqlTypes\SqlFileStream.cs - - - Microsoft\Data\SqlTypes\SQLResource.cs - - - Microsoft\Data\SqlTypes\SqlTypeWorkarounds.cs + Microsoft\Data\SqlTypes\SqlFileStream.Windows.cs Microsoft\Data\SqlTypes\SqlJson.cs @@ -1010,20 +1008,29 @@ Microsoft\Data\SqlTypes\SqlVector.cs + + Microsoft\Data\SqlTypes\SQLResource.cs + + + Microsoft\Data\SqlTypes\SqlTypeWorkarounds.cs + Microsoft\Data\SqlClient\UserAgent\UserAgentInfo.cs Microsoft\Data\SqlClient\UserAgent\UserAgentInfoDto.cs + + Resources\ResCategoryAttribute.cs + Resources\ResDescriptionAttribute.cs System\Buffers\ArrayBufferWriter.netfx.cs - - System\Diagnostics\CodeAnalysis.cs + + System\Diagnostics\CodeAnalysis.netfx.cs System\IO\StreamExtensions.netfx.cs @@ -1032,6 +1039,7 @@ System\Runtime\CompilerServices\IsExternalInit.netfx.cs + 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 48c99d4439..d932e0a23e 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs @@ -27,7 +27,6 @@ #if NETFRAMEWORK using System.Reflection; using System.Security.Permissions; -using Microsoft.SqlServer.Server; #endif #if _WINDOWS From 166ff48612f585abbff2d5714dd157fb0dade6d1 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Tue, 25 Nov 2025 18:17:23 -0600 Subject: [PATCH 30/36] Resource files in netfx project --- .../netfx/src/Microsoft.Data.SqlClient.csproj | 46 ++++++++++++------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj index 529c4a0c05..5ac62c9e86 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj @@ -1023,6 +1023,9 @@ Resources\ResCategoryAttribute.cs + + Resources\StringsHelper.cs + Resources\ResDescriptionAttribute.cs @@ -1040,17 +1043,15 @@ - + - - Resources\StringsHelper.cs - - - Resources\Strings.Designer.cs - True - True - Strings.resx - + + Resources\Microsoft.Data.SqlClient.SqlMetaData.xml + Microsoft.Data.SqlClient.SqlMetaData.xml + PreserveNewest + + + Resources\Strings.resx Microsoft.Data.SqlClient.Resources.Strings.resources @@ -1058,16 +1059,23 @@ ResXFileCodeGenerator Strings.Designer.cs + + Resources\%(RecursiveDir)%(Filename)%(Extension) Microsoft.Data.SqlClient.Resources.%(Filename).resources - - Microsoft.Data.SqlClient.SqlMetaData.xml - Resources\Microsoft.Data.SqlClient.SqlMetaData.xml - PreserveNewest - + + + + Resources\Strings.Designer.cs + True + True + Strings.resx + + + @@ -1084,10 +1092,14 @@ - - + + + + + + From 5b3401911929434562137d7f1b3278f6793b6e30 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Tue, 25 Nov 2025 18:17:42 -0600 Subject: [PATCH 31/36] Sort a few of the netfx properties to match netcore :shrug: --- .../netfx/src/Microsoft.Data.SqlClient.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj index 5ac62c9e86..213d91aa8b 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj @@ -1,11 +1,11 @@  - {407890AC-9876-4FEF-A6F1-F36A876BAADE} - + Microsoft.Data.SqlClient net462 $(OS) + {407890AC-9876-4FEF-A6F1-F36A876BAADE} + true - Microsoft.Data.SqlClient AnyCPU $(BinFolder)$(Configuration).$(OutputPlatform)\ $(ObjFolder)$(Configuration).$(OutputPlatform)\ From 2576df71e1142ee762983c8604a921f871e939f6 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Wed, 26 Nov 2025 13:35:25 -0600 Subject: [PATCH 32/36] First round of PR comments --- build.proj | 7 +++++++ .../src/Microsoft.Data.SqlClient.csproj | 2 +- .../Windows/Kernel32/Kernel32Safe.netfx.cs | 2 +- .../Windows/Secur32/ContextAttribute.netfx.cs | 2 +- .../Windows/Secur32/CredHandle.netfx.cs | 2 +- .../Interop/Windows/Secur32/Secur32.netfx.cs | 2 +- .../Sni/SniNativeMethodsArm64.netfx.cs | 2 +- .../Sni/SniNativeMethodsNotSupported.netfx.cs | 2 +- .../Windows/Sni/SniNativeMethodsX64.netfx.cs | 2 +- .../Windows/Sni/SniNativeMethodsX86.netfx.cs | 2 +- ...ependencyProcessDispatcherStorage.netfx.cs | 2 +- .../DbConnectionPoolIdentity.cs | 20 +++++++------------ .../Data/SqlClient/LocalAppContextSwitches.cs | 2 +- 13 files changed, 25 insertions(+), 24 deletions(-) diff --git a/build.proj b/build.proj index 79635218ff..330a76be56 100644 --- a/build.proj +++ b/build.proj @@ -153,6 +153,13 @@ + + + + + diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj index 7330072cac..ee748f7dca 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -1056,7 +1056,7 @@ Resources\Strings.resx - Microsoft.Data.SqlCLient.Resources.Strings.resources + Microsoft.Data.SqlClient.Resources.Strings.resources ResXFileCodeGenerator Strings.Designer.cs System diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Kernel32/Kernel32Safe.netfx.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Kernel32/Kernel32Safe.netfx.cs index 1ab634a0d6..156d16dbd1 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Kernel32/Kernel32Safe.netfx.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Kernel32/Kernel32Safe.netfx.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if NETFRAMEWORK && _WINDOWS +#if NETFRAMEWORK using System; using System.Runtime.InteropServices; diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Secur32/ContextAttribute.netfx.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Secur32/ContextAttribute.netfx.cs index 85fe936600..109561c967 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Secur32/ContextAttribute.netfx.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Secur32/ContextAttribute.netfx.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if _WINDOWS +#if NETFRAMEWORK namespace Interop.Windows.Secur32 { diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Secur32/CredHandle.netfx.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Secur32/CredHandle.netfx.cs index f9c9a9d1d9..c410674bc2 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Secur32/CredHandle.netfx.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Secur32/CredHandle.netfx.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if NETFRAMEWORK && _WINDOWS +#if NETFRAMEWORK using System; using System.Runtime.InteropServices; diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Secur32/Secur32.netfx.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Secur32/Secur32.netfx.cs index 1573b015ed..55a391c79b 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Secur32/Secur32.netfx.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Secur32/Secur32.netfx.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if NETFRAMEWORK && _WINDOWS +#if NETFRAMEWORK using System; using System.Runtime.InteropServices; 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 c39c1dbefa..7839a047cd 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 @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if NETFRAMEWORK && _WINDOWS +#if NETFRAMEWORK using System; using System.Runtime.InteropServices; 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 0d8600f193..7139ee0b08 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 @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if NETFRAMEWORK && _WINDOWS +#if NETFRAMEWORK using System; using System.Runtime.InteropServices; 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 0849e1a22d..e899250786 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 @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if NETFRAMEWORK && _WINDOWS +#if NETFRAMEWORK using System; using System.Runtime.InteropServices; 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 270a522aa6..4c022821dd 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 @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if NETFRAMEWORK && _WINDOWS +#if NETFRAMEWORK using System; using System.Runtime.InteropServices; diff --git a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SqlDependencyProcessDispatcherStorage.netfx.cs b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SqlDependencyProcessDispatcherStorage.netfx.cs index 19d8b261c3..dddfcb5e07 100644 --- a/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SqlDependencyProcessDispatcherStorage.netfx.cs +++ b/src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SqlDependencyProcessDispatcherStorage.netfx.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if NETFRAMEWORK && _WINDOWS +#if NETFRAMEWORK using System; using System.Diagnostics; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/DbConnectionPoolIdentity.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/DbConnectionPoolIdentity.cs index 725ba5dc4f..7eca7bd0f6 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/DbConnectionPoolIdentity.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/DbConnectionPoolIdentity.cs @@ -93,19 +93,13 @@ private static DbConnectionPoolIdentity GetCurrentManaged() : $@"{domainString}\{Environment.UserName}"; var lastIdentity = s_lastIdentity; - - DbConnectionPoolIdentity current; - if (lastIdentity != null && - lastIdentity._sidString == sidString && - !lastIdentity._isRestricted && - !lastIdentity._isNetwork) - { - current = lastIdentity; - } - else - { - current = new DbConnectionPoolIdentity(sidString, isRestricted: false, isNetwork: false); - } + + DbConnectionPoolIdentity current = lastIdentity != null && + lastIdentity._sidString == sidString && + !lastIdentity._isRestricted && + !lastIdentity._isNetwork + ? lastIdentity + : new DbConnectionPoolIdentity(sidString, isRestricted: false, isNetwork: false); s_lastIdentity = current; return current; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs index 23a40a4df7..f507c3a18f 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs @@ -457,7 +457,7 @@ public static bool UseManagedNetworking } #else /// - /// .NET Core on Unix does not support the natuve SNI, so this will always be true. + /// .NET Core on Unix does not support the native SNI, so this will always be false. /// public const bool UseManagedNetworking = false; #endif From deda198fbc6c4d4b2e61463af3ad247d5e076b05 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Wed, 26 Nov 2025 14:06:52 -0600 Subject: [PATCH 33/36] Fix file inclusion --- .../netcore/src/Microsoft.Data.SqlClient.csproj | 4 ++-- ...r.cs => NativeSspiContextProvider.windows.cs} | 16 ++++++++++++---- .../SSPI/NegotiateSspiContextProvider.cs | 4 ++++ .../SSPI/SspiAuthenticationParameters.cs | 6 +++++- .../Data/SqlClient/SSPI/SspiContextProvider.cs | 6 +++++- ...cs => TdsParserStateObjectFactory.windows.cs} | 5 ++++- .../Data/SqlTypes/SqlFileStream.windows.cs | 4 ++++ 7 files changed, 36 insertions(+), 9 deletions(-) rename src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/{NativeSspiContextProvider.cs => NativeSspiContextProvider.windows.cs} (88%) rename src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/{TdsParserStateObjectFactory.Windows.cs => TdsParserStateObjectFactory.windows.cs} (99%) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj index ee748f7dca..52fccaa43a 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -926,8 +926,8 @@ Microsoft\Data\SqlClient\SqlUtil.cs - - Microsoft\Data\SqlClient\SSPI\NativeSspiContextProvider.cs + + Microsoft\Data\SqlClient\SSPI\NativeSspiContextProvider.windows.cs Microsoft\Data\SqlClient\SSPI\NegotiateSspiContextProvider.cs 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.windows.cs similarity index 88% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NativeSspiContextProvider.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NativeSspiContextProvider.windows.cs index 45260bcd93..b6d65d4452 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NativeSspiContextProvider.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NativeSspiContextProvider.windows.cs @@ -1,4 +1,10 @@ -using System; +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#if _WINDOWS + +using System; using System.Buffers; using System.Diagnostics; @@ -14,7 +20,7 @@ internal sealed class NativeSspiContextProvider : SspiContextProvider private static bool s_fSSPILoaded; // variable to hold max SSPI data size, keep for token from server - private volatile static uint s_maxSSPILength; + private static volatile uint s_maxSSPILength; private protected override void Initialize() { @@ -53,9 +59,10 @@ private void LoadSSPILibrary() protected override bool GenerateContext(ReadOnlySpan incomingBlob, IBufferWriter outgoingBlobWriter, SspiAuthenticationParameters authParams) { -#if NET + #if NET Debug.Assert(_physicalStateObj.SessionHandle.Type == SessionHandle.NativeHandleType); -#endif + #endif + SNIHandle handle = _physicalStateObj.SessionHandle.NativeHandle; // This must start as the length of the input, but will be updated by the call to SNISecGenClientContext to the written length @@ -79,3 +86,4 @@ protected override bool GenerateContext(ReadOnlySpan incomingBlob, IBuffer } } +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NegotiateSspiContextProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NegotiateSspiContextProvider.cs index b9b6cbf36e..5971d48409 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NegotiateSspiContextProvider.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/NegotiateSspiContextProvider.cs @@ -1,3 +1,7 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + #if NET using System; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/SspiAuthenticationParameters.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/SspiAuthenticationParameters.cs index dce0858360..b82e779463 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/SspiAuthenticationParameters.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/SspiAuthenticationParameters.cs @@ -1,4 +1,8 @@ -#nullable enable +// 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 { 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 f70e2e8a12..49ceebdadd 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 @@ -1,4 +1,8 @@ -using System; +// 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.Connection; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObjectFactory.Windows.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObjectFactory.windows.cs similarity index 99% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObjectFactory.Windows.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObjectFactory.windows.cs index 2c8335d91f..eed5187596 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObjectFactory.Windows.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObjectFactory.windows.cs @@ -2,8 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#if _WINDOWS + #if NET -using System; using Microsoft.Data.SqlClient.ManagedSni; #endif @@ -70,3 +71,5 @@ internal TdsParserStateObject CreateSessionObject(TdsParser tdsParser, TdsParser } } } + +#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlTypes/SqlFileStream.windows.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlTypes/SqlFileStream.windows.cs index 09e2ed52b8..9338cf03b1 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlTypes/SqlFileStream.windows.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlTypes/SqlFileStream.windows.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. +#if _WINDOWS + using System; using System.ComponentModel; using System.Diagnostics; @@ -961,3 +963,5 @@ private void ThrowIfDisposed() #endregion } } + +#endif From 6682db110a03fd259e5497d75a1cef26a0af041f Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Wed, 26 Nov 2025 14:12:56 -0600 Subject: [PATCH 34/36] Fix "unreachable code detected" issue in unix build --- .../Data/SqlClient/LocalAppContextSwitches.cs | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs index f507c3a18f..e84c44b43d 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs @@ -27,13 +27,17 @@ private enum Tristate : byte private const string TruncateScaledDecimalString = @"Switch.Microsoft.Data.SqlClient.TruncateScaledDecimal"; private const string IgnoreServerProvidedFailoverPartnerString = @"Switch.Microsoft.Data.SqlClient.IgnoreServerProvidedFailoverPartner"; private const string EnableUserAgentString = @"Switch.Microsoft.Data.SqlClient.EnableUserAgent"; -#if NET + + #if NET private const string GlobalizationInvariantModeString = @"System.Globalization.Invariant"; private const string GlobalizationInvariantModeEnvironmentVariable = "DOTNET_SYSTEM_GLOBALIZATION_INVARIANT"; + + #if _WINDOWS private const string UseManagedNetworkingOnWindowsString = "Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows"; -#else + #endif + #else private const string DisableTnirByDefaultString = @"Switch.Microsoft.Data.SqlClient.DisableTNIRByDefaultInConnectionString"; -#endif + #endif // this field is accessed through reflection in tests and should not be renamed or have the type changed without refactoring NullRow related tests private static Tristate s_legacyRowVersionNullBehavior; @@ -48,12 +52,16 @@ private enum Tristate : byte private static Tristate s_truncateScaledDecimal; private static Tristate s_ignoreServerProvidedFailoverPartner; private static Tristate s_enableUserAgent; -#if NET + + #if NET private static Tristate s_globalizationInvariantMode; + + #if _WINDOWS private static Tristate s_useManagedNetworking; -#else + #endif + #else private static Tristate s_disableTnirByDefault; -#endif + #endif #if NET static LocalAppContextSwitches() @@ -459,14 +467,14 @@ public static bool UseManagedNetworking /// /// .NET Core on Unix does not support the native SNI, so this will always be false. /// - public const bool UseManagedNetworking = false; + public static bool UseManagedNetworking => false; #endif #else /// /// .NET Framework does not support the managed SNI, so this will always be false. /// - public const bool UseManagedNetworking = false; + public static bool UseManagedNetworking => false; #endif #if NETFRAMEWORK From d8a4c475ae899ea2dadc28d70e8b10d8ffbf46e8 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Mon, 1 Dec 2025 13:49:58 -0600 Subject: [PATCH 35/36] Addressing comments from @paulmedynski --- .../netcore/src/Microsoft.Data.SqlClient.csproj | 4 ++-- .../netfx/src/Microsoft.Data.SqlClient.csproj | 2 +- .../src/Microsoft.Data.SqlClient.csproj | 4 ++-- .../src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj index 52fccaa43a..8aa5b5295e 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -41,8 +41,8 @@ - _UNIX - _WINDOWS + $(DefineConstants),_UNIX + $(DefineConstants),_WINDOWS diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj index b3d9e77333..ade3d9fc07 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj @@ -103,7 +103,7 @@ - _WINDOWS + $(DefineConstants),_WINDOWS diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/src/Microsoft.Data.SqlClient.csproj index 5a96567e7f..6fb8a8e509 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/src/Microsoft.Data.SqlClient.csproj @@ -17,8 +17,8 @@ - _UNIX - _WINDOWS + $(DefineConstants),_UNIX + $(DefineConstants),_WINDOWS diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs index e84c44b43d..a12587411c 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs @@ -465,9 +465,9 @@ public static bool UseManagedNetworking } #else /// - /// .NET Core on Unix does not support the native SNI, so this will always be false. + /// .NET Core on Unix does not support the native SNI, so this will always be true. /// - public static bool UseManagedNetworking => false; + public static bool UseManagedNetworking => true; #endif #else From 2e2de79dfb92b7d27a6420c7517ad24f69f7d15f Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Tue, 2 Dec 2025 13:45:19 -0600 Subject: [PATCH 36/36] Add OS constants to test common project, wrap app context switches that are platform specific in Fix case-sensitivity issues in netfx project --- .../netfx/src/Microsoft.Data.SqlClient.csproj | 28 ++++---- .../src/Microsoft.Data.SqlClient.csproj | 1 - .../tests/Common/Common.csproj | 7 +- .../Common/LocalAppContextSwitchesHelper.cs | 66 ++++++++++++++----- 4 files changed, 69 insertions(+), 33 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj index ade3d9fc07..c4fb2c7071 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj @@ -489,8 +489,8 @@ Microsoft\Data\SqlClient\LocalAppContextSwitches.cs - - Microsoft\Data\SqlClient\LocalDb\LocalDbApi.Windows.cs + + Microsoft\Data\SqlClient\LocalDb\LocalDbApi.windows.cs Microsoft\Data\SqlClient\LocalDb\LocalDbConfigurationSection.netfx.cs @@ -726,11 +726,11 @@ Microsoft\Data\SqlClient\SqlColumnEncryptionCertificateStoreProvider.cs - - Microsoft\Data\SqlClient\SqlColumnEncryptionCngProvider.Windows.cs + + Microsoft\Data\SqlClient\SqlColumnEncryptionCngProvider.windows.cs - - Microsoft\Data\SqlClient\SqlColumnEncryptionCspProvider.Windows.cs + + Microsoft\Data\SqlClient\SqlColumnEncryptionCspProvider.windows.cs Microsoft\Data\SqlClient\SqlColumnEncryptionEnclaveProvider.cs @@ -939,8 +939,8 @@ Microsoft\Data\SqlClient\TdsParser.cs - - Microsoft\Data\SqlClient\TdsParserSafeHandles.Windows.cs + + Microsoft\Data\SqlClient\TdsParserSafeHandles.windows.cs Microsoft\Data\SqlClient\TdsParserStateObject.cs @@ -948,11 +948,11 @@ Microsoft\Data\SqlClient\TdsParserStateObject.Multiplexer.cs - - Microsoft\Data\SqlClient\TdsParserStateObjectFactory.Windows.cs + + Microsoft\Data\SqlClient\TdsParserStateObjectFactory.windows.cs - - Microsoft\Data\SqlClient\TdsParserStateObjectNative.Windows.cs + + Microsoft\Data\SqlClient\TdsParserStateObjectNative.windows.cs Microsoft\Data\SqlClient\TdsParserStaticMethods.cs @@ -990,8 +990,8 @@ Microsoft\Data\SqlDbTypeExtensions.cs - - Microsoft\Data\SqlTypes\SqlFileStream.Windows.cs + + Microsoft\Data\SqlTypes\SqlFileStream.windows.cs Microsoft\Data\SqlTypes\SqlJson.cs diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/src/Microsoft.Data.SqlClient.csproj index 6fb8a8e509..e4e71f0b7f 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/src/Microsoft.Data.SqlClient.csproj @@ -10,7 +10,6 @@ $(OS) - diff --git a/src/Microsoft.Data.SqlClient/tests/Common/Common.csproj b/src/Microsoft.Data.SqlClient/tests/Common/Common.csproj index 4133622d20..ffcd2869f9 100644 --- a/src/Microsoft.Data.SqlClient/tests/Common/Common.csproj +++ b/src/Microsoft.Data.SqlClient/tests/Common/Common.csproj @@ -1,5 +1,4 @@  - Common netfx @@ -11,6 +10,12 @@ true + + + $(DefineConstants),_UNIX + $(DefineConstants),_WINDOWS + + diff --git a/src/Microsoft.Data.SqlClient/tests/Common/LocalAppContextSwitchesHelper.cs b/src/Microsoft.Data.SqlClient/tests/Common/LocalAppContextSwitchesHelper.cs index 0f7b994e5e..1798e1fcf4 100644 --- a/src/Microsoft.Data.SqlClient/tests/Common/LocalAppContextSwitchesHelper.cs +++ b/src/Microsoft.Data.SqlClient/tests/Common/LocalAppContextSwitchesHelper.cs @@ -33,10 +33,16 @@ public sealed class LocalAppContextSwitchesHelper : IDisposable private readonly PropertyInfo _truncateScaledDecimalProperty; private readonly PropertyInfo _ignoreServerProvidedFailoverPartner; private readonly PropertyInfo _enableUserAgent; -#if NET + + #if NET private readonly PropertyInfo _globalizationInvariantModeProperty; + #endif + + #if NET && _WINDOWS private readonly PropertyInfo _useManagedNetworkingProperty; - #else + #endif + + #if NETFRAMEWORK private readonly PropertyInfo _disableTnirByDefaultProperty; #endif @@ -63,12 +69,18 @@ public sealed class LocalAppContextSwitchesHelper : IDisposable private readonly Tristate _ignoreServerProvidedFailoverPartnerOriginal; private readonly FieldInfo _enableUserAgentField; private readonly Tristate _enableUserAgentOriginal; -#if NET + + #if NET private readonly FieldInfo _globalizationInvariantModeField; private readonly Tristate _globalizationInvariantModeOriginal; + #endif + + #if NET && _WINDOWS private readonly FieldInfo _useManagedNetworkingField; private readonly Tristate _useManagedNetworkingOriginal; - #else + #endif + + #if NETFRAMEWORK private readonly FieldInfo _disableTnirByDefaultField; private readonly Tristate _disableTnirByDefaultOriginal; #endif @@ -169,15 +181,19 @@ void InitProperty(string name, out PropertyInfo property) "EnableUserAgent", out _enableUserAgent); -#if NET + #if NET InitProperty( "GlobalizationInvariantMode", out _globalizationInvariantModeProperty); - + #endif + + #if NET && _WINDOWS InitProperty( "UseManagedNetworking", out _useManagedNetworkingProperty); - #else + #endif + + #if NETFRAMEWORK InitProperty( "DisableTnirByDefault", out _disableTnirByDefaultProperty); @@ -253,17 +269,21 @@ void InitField(string name, out FieldInfo field, out Tristate value) out _enableUserAgentField, out _enableUserAgentOriginal); -#if NET + #if NET InitField( "s_globalizationInvariantMode", out _globalizationInvariantModeField, out _globalizationInvariantModeOriginal); - + #endif + + #if NET && _WINDOWS InitField( "s_useManagedNetworking", out _useManagedNetworkingField, out _useManagedNetworkingOriginal); - #else + #endif + + #if NETFRAMEWORK InitField( "s_disableTnirByDefault", out _disableTnirByDefaultField, @@ -339,15 +359,19 @@ void RestoreField(FieldInfo field, Tristate value) _enableUserAgentField, _enableUserAgentOriginal); -#if NET + #if NET RestoreField( _globalizationInvariantModeField, _globalizationInvariantModeOriginal); - + #endif + + #if NET && _WINDOWS RestoreField( _useManagedNetworkingField, _useManagedNetworkingOriginal); - #else + #endif + + #if NETFRAMEWORK RestoreField( _disableTnirByDefaultField, _disableTnirByDefaultOriginal); @@ -450,7 +474,7 @@ public bool EnableUserAgent get => (bool)_enableUserAgent.GetValue(null); } -#if NET + #if NET /// /// Access the LocalAppContextSwitches.GlobalizationInvariantMode property. /// @@ -458,7 +482,9 @@ public bool GlobalizationInvariantMode { get => (bool)_globalizationInvariantModeProperty.GetValue(null); } + #endif + #if NET && _WINDOWS /// /// Access the LocalAppContextSwitches.UseManagedNetworking property. /// @@ -466,7 +492,9 @@ public bool UseManagedNetworking { get => (bool)_useManagedNetworkingProperty.GetValue(null); } - #else + #endif + + #if NETFRAMEWORK /// /// Access the LocalAppContextSwitches.DisableTnirByDefault property. /// @@ -580,7 +608,7 @@ public Tristate EnableUserAgentField set => SetValue(_enableUserAgentField, value); } -#if NET + #if NET /// /// Get or set the LocalAppContextSwitches.GlobalizationInvariantMode switch value. /// @@ -589,7 +617,9 @@ public Tristate GlobalizationInvariantModeField get => GetValue(_globalizationInvariantModeField); set => SetValue(_globalizationInvariantModeField, value); } + #endif + #if NET && _WINDOWS /// /// Get or set the LocalAppContextSwitches.UseManagedNetworking switch value. /// @@ -598,7 +628,9 @@ public Tristate UseManagedNetworkingField get => GetValue(_useManagedNetworkingField); set => SetValue(_useManagedNetworkingField, value); } - #else + #endif + + #if NETFRAMEWORK /// /// Get or set the LocalAppContextSwitches.DisableTnirByDefault switch /// value.